USB 音频缓冲区溢出

USB Audio Buffer Underrun

我正在微控制器上进行 USB 音频异步实现,我似乎运行进入缓冲区 运行 48kHz 采样 [=36] 输入端的问题=] 比特率(虽然它工作在 44.1kHz)。

我在我的实现中使用双缓冲:

(1) 编解码器 -> DMA 有几个缓冲区。当一个缓冲区完全填满时,我将其加载到我的 USB 缓冲区中。

(2) USB端有40个缓冲区(基本上是40ms的数据)。当缓冲区的状态为 "FILLED" 时,可以发送。 USB 传输成功后完成 USB 回调并发送下一个填充的缓冲区。

在我的实现中,我在 USB 开始传输实际数据之前填充了至少 3/4 的缓冲区(30 个缓冲区)(因此在前 30 毫秒内,它只是 "silent" 数据)。基本上,运行 下的缓冲区发生在我的 codec/dma 缓冲区尚未完全填满时,下一个要读取的缓冲区是 "EMPTY"。我觉得最简单的解决方案是拥有更多缓冲区(显然 40 个缓冲区不够;大约 11kb 的数据,因为 40 * 294 字节 = 11760 字节),但是我不能增加它,因为我的微控制器只是 运行可用内存不足。

此时我有哪些解决方案?我 have/available 剩余内存的可用缓冲区限制是否有解决方法?或者是添加 SRAM 以获得足够可用缓冲区的唯一方法。

谢谢!

编辑:看起来这有点令人困惑。基本上编解码器的填充速度不够快;因此,USB 缓冲区中存在数据间隙并创建 "underrun" 数据。

EDIT2:我正在 运行 使用隐式同步端点的异步;主机每帧被读取一次。抱歉,这也不清楚。

您的端点应由主机每帧读取一次(我假设您正在构建等时 IN 端点,异步与隐式同步)。如果您的情况并非如此,请在您的问题中明确说明,因为这将是一个非常奇怪的问题。

无论如何,正因为如此,三个以上的缓冲区没有多大用处(两个也需要仔细考虑)。您不需要更多缓冲区。但是您的缓冲区应该比计算出的每帧标称样本长一些,并且您的端点的描述符应该包含这个扩展长度。

然后,您总是切换缓冲区被填充,并且仅在 USB 帧的开始(或与 USB SOF 同步的任何其他事件)。 无论当前缓冲区中的数据量如何! 当 USB 主机想要从您的端点读取数据时,您的设备必须 return 当前缓冲区中实际存在的样本数读取缓冲区。不多也不少

所以不会有欠载的机会。当正在读取的缓冲区之前未完全填满时,您只需向主机发送较少数量的样本,主机的任务就是以任何合适的方式处理时钟漂移和重采样。另一方面,您可能 担心超限。如果 SOF 频率与 ADC 的采样率相比太低,您可能会在 SOF 到来之前填满整个缓冲区,并最终无处可用于下一个采样。简单的解决方法是使您的缓冲区至少比计算的标称速率长几个样本。那你应该是安全的,否则其他地方可能已经坏了很多。

您可能担心的最后一个问题是当 SOF 正常运行时主机没有为您的端点发送读取请求。好吧,在这种情况下,覆盖旧缓冲区不会造成太大伤害,因为此时主机显然对数据不感兴趣,并且缓冲事物 - 从而增加延迟 - 可能弊大于利。