4
votes

I'm working on an VOIP project for iOS and noticed a weird issue. My setup looks like below:

  1. Capture end has an VoiceProcessingIO unit (for echo cancellation), with both output scope, output bus and input scope, input bus enabled.
  2. Render end has an RemoteIO unit, with output scope, output bus enabled.

I don't use any audio graph so far.

When I start recording voice, I notice the setup above caused a very low output voice, until I turn off the output scope, output bus of VoiceProcessingIO. Though it sounds like a bug in my code (setting wrong IO bus), it still makes no sense that why a change in capture end affects render end.

After reading the Audio Unit Hosting Guide for iOS from developer.apple.com, I noticed it mentioned multiple times that each design pattern should include only one I/O audio unit. I'm wondering if this is mandatory, or just optional. Is it safe to keep my code with two audio units?

Indeed, using two audio units may have its own reason, as I can simply turn off one unit if I want to mute one end. I can't do it with kAudioUnitProperty_EnableIO because it can't be changed after AudioUnitInitialize(), which means the one-audio-unit solution may have to turn off both channels and reinitialize audio unit again if I want to disable one of them. This causes a bad user experiences because the voice may pause for a short while during this moment.

Thanks, Fuzhou

3
This might be a useless combination, as voice processing may do zero echo cancellation unless used for both input and output.hotpaw2
Were you able to find an answer to this?Namratha
Thanks buddy. Though I still have no answer myself, I posted an semi-answer with my experiments. Let's see if we can find more inputs from other experts.Fuzhou Chen
do you have an example of echo cancellation ? I've read the apple docs and can only find references to voice processingIO having this ability, but no reference to how or an exampleSimon McLoughlin
I'm also trying to use vpio and remoteio, but alternatively. When I switch from vpio to remoteio, the recording volume from the remoteio drops. I'm actually also wondering if vpio is remoteio in disguise. ie. If i bypass the voice processing on the vpio, is that equal to a remoteio? Thanks.lppier

3 Answers

1
votes

Well, it looks like I'm asking a corner question. Anyway, I think I have some ideas based on my experiments so far:

  1. It I use two RemoteIO units... It may look fine in local end but will cause problem in remote end. Remember I mentioned I was working on an VOIP app? I found my capture end can only pass very low volume to remote end when using render end is using loudspeaker.

  2. If I use two VoiceProcessingIO units... Although it looks like we can create two audio unit objects, they are actually the same one. I mean, in my code, if I create two units and close one of them (e.g., muting microphone), then the other one stops working as well.

  3. If I use one VoiceProcessingIO unit and one RemoteIO unit... That's more complex. First, don't use VoiceProcessingIO unit as render end only. It won't trigger echo cancellation. So the only choice is to use VoiceProcessingIO unit as capture and RemoteIO as rendering. It may work but be careful. If you happened to enable both input and output end of VoiceProcessingIO unit, you may hear a more lower volume output from your own speaker or loudspeaker.

BTW, all discussions are for iOS only. I didn't get a chance to play with Mac.

So yes, looks like there's no guaranteed behavior if we really do so, and the last hope -- is to follow Apple's Audio Unit Hosting Guide.

I'm still expecting more guys to have your inputs here. Kindly let me know if you find anything new.

0
votes

Well, it seems i have met the same problem with you, i also use two audio unit for my app, process IO for record and remote for play, and i found that the output volume be depress.

From your tip: "If you happened to enable both input and output end of VoiceProcessingIO unit, you may hear a more lower volume output from your own speaker or loudspeaker.", now i try to disable the output of the precess IO like this:

flag = 0;
status = AudioUnitSetProperty(_recordAudioUnit,
                              kAudioOutputUnitProperty_EnableIO,
                              kAudioUnitScope_Output,
                              kOutputBus,
                              &flag,
                              sizeof(flag));

Yes, final i got a louder volume of render, but another problem happen, which is record not work again.

I don't know whether you meet such problem either, so wish to see your update soon.

0
votes

There is an Error code for AUGraph

kAUGraphErr_OutputNodeErr AUGraphs can only contain one OutputUnit. this error is returned if trying to add a second output unit or the graph's output unit is removed while the graph is running

AUGraph.h, line 106