1

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);
goodmanship
  • 334
  • 1
  • 13
Chris Scott
  • 5,388
  • 10
  • 53
  • 123
  • try to execute the code in background thread ? See: http://stackoverflow.com/a/3869355/188331 – Raptor Feb 08 '13 at 03:01

1 Answers1

1

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]);
danh
  • 55,236
  • 10
  • 89
  • 124
  • As early as appDidFinishLaunching. I realize that might be a pain, since you'd then need to convey that soundID to the view controller that uses it. But just to see if it feels right speed-wise, try it there first to see if it's good (make soundID a public property on your appDelegate, then get it like: [[UIApplication sharedApplication] delegate].soundID; – danh Feb 08 '13 at 03:32
  • but what if I have different sounds throughout the view controller? – Chris Scott Feb 08 '13 at 03:34
  • Just to get it working, use the same sound in each place. If you find the speed acceptable, you can change it to an NSArray of soundIDs. – danh Feb 08 '13 at 03:38