IAudioClient
COM公式ドキュメント
IAudioClient インターフェイスは、クライアントがオーディオアプリケーションとオーディオエンジンの間(共有モードストリームの場合)、またはオーディオエンドポイントデバイスのハードウェアバッファーとの間(排他モードストリームの場合)にオーディオストリームを作成し、初期化するための機能を提供します。
解説(Remarks)
メソッド 12
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
Initialize メソッドは、オーディオストリームを初期化します。
| ShareMode | AUDCLNT_SHAREMODE | in | 接続の共有モード。このパラメーターを通じて、クライアントはオーディオエンジンに対し、他のクライアントとオーディオエンドポイントデバイスを共有したいかどうかを伝えます。クライアントはこのパラメーターに、次の AUDCLNT_SHAREMODE 列挙値のいずれかを設定します: |
| StreamFlags | DWORD | in | ストリームの作成を制御するフラグ。クライアントはこのパラメーターに 0、または 1 つ以上の AUDCLNT_STREAMFLAGS_XXX 定数あるいは AUDCLNT_SESSIONFLAGS_XXX 定数のビット単位の OR を設定します。 |
| hnsBufferDuration | LONGLONG | in | 時間値として表したバッファーの容量。このパラメーターは REFERENCE_TIME 型で、100 ナノ秒単位で表されます。このパラメーターには、オーディオアプリケーションがオーディオエンジンと共有する(共有モードの場合)、またはエンドポイントデバイスと共有する(排他モードの場合)バッファーについて、呼び出し元が要求するバッファーサイズを指定します。呼び出しが成功すると、メソッドは少なくともこのサイズのバッファーを割り当てます。REFERENCE_TIME の詳細については、Windows SDK のドキュメントを参照してください。バッファリング要件の詳細については、「解説」を参照してください。 |
| hnsPeriodicity | LONGLONG | in | デバイス周期。このパラメーターは排他モードの場合にのみゼロ以外の値を指定できます。共有モードでは、このパラメーターには常に 0 を設定します。排他モードでは、このパラメーターはオーディオエンドポイントデバイスによる連続したバッファーアクセスに対して要求されるスケジューリング周期を指定します。要求されたデバイス周期が、デバイスの最小周期とシステムの最大周期によって設定される範囲外にある場合、メソッドは周期をその範囲内に丸めます。このパラメーターが 0 の場合、メソッドはデバイス周期を既定値に設定します。既定のデバイス周期を取得するには、IAudioClient::GetDevicePeriod メソッドを呼び出します。AUDCLNT_STREAMFLAGS_EVENTCALLBACK ストリームフラグが設定されており、かつ ShareMode に AUDCLNT_SHAREMODE_EXCLUSIVE が設定されている場合、hnsPeriodicity はゼロ以外で、hnsBufferDuration と等しくなければなりません。 |
| pFormat | WAVEFORMATEX* | in | フォーマット記述子へのポインター。このパラメーターは、WAVEFORMATEX(または WAVEFORMATEXTENSIBLE)型の有効なフォーマット記述子を指す必要があります。詳細については、「解説」を参照してください。 |
| AudioSessionGuid | GUID* | inoptional | セッション GUID へのポインター。このパラメーターは、ストリームが属するオーディオセッションを識別する GUID 値を指します。この GUID が以前に開かれたセッションを識別する場合、メソッドはそのセッションにストリームを追加します。GUID が既存のセッションを識別しない場合、メソッドは新しいセッションを開いてそのセッションにストリームを追加します。ストリームはその存続期間を通じて同じセッションのメンバーであり続けます。このパラメーターに NULL を設定することは、GUID_NULL 値へのポインターを渡すことと同等です。 |
戻り値
メソッドが成功した場合は S_OK を返します。失敗した場合、返される可能性のあるコードには次の表に示す値が含まれますが、これらに限定されません。
| Return code | Description |
|---|---|
| IAudioClient オブジェクトは既に初期化されています。 | |
| AUDCLNT_STREAMFLAGS_LOOPBACK フラグが設定されていますが、エンドポイントデバイスがレンダリングデバイスではなくキャプチャデバイスです。 | |
|
Note Windows 7 以降に適用されます。
|
|
|
Note Windows 7 以降に適用されます。
|
|
| プロセスパスの継続時間が最大 CPU 使用率を超えたことを示します。オーディオエンジンは、プロセスパスの継続時間が最大 CPU 使用率を超えた回数を保持することで CPU 使用率を追跡します。最大 CPU 使用率は、エンジンの周期に対する割合として計算されます。このパーセンテージ値はシステムの CPU スロットル値(10% から 90% の範囲内)です。この値が見つからない場合は、既定値の 40% を使用して最大 CPU 使用率が計算されます。 | |
| オーディオエンドポイントデバイスが取り外されたか、オーディオハードウェアまたは関連するハードウェアリソースが再構成、無効化、削除、あるいはその他の理由で使用できなくなりました。 | |
|
ストリームのリソースが無効化されました。このエラーは次の理由でスローされることがあります: - ストリームが中断されている。 - 排他モードまたはオフロードストリームが切断された。 - 排他モードまたはオフロードストリームを持つパッケージ化アプリケーションが休止された。 - 「保護された出力」ストリームが閉じられた。 |
|
| エンドポイントデバイスは既に使用中です。デバイスが排他モードで使用されているか、デバイスが共有モードで使用されており呼び出し元がデバイスを排他モードで使用しようとしたかのいずれかです。 | |
| メソッドがレンダリングデバイスまたはキャプチャデバイスのオーディオエンドポイントの作成に失敗しました。これは、オーディオエンドポイントデバイスが取り外されたか、オーディオハードウェアまたは関連するハードウェアリソースが再構成、無効化、削除、あるいはその他の理由で使用できなくなった場合に発生する可能性があります。 | |
|
Note Windows 7 以降に適用されます。
|
|
| オーディオエンジン(共有モード)またはオーディオエンドポイントデバイス(排他モード)が、指定されたフォーマットをサポートしていません。 | |
| 呼び出し元がエンドポイントデバイスの排他モードでの使用を要求していますが、ユーザーがデバイスの排他モードでの使用を無効にしています。 | |
| AUDCLNT_STREAMFLAGS_EVENTCALLBACK フラグが設定されていますが、パラメーター hnsBufferDuration と hnsPeriodicity が等しくありません。 | |
| Windows オーディオサービスが実行されていません。 | |
| パラメーター pFormat が NULL です。 | |
|
パラメーター pFormat が無効なフォーマット記述を指しています。または、AUDCLNT_STREAMFLAGS_LOOPBACK フラグが設定されているが ShareMode が AUDCLNT_SHAREMODE_SHARED と等しくありません。あるいは、AUDCLNT_STREAMFLAGS_CROSSPROCESS フラグが設定されているが ShareMode が AUDCLNT_SHAREMODE_EXCLUSIVE と等しくなっています。
オーディオ/レンダリングストリームに対して無効なカテゴリを指定して、SetClientProperties が事前に呼び出されました。 |
|
| メモリ不足です。 |
解説(Remarks)
オーディオエンドポイントデバイス上で IAudioClient インターフェイスをアクティブ化した後、クライアントはクライアントとデバイスの間のオーディオストリームを初期化するために、Initialize を 1 回だけ正常に呼び出す必要があります。クライアントは、オーディオハードウェアに直接接続する(排他モード)か、オーディオエンジンを介して間接的に接続する(共有モード)ことができます。Initialize の呼び出しでは、クライアントはストリームのオーディオデータフォーマット、バッファーサイズ、およびオーディオセッションを指定します。
ストリームがイベント駆動かつ共有モードで初期化される場合、ShareMode は AUDCLNT_SHAREMODE_SHARED に設定され、設定されるストリームフラグの 1 つに AUDCLNT_STREAMFLAGS_EVENTCALLBACK が含まれます。このようなストリームでは、関連するアプリケーションは IAudioClient::SetEventHandle を呼び出してハンドルを取得する必要もあります。ストリームを破棄する時が来ると、オーディオエンジンはそのハンドルを使用してストリームオブジェクトを解放できます。ストリームオブジェクトを解放する前に IAudioClient::SetEventHandle を呼び出さないと、オーディオエンジンが利用可能なハンドルを待機する間、数秒(タイムアウト期間)の遅延が発生する可能性があります。タイムアウト期間が経過すると、オーディオエンジンはストリームオブジェクトを解放します。
排他モードストリームの作成の試みが成功するかどうかは、デバイスの可用性や、デバイスの排他モード動作を制御するユーザー設定など、いくつかの要因によって決まります。詳細については、「Exclusive-Mode Streams」を参照してください。
IAudioClient オブジェクトは、オーディオエンジンまたはオーディオハードウェアへの接続を正確に 1 つだけサポートします。この接続は IAudioClient オブジェクトの存続期間中維持されます。
クライアントは、次のメソッドを Initialize の呼び出し後にのみ呼び出す必要があります:
- IAudioClient::GetBufferSize
- IAudioClient::GetCurrentPadding
- IAudioClient::GetService
- IAudioClient::GetStreamLatency
- IAudioClient::Reset
- IAudioClient::SetEventHandle
- IAudioClient::Start
- IAudioClient::Stop
共有モードまたは排他モードの接続を設定するために Initialize を呼び出す前に、クライアントは IAudioClient::IsFormatSupported メソッドを呼び出して、オーディオエンジンまたはオーディオエンドポイントデバイスがそのモードで特定のフォーマットをサポートするかどうかを確認できます。共有モード接続を開く前に、クライアントは IAudioClient::GetMixFormat メソッドを呼び出してオーディオエンジンのミックスフォーマットを取得できます。
クライアントとオーディオエンジンの間で共有されるエンドポイントバッファーは、クライアントとオーディオエンジンによる処理パスの間にオーディオストリームでグリッチが発生しないように十分な大きさである必要があります。レンダリングエンドポイントの場合、クライアントスレッドは定期的にバッファーにデータを書き込み、オーディオエンジンスレッドは定期的にバッファーからデータを読み取ります。キャプチャエンドポイントの場合、エンジンスレッドが定期的にバッファーに書き込み、クライアントスレッドが定期的にバッファーから読み取ります。いずれの場合も、クライアントスレッドとエンジンスレッドの周期が等しくない場合、バッファーはグリッチが発生することなく 2 つの周期のうち長い方に対応できるだけの大きさである必要があります。
クライアントは hnsBufferDuration パラメーターを通じてバッファーサイズを指定します。クライアントは、バッファーに対して実行する定期的な処理パスの間にグリッチが発生しないように、十分な大きさのバッファーを要求する責任があります。同様に、Initialize メソッドは、エンジンスレッドがバッファーに対して実行する定期的な処理パスの間にグリッチが発生しないようにするために必要な最小バッファーサイズよりもバッファーが小さくならないようにします。クライアントがオーディオエンジンの必要とする最小バッファーサイズよりも小さいバッファーサイズを要求した場合、メソッドはクライアントが要求したバッファーサイズではなく、この最小バッファーサイズにバッファーサイズを設定します。
クライアントが(hnsBufferDuration パラメーターを通じて)オーディオフレームの整数個ではないバッファーサイズを要求した場合、メソッドは要求されたバッファーサイズを次の整数個のフレームに切り上げます。
Initialize の呼び出し後、クライアントは IAudioClient::GetBufferSize メソッドを呼び出してエンドポイントバッファーの正確なサイズを取得する必要があります。各処理パスの間、クライアントはバッファーとの間で転送するデータ量を計算するために実際のバッファーサイズを必要とします。クライアントは IAudioClient::GetCurrentPadding メソッドを呼び出して、バッファー内のデータのうち現在処理可能な量を判断します。
クライアントアプリケーションとオーディオエンドポイントデバイスの間で最小のストリームレイテンシを達成するには、クライアントスレッドをオーディオエンジンスレッドと同じ周期で実行する必要があります。エンジンスレッドの周期は固定されており、クライアントが制御することはできません。クライアントの周期をエンジンの周期より小さくすると、レイテンシを改善したりバッファーサイズを削減したりすることなく、プロセッサ上のクライアントスレッドの負荷が不必要に増加します。エンジンスレッドの周期を判断するには、クライアントは IAudioClient::GetDevicePeriod メソッドを呼び出すことができます。バッファーをエンジンスレッドが必要とする最小サイズに設定するには、クライアントは hnsBufferDuration パラメーターを 0 に設定して Initialize を呼び出す必要があります。Initialize の呼び出し後、クライアントは IAudioClient::GetBufferSize を呼び出して結果として得られるバッファーのサイズを取得できます。
クライアントは、タイミンググリッチをまれにするか発生しないようにするために厳密に必要なサイズよりも大きいバッファーサイズを要求することもできます。バッファーサイズを増やしても、必ずしもストリームレイテンシが増加するわけではありません。レンダリングストリームの場合、バッファーを通過するレイテンシは、クライアントの書き込みポインターとエンジンの読み取りポインターの間隔のみによって決まります。キャプチャストリームの場合、バッファーを通過するレイテンシは、エンジンの書き込みポインターとクライアントの読み取りポインターの間隔のみによって決まります。
ループバックフラグ(AUDCLNT_STREAMFLAGS_LOOPBACK)はオーディオループバックを有効にします。クライアントは、共有モードストリームを使用したレンダリングエンドポイントでのみオーディオループバックを有効にできます。オーディオループバックは、主に音響エコーキャンセル(AEC)をサポートするために提供されています。
AEC クライアントには、レンダリングエンドポイントと、オーディオエンジンからの出力ストリームをキャプチャする機能の両方が必要です。エンジンの出力ストリームは、オーディオデバイスがスピーカーを通して再生するグローバルミックスです。オーディオループバックが有効な場合、クライアントは IAudioClient::GetService メソッドを呼び出してレンダリングストリームオブジェクト上の IAudioCaptureClient インターフェイスを取得することで、グローバルオーディオミックス用のキャプチャバッファーを開くことができます。オーディオループバックが有効でない場合、レンダリングストリームでキャプチャバッファーを開こうとすると失敗します。キャプチャバッファー内のループバックデータはデバイスフォーマットになっており、これはデバイスの PKEY_AudioEngine_DeviceFormat プロパティを照会することでクライアントが取得できます。
Windows 10 より前の Windows バージョンでは、ストリームがイベント駆動バッファリング(AUDCLNT_STREAMFLAGS_EVENTCALLBACK)で初期化され、かつループバックが有効(AUDCLNT_STREAMFLAGS_LOOPBACK)である場合、プルモードのキャプチャクライアントはイベントを受け取りません。この構成でストリームが開かれた場合、Initialize の呼び出しは成功しますが、バッファーが処理可能になるたびにキャプチャクライアントに通知する関連イベントは発生しません。これを回避するには、レンダリングストリームをイベント駆動モードで初期化します。クライアントはレンダリングストリームのイベントを受け取るたびに、キャプチャエンドポイントバッファーから次のサンプルセットを読み取るキャプチャスレッドを実行するようにキャプチャクライアントに通知する必要があります。 Windows 10 以降では、アクティブなループバック有効ストリームに対して関連するイベントハンドルが設定されるようになりました。
排他モードストリームはループバックモードで動作できないため、すべてのストリームは共有モードで開く必要があることに注意してください。 オーディオループバックの詳細については、「Loopback Recording」を参照してください。
AUDCLNT_STREAMFLAGS_EVENTCALLBACK フラグは、クライアントによるオーディオバッファーの処理がイベント駆動になることを示します。WASAPI はイベント駆動バッファリングをサポートし、共有モードストリームと排他モードストリームの両方の低レイテンシ処理を可能にします。
Windows Vista の初期リリースでは、イベント駆動バッファリング(つまり AUDCLNT_STREAMFLAGS_EVENTCALLBACK フラグの使用)をレンダリングストリームでのみサポートしています。
Windows Vista の初期リリースでは、キャプチャストリームの場合、AUDCLNT_STREAMFLAGS_EVENTCALLBACK フラグは共有モードでのみサポートされます。このフラグを設定しても、排他モードのキャプチャストリームには効果がありません。つまり、アプリケーションが Initialize の呼び出しで排他モードでこのフラグを指定しても、通常オーディオストリームのキャプチャに必要なイベントを受け取ることはありません。Windows Vista Service Pack 1 リリースでは、このフラグは共有モードと排他モードの両方で機能します。アプリケーションはこのフラグを設定してキャプチャストリームのイベントバッファリングを有効にできます。オーディオストリームのキャプチャの詳細については、「Capturing a Stream」を参照してください。
イベント駆動バッファリングを有効にするには、クライアントはシステムにイベントハンドルを提供する必要があります。Initialize の呼び出し後、ストリームを開始するために IAudioClient::Start メソッドを呼び出す前に、クライアントは IAudioClient::SetEventHandle メソッドを呼び出してイベントハンドルを設定する必要があります。ストリームの実行中、システムは定期的にイベントをシグナル状態にして、オーディオデータが処理可能であることをクライアントに示します。処理パスの間、クライアントスレッドは WaitForSingleObject などの同期関数を呼び出してイベントハンドルを待機します。同期関数の詳細については、Windows SDK のドキュメントを参照してください。
イベント駆動バッファリングを使用する共有モードストリームでは、呼び出し元は hnsPeriodicity と hnsBufferDuration の両方を 0 に設定する必要があります。Initialize メソッドは、オーディオエンジンのスケジューリング周期に基づいて割り当てるバッファーのサイズを決定します。クライアントのバッファー処理スレッドはイベント駆動ですが、前述の基本的なバッファー管理プロセスは変わりません。スレッドが起動するたびに、IAudioClient::GetCurrentPadding を呼び出して、レンダリングバッファーに書き込むデータ量またはキャプチャバッファーから読み取るデータ量を判断する必要があります。イベント駆動バッファリングを使用する排他モードストリームに対して Initialize メソッドが割り当てる 2 つのバッファーとは対照的に、共有モードストリームでは単一のバッファーが必要です。
イベント駆動バッファリングを使用する排他モードストリームでは、呼び出し元は hnsPeriodicity と hnsBufferDuration にゼロ以外の値を指定する必要があり、これら 2 つのパラメーターの値は等しくなければなりません。Initialize メソッドはストリームに 2 つのバッファーを割り当てます。各バッファーの継続時間は hnsBufferDuration パラメーターの値と等しくなります。レンダリングストリームの場合、Initialize の呼び出し後、呼び出し元はストリームを開始する前に 2 つのバッファーのうち最初のものを埋める必要があります。キャプチャストリームの場合、バッファーは最初は空であり、呼び出し元は各バッファーのイベントがシグナル状態になるまでそのバッファーが空のままであると想定する必要があります。ストリームの実行中、システムは一方のバッファーともう一方のバッファーを交互にクライアントに送信します。この形式のダブルバッファリングは「ピンポン」と呼ばれます。クライアントはシステムからバッファーを受け取るたびに(システムはイベントをシグナル状態にすることでこれを示します)、バッファー全体を処理する必要があります。たとえば、クライアントが IAudioRenderClient::GetBuffer メソッドにバッファーサイズと一致しないパケットサイズを要求した場合、メソッドは失敗します。パケットサイズは常にバッファーサイズと等しくなければならないため、IAudioClient::GetCurrentPadding メソッドの呼び出しは不要です。前述のバッファリングモードとは対照的に、イベント駆動の排他モードストリームのレイテンシはバッファーサイズに直接依存します。
「Audio Sessions」で説明されているように、レンダリングストリームを含むセッションの既定の動作は、そのボリュームおよびミュート設定がアプリケーションの再起動をまたいで保持されることです。AUDCLNT_STREAMFLAGS_NOPERSIST フラグは既定の動作を上書きし、設定を非永続的にします。このフラグは、キャプチャストリームを含むセッションには効果がありません。それらのセッションの設定は決して永続的にはなりません。さらに、ループバックストリーム(AUDCLNT_STREAMFLAGS_LOOPBACK フラグで初期化されたストリーム)を含むセッションの設定は永続的ではありません。
レンダリングエンドポイントデバイスに接続するセッションのみが、永続的なボリュームおよびミュート設定を持つことができます。セッションに最初に追加されるストリームによって、セッションの設定が永続的かどうかが決まります。したがって、最初のストリームの初期化時に AUDCLNT_STREAMFLAGS_NOPERSIST または AUDCLNT_STREAMFLAGS_LOOPBACK フラグが設定されている場合、セッションの設定は永続的ではありません。それ以外の場合は永続的です。その永続性は、セッションオブジェクトの存続期間中にその後追加または削除される可能性のある追加のストリームの影響を受けません。
Initialize の呼び出しによって IAudioClient インターフェイスインスタンスが正常に初期化された後、同じインターフェイスインスタンスを初期化するために Initialize を再度呼び出すと失敗し、エラーコード E_ALREADY_INITIALIZED が返されます。
Initialize の最初の呼び出しが失敗した場合、インターフェイスが初期化されていなくても、その後の Initialize の呼び出しが失敗してエラーコード E_ALREADY_INITIALIZED が返されることがあります。これが発生した場合は、IAudioClient インターフェイスを解放し、Initialize を再度呼び出す前に MMDevice API から新しい IAudioClient インターフェイスを取得してください。
Initialize メソッドを呼び出すコード例については、次のトピックを参照してください:
Windows 7 以降では、Initialize はレンダリングデバイスまたはキャプチャデバイスに対して AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED を返すことがあります。これは、呼び出し元が hnsBufferDuration パラメーターで指定したバッファーサイズが整列されていないことを示します。このエラーコードは、呼び出し元が排他モードストリーム(AUDCLNT_SHAREMODE_EXCLUSIVE)とイベント駆動バッファリング(AUDCLNT_STREAMFLAGS_EVENTCALLBACK)を要求した場合にのみ返されます。Initialize が AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED を返した場合、呼び出し元は Initialize を再度呼び出し、整列されたバッファーサイズを指定する必要があります。次の手順を使用します:
- IAudioClient::GetBufferSize を呼び出して、次に高い整列されたバッファーサイズ(フレーム単位)を取得します。
- IAudioClient::Release を呼び出して、AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED を返した前回の呼び出しで使用したオーディオクライアントを解放します。
- 整列されたバッファーサイズを 100 ナノ秒単位(hns)で計算します。バッファーサイズは
(REFERENCE_TIME)((10000.0 * 1000 / WAVEFORMATEX.nSamplesPerSecond * nFrames) + 0.5)です。この式で、nFramesは GetBufferSize で取得したバッファーサイズです。 - iid パラメーターを REFIID IID_IAudioClient に設定して IMMDevice::Activate メソッドを呼び出し、新しいオーディオクライアントを作成します。
- 作成したオーディオクライアントで Initialize を再度呼び出し、新しいバッファーサイズと周期を指定します。
Windows 10 以降では、ハードウェアオフロードされたオーディオストリームはイベント駆動でなければなりません。つまり、IAudioClient2::SetClientProperties を呼び出して AudioClientProperties の bIsOffload パラメーターを TRUE に設定する場合は、IAudioClient::Initialize の StreamFlags パラメーターに AUDCLNT_STREAMFLAGS_EVENTCALLBACK フラグを指定する必要があります。
例
次のコード例は、 AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED の戻りコードに対応する方法を示しています。
#define REFTIMES_PER_SEC 10000000
HRESULT CreateAudioClient(IMMDevice* pDevice, IAudioClient** ppAudioClient)
{
if (!pDevice)
{
return E_INVALIDARG;
}
if (!ppAudioClient)
{
return E_POINTER;
}
HRESULT hr = S_OK;
WAVEFORMATEX *pwfx = NULL;
REFERENCE_TIME hnsRequestedDuration = REFTIMES_PER_SEC;
UINT32 nFrames = 0;
IAudioClient *pAudioClient = NULL;
// Get the audio client.
CHECK_HR( hr = pDevice->Activate(
__uuidof(IAudioClient),
CLSCTX_ALL,
NULL,
(void**)&pAudioClient));
// Get the device format.
CHECK_HR( hr = pAudioClient->GetMixFormat(&pwfx));
// Open the stream and associate it with an audio session.
hr = pAudioClient->Initialize(
AUDCLNT_SHAREMODE_EXCLUSIVE,
AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
hnsRequestedDuration,
hnsRequestedDuration,
pwfx,
NULL);
// If the requested buffer size is not aligned...
if (hr == AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED)
{
// Get the next aligned frame.
CHECK_HR( hr = pAudioClient->GetBufferSize(&nFrames));
hnsRequestedDuration = (REFERENCE_TIME)
((10000.0 * 1000 / pwfx->nSamplesPerSec * nFrames) + 0.5);
// Release the previous allocations.
SAFE_RELEASE(pAudioClient);
CoTaskMemFree(pwfx);
// Create a new audio client.
CHECK_HR( hr = pDevice->Activate(
__uuidof(IAudioClient),
CLSCTX_ALL,
NULL,
(void**)&pAudioClient));
// Get the device format.
CHECK_HR( hr = pAudioClient->GetMixFormat(&pwfx));
// Open the stream and associate it with an audio session.
CHECK_HR( hr = pAudioClient->Initialize(
AUDCLNT_SHAREMODE_EXCLUSIVE,
AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
hnsRequestedDuration,
hnsRequestedDuration,
pwfx,
NULL));
}
else
{
CHECK_HR (hr);
}
// Return to the caller.
*(ppAudioClient) = pAudioClient;
(*ppAudioClient)->AddRef();
done:
// Clean up.
CoTaskMemFree(pwfx);
SAFE_RELEASE(pAudioClient);
return hr;
}
GetBufferSize メソッドは、エンドポイントバッファーのサイズ(最大容量)を取得します。
| pNumBufferFrames | DWORD* | out | メソッドがバッファーに保持できるオーディオフレーム数を書き込む UINT32 変数へのポインター。 |
戻り値
メソッドが成功した場合は S_OK を返します。失敗した場合、返される可能性のあるコードには次の表に示す値が含まれますが、これらに限定されません。
| Return code | Description |
|---|---|
| オーディオストリームが正常に初期化されていません。 | |
| オーディオエンドポイントデバイスが取り外されたか、オーディオハードウェアまたは関連するハードウェアリソースが再構成、無効化、削除、あるいはその他の理由で使用できなくなりました。 | |
|
ストリームのリソースが無効化されました。このエラーは次の理由でスローされることがあります: - ストリームが中断されている。 - 排他モードまたはオフロードストリームが切断された。 - 排他モードまたはオフロードストリームを持つパッケージ化アプリケーションが休止された。 - 「保護された出力」ストリームが閉じられた。 |
|
| Windows オーディオサービスが実行されていません。 | |
| パラメーター pNumBufferFrames が NULL です。 |
解説(Remarks)
このメソッドには、IAudioClient インターフェイスの事前の初期化が必要です。このメソッドへのすべての呼び出しは、クライアントが IAudioClient::Initialize メソッドを正常に呼び出してオーディオストリームを初期化するまで、エラー AUDCLNT_E_NOT_INITIALIZED で失敗します。
このメソッドは、クライアントアプリケーションとオーディオエンジンの間で共有されるエンドポイントバッファーの長さを取得します。長さは、バッファーが保持できるオーディオフレーム数として表されます。オーディオフレームのバイト単位のサイズは、ストリーム内のチャネル数にチャネルあたりのサンプルサイズを掛けて計算されます。たとえば、16 ビットサンプルのステレオ(2 チャネル)ストリームの場合、フレームサイズは 4 バイトです。
IAudioClient::Initialize メソッドがバッファーを割り当てます。クライアントは、Initialize メソッドに渡す hnsBufferDuration パラメーター値でバッファー長を指定します。レンダリングクライアントの場合、バッファー長は、単一の処理パス中にアプリケーションがエンドポイントバッファーに書き込むことができるレンダリングデータの最大量を決定します。キャプチャクライアントの場合、バッファー長は、単一の処理パス中にオーディオエンジンがエンドポイントバッファーから読み取ることができるキャプチャデータの最大量を決定します。クライアントは、要求したサイズと異なる可能性のある、割り当てられたバッファーの実際のサイズを判断するために、Initialize の呼び出し後に常に GetBufferSize を呼び出す必要があります。
レンダリングクライアントは、この値を使用して、各処理パス中に IAudioRenderClient::GetBuffer から要求できる最大のレンダリングバッファーサイズを計算できます。
GetBufferSize メソッドを呼び出すコード例については、次のトピックを参照してください:
GetStreamLatency メソッドは、現在のストリームの最大レイテンシを取得します。このメソッドはストリームが初期化された後であればいつでも呼び出すことができます。
| phnsLatency | LONGLONG* | out | メソッドがレイテンシを表す時間値を書き込む REFERENCE_TIME 変数へのポインター。時間は 100 ナノ秒単位で表されます。REFERENCE_TIME の詳細については、Windows SDK のドキュメントを参照してください。 |
戻り値
メソッドが成功した場合は S_OK を返します。失敗した場合、返される可能性のあるコードには次の表に示す値が含まれますが、これらに限定されません。
| Return code | Description | ||
|---|---|---|---|
| オーディオストリームが正常に初期化されていません。 | |||
|
ストリームのリソースが無効化されました。このエラーは次の理由でスローされることがあります: |
- ストリームが中断されている。 - 排他モードまたはオフロードストリームが切断された。 - 排他モードまたはオフロードストリームを持つパッケージ化アプリケーションが休止された。 - 「保護された出力」ストリームが閉じられた。 |
オーディオエンドポイントデバイスが取り外されたか、オーディオハードウェアまたは関連するハードウェアリソースが再構成、無効化、削除、あるいはその他の理由で使用できなくなりました。 |
| Windows オーディオサービスが実行されていません。 | |||
| パラメーター phnsLatency が NULL です。 |
解説(Remarks)
このメソッドには、IAudioClient インターフェイスの事前の初期化が必要です。このメソッドへのすべての呼び出しは、クライアントが IAudioClient::Initialize メソッドを正常に呼び出してオーディオストリームを初期化するまで、エラー AUDCLNT_E_NOT_INITIALIZED で失敗します。
このメソッドは、現在のストリームの最大レイテンシを取得します。この値は IAudioClient オブジェクトの存続期間中変化しません。
レンダリングクライアントは、このレイテンシ値を使用して、単一の処理パス中に書き込むことができるデータの最小量を計算できます。この最小量より少なく書き込むと、オーディオストリームにグリッチが発生するリスクがあります。詳細については、「IAudioRenderClient::GetBuffer」を参照してください。
GetCurrentPadding メソッドは、エンドポイントバッファー内のパディングのフレーム数を取得します。
| pNumPaddingFrames | DWORD* | out | メソッドがフレーム数(バッファー内のパディングのオーディオフレーム数)を書き込む UINT32 変数へのポインター。 |
戻り値
メソッドが成功した場合は S_OK を返します。失敗した場合、返される可能性のあるコードには次の表に示す値が含まれますが、これらに限定されません。
| Return code | Description |
|---|---|
| オーディオストリームが正常に初期化されていません。 | |
| オーディオエンドポイントデバイスが取り外されたか、オーディオハードウェアまたは関連するハードウェアリソースが再構成、無効化、削除、あるいはその他の理由で使用できなくなりました。 | |
|
ストリームのリソースが無効化されました。このエラーは次の理由でスローされることがあります: - ストリームが中断されている。 - 排他モードまたはオフロードストリームが切断された。 - 排他モードまたはオフロードストリームを持つパッケージ化アプリケーションが休止された。 - 「保護された出力」ストリームが閉じられた。 |
|
| Windows オーディオサービスが実行されていません。 | |
| パラメーター pNumPaddingFrames が NULL です。 |
解説(Remarks)
このメソッドには、IAudioClient インターフェイスの事前の初期化が必要です。このメソッドへのすべての呼び出しは、クライアントが IAudioClient::Initialize メソッドを正常に呼び出してオーディオストリームを初期化するまで、エラー AUDCLNT_E_NOT_INITIALIZED で失敗します。
このメソッドは、エンドポイントバッファーに現在含まれている、有効で未読のデータの量を示すパディング値を取得します。レンダリングアプリケーションは、パディング値を使用して、オーディオエンジンがバッファーからまだ読み取っていない、以前に書き込んだデータを上書きせずに安全にエンドポイントバッファーに書き込める新しいデータの量を判断できます。キャプチャアプリケーションは、パディング値を使用して、オーディオエンジンがまだ有効なデータを書き込んでいないバッファー領域から無効なデータを読み取ることなく、安全にエンドポイントバッファーから読み取れる新しいデータの量を判断できます。
パディング値はオーディオフレーム数として表されます。オーディオフレームのサイズは、クライアントが IAudioClient::Initialize メソッドに渡した WAVEFORMATEX(または WAVEFORMATEXTENSIBLE)構造体の nBlockAlign メンバーによって指定されます。オーディオフレームのバイト単位のサイズは、ストリーム内のチャネル数にチャネルあたりのサンプルサイズを掛けたものと等しくなります。たとえば、16 ビットサンプルのステレオ(2 チャネル)ストリームの場合、フレームサイズは 4 バイトです。
共有モードのレンダリングストリームの場合、GetCurrentPadding によって報告されるパディング値は、エンドポイントバッファー内で再生待ちになっているオーディオフレーム数を指定します。エンドポイントバッファーに書き込む前に、クライアントはバッファー長からパディング値を減算することで、バッファー内の空き領域の量を計算できます。後続の IAudioRenderClient::GetBuffer メソッドの呼び出しが成功するように、クライアントはバッファー内の空き領域を超えないパケット長を要求する必要があります。バッファー長を取得するには、IAudioClient::GetBufferSize メソッドを呼び出します。
共有モードのキャプチャストリームの場合、GetCurrentPadding によって報告されるパディング値は、エンドポイントバッファー内の次のパケットで利用可能なキャプチャデータのフレーム数を指定します。特定の時点で、クライアントがバッファーから読み取れるキャプチャデータのパケットは 0 個、1 個、または複数個ある場合があります。現在利用可能なパケットがない場合、メソッドはパディング値 0 を報告します。GetCurrentPadding の呼び出しに続いて、IAudioCaptureClient::GetBuffer メソッドの呼び出しは、GetCurrentPadding によって報告されたパディング値と正確に等しい長さのパケットを取得します。GetBuffer の各呼び出しは 1 つのパケット全体を取得します。パケットには常に整数個のオーディオフレームが含まれます。
共有モードのキャプチャストリームの場合、GetCurrentPadding の呼び出しは IAudioCaptureClient::GetNextPacketSize メソッドの呼び出しと同等です。つまり、GetCurrentPadding によって報告されるパディング値は、GetNextPacketSize によって報告されるパケット長と等しくなります。
AUDCLNT_STREAMFLAGS_EVENTCALLBACK フラグで初期化された排他モードのレンダリングまたはキャプチャストリームの場合、クライアントは通常 GetCurrentPadding によって報告されるパディング値を使用しません。代わりに、クライアントは各処理パス中にバッファー全体にアクセスします。バッファーが処理可能になるたびに、オーディオエンジンはクライアントのイベントハンドルをシグナル状態にすることでクライアントに通知します。このフラグの詳細については、「IAudioClient::Initialize」を参照してください。
AUDCLNT_STREAMFLAGS_EVENTCALLBACK フラグで初期化されなかった排他モードのレンダリングまたはキャプチャストリームの場合、クライアントは GetCurrentPadding から取得したパディング値を、前述の共有モードストリームで説明したのと同様の方法で使用できます。詳細は次のとおりです。
まず、排他モードのレンダリングストリームの場合、パディング値はエンドポイントバッファー内で再生待ちになっているオーディオフレーム数を指定します。前と同様に、クライアントはバッファー長からパディング値を減算することでバッファー内の空き領域の量を計算できます。
次に、排他モードのキャプチャストリームの場合、GetCurrentPadding によって報告されるパディング値は、次のパケットの現在の長さを指定します。ただし、このパディング値はパケット長のスナップショットであり、クライアントが IAudioCaptureClient::GetBuffer メソッドを呼び出す前に増加する可能性があります。したがって、GetBuffer によって取得されるパケットの長さは、少なくとも GetCurrentPadding の呼び出しによって報告されたパディング値と同じ大きさですが、それより大きい場合があります。対照的に、共有モードのキャプチャストリームの場合、GetBuffer から取得されるパケットの長さは、先行する GetCurrentPadding の呼び出しによって報告されたパディング値と常に等しくなります。
GetCurrentPadding メソッドを呼び出すコード例については、「Rendering a Stream」を参照してください。
IsFormatSupported メソッドは、オーディオエンドポイントデバイスが特定のストリームフォーマットをサポートしているかどうかを示します。
| ShareMode | AUDCLNT_SHAREMODE | in | ストリームフォーマットの共有モード。このパラメーターを通じて、クライアントは指定されたフォーマットを排他モードで使用するか共有モードで使用するかを示します。クライアントはこのパラメーターに、次の AUDCLNT_SHAREMODE 列挙値のいずれかを設定します: |
| pFormat | WAVEFORMATEX* | in | 指定されたストリームフォーマットへのポインター。このパラメーターは、WAVEFORMATEX または WAVEFORMATEXTENSIBLE 型の、呼び出し元が割り当てたフォーマット記述子を指します。クライアントはこのメソッドを呼び出す前に、この構造体にフォーマット記述を書き込みます。WAVEFORMATEX と WAVEFORMATEXTENSIBLE の詳細については、Windows DDK のドキュメントを参照してください。 |
| ppClosestMatch | WAVEFORMATEX** | outoptional | メソッドが WAVEFORMATEX または WAVEFORMATEXTENSIBLE 構造体のアドレスを書き込むポインター変数へのポインター。この構造体は、クライアントが pFormat パラメーターを通じて指定したフォーマットに最も近い、サポートされるフォーマットを指定します。共有モード(つまり ShareMode パラメーターが AUDCLNT_SHAREMODE_SHARED の場合)では、ppClosestMatch を有効な非 NULL のポインター変数を指すように設定します。排他モードでは、ppClosestMatch を NULL に設定します。メソッドがこの構造体のストレージを割り当てます。呼び出し元は、不要になったときに CoTaskMemFree 関数を呼び出してストレージを解放する責任があります。IsFormatSupported の呼び出しが失敗し、ppClosestMatch が非 NULL の場合、メソッドは *ppClosestMatch を NULL に設定します。CoTaskMemFree の詳細については、Windows SDK のドキュメントを参照してください。 |
戻り値
| Return code | Description |
|---|---|
| 成功し、オーディオエンドポイントデバイスが指定されたストリームフォーマットをサポートしています。 | |
| 成功し、指定されたフォーマットに最も近い一致が得られました。 | |
| 成功しましたが、指定されたフォーマットは排他モードではサポートされていません。 |
操作が失敗した場合、返される可能性のあるコードには次の表に示す値が含まれますが、これらに限定されません。
| Return code | Description |
|---|---|
| パラメーター pFormat が NULL です。または、ppClosestMatch が NULL かつ ShareMode が AUDCLNT_SHAREMODE_SHARED です。 | |
| パラメーター ShareMode が AUDCLNT_SHAREMODE_SHARED または AUDCLNT_SHAREMODE_EXCLUSIVE 以外の値です。 | |
| オーディオエンドポイントデバイスが取り外されたか、オーディオハードウェアまたは関連するハードウェアリソースが再構成、無効化、削除、あるいはその他の理由で使用できなくなりました。 | |
|
ストリームのリソースが無効化されました。このエラーは次の理由でスローされることがあります: - ストリームが中断されている。 - 排他モードまたはオフロードストリームが切断された。 - 排他モードまたはオフロードストリームを持つパッケージ化アプリケーションが休止された。 - 「保護された出力」ストリームが閉じられた。 |
|
| Windows オーディオサービスが実行されていません。 |
解説(Remarks)
このメソッドは、クライアントが IAudioClient::Initialize を呼び出す前に、オーディオエンジンが特定のストリームフォーマットをサポートしているかどうかを判断する手段を提供します。
排他モードの場合、IsFormatSupported は、オーディオエンドポイントデバイスが呼び出し元の指定したフォーマットをサポートしていれば S_OK を返し、デバイスがそのフォーマットをサポートしていなければ AUDCLNT_E_UNSUPPORTED_FORMAT を返します。ppClosestMatch パラメーターは NULL にできます。NULL でない場合、メソッドは *ppClosestMatch に NULL を書き込みます。
共有モードの場合、オーディオエンジンが呼び出し元の指定したフォーマットをサポートしていれば、IsFormatSupported は *ppClosestMatch を NULL に設定して S_OK を返します。オーディオエンジンが呼び出し元の指定したフォーマットをサポートしていないが、類似のフォーマットをサポートしている場合、メソッドは ppClosestMatch パラメーターを通じて類似のフォーマットを取得して S_FALSE を返します。オーディオエンジンが呼び出し元の指定したフォーマットも類似のフォーマットもサポートしていない場合、メソッドは *ppClosestMatch を NULL に設定して AUDCLNT_E_UNSUPPORTED_FORMAT を返します。
共有モードでは、オーディオエンジンは常にミックスフォーマットをサポートしています。ミックスフォーマットは、クライアントが IAudioClient::GetMixFormat メソッドを呼び出して取得できます。さらに、オーディオエンジンは、ミックスフォーマットと同じサンプルレートおよびチャネル数を持ちながら、オーディオサンプル値の表現が異なる類似のフォーマットをサポートしている場合があります。オーディオエンジンは内部的にサンプル値を浮動小数点数として表現しますが、呼び出し元の指定したフォーマットがサンプル値を整数として表現する場合、オーディオエンジンは通常、整数のサンプル値と内部の浮動小数点表現の間で変換できます。
オーディオデバイスのインストールパッケージにフォーマット変換を処理できるローカルエフェクト(LFX)オーディオ処理オブジェクト(APO)が含まれている場合、オーディオエンジンはさらに広範囲の共有モードフォーマットをサポートできる可能性があります。LFX APO は、オーディオストリームのデバイス固有の処理を実行するソフトウェアモジュールです。Windows オーディオサービスのオーディオグラフビルダーは、各クライアントとオーディオエンジンの間のストリームに LFX APO を挿入します。クライアントが IsFormatSupported メソッドを呼び出し、メソッドがデバイスで使用するために LFX APO がインストールされていると判断した場合、メソッドはクエリを LFX APO に転送し、LFX APO は呼び出し元の指定したフォーマットをサポートするかどうかを示します。
たとえば、特定の LFX APO はクライアントから 6 チャネルのサラウンドサウンドストリームを受け入れ、ストリームをヘッドフォンで再生できるステレオフォーマットに変換する場合があります。通常、LFX APO は、ミックスフォーマットのサンプルレートと一致するサンプルレートを持つクライアントフォーマットのみをサポートします。
APO の詳細については、「Windows Audio Processing Objects」を参照してください。IsFormatSupported メソッドの詳細については、「Device Formats」を参照してください。
GetMixFormat メソッドは、オーディオエンジンが共有モードストリームの内部処理に使用するストリームフォーマットを取得します。
| ppDeviceFormat | WAVEFORMATEX** | out | メソッドがミックスフォーマットのアドレスを書き込むポインター変数へのポインター。このパラメーターは、有効な非 NULL のポインター変数へのポインターでなければなりません。メソッドはこの変数に WAVEFORMATEX(または WAVEFORMATEXTENSIBLE)構造体のアドレスを書き込みます。メソッドがこの構造体のストレージを割り当てます。呼び出し元は、不要になったときに CoTaskMemFree 関数を呼び出してストレージを解放する責任があります。GetMixFormat の呼び出しが失敗した場合、*ppDeviceFormat は NULL になります。WAVEFORMATEX、WAVEFORMATEXTENSIBLE、および CoTaskMemFree の詳細については、Windows SDK のドキュメントを参照してください。 |
戻り値
メソッドが成功した場合は S_OK を返します。失敗した場合、返される可能性のあるコードには次の表に示す値が含まれますが、これらに限定されません。
| Return code | Description |
|---|---|
| オーディオエンドポイントデバイスが取り外されたか、オーディオハードウェアまたは関連するハードウェアリソースが再構成、無効化、削除、あるいはその他の理由で使用できなくなりました。 | |
|
ストリームのリソースが無効化されました。このエラーは次の理由でスローされることがあります: - ストリームが中断されている。 - 排他モードまたはオフロードストリームが切断された。 - 排他モードまたはオフロードストリームを持つパッケージ化アプリケーションが休止された。 - 「保護された出力」ストリームが閉じられた。 |
|
| Windows オーディオサービスが実行されていません。 | |
| パラメーター ppDeviceFormat が NULL です。 | |
| メモリ不足です。 |
解説(Remarks)
クライアントは、IAudioClient::Initialize メソッドを呼び出す前にこのメソッドを呼び出すことができます。オーディオエンドポイントデバイス用の共有モードストリームを作成する際、Initialize メソッドは、同じデバイスに対する GetMixFormat の呼び出しから取得したストリームフォーマットを常に受け入れます。
ミックスフォーマットは、オーディオエンジンが共有モードストリームのデジタル処理に内部的に使用するフォーマットです。このフォーマットは、必ずしもオーディオエンドポイントデバイスがサポートするフォーマットとは限りません。したがって、呼び出し元は GetMixFormat を呼び出して取得したフォーマットで排他モードストリームを作成できない場合があります。
たとえば、デジタルオーディオ処理を容易にするために、オーディオエンジンはサンプルを浮動小数点値として表現するミックスフォーマットを使用する場合があります。デバイスが整数 PCM サンプルのみをサポートしている場合、エンジンはデバイスとエンジンの間の接続でサンプルを整数 PCM 値との間で変換します。ただし、リサンプリングを回避するために、エンジンはデバイスがサポートするサンプルレートを持つミックスフォーマットを使用する場合があります。
Initialize メソッドが特定のフォーマットで共有モードまたは排他モードのストリームを作成できるかどうかを判断するには、IAudioClient::IsFormatSupported メソッドを呼び出します。
WAVEFORMATEX 構造体だけでは、チャネルからスピーカー位置へのマッピングを指定できません。さらに、WAVEFORMATEX は各オーディオサンプルのコンテナーのサイズを指定できますが、サンプル内の精度のビット数(たとえば 24 ビットコンテナー内の 20 ビットの精度)を指定できません。しかし、WAVEFORMATEXTENSIBLE 構造体は、チャネルからスピーカーへのマッピングと各サンプルの精度のビット数の両方を指定できます。このため、GetMixFormat メソッドは、単独の WAVEFORMATEX 構造体ではなく、WAVEFORMATEXTENSIBLE 構造体の形式のフォーマット記述子を取得します。ppDeviceFormat パラメーターを通じて、メソッドはこの WAVEFORMATEXTENSIBLE 構造体の先頭に埋め込まれた WAVEFORMATEX 構造体へのポインターを出力します。WAVEFORMATEX と WAVEFORMATEXTENSIBLE の詳細については、Windows DDK のドキュメントを参照してください。
GetMixFormat メソッドの詳細については、「Device Formats」を参照してください。GetMixFormat を呼び出すコード例については、次のトピックを参照してください:
GetDevicePeriod メソッドは、オーディオエンジンがエンドポイントバッファー内のデータに対して連続した処理パスを行う間の周期的な間隔の長さを取得します。
| phnsDefaultDevicePeriod | LONGLONG* | outoptional | メソッドがオーディオエンジンによる周期的な処理パス間の既定の間隔を指定する時間値を書き込む REFERENCE_TIME 変数へのポインター。時間は 100 ナノ秒単位で表されます。REFERENCE_TIME の詳細については、Windows SDK のドキュメントを参照してください。 |
| phnsMinimumDevicePeriod | LONGLONG* | outoptional | メソッドがオーディオエンドポイントデバイスによる周期的な処理パス間の最小の間隔を指定する時間値を書き込む REFERENCE_TIME 変数へのポインター。時間は 100 ナノ秒単位で表されます。 |
戻り値
メソッドが成功した場合は S_OK を返します。失敗した場合、返される可能性のあるコードには次の表に示す値が含まれますが、これらに限定されません。
| Return code | Description |
|---|---|
| オーディオエンドポイントデバイスが取り外されたか、オーディオハードウェアまたは関連するハードウェアリソースが再構成、無効化、削除、あるいはその他の理由で使用できなくなりました。 | |
|
ストリームのリソースが無効化されました。このエラーは次の理由でスローされることがあります: - ストリームが中断されている。 - 排他モードまたはオフロードストリームが切断された。 - 排他モードまたはオフロードストリームを持つパッケージ化アプリケーションが休止された。 - 「保護された出力」ストリームが閉じられた。 |
|
| Windows オーディオサービスが実行されていません。 | |
| パラメーター phnsDefaultDevicePeriod と phnsMinimumDevicePeriod の両方が NULL です。 |
解説(Remarks)
クライアントは、IAudioClient::Initialize メソッドを呼び出す前にこのメソッドを呼び出すことができます。
phnsDefaultDevicePeriod パラメーターは、共有モードストリームの既定のスケジューリング周期を指定します。phnsMinimumDevicePeriod パラメーターは、排他モードストリームの最小スケジューリング周期を指定します。
2 つのパラメーター phnsDefaultDevicePeriod と phnsMinimumDevicePeriod のうち少なくとも 1 つは非 NULL でなければなりません。そうでない場合、メソッドはエラーコード E_POINTER を返してただちに終了します。両方のパラメーターが非 NULL の場合、メソッドは既定の周期と最小の周期の両方を出力します。
共有モードストリームの場合、オーディオエンジンは、クライアントアプリケーションと共有するエンドポイントバッファー内のデータを定期的に処理します。エンジンは、一定の間隔でこれらの処理パスを実行するようにスケジュールします。
オーディオエンジンによる処理パス間の周期は特定のオーディオエンドポイントデバイスに対して固定されており、オーディオエンジンの最小の処理量子を表します。この周期に、バッファーとエンドポイントデバイスの間のストリームレイテンシを加えたものが、オーディオアプリケーションが達成できる最小のレイテンシを表します。
クライアントは、周期的な処理スレッドをオーディオエンジンと同じ時間間隔で実行するようにスケジュールするオプションがあります。この方法により、クライアントは共有モードストリームで可能な限り小さいレイテンシを達成できます。ただし、レイテンシがそれほど重要でないアプリケーションでは、クライアントは処理パスの発生頻度を下げるようにスケジュールすることで、CPU 上のプロセス切り替えのオーバーヘッドを削減できます。この場合、処理パス間の周期が長くなることを補うために、エンドポイントバッファーは比例して大きくする必要があります。
クライアントは、IAudioClient::Initialize メソッドの呼び出し中にバッファーサイズを決定します。共有モードストリームの場合、クライアントがこのメソッドに hnsBufferDuration パラメーター値として 0 を渡すと、メソッドはクライアントとオーディオエンジンの周期が確実に等しいと想定し、可能な限り小さいレイテンシを達成できるだけの小さいバッファーを割り当てます。(実際には、0 からオーディオエンジンの周期とデバイスレイテンシの合計までの間の hnsBufferDuration の値は、いずれも同じ結果になります。)同様に、排他モードストリームの場合、クライアントが hnsBufferDuration を 0 に設定すると、メソッドはクライアントの周期がオーディオエンドポイントデバイスの最小周期に設定されていると想定し、可能な限り小さいレイテンシを達成できるだけの小さいバッファーを割り当てます。
クライアントがレイテンシの増加という代償を払って周期的な処理スレッドの実行頻度を下げることを選択する場合、IAudioClient::Initialize の呼び出し中に十分な大きさのエンドポイントバッファーを作成する限り、それが可能です。
Start メソッドは、オーディオストリームを開始します。
戻り値
メソッドが成功した場合は S_OK を返します。失敗した場合、返される可能性のあるコードには次の表に示す値が含まれますが、これらに限定されません。
| Return code | Description |
|---|---|
| オーディオストリームが正常に初期化されていません。 | |
| Start の呼び出し時点でオーディオストリームが停止されていませんでした。 | |
| オーディオストリームはイベント駆動バッファリングを使用するように構成されていますが、呼び出し元がストリームにイベントハンドルを設定するために IAudioClient::SetEventHandle を呼び出していません。 | |
| オーディオエンドポイントデバイスが取り外されたか、オーディオハードウェアまたは関連するハードウェアリソースが再構成、無効化、削除、あるいはその他の理由で使用できなくなりました。 | |
| Windows オーディオサービスが実行されていません。 |
解説(Remarks)
このメソッドには、IAudioClient インターフェイスの事前の初期化が必要です。このメソッドへのすべての呼び出しは、クライアントが IAudioClient::Initialize メソッドを正常に呼び出してオーディオストリームを初期化するまで、エラー AUDCLNT_E_NOT_INITIALIZED で失敗します。
Start は、オーディオストリームを開始するためにクライアントが呼び出す制御メソッドです。ストリームを開始すると、IAudioClient オブジェクトがエンドポイントバッファーとオーディオエンジンの間でデータのストリーミングを開始します。また、ストリームのオーディオクロックが現在の位置からカウントを再開します。
ストリームの初期化後にこのメソッドが最初に呼び出されると、IAudioClient オブジェクトのストリーム位置カウンターは 0 から始まります。それ以外の場合、クロックはストリームが最後に停止された時点の位置から再開します。ストリームをリセットすると、ストリーム位置は強制的に 0 に戻されます。
レンダリングストリームで起動時のグリッチを回避するために、クライアントはレンダリングインターフェイスの IAudioRenderClient::GetBuffer および IAudioRenderClient::ReleaseBuffer メソッドを呼び出してオーディオエンジンに最初にデータを読み込むまで、Start を呼び出さないようにする必要があります。
Start メソッドを呼び出すコード例については、次のトピックを参照してください:
Stop メソッドは、オーディオストリームを停止します。
戻り値
メソッドが成功してストリームを停止した場合は S_OK を返します。メソッドが成功したがストリームが既に停止していた場合は S_FALSE を返します。失敗した場合、返される可能性のあるコードには次の表に示す値が含まれますが、これらに限定されません。
| Return code | Description |
|---|---|
| クライアントが正常に初期化されていません。 | |
| Windows オーディオサービスが実行されていません。 |
解説(Remarks)
このメソッドには、IAudioClient インターフェイスの事前の初期化が必要です。このメソッドへのすべての呼び出しは、クライアントが IAudioClient::Initialize メソッドを正常に呼び出してオーディオストリームを初期化するまで、エラー AUDCLNT_E_NOT_INITIALIZED で失敗します。
Stop は、実行中のオーディオストリームを停止する制御メソッドです。このメソッドは、オーディオエンジンとのクライアントの接続を通じたデータのストリーミングを停止します。ストリームを停止すると、ストリームのオーディオクロックが現在のストリーム位置で固定されます。IAudioClient::Start を後続して呼び出すと、ストリームはその位置から実行を再開します。必要に応じて、クライアントはストリームが停止している間に IAudioClient::Reset メソッドを呼び出して位置をリセットできます。
Stop メソッドを呼び出すコード例については、次のトピックを参照してください:
Reset メソッドは、オーディオストリームをリセットします。
戻り値
メソッドが成功した場合は S_OK を返します。メソッドが成功したがストリームが既にリセットされていた場合は S_FALSE を返します。失敗した場合、返される可能性のあるコードには次の表に示す値が含まれますが、これらに限定されません。
| Return code | Description |
|---|---|
| オーディオストリームが正常に初期化されていません。 | |
| 呼び出しが行われた時点でオーディオストリームが停止されていませんでした。 | |
| クライアントは現在バッファーへの書き込みまたはバッファーからの読み取りを行っています。 | |
| Windows オーディオサービスが実行されていません。 |
解説(Remarks)
このメソッドには、IAudioClient インターフェイスの事前の初期化が必要です。このメソッドへのすべての呼び出しは、クライアントが IAudioClient::Initialize メソッドを正常に呼び出してオーディオストリームを初期化するまで、エラー AUDCLNT_E_NOT_INITIALIZED で失敗します。
Reset は、停止したオーディオストリームをリセットするためにクライアントが呼び出す制御メソッドです。ストリームをリセットすると、保留中のすべてのデータがフラッシュされ、オーディオクロックのストリーム位置が 0 にリセットされます。このメソッドは、停止していないストリームに対して呼び出された場合は失敗します。
SetEventHandle メソッドは、オーディオバッファーがクライアントによる処理の準備が整ったときにシステムがシグナル状態にするイベントハンドルを設定します。
| eventHandle | HANDLE | in | イベントハンドル。 |
戻り値
メソッドが成功した場合は S_OK を返します。失敗した場合、返される可能性のあるコードには次の表に示す値が含まれますが、これらに限定されません。
| Return code | Description |
|---|---|
| パラメーター eventHandle が NULL または無効なハンドルです。 | |
| オーディオストリームがイベント駆動バッファリング用に初期化されていません。 | |
| オーディオストリームが正常に初期化されていません。 | |
| オーディオエンドポイントデバイスが取り外されたか、オーディオハードウェアまたは関連するハードウェアリソースが再構成、無効化、削除、あるいはその他の理由で使用できなくなりました。 | |
| Windows オーディオサービスが実行されていません。 |
解説(Remarks)
このメソッドには、IAudioClient インターフェイスの事前の初期化が必要です。このメソッドへのすべての呼び出しは、クライアントが IAudioClient::Initialize メソッドを正常に呼び出してオーディオストリームを初期化するまで、エラー AUDCLNT_E_NOT_INITIALIZED で失敗します。
ストリームの初期化中に、クライアントはオプションとしてイベント駆動バッファリングを有効にできます。そのためには、クライアントは AUDCLNT_STREAMFLAGS_EVENTCALLBACK フラグを設定して IAudioClient::Initialize メソッドを呼び出します。イベント駆動バッファリングを有効にした後、ストリームを開始するために IAudioClient::Start メソッドを呼び出す前に、クライアントは SetEventHandle を呼び出して、バッファーがクライアントによる処理の準備が整うたびにシステムがシグナル状態にするイベントハンドルを登録する必要があります。
イベントハンドルは、クライアントが Start メソッドを呼び出す時点で非シグナル状態である必要があります。
クライアントがストリームのイベント駆動バッファリングを有効にしたにもかかわらず、最初に SetEventHandle を呼び出さずにそのストリームに対して Start メソッドを呼び出した場合、Start の呼び出しは失敗してエラーコードを返します。
クライアントがストリームのイベント駆動バッファリングを有効にしていないのに SetEventHandle を呼び出してストリームのイベントハンドルを設定しようとした場合、その呼び出しは失敗してエラーコードを返します。
SetEventHandle メソッドを呼び出すコード例については、「Exclusive-Mode Streams」を参照してください。
GetService メソッドは、オーディオクライアントオブジェクトから追加のサービスにアクセスします。
| riid | GUID* | in | 要求するサービスのインターフェイス ID。クライアントはこのパラメーターに、次の REFIID 値のいずれかを設定します: IID_IAudioCaptureClient IID_IAudioClientDuckingControl IID_IAudioClock IID_IAudioRenderClient IID_IAudioSessionControl IID_IAudioStreamVolume IID_IChannelAudioVolume IID_IMFTrustedOutput IID_ISimpleAudioVolume 詳細については、「解説」を参照してください。 |
| ppv | void** | out | メソッドが要求されたインターフェイスのインスタンスのアドレスを書き込むポインター変数へのポインター。このメソッドを通じて、呼び出し元はインターフェイスへの参照カウント付きの参照を取得します。呼び出し元は、不要になったときにインターフェイスの Release メソッドを呼び出してインターフェイスを解放する責任があります。GetService の呼び出しが失敗した場合、*ppv は NULL になります。 |
戻り値
メソッドが成功した場合は S_OK を返します。失敗した場合、返される可能性のあるコードには次の表に示す値が含まれますが、これらに限定されません。
| Return code | Description |
|---|---|
| パラメーター ppv が NULL です。 | |
| 要求されたインターフェイスは利用できません。 | |
| オーディオストリームが初期化されていません。 | |
| 呼び出し元が、レンダリングエンドポイントで IAudioCaptureClient インターフェイスに、またはキャプチャエンドポイントで IAudioRenderClient インターフェイスにアクセスしようとしました。 | |
| オーディオエンドポイントデバイスが取り外されたか、オーディオハードウェアまたは関連するハードウェアリソースが再構成、無効化、削除、あるいはその他の理由で使用できなくなりました。 | |
|
ストリームのリソースが無効化されました。このエラーは次の理由でスローされることがあります: - ストリームが中断されている。 - 排他モードまたはオフロードストリームが切断された。 - 排他モードまたはオフロードストリームを持つパッケージ化アプリケーションが休止された。 - 「保護された出力」ストリームが閉じられた。 |
|
| Windows オーディオサービスが実行されていません。 |
解説(Remarks)
このメソッドには、IAudioClient インターフェイスの事前の初期化が必要です。このメソッドへのすべての呼び出しは、クライアントが IAudioClient::Initialize メソッドを正常に呼び出してオーディオストリームを初期化するまで、エラー AUDCLNT_E_NOT_INITIALIZED で失敗します。
GetService メソッドは、次のサービスインターフェイスをサポートします:
- IAudioCaptureClient
- IAudioClock
- IAudioRenderClient
- IAudioSessionControl
- IAudioStreamVolume
- IChannelAudioVolume
- IMFTrustedOutput
- ISimpleAudioVolume
OTA での信頼されたオーディオドライバーの使用については、「Protected User Mode Audio (PUMA)」を参照してください。
このメカニズムを通じた IMFTrustedOutput のアクティブ化は、呼び出し元が PMP で実行されているかどうかに関係なく機能することに注意してください。ただし、呼び出し元が保護されたプロセスで実行されていない(つまり、呼び出し元が Media Foundation の PMP 内にない)場合、オーディオ OTA は PMP 内で動作しない可能性があり、保護設定はそれほど堅牢ではありません。
サービスインターフェイスのインターフェイス ID を取得するには、__uuidof 演算子を使用します。たとえば、IAudioCaptureClient のインターフェイス ID は次のように定義されます:
const IID IID_IAudioCaptureClient __uuidof(IAudioCaptureClient)
__uuidof 演算子の詳細については、Windows SDK のドキュメントを参照してください。
IAudioClient オブジェクトを解放し、関連するすべてのリソースを解放するには、クライアントは IAudioClient インターフェイス自体に対して Release を呼び出すことに加えて、GetService を呼び出して作成したすべてのサービスオブジェクトへのすべての参照を解放する必要があります。クライアントは、IAudioClient オブジェクトを解放するのと同じスレッドからサービスを解放する必要があります。
IAudioSessionControl、IAudioStreamVolume、IChannelAudioVolume、および ISimpleAudioVolume インターフェイスは、オーディオセッションと共有モードストリームのさまざまな側面を制御および監視します。これらのインターフェイスは排他モードストリームでは機能しません。
GetService メソッドを呼び出すコード例については、次のトピックを参照してください:
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IAudioClient "{1CB9AD4C-DBFA-4C32-B178-C2F568A703B2}" #usecom global IAudioClient IID_IAudioClient "{}" #comfunc global IAudioClient_Initialize 3 int,int,int64,int64,var,var #comfunc global IAudioClient_GetBufferSize 4 var #comfunc global IAudioClient_GetStreamLatency 5 var #comfunc global IAudioClient_GetCurrentPadding 6 var #comfunc global IAudioClient_IsFormatSupported 7 int,var,var #comfunc global IAudioClient_GetMixFormat 8 var #comfunc global IAudioClient_GetDevicePeriod 9 var,var #comfunc global IAudioClient_Start 10 #comfunc global IAudioClient_Stop 11 #comfunc global IAudioClient_Reset 12 #comfunc global IAudioClient_SetEventHandle 13 sptr #comfunc global IAudioClient_GetService 14 var,sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_IAudioClient "{1CB9AD4C-DBFA-4C32-B178-C2F568A703B2}" #usecom global IAudioClient IID_IAudioClient "{}" #comfunc global IAudioClient_Initialize 3 int,int,int64,int64,sptr,sptr #comfunc global IAudioClient_GetBufferSize 4 sptr #comfunc global IAudioClient_GetStreamLatency 5 sptr #comfunc global IAudioClient_GetCurrentPadding 6 sptr #comfunc global IAudioClient_IsFormatSupported 7 int,sptr,sptr #comfunc global IAudioClient_GetMixFormat 8 sptr #comfunc global IAudioClient_GetDevicePeriod 9 sptr,sptr #comfunc global IAudioClient_Start 10 #comfunc global IAudioClient_Stop 11 #comfunc global IAudioClient_Reset 12 #comfunc global IAudioClient_SetEventHandle 13 sptr #comfunc global IAudioClient_GetService 14 sptr,sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。