我正在微控制器上进行USB音频同步实现,我似乎在输入端以48kHz采样率/ 24位速率运行缓冲区欠载问题(但它的工作频率为44.1kHz)。 / p>
我在实施中是双缓冲:
(1)编解码器 - > DMA有几个缓冲区。当一个缓冲区完全填满后,我将其加载到USB缓冲区中。
(2)USB端有40个缓冲区(基本上是40ms的数据)。当缓冲区的状态为“FILLED”时,可以发送。成功进行USB传输后,将完成USB回调并发送下一个填充缓冲区。
在我的实现中,我在USB开始传输实际数据之前填充了至少3/4的缓冲区(30个缓冲区)(所以在前30ms,它只是“静音”数据)。基本上,缓冲区欠载发生的原因是我的编解码器/ dma缓冲区尚未完全填满,而下一个要读取的缓冲区是“EMPTY”。我觉得最简单的解决方案就是拥有更多的缓冲区(显然40个缓冲区是不够的;大约11kb的数据,因为40 * 294字节= 11760字节)但是我无法增加它,因为我的微控制器已经完全耗尽了存储器中。
此时我有什么选择解决这个问题?是否存在可用缓冲区限制的解决方法?我有/可用的剩余内存?或者是添加SRAM以获得足够可用缓冲区的唯一方法。
谢谢!
编辑:看起来这有点令人困惑。基本上编解码器的填充速度不够快;因此,USB缓冲区中存在数据空白并导致数据“欠载”。
EDIT2 :我正在使用隐式同步端点运行异步;主机每帧读取一次。对不起,也不清楚。
答案 0 :(得分:1)
您的端点应该由主机每帧读取一次(我假设您正在构建等时IN端点,异步与隐式同步)。如果在您的情况下不是这样,请在您的问题中明确说明,因为这将是一个非常奇怪的问题。
无论如何,正因为如此,对于超过三个缓冲区的用处不多(两个也会考虑一点仔细思考)。您不需要更多缓冲区。但是你的缓冲区应该比每帧计算的名义样本长一些,并且你的端点的描述符应该包含这个扩展的长度。
然后,总是切换缓冲区被填充,仅在USB帧的开始(或与USB SOF同步的任何其他事件)上。 无论当前缓冲区中的数据量是多少!当USB主机想要从您的端点读取数据时,您的设备必须返回与当前读取缓冲区中实际数量一样多的样本。不多也不少。
所以没有机会进行不足。当读取的缓冲区之前未完全填充时,您只需向主机发送较少数量的样本,并且主机的任务是以任何合适的方式处理时钟漂移和重新采样。另一方面,可能担心超支。如果SOF频率与ADC的采样率相比太低,您可以在SOF到来之前填充整个缓冲区,最终没有下一个样本的位置。简单的解决方法是使您的缓冲区至少比计算的名义速率长几个样本。那么你应该是安全的,否则其他地方的事情可能已经被打破了。
您可能担心的最后一个问题是,当SOF正常滴答时,主机不会为您的终端发送读取请求。好吧,在这种情况下,覆盖旧缓冲区不会有太大影响,因为主机显然对此时的数据不感兴趣,并且缓冲事物 - 从而增加延迟 - 可能会做得更糟糕。