1

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

这不应该与重采样问题有关:即使只有 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 的方式来向声卡询问实际播放的样本数?

4

1 回答 1

2

这是一个已知的效果,例如在 Windows 中由 Rate Matching 解决,此处描述为Live Sources

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

在捕获时,硬件本身就好像它以准确请求的速率传送数据一样。我认为您能做的最好的事情是测量有效速率并将音频从有效采样率重新采样到正确的采样率。

于 2012-03-19T16:19:49.003 回答