我有一个主要使用PyAudio的实验室项目,为了进一步了解它的工作方式,我进行了一些测量,在这种情况下是回调之间的时间(使用回调模式)。
我计时,得到了一个有趣的结果
(@ 256块大小,44.1k fs):0.0099701; 0.0000365; 0.0000201; 0.0201579
这种模式不断发展。
在两个较长的通话之间,我们有两个较短的通话,有时候通话时间较短(请注意,我在程序中没有做任何其他事情而不是回调时间)。
如果我们对此进行平均,我们会得到所需的回调时间:
1/44100 * 256(大约5.8ms)
以下是我的测量结果:
有人可以解释一下这里究竟发生了什么?
答案 0 :(得分:6)
PortAudio幕后发生的事情取决于许多因素,包括:
Pa_OpenStream()
在某些情况下,PortAudio将从本机音频API请求更大的缓冲区,然后快速连续多次调用PortAudio用户回调。如果您选择了较小的回调缓冲区大小和较长的延迟,则会发生这种情况。
另一种情况是原生音频API不支持您为回调大小请求的缓冲区大小(framesPerBuffer
参数到Pa_OpenStream()
)。在这种情况下,PortAudio将被迫使用驱动程序支持的缓冲区大小,然后"适应"在缓冲区大小和回调缓冲区大小之间。这种适应过程会导致不规则的时间安排。
另一种可能性是本机音频API使用大型环形缓冲区。每次PortAudio轮询本机主机API时,它都可以通过根据需要多次调用回调来填充本机环形缓冲区。在这种情况下,不规则的时间与轮询率有关。
以上不是唯一的可能性。
在你的情况下发生的事情的一个可能的解释是,PortAudio正在快速连续调用你的回调3次(猜测是本机缓冲区大小是你的回调缓冲区大小的3倍),原因之一是上述原因之一。
另一种可能性是本机音频子系统不规则地发信号通知PortAudio。如果PortAudio下面的系统层正在执行与上述相似的缓冲,则会发生这种情况。我已经看到这种情况发生在Windows 7上的DirectSound上。 ASIO4ALL驱动程序将出现+/- 1ms抖动(这不是您所看到的)。
您可以尝试将请求的流延迟减少到0,看看是否会更改结果。这将强制双缓冲,这可能会或可能不会产生稳定的输出。另一个尝试是使用paFramesPerBufferUnspecified
参数,这将导致使用本机缓冲区大小调用回调 - 然后您可以观察是否有更大的周期性,缓冲区大小是什么,以及是否缓冲区大小因回调而变化。
您没有说明您要定位的操作系统和主机API,因此很难提供比上述更具体的详细信息。
回答相关问题:为什么会这样?除了它是本机音频子系统的较低层或缓冲区适应过程的功能之外,它通常是指定Pa_OpenStream()
的大建议延迟的结果。如果指定的延迟非常高,某些PortAudio主机API将放宽缓冲区周期,以减少由高频定时器回调引起的系统负载。