在 iOS 中同时使用两个音频单元进行 I/O 是不是安全?

Posted

技术标签:

【中文标题】在 iOS 中同时使用两个音频单元进行 I/O 是不是安全?【英文标题】:Is it safe to use two audio units for simultaneous I/O in iOS?在 iOS 中同时使用两个音频单元进行 I/O 是否安全? 【发布时间】:2012-05-22 12:47:22 【问题描述】:

我正在为 ios 开发一个 VOIP 项目,并注意到一个奇怪的问题。我的设置如下所示:

    采集端有一个 VoiceProcessingIO 单元(用于回声消除),同时具有输出范围、输出总线和输入范围、输入总线启用。 渲染端有一个 RemoteIO 单元,具有输出范围,输出总线已启用。

到目前为止,我没有使用任何音频图表。

当我开始录制语音时,我注意到上面的设置导致输出语音非常低,直到我关闭输出范围,VoiceProcessingIO 的输出总线。虽然这听起来像是我的代码中的一个错误(设置了错误的 IO 总线),但捕获端的更改为什么会影响渲染端仍然没有意义。

在阅读 developer.apple.com 的 iOS 音频单元托管指南后,我注意到它多次提到每个设计模式应该只包含一个 I/O 音频单元。我想知道这是强制性的,还是可选的。用两个音频单元保存我的代码是否安全?

确实,使用两个音频单元可能有其自身的原因,因为如果我想将一端静音,我可以简单地关闭一个单元。我不能用 kAudioUnitProperty_EnableIO 来做到这一点,因为它在 AudioUnitInitialize() 之后无法更改,这意味着如果我想禁用其中一个,单音频单元解决方案可能必须关闭两个通道并再次重新初始化音频单元。这会导致糟糕的用户体验,因为此时语音可能会暂停一小会儿。

谢谢, 福州

【问题讨论】:

这可能是一个无用的组合,因为语音处理可能会进行零回声消除,除非同时用于输入和输出。 你能找到答案吗? 谢谢哥们。虽然我自己仍然没有答案,但我在我的实验中发布了一个半答案。让我们看看是否可以从其他专家那里找到更多意见。 你有回声消除的例子吗?我已经阅读了苹果文档,只能找到具有这种能力的语音处理IO的参考,但没有参考如何或示例 我也在尝试使用 vpio 和 remoteio,但可以选择。当我从 vpio 切换到 remoteio 时,remoteio 的录制音量会下降。我实际上也想知道 vpio 是否是变相的 remoteio。 IE。如果我绕过vpio上的语音处理,那是否等于remoteio?谢谢。 【参考方案1】:

好吧,看来我在问一个角落问题。无论如何,我想我有一些基于我迄今为止的实验的想法:

    我使用两个 RemoteIO 单元...它在本地端可能看起来不错,但在远程端会导致问题。还记得我提到我正在开发一个 VOIP 应用程序吗?当使用渲染端使用扬声器时,我发现我的捕获端只能将非常低的音量传递给远程端。

    如果我使用两个 VoiceProcessingIO 单元...虽然看起来我们可以创建两个音频单元对象,但它们实际上是同一个。我的意思是,在我的代码中,如果我创建两个单元并关闭其中一个(例如静音麦克风),那么另一个也会停止工作。

    如果我使用一个 VoiceProcessingIO 单元和一个 RemoteIO 单元...那就更复杂了。首先,不要只使用 VoiceProcessingIO 单元作为渲染端。它不会触发回声消除。所以唯一的选择是使用 VoiceProcessingIO 单元作为捕获和 RemoteIO 作为渲染。它可能有效,但要小心。如果您碰巧同时启用了 VoiceProcessingIO 单元的输入和输出端,您可能会听到来自您自己的扬声器或扬声器的更低音量输出。

顺便说一句,所有讨论仅针对 iOS。我没有机会玩 Mac。

所以是的,如果我们真的这样做,看起来并不能保证行为,最后的希望是遵循 Apple 的音频单元托管指南。

我仍然期待更多的人在这里提供您的意见。如果您发现任何新内容,请告诉我。

【讨论】:

您找到解决方案了吗?我在这里遇到了同样的问题。【参考方案2】:

好吧,看来我遇到了同样的问题,我的应用程序也使用了两个音频单元,处理 IO 进行录制和远程播放,我发现输出音量被压低了。

根据您的提示:“如果您碰巧启用了 VoiceProcessingIO 单元的输入和输出端,您可能会从您自己的扬声器或扬声器中听到更低音量的输出。”,现在我尝试禁用进动 IO 的输出像这样:

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

是的,最后我得到了更大音量的渲染,但是又出现了另一个问题,那就是无法再次录制。

我也不知道你有没有遇到这样的问题,所以希望尽快看到你的更新。

【讨论】:

【参考方案3】:

AUGraph 有一个错误代码

kAUGraphErr_OutputNodeErr AUGraphs 只能包含一个 OutputUnit。 如果尝试添加第二个输出单元,则会返回此错误 或者在图表运行时移除图表的输出单元

AUGraph.h,第 106 行

【讨论】:

以上是关于在 iOS 中同时使用两个音频单元进行 I/O 是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章

Remote I/O 音频单元是不是设置缓冲区中的通道数?

编写远程 I/O 渲染回调函数时遇到问题

来自远程 I/O 单元的原始音频数据的测量单位是啥?

如何渲染来自远程 I/O 音频单元的系统输入并以立体声播放这些样本

使用内存磁盘进行 I/O 单元测试

如果该单元同时连接到输入单元和输出单元,是不是有 iOS 核心音频单元的回调?