Matt Coneybeare

MC

Using AudioStreamer With AVAudioPlayer and Avoiding Hardware Locking

| Comments

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:
 

 
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:
 

 
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.

Comments

My name is Matt Coneybeare, I design and develop for iOS (iPhone, iPad and iPod Touch), Mac OS X and the Web out of New York. In 2008 I started a software company called Urban Apps that has made some pretty popular apps such as Ambiance and Hourly News. My current Stack Overflow reputation is about 27k.

I was a Rockstar a decade ago, but then went back to school and collected a Bachelor's Degree in Computer Science from U.C. Berkeley. Now I am settled down with my beautiful wife Di and our two doggies Hamachi and Foxy. While coding, I walk several miles/day on my Treadmill Desk. When not at my desk, I love exploring New York City as a Yelp Elite, or training for marathons.

Contact information

Name
Matt Coneybeare
Email
Website
Twitter
Instagram
GitHub
LinkedIn
Google+