4
votes

I am trying to acquire microphone while the app is in the background. I am using audio unit technology and able to record audio while in background. But once my AudioSession gets interrupted, I am unable to restart the AudioSession with app in the background. Note: I am able to restart the AudioSession if the app is in foreground. Here is the code corresponding to interruption:

- (void) beginInterruption {
    [[AVAudioSession sharedInstance] setActive:NO error:&error];
    AudioOutputUnitStop(m_audioUnit);
}
- (void) endInterruptionWithFlags:(NSUInteger) flags{
    [[AVAudioSession sharedInstance] setActive:YES error:&error];
    AudioOutputUnitStart(m_audioUnit);
}

Code corresponding to AudioSession setup

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord error:&error];
[[AVAudioSession sharedInstance] setActive:YES error:&error];

Code corresponding to AudioUnit

// Describe audio component
AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_RemoteIO;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;

// Get component
AudioComponent inputComponent = AudioComponentFindNext(NULL, &desc);

// Get audio units
oserr = AudioComponentInstanceNew(inputComponent, &m_audioUnit);
checkStatus(oserr);

// Enable IO for recording
UInt32 flag = 1;
oserr = AudioUnitSetProperty(m_audioUnit,
                             kAudioOutputUnitProperty_EnableIO,
                             kAudioUnitScope_Input,
                             1,
                             &flag,
                             sizeof(flag));
checkStatus(oserr);

UInt32 enableOutput        = 0;    // to disable output
AudioUnitElement outputBus = 0;

// Disable output
oserr = AudioUnitSetProperty (
                              m_audioUnit,
                              kAudioOutputUnitProperty_EnableIO,
                              kAudioUnitScope_Output,
                              outputBus,
                              &enableOutput,
                              sizeof (enableOutput)
                              );
checkStatus(oserr);

oserr = AudioUnitInitialize(m_audioUnit);

oserr = AudioOutputUnitStart(m_audioUnit);

Most of the popular recording apps does not seem to support it, even iOS native "Voice Memo" gets suspended upon starting the Siri.

These are the errors I get in EndInterruption: AUIOClient_StartIO failed (-12985) AURemoteIO::ChangeHardwareFormats: error -10875

Has anyone been successful in reacquisition of microphone while the app is in background?

1
Interesting question. I hadn't tested that until now, but I see the same problem.Lewis Gordon
Any idea what -12985 actually means? I've seen it too but can't find it in any headers.robbie_c

1 Answers

4
votes

I got this working after adding

[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

in viewDidAppear. Thanks to the post MPMoviePlayerController / AVAudioSession in background doesn't restart play after incoming call

It is unclear to me how beginReceivingRemoteControlEvents is impacting the AudioSession here.

Another important thing I observed is independent of answering/declining phone call you do receive an endInterruption event. Apple documentation makes you think that you may not be getting endInterruption in case of answering a phone call