我能给PCM缓冲区的(可管理的)最小样本量是多少



一些API,比如这个,可以从样本数组(用数字表示(创建PCM缓冲区。

假设我想生成并播放一些(接近(实时的音频。我可以生成一个带有100个样本的PCM缓冲区,并使用我神奇的API函数将它们从声卡中发送出去。当这100个样本正在播放时,又产生了100个样本,然后切换缓冲器。最后,我可以重复编写/播放/切换过程来创建源源不断的音频。

现在,我的问题。在音频流中没有可感知的停顿的情况下,我可以使用写入/播放/切换方法的最小样本大小是多少?我知道这里的答案将取决于采样率、处理器速度和到声卡的传输时间,所以如果更合适的话,请提供一个类似"经验法则"的答案!

(我对音频有点陌生,所以请随时指出我可能存在的任何误解!(

TL;DR:1ms缓冲区在桌面操作系统上很容易实现,如果小心的话;从性能和能源使用的角度来看,这可能是不可取的。

缓冲区大小的下限(以及此输出延迟(受操作系统的最坏情况调度延迟的限制。

事件顺序为:

  1. 音频硬件从其缓冲区逐步输出样本
  2. 在某个时刻,它达到了一个低水位,并产生了一个中断,表明缓冲区需要补充更多的样本
  3. 操作系统为中断提供服务,并将线程标记为准备运行
  4. 操作系统安排线程在CPU上运行
  5. 线程计算或以其他方式获取样本,并将它们写入输出缓冲区

调度延迟是上述步骤2和4之间的时间,并且主要由主机操作的设计决定。如果使用具有先发制人优先级调度的硬RTOS(如VxWorks或eCos(,最坏的情况可能是uS的分数级。

通用桌面操作系统通常不那么流畅。MacOSX支持实时用户空间调度,并且能够轻松地为1ms缓冲区提供服务。Linux内核可以配置为抢占式实时线程和内核线程处理的下半部分中断处理程序。您还应该能够在那里获得1ms缓冲区大小。我不能评论最近版本的NT内核的功能。

在步骤5中,如果进程出现页面错误,当进程填充缓冲区时,也可能出现(通常是糟糕的(延迟。通常的做法是获得所需的所有堆和堆栈内存,并将其和程序代码和数据mlock()存储到物理内存中。

绝对忘记在解释或JITed语言运行时实现低延迟。您对语言运行时的控制太少,也没有实际的前景来防止页面错误(例如内存分配(。我怀疑10ms在这些情况下会给你带来好运。

值得注意的是,由于高中断率和上下文切换,呈现短缓冲区对系统性能(和能耗(有很大影响。这些破坏一级缓存位置的方式与它们实际所做的工作不相称。

虽然1ms的音频缓冲区是可能的,但它们并不一定是理想的。例如,现代Windows的滴答声频率在10ms到30ms之间。这意味着,通常在音频驱动程序端,你需要保留一个由一堆1ms数据包组成的环形缓冲区,以应对缓冲区不足的情况,以防CPU被其他线程从你下面拉出来。

所有现代音频引擎的音频缓冲区大小都使用2的幂。从每帧256个样本开始,看看这对你来说是如何工作的。每一块硬件都是不同的,你不能依赖于Mac或PC如何给你时间切片。当你运行音频程序时,用户可能正在其他进程上计算pi。更安全的做法是保持较大的缓冲区大小,如每帧2048个样本,如果延迟困扰用户,则让用户将其调低。

最新更新