オーディオ ドライバーのクライアントは 、KSPROPERTY_AUDIO_POSITION プロパティを使用して、オーディオ ストリームの現在位置を取得および設定します。 このプロパティは、 KSAUDIO_POSITION 構造体を使用して現在の位置を記述します。 構造体には、 PlayOffset と WriteOffset の 2 つのメンバーが含 まれています。
PlayOffset メンバーと WriteOffset メンバーは、オーディオ デバイスの排他的な使用のために現在予約されているクライアント バッファーの領域の境界を定義します。 クライアントは、デバイスがこのリージョンに含まれるいずれかのデータに現在アクセスしている可能性があることを前提とする必要があります。 そのため、クライアントは、この領域の外部にあるバッファーの部分にのみアクセスする必要があります。 ストリームが進むにつれて、領域の境界が移動します。
クライアント バッファーがループされている場合 (つまり、ストリームの種類が KSINTERFACE_STANDARD_LOOPED_STREAMING)、 PlayOffset と WriteOffset はバッファー相対オフセットです。 つまり、ループされたクライアント バッファーの先頭からのバイト オフセットとして指定されます。 いずれかのオフセットがバッファーの末尾まで増加すると、オフセットはバッファーの先頭まで巻き戻ります。 (バッファーの先頭のオフセットは 0 です)。したがって、どちらのオフセットもバッファー サイズを超えることはありません。
クライアント バッファーがループされていない場合 (つまり、ストリームの種類が KSINTERFACE_STANDARD_STREAMING)、 PlayOffset と WriteOffset はストリーム相対オフセットです。 具体的には、ストリームの先頭からのバイトオフセットとして指定されます。 これらのオフセットは、ストリーム全体を含み、最初から最後まで連続する理想的なバッファーへのオフセットと考えることができます。
レンダー ストリームの場合、 PlayOffset メンバーはストリームの再生位置を指定し、 WriteOffset メンバーはストリームの書き込み位置を指定します。 次の図は、クライアント バッファー内の再生位置と書き込み位置を示しています。
再生位置は、現在再生されているサンプルのバイト オフセットです (つまり、デジタルからアナログへのコンバーターまたは DAC の入力でラッチされるサンプル)。 書き込み位置は、クライアントがバッファーに安全に書き込むことができる位置です。 ストリームが再生されるにつれて、前の図の再生位置と書き込み位置が左から右に移動します。 クライアントの書き込み操作は、常に書き込み位置を上回っている必要があります。 さらに、バッファーがループされている場合、クライアントの書き込みは再生位置を超過してはなりません。
WaveCyclic または WavePci ポート ドライバーは、再生位置を追跡するためにミニポート ドライバーに依存していますが、ポート ドライバーは書き込み位置を追跡します。 WaveCyclic および WavePci ポート ドライバーは、書き込み位置を次のように更新します。
WaveCyclic
WaveCyclic ポート ドライバーが IDmaChannel::CopyTo を 呼び出して新しいデータ ブロックを (クライアント バッファーから) 循環バッファーにコピーするたびに、書き込み位置はデータ ブロック内の最後のバイトの位置 (クライアント バッファー内) に進みます。
WavePci
既定では、WavePci ミニポート ドライバーが IPortWavePciStream::GetMapping を呼び出して (クライアント バッファーの一部の) 新しいマッピングを取得し、呼び出しが成功するたびに、書き込み位置は新しいマッピングの最後のバイトの位置 (クライアント バッファー内) に進みます。
WavePci ミニポート ドライバーは、ポート ドライバーへのプリフェッチ オフセットを指定して既定の動作をオーバーライドする場合、現在の書き込み位置は常に現在の再生位置とプリフェッチ オフセットの合計と等しくなります。 詳細については、「 プリフェッチ オフセット」を参照してください。
キャプチャ ストリームの場合、 PlayOffset メンバーはストリームのレコード位置を指定し、 WriteOffset メンバーはストリームの読み取り位置を指定します。 次の図は、クライアント バッファー内のレコードと読み取り位置を示しています。
レコード位置は、アナログ・デジタル・コンバータ (ADC) の出力でラッチされる最新のサンプルのバイト・オフセットです。 (この位置は、オーディオ デバイスの DMA エンジンが最終的にサンプルを書き込むバッファーの場所を指定します)。読み取り位置は、クライアントがバッファーから安全に読み取ることができない位置です。 ストリームの記録が進行すると、前の図の読み取りとレコードの位置が左から右に進みます。 クライアントの読み取りでは、読み取り位置を追跡する必要があります。 さらに、バッファーがループされている場合、クライアントの読み取りはレコード位置の前に留まる必要があります。
WaveCyclic または WavePci ポート ドライバーは、ミニポート ドライバーに依存してレコード位置を追跡しますが、ポート ドライバーは読み取り位置を追跡します。 WaveCyclic および WavePci ポート ドライバーは、読み取り位置を次のように更新します。
WaveCyclic
WaveCyclic ポート ドライバーが IDmaChannel::CopyFrom を 呼び出して循環バッファーから (クライアント バッファーに) 新しいデータ ブロックをコピーするたびに、読み取り位置はデータ ブロック内の最後のバイトの位置 (クライアント バッファー内) に進みます。
WavePci
WavePci ミニポート ドライバーが IPortWavePciStream::ReleaseMapping を呼び出して以前に取得したマッピング (クライアント バッファーの一部) を解放するたびに、読み取り位置は解放されたマッピングの最後のバイトの位置 (クライアント バッファー内) に進みます。
ミニポートドライバーは、KSPROPERTY_AUDIO_POSITIONプロパティ要求に対するハンドラー ルーチンを実装する必要はありません。 代わりに、WaveCyclic および WavePci ポート ドライバーは、ミニポート ドライバーの代わりにこれらの要求を処理します。 get-property 要求を処理する場合、WaveCyclic または WavePci ポート ドライバーには 、WriteOffset 値を計算するために必要なすべての情報が既に含まれますが、 PlayOffset 値を計算するにはミニポート ドライバーからの情報が必要です。 この情報を取得するには、ポート ドライバーは、ミニポート ドライバーの IMiniportWaveCyclicStream::GetPosition または IMiniportWavePciStream::GetPosition メソッドを 呼び出します。
レンダー ストリームの場合、 GetPosition メソッドは再生位置 (DAC を介して現在再生されているサンプルのバイト オフセット) を取得します。 キャプチャ ストリームの場合、 GetPosition メソッドは、ADC によってキャプチャされる最新のサンプルのバイト オフセットであるレコード位置を取得します。
GetPosition 呼び出しによって取得されるオフセット値は、現在スピーカー ジャックを介して送信されている信号に対応する再生位置か、マイク ジャックを介して現在受信されている信号に対応するレコード位置のいずれかであることに注意してください。 DMA の位置ではありません。 (DMA 位置は、オーディオ デバイス内の DMA エンジンが現在 DMA バッファーとの間で転送しているサンプルのバイト オフセットです)。
一部のオーディオ ハードウェアには、各 DAC または ADC で現在サンプルのバイト オフセットを追跡するための位置レジスタが含まれています。その場合、 GetPosition メソッドは、適切なストリームの位置レジスタの内容を取得するだけです。 その他のオーディオハードウェアがDMA位置しかドライバーに提供できない場合、GetPositionメソッドは、現在のDMA位置とデバイス内部のバッファリング遅延を考慮して、DACまたはADCでのサンプルのバイトオフセットを最適に推定しなければなりません。
WaveCyclic または WavePci ポート ドライバーのプロパティ ハンドラーは、ストリーム相対またはバッファー相対バイト オフセットを提供するかどうかを決定するループバッファーと非ループ バッファーを区別する必要がありますが、この詳細 (つまり、バッファーがループまたは非ループかどうか) はミニポート ドライバーに対して透過的です。
IMiniportWaveCyclicStream::GetPosition メソッドは、クライアント バッファーがループされているかループされていないかに関係なく、常にバッファー相対再生またはレコード位置を報告します。 クライアント バッファーが連続してループ処理される場合、プロパティ ハンドラーはミニポート ドライバーによって報告される、サイクリックバッファー内のバッファー相対位置をクライアント バッファー内のオフセットに変換し、そのオフセットをPlayOffset メンバーに書き込みます。 クライアント バッファーがループされていない場合、プロパティ ハンドラーは、 PlayOffset メンバーに書き込む前に、バッファー相対再生位置をストリーム相対再生位置に変換します。
IMiniportWavePciStream::GetPosition メソッドは、クライアント バッファーがループされているかループされていないかに関係なく、ストリーム相対再生またはレコード位置を常に報告します。 クライアント バッファーがループされている場合、プロパティ ハンドラーは、ストリーム相対再生位置をバッファー相対再生位置 (クライアント バッファーへのオフセットとして表されます) に変換してから、プロパティ要求のKSAUDIO_POSITION構造体の PlayOffset メンバーに書き込みます。 クライアント バッファーがループされていない場合、プロパティ ハンドラーはストリーム相対位置を PlayOffset メンバーに書き込みます。
再生位置またはレコード位置は、ストリームの初期化直後にゼロになります。 KSSTATE_STOP状態に遷移すると ( KSSTATE を参照)、位置が 0 にリセットされます。 KSSTATE_RUNからKSSTATE_PAUSEまたはKSSTATE_ACQUIREへの遷移によってストリームが停止すると、位置が固定されます。 ストリームがKSSTATE_PAUSEまたはKSSTATE_ACQUIREからKSSTATE_RUNに遷移すると、固定解除されます。
WaveCyclic ミニポート ドライバーと WavePci ミニポート ドライバーの GetPosition メソッドの実装例については、Windows ドライバー キット (WDK) のサンプル オーディオ ドライバーを参照してください。