Chris Hansen
Chris Hansen

Reputation: 8671

asynchronous sounds in iphone app

I use the following code to play the sounds in my app, but the problem is that it slows down the app. How can I make the sounds happen asynchronously without slowing down the actions?

SystemSoundID soundID;
NSString *soundFile = [[NSBundle mainBundle] pathForResource: _sound ofType:@ "wav"];
AudioServicesCreateSystemSoundID((__bridge CFURLRef) [NSURL fileURLWithPath:soundFile], &soundID);
AudioServicesPlaySystemSound(soundID);

Upvotes: 1

Views: 578

Answers (1)

danh
danh

Reputation: 62676

Do the AudioServicesCreateSystemSoundID during app initialization, or at some other point ahead of time when the user can expect/accept a little lag. It can be performed in the background, but the sound can't be played until it's finished.

AudioServicesPlaySystemSound is asynchronous already.

In other words, to demonstrate how do the init early, appDidFinishLaunching is the earliest opportunity. Make your sounds available to other parts of the app with a public property...

// AppDelegate.h, add this inside the @interface
@property (strong, nonatomic) NSArray *sounds;

// AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    NSMutableArray *tempSounds = [NSMutableArray array];

    SystemSoundID soundID0;
    // you need to initialize _sound0, _sound1, etc. as your resource names
    NSString *soundFile0 = [[NSBundle mainBundle] pathForResource: _sound0 ofType:@ "wav"];
    AudioServicesCreateSystemSoundID((__bridge CFURLRef) [NSURL fileURLWithPath:soundFile0], &soundID0);

    [tempSounds addObject:[NSNumber numberWithInt:soundID0]];

    SystemSoundID soundID1;
    NSString *soundFile1 = [[NSBundle mainBundle] pathForResource: _sound1 ofType:@ "wav"];
    AudioServicesCreateSystemSoundID((__bridge CFURLRef) [NSURL fileURLWithPath:soundFile1], &soundID1);

    // SystemSoundID is an int type, so we wrap it in an NSNumber to keep in the array
    [tempSounds addObject:[NSNumber numberWithInt:soundID1]];

    self.sounds = [NSArray arrayWithArray:tempSounds];

    // do anything else you do for app init here

    return YES;
}

Then in SomeViewController.m ...

#import "AppDelegate.h"

// when you want to play a sound (the first one at index 0 in this e.g.)
NSArray *sounds = ((AppDelegate *)[[UIApplication sharedApplication] delegate]).sounds;

AudioServicesPlaySystemSound([sounds[0] intValue]);

Upvotes: 1

Related Questions