采样率偏差和声音播放位置

时间:2012-03-19 08:30:57

标签: c++ audio callback synchronization alsa

当您将声卡速率设置为例如44100时,您无法保证实际速率等于44100.在我的情况下,应用程序和ALSA之间的流量测量(以样本/秒为单位)给出的值为44066 ... 44084。 / p>

这与重采样问题无关:即使只有-48000硬件也必须以“44100”模式以44100速率“吃掉”数据。

当我在播放此波形时尝试在波形上绘制光标时,会出现问题。我使用从WAV文件(22050,...,44100,...,48000)读取的“理想”采样率和播放开始后花费的毫秒数来计算光标位置,使用以下C ++函数:

long long getCurrentTimeMs(void)
{
    boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
    boost::posix_time::ptime    epoch_start(boost::gregorian::date(1970,1,1));
    boost::posix_time::time_duration dur = now - epoch_start;
    return dur.total_milliseconds();
}

QTimer用于生成光标动画的帧,但我不依赖于QTimer精度,因为我通过getCurrentTimeMs()询问时间(确认它足够精确)每帧,所以我可以使用不同的帧速率。

在播放2-3分钟后,我看到我听到的内容和我看到的内容之间有一点区别 - 光标位置大于播放位置,大约是1/20秒左右。

当我测量通过ALSA回调的流量时,我的平均值为44083.7样本/秒。然后我在屏幕绘图功能中使用此值作为实际速率。现在问题消失了。该程序是跨平台的,因此我将在Windows和另一个声卡上测试此测量值。

但是有更好的方法来同步声音和屏幕吗?例如,是否有一些不太耗费CPU的方式询问有关实际播放样本号的声卡?

1 个答案:

答案 0 :(得分:2)

这是一种已知的效果,例如在Windows中通过速率匹配解决,在此处描述Live Sources

在播放时,通常通过将音频硬件用作“时钟”并同步到音频播放而不是“真实”时钟来解决效果。也就是说,例如,对于音频采样率44100,25fps视频的下一视频帧与44100/25样本回放同步呈现,而不是使用1/25系统时间增量。这可以补偿不精确的有效播放速率。

捕获时,硬件本身就像是按照要求的速率提供数据。我认为你能做的最好的事情就是测量有效率,并从有效的采样率中重新采样音频。