IMMDeviceEnumerator
COM公式ドキュメント
IMMDeviceEnumerator インターフェイスは、マルチメディアデバイスリソースを列挙するためのメソッドを提供します。
メソッド 5
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
EnumAudioEndpoints メソッドは、指定された条件を満たすオーディオエンドポイントデバイスのコレクションを生成します。
| dataFlow | EDataFlow | in | コレクションに含めるエンドポイントデバイスのデータフロー方向。呼び出し元は、このパラメーターに次の EDataFlow 列挙値のいずれかを設定します。 eRender eCapture eAll 呼び出し元が eAll を指定した場合、このメソッドはレンダリングエンドポイントとキャプチャエンドポイントの両方をコレクションに含めます。 |
| dwStateMask | DEVICE_STATE | in | コレクションに含めるエンドポイントの状態。呼び出し元は、このパラメーターに次の DEVICE_STATE_XXX 定数の 1 つ以上のビット単位 OR を設定します。 たとえば、呼び出し元が dwStateMask パラメーターに DEVICE_STATE_ACTIVE | DEVICE_STATE_UNPLUGGED を設定した場合、このメソッドはアクティブなエンドポイント、またはジャックから取り外されたエンドポイントを含めますが、無効化された、または存在しないオーディオアダプター上のエンドポイントは除外します。状態に関係なくすべてのエンドポイントを含めるには、dwStateMask = DEVICE_STATEMASK_ALL を設定します。 |
| ppDevices | IMMDeviceCollection** | out | デバイスコレクションオブジェクトの IMMDeviceCollection インターフェイスのアドレスをメソッドが書き込むポインター変数へのポインター。このメソッドを通じて、呼び出し元はインターフェイスへの参照カウントされた参照を取得します。呼び出し元は、インターフェイスが不要になったときに、そのインターフェイスの Release メソッドを呼び出して解放する責任があります。EnumAudioEndpoints の呼び出しが失敗した場合、*ppDevices は NULL になります。 |
戻り値
メソッドが成功した場合は S_OK を返します。失敗した場合、戻り値には次の表に示す値が含まれますが、これらに限定されません。
| 戻り値 | 説明 |
|---|---|
| パラメーター ppDevices が NULL です。 | |
| パラメーター dataFlow または dwStateMask が範囲外です。 | |
| メモリ不足です。 |
解説(Remarks)
たとえば、次の呼び出しは、現在アクティブな(存在し、かつ無効化されていない)すべてのオーディオレンダリングエンドポイントデバイスを列挙します。
hr = pDevEnum->EnumAudioEndpoints(
eRender, DEVICE_STATE_ACTIVE,
&pEndpoints);
上記のコードフラグメントでは、変数 hr は HRESULT 型、pDevEnum は IMMDeviceEnumerator インターフェイスへのポインター、pEndpoints は IMMDeviceCollection インターフェイスへのポインターです。
例
EnumAudioEndpoints メソッドを呼び出すコード例については、Device Properties を参照してください。
GetDefaultAudioEndpoint メソッドは、指定されたデータフロー方向とロールに対する既定のオーディオエンドポイントを取得します。
| dataFlow | EDataFlow | in | エンドポイントデバイスのデータフロー方向。呼び出し元は、このパラメーターに次の 2 つの EDataFlow 列挙値のいずれかを設定します。 eRender eCapture レンダリングデバイスのデータフロー方向は eRender です。キャプチャデバイスのデータフロー方向は eCapture です。 |
| role | ERole | in | エンドポイントデバイスのロール。呼び出し元は、このパラメーターに次の ERole 列挙値のいずれかを設定します。 eConsole eMultimedia eCommunications 詳細については、「解説」を参照してください。 |
| ppEndpoint | IMMDevice** | out | 既定のオーディオエンドポイントデバイスのエンドポイントオブジェクトの IMMDevice インターフェイスのアドレスをメソッドが書き込むポインター変数へのポインター。このメソッドを通じて、呼び出し元はインターフェイスへの参照カウントされた参照を取得します。呼び出し元は、インターフェイスが不要になったときに、そのインターフェイスの Release メソッドを呼び出して解放する責任があります。GetDefaultAudioEndpoint の呼び出しが失敗した場合、*ppDevice は NULL になります。 |
戻り値
メソッドが成功した場合は S_OK を返します。失敗した場合、戻り値には次の表に示す値が含まれますが、これらに限定されません。
| 戻り値 | 説明 |
|---|---|
| パラメーター ppDevice が NULL です。 | |
| パラメーター dataFlow または role が範囲外です。 | |
| 使用可能なデバイスがありません。 | |
| メモリ不足です。 |
解説(Remarks)
メモ
Windows Vista では、MMDevice API はデバイスロールをサポートしていますが、システム提供のユーザーインターフェイスプログラムはサポートしていません。Windows Vista のユーザーインターフェイスでは、ユーザーはレンダリング用の既定オーディオデバイスとキャプチャ用の既定オーディオデバイスを選択できます。ユーザーが既定のレンダリングデバイスまたはキャプチャデバイスを変更すると、システムは 3 つのデバイスロール(eConsole、eMultimedia、eCommunications)すべてをそのデバイスに割り当てます。したがって、GetDefaultAudioEndpoint は、role パラメーターで示されるロールに関係なく、常に既定のレンダリングデバイスまたはキャプチャデバイスを選択します。将来のバージョンの Windows では、ユーザーインターフェイスによってユーザーが個々のロールを異なるデバイスに割り当てられるようになる可能性があります。その場合、GetDefaultAudioEndpoint によるレンダリングデバイスまたはキャプチャデバイスの選択は role パラメーターに依存する可能性があります。したがって、Windows Vista で動作するように開発されたオーディオアプリケーションの動作は、将来のバージョンの Windows で実行したときに変わる可能性があります。詳細については、Device Roles in Windows Vista を参照してください。
このメソッドは、指定されたデータフロー方向(レンダリングまたはキャプチャ)とロールに対する既定のエンドポイントデバイスを取得します。たとえば、クライアントは次の呼び出しを行うことで、既定のコンソール再生デバイスを取得できます。
hr = pDevEnum->GetDefaultAudioEndpoint(
eRender, eConsole, &pDeviceOut);
上記のコードフラグメントでは、変数 hr は HRESULT 型、pDevEnum は IMMDeviceEnumerator インターフェイスへのポインター、pDeviceOut は IMMDevice インターフェイスへのポインターです。
Windows システムには、デスクトップスピーカー、高音質ヘッドホン、デスクトップマイク、スピーカーとマイク付きのヘッドセット、高音質マルチチャネルスピーカーなど、さまざまなオーディオエンドポイントデバイスの組み合わせが含まれる場合があります。ユーザーは、これらのデバイスに適切なロールを割り当てることができます。たとえば、音声通信ストリームを管理するアプリケーションは、GetDefaultAudioEndpoint を呼び出して、そのロールに指定されたレンダリングデバイスとキャプチャデバイスを識別できます。
レンダリングデバイスまたはキャプチャデバイスが 1 つしか使用できない場合、システムは常に 3 つのレンダリングロールまたはキャプチャロールすべてをそのデバイスに割り当てます。指定されたロールに対するレンダリングデバイスまたはキャプチャデバイスの検出にメソッドが失敗した場合、それはレンダリングデバイスまたはキャプチャデバイスがまったく使用できないことを意味します。使用可能なデバイスがない場合、メソッドは *ppEndpoint = NULL を設定し、ERROR_NOT_FOUND を返します。
GetDefaultAudioEndpoint メソッドを呼び出すコード例については、次のトピックを参照してください。
GetDevice メソッドは、エンドポイント ID 文字列で識別されるオーディオエンドポイントデバイスを取得します。
| pwstrId | LPWSTR | in | エンドポイント ID を格納した文字列へのポインター。呼び出し元は通常、この文字列を IMMDevice::GetId メソッド、または IMMNotificationClient インターフェイスのいずれかのメソッドから取得します。 |
| ppDevice | IMMDevice** | out | 指定されたデバイスの IMMDevice インターフェイスのアドレスをメソッドが書き込むポインター変数へのポインター。このメソッドを通じて、呼び出し元はインターフェイスへの参照カウントされた参照を取得します。呼び出し元は、インターフェイスが不要になったときに、そのインターフェイスの Release メソッドを呼び出して解放する責任があります。GetDevice の呼び出しが失敗した場合、*ppDevice は NULL になります。 |
戻り値
メソッドが成功した場合は S_OK を返します。失敗した場合、戻り値には次の表に示す値が含まれますが、これらに限定されません。
| 戻り値 | 説明 |
|---|---|
| パラメーター pwstrId または ppDevice が NULL です。 | |
| デバイス ID が、このシステム内に存在するオーディオデバイスを識別していません。 | |
| メモリ不足です。 |
解説(Remarks)
2 つのプログラムが 2 つの異なるプロセスで実行されており、両方が同じオーディオエンドポイントデバイスにアクセスする必要がある場合、一方のプログラムがデバイスの IMMDevice インターフェイスをもう一方のプログラムに単純に渡すことはできません。ただし、これらのプログラムは次の手順に従うことで同じデバイスにアクセスできます。
- 最初のプログラムが最初のプロセスで IMMDevice::GetId メソッドを呼び出し、デバイスを識別するエンドポイント ID 文字列を取得します。
- 最初のプログラムが、そのエンドポイント ID 文字列をプロセス境界を越えて 2 番目のプログラムに渡します。
- 2 番目のプロセスでデバイスの IMMDevice インターフェイスへの参照を取得するために、2 番目のプログラムがエンドポイント ID 文字列を指定して GetDevice を呼び出します。
RegisterEndpointNotificationCallback メソッドは、クライアントの通知コールバックインターフェイスを登録します。
| pClient | IMMNotificationClient* | in | クライアントが通知コールバックのために登録する IMMNotificationClient インターフェイスへのポインター。 |
戻り値
メソッドが成功した場合は S_OK を返します。失敗した場合、戻り値には次の表に示す値が含まれますが、これらに限定されません。
| 戻り値 | 説明 |
|---|---|
| パラメーター pNotify が NULL です。 | |
| メモリ不足です。 |
解説(Remarks)
このメソッドは、エンドポイントデバイスのロール、状態、存在、またはプロパティが変化したときにシステムから呼び出される IMMNotificationClient インターフェイスを登録します。呼び出し元は IMMNotificationClient インターフェイスを実装します。
通知が不要になったとき、クライアントは IMMDeviceEnumerator::UnregisterEndpointNotificationCallback メソッドを呼び出して通知を終了できます。
クライアントは、RegisterEndpointNotificationCallback の呼び出し後、かつ UnregisterEndpointNotificationCallback を呼び出す前に、IMMNotificationClient オブジェクトが解放されないようにする必要があります。これらのメソッドは、クライアントの IMMNotificationClient::AddRef および IMMNotificationClient::Release の実装を呼び出しません。クライアントは IMMNotificationClient オブジェクトの参照カウントを維持する責任があります。クライアントは、RegisterEndpointNotificationCallback の呼び出しが成功した場合はカウントをインクリメントし、UnregisterEndpointNotificationCallback を呼び出した後にのみ最後の参照を解放するか、または UnregisterEndpointNotificationCallback が呼び出される前にオブジェクトが削除されないようにするための何らかの別のメカニズムを実装する必要があります。そうしないと、アプリケーションは IMMNotificationClient および同じコンテナー内に実装されているその他のオブジェクトが保持するリソースをリークします。
AddRef および Release メソッドの詳細については、Windows SDK ドキュメントの IUnknown インターフェイスに関する説明を参照してください。
UnregisterEndpointNotificationCallback メソッドは、クライアントが以前に IMMDeviceEnumerator::RegisterEndpointNotificationCallback メソッドの呼び出しで登録した通知インターフェイスの登録を削除します。
| pClient | IMMNotificationClient* | in | クライアントの IMMNotificationClient インターフェイスへのポインター。クライアントは、以前の IMMDeviceEnumerator::RegisterEndpointNotificationCallback メソッドの呼び出しで、この同じインターフェイスポインターをデバイス列挙子に渡しました。詳細については、「解説」を参照してください。 |
戻り値
メソッドが成功した場合は S_OK を返します。失敗した場合、戻り値には次の表に示す値が含まれますが、これらに限定されません。
| 戻り値 | 説明 |
|---|---|
| パラメーター pNotify が NULL です。 | |
| 指定された通知インターフェイスが見つかりませんでした。 |
解説(Remarks)
クライアントは、RegisterEndpointNotificationCallback の呼び出し後、かつ UnregisterEndpointNotificationCallback を呼び出す前に、IMMNotificationClient オブジェクトが解放されないようにする必要があります。これらのメソッドは、クライアントの IMMNotificationClient::AddRef および IMMNotificationClient::Release の実装を呼び出しません。クライアントは IMMNotificationClient オブジェクトの参照カウントを維持する責任があります。クライアントは、RegisterEndpointNotificationCallback の呼び出しが成功した場合はカウントをインクリメントし、UnregisterEndpointNotificationCallback を呼び出した後にのみ最後の参照を解放するか、または UnregisterEndpointNotificationCallback が呼び出される前にオブジェクトが削除されないようにするための何らかの別のメカニズムを実装する必要があります。そうしないと、アプリケーションは IMMNotificationClient および同じコンテナー内に実装されているその他のオブジェクトが保持するリソースをリークします。
AddRef および Release メソッドの詳細については、Windows SDK ドキュメントの IUnknown インターフェイスに関する説明を参照してください。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IMMDeviceEnumerator "{A95664D2-9614-4F35-A746-DE8DB63617E6}"
#usecom global IMMDeviceEnumerator IID_IMMDeviceEnumerator "{BCDE0395-E52F-467C-8E3D-C4579291692E}"
#comfunc global IMMDeviceEnumerator_EnumAudioEndpoints 3 int,int,sptr
#comfunc global IMMDeviceEnumerator_GetDefaultAudioEndpoint 4 int,int,sptr
#comfunc global IMMDeviceEnumerator_GetDevice 5 wstr,sptr
#comfunc global IMMDeviceEnumerator_RegisterEndpointNotificationCallback 6 sptr
#comfunc global IMMDeviceEnumerator_UnregisterEndpointNotificationCallback 7 sptr
; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。
; ※#usecom 末尾は CoCreateInstance 用のクラスID(コクラスCLSID, SDKから自動取得)。
; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。