CoreAudio 和 AVFoundation 之间的性能

Performance between CoreAudio and AVFoundation

我有一个关于 CoreAudio 和 AVFoundation 的问题。

我使用带有 AUGraph 和 AudioUnit 的 CoreAudio 构建了一个专业音频应用程序。

我想切换到 AVFoundation 框架,它看起来真的很棒。但因为我担心性能,所以我想了解更多。

在我的核心音频渲染回调中,我可以以 44100kHz 的采样率处理 512 个样本,因此我的回调每 10 毫秒调用一次,我认为它可以轻松地更快(我说的对吗?)。

现在在AVFoundation中,渲染回调是AVAudioNode的Tap。我在评论中读到 bufferSize 参数是 the requested size of the incoming buffers in sample frames. Supported range is [100, 400] ms. 那么这是否意味着我无法在每次调用时处理少于 4410 个样本?

限制是否来自 Objective-C 约束(消息调用、锁定等)?

不会影响实时DSP处理吗?

在我使用 iOS AVAudioEngine API (iOS 10.3.3) 的实验中,我确实发现在 AVAudioNode 总线上安装分路器不会传送短于 4410 的缓冲区iPhone 7 上的示例。这可能是因为 AVAudioEngine tap 将缓冲区传递给优先级低于 CoreAudio 音频单元回调的线程,因此无法经常可靠地调用,从而导致更高的延迟。

但是,可以创建一个 V3 AUAudioUnit 子类,其中接收的缓冲区(由实例的 internalRenderBlock 用于输出)配置为在 iPhone 上从 512 减少到短至 64 个样本 7. 调用 setPreferredIOBufferDuration音频会话似乎设置了首选的 AUAudioUnit 呈现块缓冲区大小。我发布了一些测试代码(混合 Swift 3 加 Objective C),用于创建我认为有效的低延迟 V3 AUAudioUnit 音调生成器子类 here。人们确实需要理解并遵循渲染块内的实时编码限制(无方法调用、锁、内存分配等),因此块内音频上下文代码的纯 C 语言似乎是最好的(甚至可能是强制性的)。

对于具有同样短缓冲区的低延迟麦克风输入,您可以尝试将音频单元子类连接到音频引擎的输入节点,然后在单元渲染块中调用输入的 AURenderPullInputBlock。