A customer recently got in touch with me with an odd problem — Talkie for iPhone was going silent on him. After a little diagnosis, it turned out the audio system was throwing up an undocumented error — -12986 — while starting up on his iPod Touch.
Some googling turned up this thread on Stack Overflow, which presented a solution for the AVAudioSession framework: It turns out, on recent SDKs (somewhere equal to or above 3.0), the audio system will refuse to start up if the session is set to a recording mode, with no input device available, spitting out this error. Alas, the error isn’t listed anywhere that I could find.
So, the way to fix it is to check whether there’s an input device available, then choose an audio category accordingly:
OSStatus status; UInt32 inputAvailable=0; UInt32 size = sizeof(inputAvailable); AudioSessionGetProperty(kAudioSessionProperty_AudioInputAvailable, &size, &inputAvailable); UInt32 sessionCategory; if ( inputAvailable ) { // Set the audio session category for simultaneous play and record sessionCategory = kAudioSessionCategory_PlayAndRecord; } else { // Just playback sessionCategory = kAudioSessionCategory_MediaPlayback; } status = AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (sessionCategory), &sessionCategory); checkStatus(status);
It’s probably a good idea to respond when input becomes available or goes away, so add a property listener too:
void inputAvailablePropertyListener (void *inClientData, AudioSessionPropertyID inID, UInt32 inDataSize, const void *inData) { if ( inID = kAudioSessionProperty_AudioInputAvailable ) { UInt32 *inputAvailable = (UInt32*)inData; UInt32 sessionCategory; if ( *inputAvailable ) { // Set the audio session category for simultaneous play and record sessionCategory = kAudioSessionCategory_PlayAndRecord; } else { // Just playback sessionCategory = kAudioSessionCategory_MediaPlayback; } OSStatus status = AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (sessionCategory), &sessionCategory); checkStatus(status); } }
then:
// Listen for audio input availability status = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioInputAvailable, inputAvailablePropertyListener, NULL);
Related posts
- Core Audio and freakin’ error -66632 This will only be of interest to a very small...
- Easy AAC compressed audio conversion on iOS From the iPhone 3Gs up, it’s possible to encode compressed...
- Understanding error codes Just in case there’s someone else that didn’t know this,...
- A simple, fast circular buffer implementation for audio processing Circular buffers are pretty much what they sound like –...
- Using RemoteIO audio unit I’ve had nasty old time trying to get some audio...




One Comment
Funny, this one got me too.