次の方法で共有


記録時のストリームの遅延

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

次の図では、ストリームがバッファーを流れるにつれて、記録位置と読み取り位置が左から右に継続的に進みます。 レコードまたは読み取り位置がバッファーの終わりに達すると、バッファーの先頭に戻ります。

Diagram showing the record and read positions in a cyclic buffer during audio recording.

上の図は、オーディオ デバイスが現在録音している (アナログ - デジタル コンバーター、またはADC を介してマイクからキャプチャしている) サンプルのバッファー位置として録音位置を示しています。 録音位置は、オーディオ デバイスが FIFO を通過した後にサンプルを書き込む将来のバッファ位置であることに注意してください。 読み取り位置は、オーディオ エンジンが次のサンプルを読み取るバッファ位置です。

オーディオ デバイスが ADC でオーディオ サンプルをキャプチャしてからクライアントがそれを読み取るまでのレイテンシは、単に録音位置と読み取り位置の間の間隔です。 この分離は、次の遅延の原因の合計です (図では A と B としてマークされています):

レイテンシ A: ADC からデータをキャプチャした後、オーディオ デバイスは、巡回バッファにデータを書き込むことができるまで、そのデータをハードウェア FIFO に保存します。

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

クライアントはレイテンシ A を制御できず、レイテンシ A はハードウェアに完全に依存します。 一般的な FIFO は、ADC から約 64 個のサンプルを保存します。 ただし、クライアントはレイテンシー B を制御します。レイテンシー B を大きくしすぎると、システムに不要な遅延が生じますが、小さくしすぎると、オーディオ デバイスがバッファーに書き込む前にデータが読み取られるのが早すぎる危険があります。

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

オーディオ デバイスがオーディオ エンジンに定期的に通知するようにすることで、クライアントは遅延を実際よりも小さくすることができます。

クライアント (通常はオーディオ エンジン) は、KSPROPERTY_RTAUDIO_HWLATENCY リクエストを WaveRT ポート ドライバーに送信することで、オーディオ デバイスがストリーム遅延に寄与する遅延の概要を取得できます。

クライアントは、録音位置と読み取り位置の間で維持する間隔の量を決定した後、録音位置の変化を監視して、読み取り位置がどの程度遅れるかを決定します。 Windows Server 2008 以降のオペレーティング システムでは、クライアントは KSPROPERTY_AUDIO_POSITION または KSPROPERTY_RTAUDIO_POSITIONREGISTER プロパティ要求を送信して、録音位置を決定します。 後者の要求方法は、情報を取得するためにカーネル モード ルーチンに移行することなく、クライアントが録音位置を直接読み取ることができるため、より効率的です。