Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recording volume drop switching between RemoteIO and VPIO

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];
}  
}
like image 401
lppier Avatar asked Dec 10 '12 12:12

lppier


2 Answers

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. :/

like image 122
lppier Avatar answered Oct 01 '22 20:10

lppier


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().

like image 42
rocky Avatar answered Oct 01 '22 19:10

rocky