« Back to blog

Using AudioStreamer with AVAudioPlayer and Avoiding Hardware Locking

In Ambiance, I use some customized AVAudioPlayers to play the apps audio. When possible, these AVAudioPLayers use hardware decoding of the audio files which speeds up the audio processing considerably and frees the software from having to dedicate resources to the process.

 
I also use Matt Gallagher's AudioStreamer to play remote files off my server for Ambiance previews.  In the latest version of the app, I was getting some feedback from beta testers that preview was not always working. One of them sent me a screenshot:
 
Image
 
So I set out on trying to reproduce and I found that playing an AudioStreamer stream worked fine when no other audio was playing, but when other audio was playing, it failed.  Setting breakpoints in the code, I saw that it was failing in the enqueueBuffer method in this code:
 
err = AudioQueueStart(audioQueue, NULL);
if (err)
{
    [self failWithErrorCode:AS_AUDIO_QUEUE_START_FAILED];
    return;
}
err was returning a code of 1752656245. Knowing that Audio Queue codes are actually ascii codes, I threw it into calculator:
 
Screen_shot_2010-07-02_at_11
 
and saw "hwiu" as the code.  A quick google search led me to the docs where I saw that this means that the streamer was unable to obtain the hardware codec.  This makes sense! Ambiance uses the hardware codec to play sounds, and when a preview comes along and tries to play a streaming sound it cannot due to the fact that that hardware spot is taken.  I had been pausing the main sound, but that did not release the hold on the hardware codec.
 
It turns out the solution to my problem was much easier. Previews in my app are not used for very long durations, so using the software to play them isn't too taxing.  I decided to change the hardware codec preference for the audioQueue:
 
// set the software codec too on the queue.
UInt32 val = kAudioQueueHardwareCodecPolicy_PreferSoftware;
OSStatus ignorableError;
ignorableError = AudioQueueSetProperty(audioQueue, kAudioQueueProperty_HardwareCodecPolicy, &val, sizeOfUInt32);
if (ignorableError)
{
    return;
}
This code goes in "createQueue", line 1494 (as of 7/2/10).  It is telling the codec to prefer the software route, but use the hardware if anything fails.  So far, all tests have been unable to reproduce the issue and everything works fine.
| Viewed
times | Favorited 0 times

8 Comments

Aug 09, 2010
mgilk said...
Holy crap! You're the best!
Sep 03, 2010
Kelvin said...
thank you very much! indeed AudioStream can never put to production without this fix!
Sep 23, 2010
Tuyen Nguyen said...
Thank you very much Matt,
you are indeed really awesome !!!!
Mar 15, 2011
WickeyWare said...
Very Nice!
Mar 22, 2011
rk said...
Thanks a lot, this worked for me.
Dec 11, 2011
Jenny Mu said...
hi, I do that adding the coding. but my coding is still that appearing error .
as error : Audio packets are larger than kAQDefaultBufSize.

the kAQDefaultBufSize 3072

i'm a girl from China. my English is poor .

i'm looking forward to your reply

Dec 11, 2011
Matt Coneybeare said...
@Jenny, I am not sure. Perhaps you should ask the author: https://github.com/mattgallagher/AudioStreamer/issues
Dec 12, 2011
Jenny Mu said...
Ok. Tks a lot all the same 
^_^

在 2011-12-12,下午12:17, Posterous 写道:

Leave a comment...