Apple 的语音处理音频单元 (kAudioUnitSubType_VoiceProcessingIO) 在 iOS 5.1 上损坏

Posted

技术标签:

【中文标题】Apple 的语音处理音频单元 (kAudioUnitSubType_VoiceProcessingIO) 在 iOS 5.1 上损坏【英文标题】:Apple's Voice Processing Audio Unit ( kAudioUnitSubType_VoiceProcessingIO ) broken on iOS 5.1 【发布时间】:2012-10-10 14:09:27 【问题描述】:

我正在为 iPad 编写一个 VOIP 应用程序(目前针对 2&3)。

我最初使用音频单元 API 编写音频代码,带有一个 kAudioUnitSubtype_RemoteIO 单元。这运作良好,但不出所料,回声是一个问题。我尝试通过切换到使用 kAudioUnitSubType_VoiceProcessingIO 单元来使用内置的回声抑制。这在 ios 6 (iPad 3) 上运行良好,但在 iOS 5.1 (iPad 2) 上的相同代码会在麦克风输入上产生白噪声。

documentation 只是提到它应该在 iOS 3.0 及更高版本中可用

iOS 版本似乎是这里的重要区别。我尝试在两台 iPhone 4S 上运行该应用程序,一台运行 iOS 6,听起来不错,一台运行 iOS 5.1,听起来像白噪声。

我的 ASBD 如下所示:

typedef int16_t sample_t;
#define AUDIO_BUFFER_SAMPLE_RATE 48000
#define FORMAT_FLAGS (kAudioFormatFlagsIsSignedInteger | kAudioFormatFlagsIsNonInterleaved)
#define CHANNELS_PER_FRAME 1

...

const size_t bytes_per_sample = sizeof(sample_t);
const int eight_bits_per_byte = 8;
AudioStreamBasicDescription streamFormat;
streamFormat.mFormatID = kAudioFormatLinearPCM;
streamFormat.mSampleRate = AUDIO_BUFFER_SAMPLE_RATE;
streamFormat.mFormatFlags = FORMAT_FLAGS;

streamFormat.mChannelsPerFrame = CHANNELS_PER_FRAME;
streamFormat.mBytesPerFrame = bytes_per_sample * CHANNELS_PER_FRAME;
streamFormat.mBitsPerChannel = bytes_per_sample * eight_bits_per_byte;

streamFormat.mFramesPerPacket = 1;
streamFormat.mBytesPerPacket = streamFormat.mBytesPerFrame * streamFormat.mFramesPerPacket;
streamFormat.mReserved = 0;

有没有人让 kAudioUnitSubType_VoiceProcessingIO 在 iOS 5.1 上工作?

有人知道这个 IO 的任何重要文档吗?

【问题讨论】:

【参考方案1】:

TL;DR 将 kAudioFormatFlagsIsPacked 添加到 FORMAT_FLAGS

我是通过一条复杂的路线发现了这一点。这些似乎都没有在任何地方得到很好的记录,但我遇到了this SO post 谈论在 Mac 上使用 IO。提到的一件事是使用“FlagsCononical”。我试过设置:

#define FORMAT_FLAGS kAudioFormatFlagsAudioUnitCanonical

这不起作用,对 AudioUnitInitialize 的调用失败,返回码为 29759。我找不到任何关于这意味着什么的文档,但是当我尝试时:

#define FORMAT_FLAGS kAudioFormatFlagsCanonical

一切正常!成功!

如果您正在为 iPad 构建(因此将 CA_PREFER_FIXED_POINT 定义为 1),CoreAudioTypes.h 中 kAudioFormatFlagsCanonical 的定义是:

kAudioFormatFlagsCanonical = kAudioFormatFlagsIsSignedInteger
                           | kAudioFormatFlagsNativeEndian
                           | kAudioFormatFlagIsPacked;

kAudioFormatFlagIsPacked 添加到我的原始代码后,它就可以工作了。我添加了kAudioFormatFlagsNativeEndian 以获得良好的效果。我删除了kAudioFormatFlagsIsNonInterleaved,因为无论如何单声道音频都没有必要。我剩下的与kAudioFormatFlagsCanonical 相同。

所以我在 iPad 2 (iOs 5.1) 和 iPad 3 (iOS 6.0) 上的设置如下:

48000 的采样率 1 个频道 kAudioFormatFlagsCanonical int16_t样品 线性 PCM

如果有人有的话,我仍然热衷于这个 IO 的文档,当然如果这对你有帮助,别忘了点赞 :)

【讨论】:

以上是关于Apple 的语音处理音频单元 (kAudioUnitSubType_VoiceProcessingIO) 在 iOS 5.1 上损坏的主要内容,如果未能解决你的问题,请参考以下文章

mac os x 上语音处理单元的可用格式

Core Audio:用于提升信号电平的音频单元

AEC ios 多音频单元图

在 Cocoa 中捕获音频缓冲区

如何创建实现多个音频单元的 AUAudioUnit?

使用音频单元录制扬声器输出