views:

44

answers:

1

Hi all,

I can't seem to get the AudioServices sounds to play, either on the device or in the simulator. Here is my code:

NSString *sndPath = [[NSBundle mainBundle] pathForResource:@"click" ofType:@"aiff"];
SystemSoundID soundID;
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:sndPath], &soundID);
AudioServicesPlaySystemSound(soundID);
AudioServicesDisposeSystemSoundID(soundID);

I have checked my system prefs, and yes I do have "Play user interface sound effects" ticked on... What might I be doing wrong?

Thanks!

EDIT: I'm attempting to create an audio click as the user moves touches across the device, so I need it to rapidly play the same sound. Should I use AVAudioPlayer instead?

+1  A: 

Don't dispose the sound until after it finishes playing. You can do something like this:

AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, (AudioServicesSystemSoundCompletionProc)AudioServicesDisposeSystemSoundID, NULL);

Slightly icky, since we're assuming that it doesn't use the Pascal calling convention (i.e. AudioServicesDisposeSystemSoundID() can handle the extra NULL argument).

tc.
Is that going to cause problems if I am rapidly calling the sound and sometimes I want to restart it before it has finished the previous one?
Joe
I think they're created as independent objects, so they end up playing over each other. Apart from that, it should work. Try it and see.
tc.
Well it *does* work thanks!... But the performance hit is pretty nasty unfortunately. My frame rate drops from about 25fps to 16-17fps. I tried to optimise it by moving the actual sound creation code into the viewDidLoad, but now the clicks only happen intermittently (and the performance hit is still there). Should I use AVAudioPlayer instead?
Joe
If the sound creation is in viewDidLoad, I'm assuming you've moved sound disposal into viewDidUnload and dealloc. Also note that I'm not sure what the "null" system sound ID is; presumably it's 0, but this isn't documented.
tc.
oooh yes thanks - thought I had to call dispose every time, not just on the viewDidUnload... That makes it loads faster thanks! Do I need to put it in dealloc as well as viewDidUnload?
Joe
Alternatively, you can call viewDidUnload in dealloc (you might consider this icky, though). Remember to prevent a double-free ;)
tc.