Question

In my app I need to switch between these 2 different AudioUnits. Whenever I switch from VPIO to RemoteIO, there is a drop in my recording volume. Quite a significant drop. No change in the playback volume though.Anyone experienced this?

Here's the code where I do the switch, which is triggered by a routing change. (I'm not too sure whether I did the change correctly, so am asking here as well.)

How do I solve the problem of the recording volume drop?

Thanks, appreciate any help I can get.

Pier.

- (void)switchInputBoxTo : (OSType) inputBoxSubType
{
OSStatus result;

if (!remoteIONode) return; // NULL check

// Get info about current output node
AudioComponentDescription outputACD;
AudioUnit currentOutputUnit;

AUGraphNodeInfo(theGraph, remoteIONode, &outputACD, &currentOutputUnit);

if (outputACD.componentSubType != inputBoxSubType)
{
    AUGraphStop(theGraph);
    AUGraphUninitialize(theGraph); 
    result = AUGraphDisconnectNodeInput(theGraph, remoteIONode, 0);
    NSCAssert (result == noErr, @"Unable to disconnect the nodes in the audio processing graph. Error code: %d '%.4s'", (int) result, (const char *)&result);
    AUGraphRemoveNode(theGraph, remoteIONode);
    // Re-init as other type

    outputACD.componentSubType = inputBoxSubType;
    // Add the RemoteIO unit node to the graph
    result = AUGraphAddNode (theGraph, &outputACD, &remoteIONode);
    NSCAssert (result == noErr, @"Unable to add the replacement IO unit to the audio processing graph. Error code: %d '%.4s'", (int) result, (const char *)&result);

    result = AUGraphConnectNodeInput(theGraph, mixerNode, 0, remoteIONode, 0);
    // Obtain a reference to the I/O unit from its node
    result = AUGraphNodeInfo (theGraph, remoteIONode, 0, &_remoteIOUnit);
    NSCAssert (result == noErr, @"Unable to obtain a reference to the I/O unit. Error code: %d '%.4s'", (int) result, (const char *)&result);

    //result = AudioUnitUninitialize(_remoteIOUnit);

    [self setupRemoteIOTest]; // reinit all that remoteIO/voiceProcessing stuff
    [self configureAndStartAudioProcessingGraph:theGraph];
}  
}
Was it helpful?

Solution

I used my apple developer support for this. Here's what the support said :

The presence of the Voice I/O will result in the input/output being processed very differently. We don't expect these units to have the same gain levels at all, but the levels shouldn't be drastically off as it seems you indicate.

That said, Core Audio engineering indicated that your results may be related to when the voice block is created it is is also affecting the RIO instance. Upon further discussion, Core Audio engineering it was felt that since you say the level difference is very drastic it therefore it would be good if you could file a bug with some recordings to highlight the level difference that you are hearing between voice I/O and remote I/O along with your test code so we can attempt to reproduce in house and see if this is indeed a bug. It would be a good idea to include the results of the singe IO unit tests outlined above as well as further comparative results.

There is no API that controls this gain level, everything is internally setup by the OS depending on Audio Session Category (for example VPIO is expected to be used with PlayAndRecord always) and which IO unit has been setup. Generally it is not expected that both will be instantiated simultaneously.

Conclusion? I think it's a bug. :/

OTHER TIPS

There is some talk about low volume issues if you don't dispose of your audio unit correctly. Basically, the first audio component stays in memory and any successive playback will be ducked under your or other apps, causing the volume drop.

Solution: Audio units are AudioComponentInstance's and must be freed using AudioComponentInstanceDispose().

I've had success when I change the audio session category when going from voice processing io (PlayAndRecord) to Remote IO (SoloAmbient). Make sure you pause the Audio Session before changing this. You'll also have to uninitialize you're audio graph.

From a talk I had with an Apple AVAudioSession engineer.

VPIO - Is adding audio processing on the audio sample, which also creates the echo cancellation, this creats the drop in the audio level

RemoteIO - Wont do any audio processing so the volume level will remain high.

If you are lookign for echo cancellation while using the RemoteIO option, you should create you own audio processing in the render callback

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top