This issue has shown up in several other question here on SO:
Slow start for AVAudioPlayer the first time a sound is played
Delay in playing sounds using AVAudioPlayer
I've tried implementing the fixes suggested but none of them are solving my problem. My application presents the user with a grid of objects to touch, when an object is touched a sound is played. This works great except on the initial touch there is a delay of ~2 seconds.
To get around this I initialize my audio player with a dummy aiff file:
- (void)viewDidLoad{
NSString *soundFile = [Card loadCardSoundPath:@"dummy"];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:
[NSURL fileURLWithPath:soundFile] error:nil];
self.audioPlayer = player;
[audioPlayer setDelegate:self];
[audioPlayer prepareToPlay];
// [audioPlayer play];
[player release];
...
[super viewDidLoad];
}
Then when an object is touched I call:
NSString *soundFile = [Card loadCardSoundPath:name];
if (soundFile != nil){
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:
[NSURL fileURLWithPath:soundFile] error:nil];
self.audioPlayer = player;
[self.audioPlayer setDelegate:self];
[self.audioPlayer prepareToPlay];
[self.audioPlayer play];
[player release];
}
The behavior i'm observing is this: I observe the audio delay when I click the first object if I create a dummy audio player and call prepareToPlay but not play. However if I call play on the dummy audio player then I don't get the delay on the initial object but the view load gets delayed by 2 seconds.
Is there a way to get around this? Should I simply create an NSArray of AVAudioPlayers on load and tell them all to prepare to play, and then just call play when the object is clicked?
Sometimes it can help to let viewDidLoad
return by spooling off initialization like that using peformSelector:withObject:afterDelay:
. For example:
- (void)viewDidLoad{
// initialization ...
[super viewDidLoad];
[self performSelector:@selector(primeAudioPlayer) withObject:nil afterDelay:0.1];
}
-(void)primeAudioPlayer {
NSString *soundFile = [Card loadCardSoundPath:@"dummy"];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:
[NSURL fileURLWithPath:soundFile] error:nil];
[audioPlayer prepareToPlay];
[player release];
}