
Question:
I'm attempting to play a sound using AVAudioPlayer. Should be simple, but I'm seeing some odd results.
Code:
NSString *path = [[NSBundle mainBundle] pathForResource:@"pop" ofType:@"wav"];
NSURL *url = [NSURL fileURLWithPath:path];
AVAudioPlayer *sound = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[sound play];
[sound release];
What I'm seeing is that the sound doesn't play when using the app normally.
It plays <strong>only</strong> if I step through the code using the debugger, it doesn't play when executing any other way...
I'm not creating any new threads or run loops within my app, so this should all be running on the main thread, at least [NSThread isMainThread]
returns true.
Anyone got any ideas as to what is going on here?
Answer1:AVAudioPlayer's play
method is asynchronous, so you're starting to play the sound and then immediately releasing it! That's why it works when you step through it in the debugger -- you're giving it time to play before killing it. What you want to do is implement AVAudioPlayerDelegate's - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
method and release the audio player there, after the sound is done playing.
papajohn is right you should do it like this
Have a class level variable of audio player like
AVAudioPlayer *classLevelPlayer;
synthesize this object. and in the call to player method
-(void)playTheSong{
if(classLevelPlayer!=nil){
[classLevelPlayer stop];
[self setClassLevelPlayer:nil];
}
NSString *path = [[NSBundle mainBundle] pathForResource:@"pop" ofType:@"wav"];
NSURL *url = [NSURL fileURLWithPath:path];
AVAudioPlayer *sound = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
if(sound){
[self setClassLevelPlayer:sound];
[classLevelPlayer play];
}
[sound release];
}
and in
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
[self setClassLevelPlayer:nil];
}
Hope this helps.