PyAudio:什么时候修改回调缓冲区是安全的?

PyAudio: when is it safe to modify the callback buffer?

在输出模式下运行的典型 PyAudio 回调是:

def callback(ignored, frame_count, time_info, status):
    buffer = <fill and return a buffer with frame_count samples of data>
    return (buffer, pyaudio.paContinue)

我没试过,但我很确定如果我在回调 returns 后立即开始修改 buffer,它会在播放时破坏数据 -- 是的?

那么问题来了:有没有办法知道 PyAudio 何时播放完缓冲区?如果是这样,我想创建一个缓冲池,以便在 PyAudio 完成缓冲区后我可以重用它们。

(如果没有发现 PyAudio 何时完成缓冲区的机制,我看到的唯一选择是在每次回调时分配一个新缓冲区。也许这不是什么大问题。)

由于回调在不同的线程中运行,从主线程访问您的 buffer 基本上是不安全的,并且您无法立即 知道回调何时完成(至少不是没有阻塞回调,你应该尽量避免)。但是,您可以循环浏览缓冲区列表,只要它们的总长度长于系统延迟,您就应该 合理地 安全 ...

这种情况下的典型做法是使用无锁环形缓冲区将音频数据传入和传出回调。可悲的是,PortAudio 的 ringbuffer 实现不是他们共享库的一部分,据我所知,它在 PyAudio 中也不可用(也不在 sounddevice 模块中)。

无论如何,Python 一开始就不是制作实时音频的最佳环境,因此您将不得不忍受一些限制,而且您永远无法同时拥有可靠的性能 非常低的延迟。