IAudioClock
COM公式ドキュメント
IAudioClock インターフェイスを使用すると、クライアントはストリームのデータレートおよびストリーム内の現在位置を監視できます。
メソッド 3
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
GetFrequency メソッドはデバイス周波数を取得します。
| pu64Frequency | ULONGLONG* | out | メソッドがデバイス周波数を書き込む UINT64 変数へのポインター。詳細については「解説」を参照してください。 |
戻り値
メソッドが成功した場合は S_OK を返します。失敗した場合、返される可能性のあるコードには次の表に示す値が含まれますが、これらに限定されません。
| 戻り値コード | 説明 |
|---|---|
| パラメーター pu64Frequency が NULL です。 | |
| オーディオエンドポイントデバイスが取り外されたか、オーディオハードウェアまたは関連するハードウェアリソースが再構成、無効化、削除、またはその他の理由で使用できなくなりました。 | |
| Windows オーディオサービスが実行されていません。 |
解説(Remarks)
デバイス周波数とは、オーディオデバイス内のハードウェアクロックによって生成される周波数です。このメソッドは、IAudioClock::GetPosition メソッドが報告するデバイス位置の単位と互換性のある単位でデバイス周波数を報告します。たとえば、あるストリームについて GetPosition メソッドが位置 p をバイトオフセットとして表す場合、GetFrequency メソッドは周波数 f をバイト/秒で表します。どのストリームについても、ストリーム開始からの秒単位のオフセットは、p と f がどの単位で表されているかにかかわらず、常に p/f として確実に計算できます。
Windows Vista では、GetFrequency を連続して呼び出したときに報告されるデバイス周波数が、ストリームの存続期間中に変化することはありません。
オーディオデバイスが生成するクロックが公称上一定の周波数で動作していても、参照クロックに対するドリフトやジッターにより、周波数が時間とともにわずかに変動することがあります。参照クロックは、壁時計や、QueryPerformanceCounter 関数が使用するシステムクロックの場合があります。GetFrequency メソッドはこのような変動を無視し、単に一定の周波数を報告します。ただし、IAudioClient::GetPosition メソッドが報告する位置は、呼び出しのたびに正確な位置値を報告するため、このようなすべての変動を考慮に入れます。QueryPerformanceCounter の詳細については、Windows SDK ドキュメントを参照してください。
GetPosition メソッドは現在のデバイス位置を取得します。
| pu64Position | ULONGLONG* | out | メソッドがデバイス位置を書き込む UINT64 変数へのポインター。デバイス位置とは、ストリームの開始からストリーム内の現在位置までのオフセットです。ただし、このオフセットを表す単位は未定義です。デバイス位置の値は、IAudioClock::GetFrequency メソッドが報告する周波数との関係においてのみ意味を持ちます。詳細については「解説」を参照してください。 |
| pu64QPCPosition | ULONGLONG* | outoptional | GetPosition 呼び出しに応答してオーディオエンドポイントデバイスがデバイス位置(*pu64Position)を読み取った時点のパフォーマンスカウンターの値を、メソッドが書き込む UINT64 変数へのポインター。メソッドは、この値を *pu64QPCPosition に書き込む前に、カウンター値を 100 ナノ秒単位の時間に変換します。クライアントがパフォーマンスカウンター値を必要としない場合、このパラメーターは NULL にできます。 |
戻り値
メソッドが成功し、正確な位置の読み取り値を取得した場合は S_OK を返します。メソッドが成功したものの、呼び出しの所要時間が位置読み取りの精度を損なうほど長い場合は S_FALSE を返します。失敗した場合、返される可能性のあるコードには次の表に示す値が含まれますが、これらに限定されません。
| 戻り値コード | 説明 |
|---|---|
| パラメーター pu64Position が NULL です。 | |
| オーディオエンドポイントデバイスが取り外されたか、オーディオハードウェアまたは関連するハードウェアリソースが再構成、無効化、削除、またはその他の理由で使用できなくなりました。 | |
| Windows オーディオサービスが実行されていません。 |
解説(Remarks)
ストリームの現在の再生位置または録音位置に基づくクロックを公開する必要があるレンダリングクライアントまたはキャプチャクライアントは、このメソッドを使用してそのクロックを導出できます。
このメソッドは、相関する 2 つのストリーム位置値を取得します。
- デバイス位置。クライアントは出力パラメーター pu64Position を通じてデバイス位置を取得します。これは、スピーカーを通して現在再生されている(レンダリングストリームの場合)、またはマイクを通して録音されている(キャプチャストリームの場合)サンプルのストリーム位置です。
- パフォーマンスカウンター。クライアントは出力パラメーター pu64QPCPosition を通じてパフォーマンスカウンターを取得します。これは、オーディオエンドポイントデバイスがストリーム位置(*pu64Position)を記録した時点で QueryPerformanceCounter 関数を呼び出してメソッドが取得したカウンター値です。GetPosition はカウンター値を 100 ナノ秒単位の時間に変換することに注意してください。
デバイス位置はストリームを基準としたオフセットです。つまり、ストリームの開始からのオフセットとして指定されます。デバイス位置は、ストリーム全体を含み先頭から末尾まで連続した理想的なバッファーへのオフセットと考えることができます。
GetPosition 呼び出し時点のデバイス位置とパフォーマンスカウンターが得られれば、クライアントは QueryPerformanceCounter を呼び出して現在のパフォーマンスカウンターを取得し、元のデバイス位置が記録されてからカウンターがどれだけ進んだかに基づいてデバイス位置を外挿することで、わずかに後の時点におけるデバイス位置のより時宜にかなった推定値を提供できます。クライアントは QueryPerformanceFrequency 関数を呼び出して、カウンターをインクリメントするクロックの周波数を判断できます。QueryPerformanceCounter から取得した生のカウンター値を GetPosition によって *pu64QPCPosition に書き込まれた値と比較する前に、次の手順で生のカウンター値を 100 ナノ秒単位の時間に変換してください。
- 生のカウンター値に 10,000,000 を乗じます。
- その結果を QueryPerformanceFrequency から取得したカウンター周波数で除算します。
新しいストリームの作成直後は、デバイス位置は 0 です。IAudioClient::Start メソッドの呼び出し後、デバイス位置は一定の速度でインクリメントされます。IAudioClient::Stop メソッドはデバイス位置を凍結し、その後の Start 呼び出しにより、デバイス位置は Stop 呼び出し時点の値からインクリメントを再開します。IAudioClient::Reset の呼び出し(ストリームが停止している間にのみ行うべきです)は、デバイス位置を 0 にリセットします。
新規またはリセットされたレンダリングストリームが最初に実行を開始するとき、オーディオデータがエンドポイントバッファーからレンダリングエンドポイントデバイスへ伝播するのに時間がかかるため、デバイス位置は数ミリ秒間 0 のままになる場合があります。デバイスを通してデータの再生が始まると、デバイス位置は 0 から 0 以外の値に変化します。
連続するデバイスの読み取り値は単調に増加します。連続する 2 回の読み取り間でデバイス位置が変化しない場合もありますが、デバイス位置がある読み取りから次の読み取りへと減少することはありません。
pu64Position パラメーターは有効な非 NULL ポインターでなければなりません。そうでない場合、メソッドは失敗し、エラーコード E_POINTER を返します。
位置の測定は、断続的で優先度の高いイベントによって遅延することがあります。これらのイベントはオーディオとは無関係な場合があります。排他モードストリームの場合、メソッドが成功したものの呼び出しの所要時間が報告される位置の精度を損なうほど長いときには、メソッドは S_OK の代わりに S_FALSE を返すことがあります。これが発生した場合、呼び出し元はメソッドを再度呼び出して、より正確な位置(戻り値 S_OK で示される)の取得を試みることができます。ただし、メソッドが一貫して S_FALSE を返す場合に備えて、呼び出し元はこのテストを無限ループで実行することは避けるべきです。
GetCharacteristics メソッドは将来の使用のために予約されています。
| pdwCharacteristics | DWORD* | out | オーディオクロックの特性を示す値を、メソッドが書き込む DWORD 変数へのポインター。 |
戻り値
メソッドが成功した場合は S_OK を返します。失敗した場合、返される可能性のあるコードには次の表に示す値が含まれますが、これらに限定されません。
| 戻り値コード | 説明 |
|---|---|
| パラメーター pdwCharacteristics が NULL です。 |
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IAudioClock "{CD63314F-3FBA-4A1B-812C-EF96358728E7}" #usecom global IAudioClock IID_IAudioClock "{}" #comfunc global IAudioClock_GetFrequency 3 var #comfunc global IAudioClock_GetPosition 4 var,var #comfunc global IAudioClock_GetCharacteristics 5 var ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。#define global IID_IAudioClock "{CD63314F-3FBA-4A1B-812C-EF96358728E7}" #usecom global IAudioClock IID_IAudioClock "{}" #comfunc global IAudioClock_GetFrequency 3 sptr #comfunc global IAudioClock_GetPosition 4 sptr,sptr #comfunc global IAudioClock_GetCharacteristics 5 sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。