Playing multiple sounds simultaneously with AVAudioPlayer - iphone

Could someone help me with a function that fires multiple AVAudioPlayers at the same time? Right now I am trying to get a total of twelve AVAudioPlayers to fire at once if twelve buttons are activated, but there is a delay and it sounds like someone is running their finger down a piano instead of hitting all the keys at once.
I've looked at Audio Queue Services and can't understand how to actually implement that into code, but it says it can play synchronized sounds. I'm not sure sure how to set all of it up. I'm trying to remake a Tone Grid app.

Why don't you use http://www.hollance.com/2011/02/soundbankplayer-using-openal-to-play-musical-instruments-in-your-ios-app/
There you have a polyphonic player, beautifully coded and ready to rock!
I used it in my first app a while back: http://itunes.apple.com/gb/app/chordwheel-pro/id406836326?mt=8

Are you calling the method prepareToPlay on all 12 AVAudioPlayer instances. From the docs: "Calling this method, preloads the buffers and acquires hardware, to minimize delay."
See the AVAudioPlayer class reference.

Related

Playing sounds in perfect succession on the iPhone

I am developing a game for the iPhone and iPad using cocos2d, and I need to be able to play a sound exactly when another one completes.
I have a soundtrack that is chopped up in smaller pieces, and there are no room for the tinyest gap between playback when one finishes and one starts.
Btw. I cannot glue the sounds together into a single file and just play that since the order of the files will be rearranged runtime.
How can I achieve this?
With CocosDenshion you can register a delegate with
[[CDAudioManager sharedManager] setBackgroundMusicCompletionListener:self
selector:#selector(musicDidFinish)];
CDAudioManager class reference
This delegate will be called whenever the background music ends. This of course only works if you play your sound files as background music (with the playBackgroundMusic method).
If that doesn't work for you, have a look at ObjectAL. You'll have more options and greater flexibility. For example, with ALSource you can queue multiple ALBuffer objects which represent sound files. That means whenever the source's buffer count decreases to 1 you just queue the next buffer to achieve uninterrupted, sequential playback of multiple sound files (any format).
Because ObjectAL is so awesome (well, I think so :) ) it's included and ready to use in Kobold2D.
You can use a single Audio Queue or the RemoteIO Audio Unit, and just fill the callback buffers with raw/PCM audio samples from any file in any order.

(iphone) how to play sound sequentially with AVAudioPlayer?

I'd like to play multiple sound sequentially.
The sound data will be available via NSData.
(to be more precise, I'm going to play different sound whenever scrollViewDidEndScrolling is called, and stop previous sound if it is still playing)
Do I need to alloc/init AVAudioPlayer for every sequential sound?
If alloc/init/release AVAudioPlayer isn't a big deal, I could do that but I'm not sure
If using the higher-level AVAudioPlayer, then yes, you'd need to instantiate (alloc/init) an AVAudioPlayer for each.
Yet, the "expensive" part (time-wise) is prepareToPlay - which you could call in a separate thread, thus hopefully by the time you come to play any given sound, it will be fully ready to play.

AVAudioPlayer lag when calling play

I have set up an AVAudioPlayer object in viewDidLoad, as per the Apple guidelines, calling prepareToPlay as the last line in viewDidLoad (i have tried in awakeFromNib also).
When i press my play button, there is a pause, as it would appear to load the file, then it plays.
In audioPlayerDidFinishPlaying, i reload the player with a different sound, and when clicking play for a second time, the file plays instantly.
What would cause the player to lag on the first play?
Thanks.
The delay is due to AVAudioPlayer being initialised. Please see this answer.
The audio system runs on several asynchronous software processes (audio units, OS drivers, etc.) and hardware systems (DMA, DACs, audio amp power supplies, etc.) that never really all completely finish initialization until some sound is actually played all the way out the speakers or earphones.
Here's one method to do that: Create a sound file containing a half second of silence. On app start up, while your app and view controller are still loading, use AVAudioPlayer to play this file of silence. Now when your view finishes loading, AVAudioPlayer should be ready to play subsequent non-silent sounds much faster, since some audio (silence) has already already gone all the way out to the speakers.
What kind of sound are you playing? Alerts, something longer? If alerts, I did go this way and it's much better with lags ...
create system sound with AudioServicesCreateSystemSoundID
play system sound with AudioServicesPlaySystemSound
dispose system sound with AudioServicesDisposeSystemSoundID
... you only need to store SystemSoundID for each sound you would like to play.

AudioServices (Easy), AVAudioPlayer (Medium), OpenAL (Hard & Overkill?)

I need to play sounds (~5 seconds each) throughout my iphone application. When they're triggered, they need to play immediately.
For the moment I'm using AudioServices and (as you probably know) the first time you play a sound it lags, then every time there after it's perfect. Is there some code available that's clever enough to preload an AudioServices sound (by playing it silently maybe?). I've read adjusting the system volume programmatically will get your app rejected, so that's not an option. Seems AudioServices isn't made for volume correction from what I can see.
I've looked into OpenAL and while feasible seems a little over kill. AVAudioPlayer seems like a little bit of a better option, I'm using that for background music at present. Extending my music player to handle a 'sound board' might be my last resort.
On the topic of OpenAL, does anyone know of a place with a decent (app store friendly) OpenAL wrapper for the iPhone?
Thanks in advance
Finch could be perfect for you. It’s a tiny wrapper around OpenAL with very low latency and simple API. See also all SO questions tagged ‘Finch’.
If you use an AVAudioPlayer, you can call prepareToPlay when you initialize the object to reduce the delay between calling play and having the audio start.

Playing a a number of different sounds using AVAudioPlayer

I have a few single hit sounds(small sound effects) which I want to play when a button is pressed. Should I declare the player and then initialize the sound to the player in the IBAction of the button if I want to play different sounds on different buttons?
Or is there a method to call which you specify the sound as you play it?
the [audioPlayer play] statement plays what is already initialized or added to the player. How can I setup the play and call it at different places with some predefined sound?
Thanks
There's a bit of delay whenever you start playing a sound even if it's already loaded and all you have to do is hit [audioPlayer play]
If you need to initialize it before you play it i'd imagine the delay would be much more noticeable.
I think i'd make a separate audio player for each sound and populate an array with them. Keep an eye out for memory low messages and unload the objects if necessary but i don't think it will require much overhead.