何时更新 ALSA 音频驱动程序缓冲区指针

When to Update ALSA Audio Driver Buffer Pointer

我正在使用 ALSA APIs 编写 USB Audio Playback 驱动程序。为此,我试图了解 Linux 内核中现有的音频驱动程序。但是我对何时更新内核音频缓冲区指针感到困惑。我们知道内核将新的音频数据放入环形缓冲区,我们的驱动程序任务是从环形缓冲区中获取新数据,通过 USB 传递并更新内核缓冲区指针。

我正在查看的驱动程序在 URB 完成函数中处理了这个问题。假设他们有一个预定义的 USB 传输大小宏,几乎在所有情况下都约为 4096 字节。因此,当 URB 传输完成并且代码执行路径进入 URB 完成时,他们将另一个 4096 字节从内核缓冲区复制到 URB 缓冲区,提交 URB 再次发送到 USB 控制器并将内核缓冲区指针转发 4096 字节。

但我不明白的是,他们为什么如此确定在 URB 传输完成时,内核缓冲区中有 4096 字节的新数据?内核缓冲区中的新数据量可能小于 4096 字节?那为什么它总是更新缓冲区指针 4096 字节。我认为应该知道内核缓冲区中有多少新字节并且驱动程序应该只更新那个数量或者我可能误解了什么?任何建议或指南都是可取的。

这些 USB 音频驱动程序的行为与 PCI 声卡完全一样,即,当设备需要一些样本时,这些样本只是从环形缓冲区中读取。

PCI 芯片无法知道缓冲区的哪一部分实际包含有效样本。 软件稍后会检测到缓冲区欠载(设备通过中断通知驱动程序当前位置;如果位置太靠前,中断处理程序会引发欠载错误)。

USB 音频驱动程序使用完全相同的机制来检测欠载,即 snd_pcm_period_elapsed() 函数检查当前位置(由您的 .pointer 回调返回)是否超前。