何时更新 ALSA 音频驱动程序缓冲区指针
Posted
技术标签:
【中文标题】何时更新 ALSA 音频驱动程序缓冲区指针【英文标题】:When to Update ALSA Audio Driver Buffer Pointer 【发布时间】:2015-08-31 09:00:43 【问题描述】:我正在使用ALSA APIs
编写USB Audio Playback
驱动程序。为此,我试图了解Linux
内核中现有的音频驱动程序。但是我对何时更新内核音频缓冲区指针感到困惑。我们知道内核将新的音频数据放入环形缓冲区,我们的驱动程序任务是从环形缓冲区中获取新数据,通过 USB 传递并更新内核缓冲区指针。
我正在查看的驱动程序在 URB
完成函数中处理了这个问题。假设他们有一个预定义的 USB 传输大小宏,几乎在所有情况下都在 4096
字节左右。所以当URB
传输完成并且代码执行路径进入URB
完成时,他们将另一个4096
字节从内核缓冲区复制到URB
缓冲区,再次提交URB
到USB
控制器并将内核缓冲区指针转发4096
字节。
但我不明白的是,他们为什么如此确定在URB
传输完成时,内核缓冲区中有4096
字节的新数据?内核缓冲区中的新数据量可能小于4096
字节?那为什么它总是以4096
字节更新缓冲区指针。我认为应该知道内核缓冲区中有多少新字节,并且驱动程序应该只更新那个数量,或者我可能误解了什么?任何建议或指南都是值得赞赏的。
【问题讨论】:
【参考方案1】:这些 USB 音频驱动程序的行为与 PCI 声卡完全一样,即,当设备需要一些样本时,这些样本只是从环形缓冲区中读取。
PCI 芯片无法知道缓冲区的哪一部分实际包含有效样本。 稍后软件会检测到缓冲区欠载(设备通过中断通知驱动程序当前位置;如果位置超前,中断处理程序会引发欠载错误)。
USB 音频驱动程序使用完全相同的机制来检测欠载,即snd_pcm_period_elapsed()
函数检查当前位置(由您的.pointer
回调返回)是否超前。
【讨论】:
谢谢 CL。这回答了我的问题。只需要弄清楚一些事情。您说 USB 驱动程序使用 snd_pcm_period_elapsed() 函数来检查当前位置是否超前。那么如果它太超前了,它如何解决这个问题呢?我们是否必须让我们的驱动程序来解决这个问题,或者 ALSA 会处理这个问题? ALSA 负责停止流,或执行配置的任何操作。以上是关于何时更新 ALSA 音频驱动程序缓冲区指针的主要内容,如果未能解决你的问题,请参考以下文章