循环缓冲区填充速度快于 AVAudioSourceNode 渲染块可以从中读取数据

Circular buffer filling up faster than AVAudioSourceNode render block can read data from it

我正在试验 AVAudioSourceNode,已将其连接到混音器节点以输出到扬声器。我是 iOS 和音频编程的新手,所以如果这个问题无知或不清楚,我深表歉意,但我会尽力解释。

在 AVAudioSourceNode 渲染块中,我试图检索已存储在循环缓冲区中的接收流数据(例如,我目前使用 FIFO 缓冲区的基本实现,但正在考虑转移到 TPCircularBuffer)。我检查缓冲区是否有足够的字节来填充音频缓冲区,如果有,我就抓取这些字节进行输出;如果没有,我要么等待,要么尽我所能用零填充缺失的字节。

在调试中,我似乎 运行 遇到循环缓冲区填满 很多 快于渲染块调用访问的情况缓冲区从中检索数据。可以理解的是,在 运行 OK 一段时间后,一旦循环缓冲区已满(我什至不确定我应该实际将其设置多大,但我想这是另一个问题),输出就变成了垃圾。

就好像用流数据填充循环缓冲区的行为(可能还有其他任务)优先于在渲染块内进行的调用。我认为涉及音频节点的音频操作会自动设置优先级,但可能是我还没有完成需要做的事情。

我已阅读这些主题:

Synchronising with Core Audio Thread

这似乎在实质上提出了类似的问题,但对我的理解水平和情况提供更多的最新指导和解释会有所帮助,非常感谢!

对于播放,音频系统只会要求指定采样率的数据。如果您在较长时间内以比该采样率更快的速度填充循环缓冲区,那么它将溢出。

因此,您必须确保您的样本生成器或传入数据流符合音频系统配置的采样率,不多也不少(严格限制的突发或延迟抖动除外)。循环缓冲区的大小需要足够大以覆盖最大突发大小加上最大延迟抖动加上任何 pre-fill 加上安全余量。

另一个可能的错误是试图在渲染块回调中做很多事情。因此,Apple 建议不要在 real-time 音频回调中使用任何需要内存管理或锁或信号量的代码。