たとえば、サウンドカードのレートを 44100 に設定すると、実際のレートが 44100 になることを保証できません。私の場合、アプリケーションと ALSA 間のトラフィック測定 (サンプル/秒) では、44066...44084 の値が得られました。
これはリサンプリングの問題とは関係ありません。48000 のハードウェアだけでも、「44100」モードで 44100 レートでデータを「食べる」必要があります。
この波形の再生中に波形上にカーソルを描画しようとすると、問題が発生します。次の C++ 関数を使用して、WAV ファイル (22050、...、44100、...、48000) から読み取った「理想的な」サンプリング レートと、再生開始後に費やしたミリ秒を使用してカーソル位置を計算します。
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 はカーソル アニメーション用のフレームを生成するために使用されますが、フレームごとに getCurrentTimeMs() (十分に正確であると仮定) で時間を尋ねるため、QTimer の精度には依存しません。したがって、さまざまなフレームレートで作業できます。
2 ~ 3 分の再生の後、私が聞いたものと私が見たものの間にわずかな違いが見られます。
ALSA のコールバックを通過するトラフィックを測定すると、44083.7 サンプル/秒の平均値が得られます。次に、この値を画面描画関数で実際のレートとして使用します。これで問題はなくなりました。このプログラムはクロスプラットフォームなので、後で Windows と別のサウンドカードでこの測定値をテストします。
しかし、サウンドとスクリーンを同期させるより良い方法はありますか? たとえば、実際に再生中のサンプル数についてサウンドカードに問い合わせる、CPU をそれほど消費しない方法はありますか?