Hi!
I am making a counting game for kids. At the start the child is asked find a number of items, for example: "Can you find five bikes". This is all randomly put together from seperate arrays of sounds with parts of the sentence: "Can you find" + "5" + "bikes" =three seperate mp3s. When the child starts clicking on the items, they disappear and the voice counts up. "1", "2", "3","4", "5", and in the end "bikes".
I use the audioPlayerDidFinishPlaying: delegate method to put the sounds together and that works out fine ... most of the time. But sometimes the app crashes, with a "bad_access" error. After using NSZombie I got: -[AVAudioPlayer performSelector:withObject:]: message sent to deallocated instance
I think this is because either the audioplayer itself or the delegate is released prematurely.
I always use this function to play the sounds:
-(void)spillVoice:(NSString*) filnavn{
NSString *audioFilePath=[[NSBundle mainBundle] pathForResource:filnavn ofType:@"mp3"];
NSURL *audioFileURL=[NSURL fileURLWithPath:audioFilePath];
self.voicespiller=[[[AVAudioPlayer alloc] initWithContentsOfURL:audioFileURL error:nil] autorelease];
self.voicespiller.delegate=self;
[self.voicespiller prepareToPlay];
[self.voicespiller play];
NSLog(@"spiller lyden");
}
And here is the delegate (it performs different actions based on what sound has finnished):
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer*)which_player successfully:(BOOL)the_flag{
NSLog(@"ny lyd?");
[self.jenteBilde stopAnimating];
if(self.etterLyd==@"ingenting"){
NSLog(@"ingenting");
}
else if(self.etterLyd==@"lesobjekt"){
NSLog(@"lesobjekt");
self.etterLyd=@"ros";
[self spillVoice:[self.objektNedArray objectAtIndex: [self.objektnr intValue]]];
[self.jenteBilde startAnimating];
}
else if(self.etterLyd==@"introtall"){
NSLog(@"introtall");
self.etterLyd=@"introobjekt";
[self spillVoice:[self.telleOppArray objectAtIndex: [self.tilfeldig intValue]]];
[self.jenteBilde startAnimating];
}
else if(self.etterLyd==@"introobjekt"){
NSLog(@"introobjekt");
self.etterLyd=@"ingenting";
[self spillVoice:[self.objektOppArray objectAtIndex: [self.objektnr intValue]]];
[self.jenteBilde startAnimating];
}
else if(self.etterLyd==@"ros"){
NSLog(@"ros");
NSMutableArray *rosArray=[[NSMutableArray alloc] initWithObjects:@"TT_flott",@"TT_bravo",@"TT_fint",@"TT_du_er_kjempeflink",@"TT_hurra",@"TT_helt_riktig",nil];
int result=(arc4random() % (rosArray.count));
self.etterLyd=@"ingenting";
[self spillVoice:[rosArray objectAtIndex: result]];
[self.jenteBilde startAnimating];
}
}
It seems to me that the AVaudioplayers autorelease hits in too early, even though the sound has not yet finnished. I have tried not autoreleasing, and instead releasing explicitly in the delegate function. But the problem is that the sound doesnt always get to play to the end (when the child finds a new item before the voice has finnished reading)...
Can any of you shed any light on this. I would be very grateful!