0

我们有一个使用低级 OpenSL ES 编写的带有移动音频客户端的应用程序,以实现麦克风的低延迟输入。比我们向服务器发送封装在 UDP 数据报中的 10ms 帧。

在服务器上,我们正在做一些后期处理,这在很大程度上取决于来自移动客户端的帧以固定间隔(例如每帧 10 毫秒)出现的假设,因此我们可以对齐它们。

手机内部晶体频率似乎变化很大,正因为如此,我们在开始时得到了完美的对齐,但几分钟后对齐不佳。

我知道,Linux 上的 ALSA 可以告诉你晶体的确切频率——所以你可以根据这个来纠正你的计数。不幸的是,我不知道如何在 Android 中获取这些信息。

谢谢帮助

4

1 回答 1

3

您面临的问题的本质是您在具有不同本地振荡器的不同系统上拥有一个 ADC 和一个 DAC。您可能正在根据第三个(也可能是第四个)CPU 时钟来计时您的数据包。

这个问题的正确解决方案是某种时钟恢复算法。要正确地做到这一点,您需要一些准确的时间戳(例如比特精度)传输数据包的方法,然后使用 PLL 来驱动接收器采样时钟的时钟速率。这正是 IEEE1394 音频和 MPEG2 传输流使用的方法。

由于可能无法执行这些操作,因此您的方法很可能涉及定期丢弃或重复样本(甚至整个数据包),以防止接收缓冲区不足或溢出。

USB 音频同样缺乏对时钟恢复的硬件支持,并且那里使用的方法可能适用于您的情况。

依靠网络数据包的发送和接收时间是一个可怕的想法。交货时间的抖动是可怕的——尤其是在使用 Wifi 或蜂窝连接的情况下。建议您完全不要依赖它,而是像 IEEE1394 音频和 MPEG 2 TS 一样使用,即使用模型 FIFO 将音频数据传输与消耗分离,其中数据以恒定速率消耗并以不可靠的时间包形式交付给它。

至于 ALSA,它所能做的(除非有一个准确的外部时序参考)就是测量音频接口的采样时钟和 CPU 时钟之间的漂移。这不会产生任何东西的“精确频率”,因为这两个振荡器都不可能准确,并且两者都可能随温度而漂移。

于 2013-07-08T23:08:56.153 回答