views:

2757

answers:

6

Hello!

I have a performance-intensive iPhone game I would like to add sounds to. There seem to be about three main choices: (1) AVAudioPlayer, (2) Audio Queues and (3) OpenAL. I’d hate to write pages of low-level code just to play a sample, so that I would like to use AVAudioPlayer. The problem is that it seems to kill the performace – I’ve done a simple measuring using CFAbsoluteTimeGetCurrent and the play message seems to take somewhere from 9 to 30 ms to finish. That’s quite miserable, considering that 25 ms == 40 fps.

Of course there is the prepareToPlay method that should speed things up. That’s why I wrote a simple class that keeps several AVAudioPlayers at its disposal, prepares them beforehand and then plays the sample using the prepared player. No cigar, still it takes the ~20 ms I mentioned above.

Such performance is unusable for games, so what do you use to play sounds with a decent performance on iPhone? Am I doing something wrong with the AVAudioPlayer? Do you play sounds with Audio Queues? (I’ve written something akin to AVAudioPlayer before 2.2 came out and I would love to spare that experience.) Do you use OpenAL? If yes, is there a simple way to play sounds with OpenAL, or do you have to write pages of code?


Update: Yes, playing sounds with OpenAL is fairly simple.


A: 

Do you want to check the buffering with the implementation you're using? It might be somehow related to the 20ms delay you're experiencing. i.e., try to play around with the buffer size.

Suvesh Pratapa
What kind of buffering? (Sorry if the question is not clear.) I’m currently using vanilla AVAudioPlayer, just with a wrapper that keeps several players at hand and each time some of them finishes, the wrapper calls the prepareToPlay method.
zoul
At some point, the audio data should be read into a buffer in order to be played out, look for that and try to adjust the buffer size.
Suvesh Pratapa
I just checked the API, and when you're initializing and you use initWithData, try to designate a memory buffer large enough.
Suvesh Pratapa
Ah-ha. I don’t think AVAudioPlayer lets you do that. The buffer size is most probably autodetected with respect to the data format and the first buffer is primed as you call prepareToPlay.
zoul
Hmm. That's a bad way of doing it if you're streaming the audio. Sorry I can't help you then. Wait for another response or try a different approach.An OpenAL treatment of the problem is here: http://www.gehacktes.net/2009/03/iphone-programming-part-6-multiple-sounds-with-openal/
Suvesh Pratapa
+2  A: 

I use OpenAL and the classes that came with the CrashLanding sample code. It's worked fine so far to play samples and play looped music all at the same time. I'm currently learning how to release the memory I've allocated for a sound (.wav file) when, for example, I want to play some intro music just once.

MrDatabase
I am scared of the audio code in Crash Landing, that’s why I was looking for an alternative. Wrapping up a simple OpenAL class was pretty easy after all – you can take a look at the code I wrote and see if it fits better than the sound engine from Crash Landing.
zoul
+4  A: 

AVAudioPlayer is very marginal for game audio. Tackling AudioQueue or OpenAL by adapting one of the examples is definitely the way to go. latency is much more controllable that way.

Mark Bessey
A: 

@Zoul: btw does your implementation has some sortta method equivalent of AVAudio's delegate method to indicate the the playing is of a sound clip has ended?

Shoaibi
No, because OpenAL does not support such callback. It can be faked, for example by using performSelector:afterDelay:. Depends on what you need to do – if you have any questions, drop me an e-mail, so that we don’t spam it here.
zoul
+2  A: 

Use CocosDenshion – it’s free, easy, and works. It wraps AVAudioPlayer for background tracks and OpenAL for sounds.

mb
A: 

Hi Zoul, Can Finch change a sound's pitch, rate, tempo etc? I want to change the user's recorded voice into a robot's voice.

Xiu
Hello! This is not a very good place to ask, you should create a completely new question. That said, Finch lets you speed up the sound (thus making it sound higher), but it can't change the pitch without also affecting the speed.
zoul
sorry about that. I will start a new question
Xiu