I'm quite new to the iPhone platform and even more new to the concept of Audio Services.
I am able to play a system sound but if the play function is called many times, the sound will restart and try to play again. I'd like to have the play function wait until the first sound is finished before playing again.
I've looked over the iPhone Dev Reference Guide on Playing System Sound and they outline a function that will keep track if a sound is completed but I am not sure how to implement this. There is a function called "AudioServicesSystemSoundCompletionProc" which is invoked as a callback. I've looked everywhere for an example how to use this function but I have not been able to find it it any sample code (neither metronome, GLPaint nor BubbleLevel) and if anyone out there can point me how I could use this function, I would greatly appreciate it.
I have added a listener with AudioServicesSystemSoundCompleted. I am unclear how to use this in conjunction with the "AudioServicesSystemSoundCompletionProc" method if at all. :x
You're wrting the function "completionCallback", and then passing it and the current object into "AudioServicesAddSystemSoundCompletion" .
When the sound is done, it will call your function (a regular C function, not an objective-C method) with your object as a parameter. You can then cast that object back to whatever you want, and call methods on it. I'm catsing it back to a (SoundEffect*) , one of my custom classes.
You're wrting the function "completionCallback", and then passing it and the current object into "AudioServicesAddSystemSoundCompletion" .
When the sound is done, it will call your function (a regular C function, not an objective-C method) with your object as a parameter. You can then cast that object back to whatever you want, and call methods on it. I'm catsing it back to a (SoundEffect*) , one of my custom classes.
I'm using this callback almost exactly as written above and it is never reaching the callback. Is it a problem that my sounds are very short? Some are less than a second anywhere up to about 3 seconds.
Basically I'm trying to play a collection of sounds all in a row one after the other - but they all play at the same time, so I want to use something to wait until the end of each sound to play the next - I figured this callback might do the job, but it seems to never get called for me.
I'll have to post my code when I get home. I don't have any NSLogs in there, but I had break points galore, none of which ever got hit - and of course what it was supposed to do never happened.
The playWavNamed method is called in a loop, which is this:
Code:
NSMutableArray *sounds = [appDelegate getSounds];
for (Sound *sound in sounds)
{
[appDelegate playSound:sound];
while ([appDelegate soundPlaying]) {}
}
The idea is to wait until each sound is done playing before continuing the loop into playing the next sound. All this currently does it get locked up in the while loop all the while MyAudioServicesSystemSoundCompletionProc never gets called - so soundPlaying is always true.
Your "While" loop is the problem there - you can't hog the processor like that; that will prevent the systemSoundCompletionProc from being called - it'll also keep any touch events from being called.
I'd get rid of the while loop AND the for loop, and change your systemSoundCompletionProc - instead of calling setSoundPlaying:NO, write a method that plays the next sound, and call that instead. (You'll need an int to keep tack of which sound is next, etc.
That looks like it should work - you're passing self into AudioServicesAddSystemSoundCompletion; "self" is the sound queue, right?
Then you get it back as clientData when the sound is complete in MyAudioServicesSystemSoundCompletionProc and you call playQueue. You should probably also destroy the system sounds ID there.
Everything looks shipshape - what's not working? Put NSlogs in MyAudioServicesSystemSoundCompletionProc and playQueue and see if they're being run.
I can't spot the error yet. Can you show the block of code when you create your soundQueue? You don't release it, do you?
PS objectAtIndex won't return nil when there's no more objects, it'll cause an error. Check the length of the array before accessing object 0.
PPS - your initWithArray method is strange - it shares a name with another method of a different type, which causes a warning, and any init method should return self. Right now you probably init twice, right?