iphone piano app doesnt play notes as expected - iphone

Im making a piano test app, all the keyboard is sounding now playing notes that I've recorded using garage band, but I have some problems:
-the notes are 5 seconds long (minimum time of garage band), so a note cannot be repeated, I have to wait until the actual note about 1 sec sound and then silence for about 4 sec,
also sometimes notes cannot be played as expected,
Im using AVFoundation.framework,,
tried with AudioToolbox.framework, but it gives problems with my 4.1 ipod touch (doesnt work!!) but in the simulator looks fine
I also checked OpenAL, and ObjectAL, but seem a bit to much for just playing notes??
here the code
#import "pianoViewController.h"
#implementation pianoViewController
#synthesize myMusic;
#synthesize myMusic2;
#synthesize myMusic3;
#synthesize myMusic4;
#synthesize myMusic5;
#synthesize myMusic6;
#synthesize myMusic7;
#synthesize myMusic8;
#synthesize myMusic9;
#synthesize myMusic10;
#synthesize myMusic11;
#synthesize myMusic12;
-(IBAction)Play{
[myMusic play];
}
-(IBAction)Play2{
[myMusic2 play];
}
.
.
.
- (void)viewDidLoad {
NSString *pathToMusicFile = [[NSBundle mainBundle] pathForResource:#"c3" ofType:#"aif"];
myMusic = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile] error:NULL];
myMusic.delegate = self;
myMusic.numberOfLoops = 0;
myMusic.volume = 1.0;
NSString *pathToMusicFile2 = [[NSBundle mainBundle] pathForResource:#"c#" ofType:#"aif"];
myMusic2 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile2] error:NULL];
myMusic2.delegate = self;
myMusic2.numberOfLoops = 0;
myMusic2.volume = 1.0;
NSString *pathToMusicFile3 = [[NSBundle mainBundle] pathForResource:#"d" ofType:#"aif"];
myMusic3 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile3] error:NULL];
myMusic3.delegate = self;
myMusic3.numberOfLoops = 0;
myMusic3.volume = 1.0;
//[super viewDidLoad];
NSString *pathToMusicFile4 = [[NSBundle mainBundle] pathForResource:#"d#" ofType:#"aif"];
myMusic4 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile4] error:NULL];
myMusic4.delegate = self;
myMusic4.numberOfLoops = 0;
myMusic4.volume = 1.0;
//[super viewDidLoad];
NSString *pathToMusicFile5 = [[NSBundle mainBundle] pathForResource:#"e" ofType:#"aif"];
myMusic5 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile5] error:NULL];
myMusic5.delegate = self;
myMusic5.numberOfLoops = 0;
myMusic5.volume = 1.0;
NSString *pathToMusicFile6 = [[NSBundle mainBundle] pathForResource:#"f" ofType:#"aif"];
myMusic6 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile6] error:NULL];
myMusic6.delegate = self;
myMusic6.numberOfLoops = 0;
myMusic6.volume = 1.0;
NSString *pathToMusicFile7 = [[NSBundle mainBundle] pathForResource:#"f#" ofType:#"aif"];
myMusic7 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile7] error:NULL];
myMusic7.delegate = self;
myMusic7.numberOfLoops = 0;
myMusic7.volume = 1.0;
NSString *pathToMusicFile8 = [[NSBundle mainBundle] pathForResource:#"g" ofType:#"aif"];
myMusic8 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile8] error:NULL];
myMusic8.delegate = self;
myMusic8.numberOfLoops = 0;
myMusic8.volume = 1.0;
NSString *pathToMusicFile9 = [[NSBundle mainBundle] pathForResource:#"g#" ofType:#"aif"];
myMusic9 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile9] error:NULL];
myMusic9.delegate = self;
myMusic9.numberOfLoops = 0;
myMusic9.volume = 1.0;
NSString *pathToMusicFile10 = [[NSBundle mainBundle] pathForResource:#"a" ofType:#"aif"];
myMusic10 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile10] error:NULL];
myMusic10.delegate = self;
myMusic10.numberOfLoops = 0;
myMusic10.volume = 1.0;
NSString *pathToMusicFile11 = [[NSBundle mainBundle] pathForResource:#"a#" ofType:#"aif"];
myMusic11 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile11] error:NULL];
myMusic11.delegate = self;
myMusic11.numberOfLoops = 0;
myMusic11.volume = 1.0;
NSString *pathToMusicFile12 = [[NSBundle mainBundle] pathForResource:#"b" ofType:#"aif"];
myMusic12 = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile12] error:NULL];
myMusic12.delegate = self;
myMusic12.numberOfLoops = 0;
myMusic12.volume = 1.0;
[super viewDidLoad];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
So is there a way so that i can use AVFoundation to play multiple notes quickly? (almost overlapping like with AudioToolbox)
or what do you suggest?
thank you!

Instead of shoe-horning in a fix for something that shouldn't be a problem, I suggest instead that you use some audio editing software that does not have a minimum track length restriction.
One such example, which is Mac compatible and free, is Audacity: http://audacity.sourceforge.net/
Also, OpenAL is perfect for playing lots of short sounds, potentially overlapping. I think you can have 32 playing at once if you like.

Related

UIButtons event Touch up Inside not work properly?

My question is little abmigious ,thats why I posted all my code,so I request to every one please test all this code before giving me the Answer.Thanx
In my application i create all UIButtons programmatically and then save all these UIButtons in NSMutableArray. Here is my code:-
-(void)button:(id)sender
{
int btnn = 0;
int spacex = 152;
int spacey=20;
int k=0;
saveBtn = [[NSMutableArray alloc] init];
for (int i=0; i<48; i++)
{
if (btnn>6)
{
spacey=spacey+25;
spacex = 152;
btnn = 0;
}
else
{
btnn++ ;
k++;
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(spacex, spacey, 25.0, 25.0);
int idx;
idx = arc4random()%[arr count];
NSString* titre1 = [arr objectAtIndex:idx];
[btn setTitle: titre1 forState: UIControlStateNormal];
[btn setTitleColor: [UIColor yellowColor] forState: UIControlStateNormal];
[btn.titleLabel setFont:[UIFont fontWithName:#"TimesNewRomanPS-BoldMT" size:22.0]];
spacex = spacex + 25;
btn.tag=k;
[btn addTarget:self action:#selector(aMethod:)forControlEvents:UIControlEventTouchUpInside];
[saveBtn addObject:btn];
[self.view addSubview:btn];
}
}
}
Now in (aMethod:) I add click sound on Each UIButton TouchUpInside event. Here is my code.
- (void)aMethod:(id)sender
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"button-17" ofType:#"wav"];
AVAudioPlayer* theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate=self;
[theAudio play];
}
Every thing work fine in start of my application , but continiously clicking the UIButtons approximatilly after 100 clicks i hear no sound of click and when i click on Next UIButtons touchup inside event its crash.Can any body help me in this issue.Thanx
app due to uncaught exception NSInternalInconsistencyException, reason: Could not load NIB in bundle: NSBundle </Users/moon/Library/Application Support/iPhone Simulator/4.1/Applications/3E14E5D6-4D1B-4DAC-A2B9-07667E99C399/soundtesting.app‌​> (loaded) with name secondclass
Ah, yes. What we have here is a failure to understand log messages. Your UIButton, which I can only assume pushes a new view onto the stack, is referencing a NIB that simply doesn't exist. It's a naming issue, not a button issue. Most likely, I would check for any calls to -initWithNibName: and see if your NIB really is named "secondclass.". Remember, iOS file names are CaSe SeNsITive.
//.h
...
#property (nonatomic, retain) AVAudioPlayer * player;
//.m
-(void)viewDidLoad
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"button-17" ofType:#"wav"];
player=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
player.delegate=self;
//in MRC, use [path release];
}
-(void)someMethod:(id)sender
{
[player play];
}
The reason might me memory leak for playing same audio these many times it may fill memory use this code for playing audio
- (id)initWithNibName:(NSString*)nibName bundle:(NSBundle*)nibBundleOrNil
{
if (self = [super initWithNibName:nibName bundle:nibBundleOrNil]) {
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"button-17" ofType:#"wav"];
theAudio = [AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:filePath] error:NULL];
}
return self;
}
- (IBAction)playSound
{
[theAudio play];
}
- (void)dealloc
{
[theAudio release];
[super dealloc];
}
You have a memory issue. When you do :
- (void)aMethod:(id)sender
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"button-17" ofType:#"wav"];
AVAudioPlayer* theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate=self;
[theAudio play];
}
1/ path is never released
2/ theAudio is never release
So you need to release theAudio in delegate method :
– audioPlayerDidFinishPlaying:successfully:
And you need to release path like this :
- (void)aMethod:(id)sender
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"button-17" ofType:#"wav"];
AVAudioPlayer* theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate=self;
[theAudio play];
[path release];
}
I think your problem should be solved.
I test your code . Changes in your aMethod following code. Though this I can get tag value.
- (void)aMethod:(id)sender
{
UIButton *btn=(UIButton *)sender;
NSLog(#"\n\n\nselectedbutton tag === %d \n\n\n",btn.tag );
NSString *path = [[NSBundle mainBundle] pathForResource:#"button-17" ofType:#"wav"];
NSURL *url = [[NSURL alloc] initFileURLWithPath:path];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:NULL];
audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
[audioPlayer play];
}

Audio (mp3) file issue, file is not played at number of button press

I have set music file on button click in the memory game application.
Music is properly played, for some time but after the number of the buttons click looses the sound effect from the applcation.
-(void)setButtons_AsPerTheMatrixSelection
{
for ( i = 0 ; i < cv ; ++i )
{
for ( j = 0 ; j < ch ; ++j )
{
btnMatrix = [[[UIButton alloc] initWithFrame:CGRectMake(10+pw*j, 51+ph*i, width, height)] autorelease];
btnMatrix.tag = i*ch+j;
btnMatrix.userInteractionEnabled = TRUE;
bulImageStatus = FALSE;
[btnMatrix addTarget:self action:#selector(changeImage:) forControlEvents:UIControlEventTouchUpInside];
[btnMatrix setImage:imgDefaultBG forState:UIControlStateNormal];
[viewWithButtons addSubview:btnMatrix];
[arrButton addObject:btnMatrix];
}
}
}
-(void)changeImage:(id)sender
{
NSString *musicPath = [[NSBundle mainBundle] pathForResource:#"ding" ofType:#"mp3"];
if (musicPath)
TapSoud = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:musicPath] error:nil];
[TapSoud setDelegate:self];
[TapSoud prepareToPlay];
[TapSoud play];
}
This is working perfectly for number of presses but after certain click i am not able to play this button click tone.
what can be the issue & how can be solved this issue.
Is there any other way to play audio file?
Please suggest the appropriate solution.
Thanks.
AVAudioPlayer is alloced over and over but never released.
try this.
-(void)changeImage:(id)sender
{
NSString *musicPath = [[NSBundle mainBundle] pathForResource:#"ding" ofType:#"mp3"];
if (musicPath) {
if(TapSoud){ // TapSound ?
[TapSoud release];
TapSoud = nil;
}
TapSoud = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL
fileURLWithPath:musicPath] error:nil];
}
[TapSoud setDelegate:self];
[TapSoud prepareToPlay];
[TapSoud play];
}
Use same AVAudioPlayer refrence every time u play:
-(void)changeImage:(id)sender
{
NSString *musicPath = [[NSBundle mainBundle] pathForResource:#"ding" ofType:#"mp3"];
if (musicPath) {
if(!TapSoud){ // check TapSound has reference
TapSoud = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:musicPath] error:nil];
[TapSoud setDelegate:self]
}
else
{
NSNumber *time = [NSNumber numberWithDouble:0];
//NSTimeInterval interval = [time doubleValue];
[TapSoud playAtTime:[time doubleValue];// Smae Sound played at time 0:00
}
}
}

AVAudioPlayer leaks?

I've got a problem and don't know how to handle it. Tyring to build an app with sound and animation. It gives me a level 1 and then level 2 memory warning. I've tried build and analyze and i got all these potential leaks. If I release theAudio the sound won't play. Any hints?
Here is a part of the code and the leakes I've got
- (IBAction)playsound2
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"cat" ofType:#"mp3"];
AVAudioPlayer* theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
*- **Method returns an Objective-C object with a +1 retain count (owning reference)***
theAudio.delegate = self;
[theAudio play];
***- Object allocated on line 302 and stored into 'theAudio' is no longer referenced after this point and has a retain count of +1 (object leaked)***
cat1.hidden = 0;
cat.hidden = 1;
[cat1 startAnimating];
cat.center = cat1.center;
[self performSelector:#selector(loadAnimations) withObject:nil afterDelay:1.0];
catLabel.hidden = 0;
}
Here is the solution for the same problem asked so far.
- (AVAudioPlayer *)audioPlayerWithContentsOfFile:(NSString *)path {
NSData *audioData = [NSData dataWithContentsOfFile:path];
AVAudioPlayer *player = [AVAudioPlayer alloc];
if([player initWithData:audioData error:NULL]) {
[player autorelease];
} else {
[player release];
player = nil;
}
return player;
}
And for better idea you can follow this.
You have to state an instance variable for the AVAudioPlayer class instance.
//Instance variable:
{
AVAudioPlayer* theAudio;
}
- (IBAction)playsound2
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"cat" ofType:#"mp3"];
if (!theAudio ) {
theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
if (theAudio ) {
theAudio.delegate = self;
[theAudio play];
}
}
cat1.hidden = 0;
cat.hidden = 1;
[cat1 startAnimating];
cat.center = cat1.center;
[self performSelector:#selector(loadAnimations) withObject:nil afterDelay:1.0];
catLabel.hidden = 0;
}

Adjusting the size the volume, using the same uislider but for multiple sounds

I have 10 sounds in a view. And one uislider
This is the code for 1 of the sounds.
- (IBAction)oneSound:(id)sender; {
SystemSoundID soundID;
NSString *path = [[NSBundle mainBundle] pathForResource:#"1" ofType:#"mp3"];
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path],&soundID);
AudioServicesPlaySystemSound (soundID);
if (oneAudio) [oneAudio release];
NSError *error = nil;
oneAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&error];
if (error)
NSLog(#"%#",[error localizedDescription]);
oneAudio.delegate = self;
[oneAudio play];
}
- (void)viewDidLoad {
[volumeSlider addTarget:self action:#selector(updateVolume) forControlEvents:UIControlEventValueChanged];
[super viewDidLoad];
}
-(void)updateVolume {
[oneAudio, twoAudio, threeAudio, fourAudio, fiveAudio, sixAudio, sevenAudio, eightAudio, nineAudio, tenAudio, elevenAudio, twelveAudio, thirteenAudio, fourteenAudio, fifthteenAudio, sixteenAudio setVolume:volumeSlider.value];
}
This is the current method I've tried and it doesn't work. Thanks for the help
In updateVolume you can't call on multiple instances by listing them like that. What you should do is put all of these audio players into an array and loop through each and setVolume on each object in the array.

Bug in AVAudioPlayer class?

I'll keep it short and sweet - I'm building an application just for practice before I buy myself the iPhone Developer Program.
I'm experimenting with the AVFoundation.framework and I keep running into a bug which will only let me play the first sound I initialize in my code. Do you think any of you could help me out? Thanks in advance!! :)
view controller
-(IBAction)play {
if (segments.selectedSegmentIndex == 0) {
NSLog(#"Segment = 0");
NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle pathForResource:#"meow" ofType:#"wav"];
if (path != nil) {
NSURL *url = [NSURL fileURLWithPath:path];
AVAudioPlayer *player = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:NULL];
[player prepareToPlay];
[player play];
}
}
else if (segments.selectedSegmentIndex == 1) {
NSLog(#"Segment = 1");
NSBundle *bundle = [NSBundle mainBundle];
NSString *path2 = [bundle pathForResource:#"meowloud" ofType:#"wav"];
if (path2 != nil) {
NSURL *url2 = [NSURL fileURLWithPath:path2];
AVAudioPlayer *player2 = [[AVAudioPlayer alloc]initWithContentsOfURL:url2 error:NULL];
[player2 prepareToPlay];
[player2 play];
// [player2 release];
}
}
text1.textColor = [UIColor clearColor];
text2.textColor = [UIColor clearColor];
text3.textColor = [UIColor clearColor];
text4.textColor = [UIColor clearColor];
}
When this code gets executed, only the meow.wav is executed, no matter which segment is selected.
Your code has a couple of memory leaks. You allocate instances of AVAudioPlayer in your play method, but you never release those instances. See Cocoa's memory management qguidelines for details. Since the AVAudioPlayer instances need to remain in memory to play, the easiest solution is to add a member variable to your viewController class and set it up as a retain property.
For the sake of Don't Repeat Yourself (DRY), I would also suggest adding a method which encapsulates all of the code needed to play a single wav file.
Here is how I would write this view controller:
MyViewController.h
#interface MyViewController : UIViewController
{
AVAudioPlayer *player;
}
#property(nonatomic, retain) AVAudioPlayer *player;
- (void)playWavFile:(NSString *)fileName;
- (IBAction)play;
#end
MyViewController.m
#synthesize player;
- (void)dealloc {
[player release];
}
- (void)playWavFile:(NSString *)fileName {
NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle pathForResource:fileName ofType:#"wav"];
if (path != nil) {
AVAudioPlayer *newPlayer;
NSURL *url = [NSURL fileURLWithPath:path];
newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url
error:NULL];
[self setPlayer:newPlayer];
[newPlayer release];
[newPlayer prepareToPlay];
[newPlayer play];
}
}
- (IBAction)play {
if (segments.selectedSegmentIndex == 0) {
[self playWavFile:#"meow"];
}
else if (segments.selectedSegmentIndex == 1) {
[self playWavFile:#"meowloud"];
}
}