1

たとえば、サウンドカードのレートを 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 をそれほど消費しない方法はありますか?

4

1 に答える 1

2

これは既知の効果であり、たとえば Windows ではレート マッチングによって対処されます。ここで説明されているライブ ソース.

再生時には、通常、オーディオ ハードウェアを「クロック」として使用し、「実際の」クロックの代わりにオーディオ再生に同期することによって、効果に対処します。たとえば、オーディオ サンプリング レートが 44100 の場合、25 fps ビデオの次のビデオ フレームは、1/25 システム時間増分を使用するのではなく、44100/25 サンプル再生と同期して表示されます。これにより、不正確な実効再生レートが補正されます。

キャプチャ時に、ハードウェア自体は、正確に要求された速度でデータを配信しているかのように動作します。あなたができる最善のことは、有効なレートを測定し、オーディオを有効なサンプリングレートから正しいサンプリングレートにリサンプリングすることだと思います。

于 2012-03-19T16:19:49.003 に答える