次の方法で共有


再生時のストリームの遅延

オーディオ再生ストリームが Run 状態にある間、WaveRT ポート ドライバーの役割は最小限です。 次の図に示すように、再生中に、WaveRT ポート ドライバーのクライアントはそのデータを循環バッファーに書き込み、オーディオ デバイスはこのデータをバッファーから読み取ります。 このアクティビティには、ポート ドライバーの介入は必要ありません。 言い換えれば、オーディオ データは、カーネル モード ソフトウェア コンポーネントに影響されることなく、ユーザー モード アプリケーションとオーディオ ハードウェアの間を直接流れます。

この図では、オーディオ データ ストリームが循環バッファーを流れるにつれて、書き込み位置と再生位置が左から右に継続的に進みます。 再生位置または書き込み位置がバッファーの終わりに達すると、バッファーの先頭に自動的にラップアラウンドするため、バッファーは循環的であると説明されます。

再生中のストリーム遅延には 2 つの主な原因があり、次の図では A と B として示されています。

Diagram showing the latency of a playback stream with write and play positions in a cyclic buffer.

上の図では、書き込み位置は、クライアントがバッファに書き込んだ最後のサンプルの直後の位置です。 再生位置は、オーディオ デバイスがスピーカーを通じて現在再生しているサンプルです。

クライアントがオーディオ サンプルをバッファに書き込んでから、オーディオ デバイスがそれを再生するまでのレイテンシは、単に書き込み位置と再生位置の間の距離です。 この分離は、次の 2 つの遅延の原因 (図では A と B としてマーク) の合計です:

レイテンシ A:オーディオ デバイスがバッファからデータを読み取った後、オーディオ デバイスがデジタル - アナログ コンバータ (DAC) を介してデータをクロックするまで、データはハードウェアの「先入れ先出し」(FIFO) バッファ内に存在します。

レイテンシ B:クライアントが巡回バッファにデータを書き込んだ後、データはオーディオ デバイスがデータを読み取るまでバッファ内に存在します。

クライアントはレイテンシ A を制御できず、レイテンシ A はハードウェアに完全に依存します。 一般的な FIFO には、サンプル クロックの約 64 ティックの間 DAC に供給するのに十分なサンプルが格納されます。 ただし、クライアントはレイテンシ B を制御します。レイテンシ B を大きくしすぎると、システムに不必要な遅延が生じます。ただし、小さすぎるとオーディオ デバイスが消耗する危険があります。

クライアントはタイマーを設定してバッファ書き込みスレッドを定期的にアクティブにすることができますが、この方法では最小の遅延は達成されません。 待ち時間をさらに短縮するために、クライアントは、デバイスがバッファからの再生データの新しいブロックの読み取りを完了するたびにハードウェア通知を生成するようにデバイスを構成できます。 この場合、クライアント スレッドはタイマーではなくハードウェア通知によってアクティブ化されます。

バッファからのデータ ブロックの読み取りが完了するたびにオーディオ デバイスにクライアントに通知させることで、クライアントは遅延を実際よりも短くすることができます。

クライアントは、KSPROPERTY_RTAUDIO_HWLATENCY リクエストを WaveRT ポート ドライバーに送信することで、ストリーム遅延の原因となる遅延の概要を取得できます。

クライアントは、書き込み位置と再生位置の間で維持する間隔の量を決定した後、再生位置の変化を監視して、書き込み位置をどれだけ進めるかを決定します。 Windows Server 2008 以降のオペレーティング システムでは、クライアントは KSPROPERTY_RTAUDIO_POSITIONREGISTER プロパティ要求を送信して、再生位置を決定します。 この機能のサポートは、PortCls システム ドライバーの改良によって提供されます。

上の図に示すように、オーディオ デバイスに位置レジスタがある場合、プロパティ要求は、そのレジスタをユーザー モード クライアントがアクセス可能な仮想メモリ アドレスにマップします。 位置レジスタがマップされた後、クライアントはメモリ アドレスの内容を読み取って、現在の再生位置を決定できます。