Best alternative to AudioServices on the iPhone - iphone

I'm using AudioServices to play a sound in my app:
AudioServicesCreateSystemSoundID (soundFileURLRef,&soundFileObject );
and then
AudioServicesPlaySystemSound (soundFileObject);
The sound plays but because I need to play it frequently (its 0.24 seconds long) I get a strange unnatural sounding repetition.
You can hear it at http://testing.lukem.co.uk/Simulator/Simulator.html
The other noise is me adjusting the volume - oops.
Thanks!

If you want the most precise control over timing of a sound's repetition, use Audio Queues or Audio Unit RemoteIO, and count samples between where you start filling the callback buffers with your sound's raw/PCM sample array.

I went with open source openAL library Finch.

Related

Is there an open-source alternative to AVAudioPlayer which offers a callback when audio playback really started?

I am making an app which is similar to flip book animation. It plays an audio track with AVAudioPlayer and starts animations which must start exactly at same time as audio starts. Tolerance is about +/- 100 msec.
I found AVPlayer as alternative which offers a callback but it is very complicated to use.

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.

What do you use to play sound in iPhone games?

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.
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.
If you're calling play on the main thread, try running it on a separate thread. What I ended up doing is:
#include <dispatch/dispatch.h>
dispatch_queue_t playQueue = dispatch_queue_create("com.example.playqueue", NULL);
AVAudioPlayer* player = ...
dispatch_async(playQueue, ^{
[player play];
});
which fixed the worst of the framerate stuttering I was experiencing.
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.
Use CocosDenshion – it’s free, easy, and works. It wraps AVAudioPlayer for background tracks and OpenAL for sounds.
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.

Decrease the volume of sound played by AudioToolbox

If i play my sounds on the iPhone on max ringer volume it plays fine But when i reduce it to some extend ma AudioToolbox sounds are playing at the same volume But my AVAudioPlayer sounds are playing fine. Is there any way to decrease the volume of sounds played by AudioToolbox...
From: iPhone Application Programming Guide
The AudioServicesPlaySystemSound function lets you very simply play short sound files. The simplicity carries with it a few restrictions. Your sound files must be:
Shorter than 30 seconds in duration
In linear PCM or IMA4 (IMA/ADPCM)
format Packaged in a .caf, .aif, or
.wav file
In addition, when you use the AudioServicesPlaySystemSound function:
Sounds play at the current system
audio level, with no level control
available
Sounds play immediately
Looping and stereo positioning are
unavailable

AudioQueueNewInput decreases playback volume for AVAudioPlayer

I am using Stephen Celis' SCListener class to record iPhone microphone audio levels. I also am playing audio through the use of AVAudioPlayer. For example, the user presses 'Play' to kick off a sound playing in the background and then has the option to blow into the microphone to play additional, shorter sounds. The code all works fine, playing all the sounds when they should be played, however, the AVAudioPlayer sound volume greatly decreases when you begin listening with the SCListener. I have narrowed down the culprit to this line in the SCListener source code:
AudioQueueNewInput(&format, listeningCallback, self, NULL, NULL, 0, &queue);
I have racked my brain and can not find out how to keep the playback volume at it's highest level once this line has executed. I have spoken with Stephen Celis, too, and he does not know what is happening. It is possible, I suppose, that the iPhone turns down the output volume when the microphone is being used so that feedback isn't introduced, but it seems like there should be a way to disable that.
In summary:
Start playing long audio file with AVAudioPlayer - 100% volume (loud).
Enable SCListener and begin listening (which calls AudioQueueNewInput).
The output volume on the AVAudioPlayer sound greatly decreases
Call [[SCListener sharedListener] stop] to dispose of the queue
AVAudioPlayer sound resumes higher playback volume
Has anyone seen anything like this or have any ideas on how to keep the playback volume higher? I have explicitly set the volume parameter to 1.0f to ensure that the gain is at it's highest level.
you can try this:
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
I'm not familiar with Stephen Celis's work, but if tposchel's suggestion does not work, it might be of some value to look at the InputQueue's values versus the OutputQueue's audio values in debug mode (this is tricky, though, since the callbacks for these methods are realtime threads).
This may be informative in that it will tell you what the OS believes it is sending to your output device (headphone, or built-in speaker).
The brute force way to fix this problem is to manually normalize (or scale up, as it were) the values within your OutputQueue's callback. This doesn't address your root problem, perhaps, but may be a hack until you find the answer.