How can I preload a sound?

I have an iPhone app where I play a sound when the user is taking a test. Works great except for the first time the sound plays when there is a delay, I assume loading the sound into memory. How can I preload the sound? Here is my code for the sound:

- (void)doBuzz:(id)sender {
SystemSoundID buzzsoundID;
NSString *buzzsoundFile = [[NSBundle mainBundle]
                           pathForResource:@"buzz" ofType:@"caf"];

AudioServicesCreateSystemSoundID((CFURLRef)
                                 [NSURL fileURLWithPath:buzzsoundFile]
                                 , &buzzsoundID);
AudioServicesPlaySystemSound(buzzsoundID);

}

  • iOS app with hardware integration
  • iOS multiline label in Interface builder
  • How does one compare one image to another to see if they are similar by a certain percentage, on the iPhone?
  • Unwanted scrolling when animating zoomScale in UIScrollView
  • How to convert WAV file to M4A?
  • iPhone Set Tint Color of Back Bar Button Item
  • 3 Solutions Collect From Internet About “How can I preload a sound?”

    Look at AVAudioPlayer, which you can setup and re-use. But more importantly, when you set it up, you can tell it to “prepare to play”, which pre-loads the sound into memory. So when you actually tell the player to play, it plays immediately. I conveniently, recently wrote this method for something, which creates and returns an AVAudioPlayer object:

    +(AVAudioPlayer *)playerForFile:(NSString *)fileName
    {
        NSString *filePath = [[NSBundle mainBundle] pathForResource:fileName ofType:@"caf"];
        NSURL *url = [NSURL fileURLWithPath:filePath];
        NSData *soundData = [NSData dataWithContentsOfURL:url];
        NSError *error = nil;
        AVAudioPlayer *player = [[[AVAudioPlayer alloc] initWithData:soundData error:&error] autorelease];
        if (error)
            NSLog(@"error creating player for %@: %@", fileName, [error localizedDescription]);
    
        return (error ? nil : player);
    }
    

    Somewhere in your app you might setup a player object like so:

    AVAudioPlayer *buzzSoundPlayer = [MyClass playerForFile:@"buzz"];
    if (buzzSoundPlayer) {
        [buzzsoundPlayer prepareToPlay];
    }
    

    When you want to play the sound:

    [buzzSoundPlayer setCurrentTime:0];
    [buzzSoundPlayer play];
    

    You have to set the current time to 0, i.e. the beginning of the sound file, each time you play it because when the sound finishes playing, the “current time” is at the end. So subsequent requests to play it would play nothing. So we set the current time back to the beginning.

    You can setup a delegate for your player too, and be notified via a delegate method when a sound finishes playing. You could reset the current time to 0 there, alternatively.

    You can read all about AVAudioPlayer, and AVFoundation, in Apple’s documentation.

    I fixed my sound delay problem by moving my declaration for the SystemSoundID into the .h file of my UIViewController and then set the NSString and called AudioServicesCreateSystemSoundID from ViewDidLoad. Then when I wanted to play the sound, rather than calling the doBuzz method I simply replaced that with AudioServicesPlaySystemSound.

    Preload the sound using performSelectorInBackground:@selector(<SELECTOR>).

    You also could load file on application start or somewhere before, not actually on touch.