Blog

Error -12986 and you

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);
Tagged , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

One Comment

  1. Posted March 24, 2011 at 6:40 pm | Permalink

    Funny, this one got me too.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use Markdown (surround code in `back-ticks`), or these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Subscribe without commenting