DirectShow アプリケーションのデバイス ロール

Note

MMDevice API では、デバイス ロールがサポートされます。 ただし、Windows Vista のユーザー インターフェイスでは、この機能のサポートは実装されていません。 デバイス ロールのユーザー インターフェイスのサポートは、今後のバージョンの Windows で実装される可能性があります。 詳しくは、「Windows Vista のデバイス ロール」をご覧ください。

 

DirectShow API は、特定のデバイス ロールに割り当てられたオーディオ エンドポイント デバイスをアプリケーションが選択するための手段を提供しません。 ただし、Windows Vista では、コア オーディオ API を DirectShow アプリケーションと組み合わせて使用し、デバイスの役割に基づいてデバイスを選択できます。 アプリケーションは、コア オーディオ API を利用することにより、次の処理を実行できます。

  • ユーザーが特定のデバイス ロールに割り当てたオーディオ エンドポイント デバイスを特定する。
  • オーディオ エンドポイント デバイスをカプセル化する IBaseFilter インターフェイスを使用して DirectShow オーディオ レンダリング フィルターを作成する。
  • フィルターが組み込まれた DirectShow グラフを作成する。

DirectShow と IBaseFilter について詳しくは、Windows SDK のドキュメントをご覧ください。

次のコード例は、特定のデバイス ロールに割り当てられているレンダリング エンドポイント デバイスをカプセル化する DirectShow オーディオ レンダリング フィルターを作成する方法を示しています。

//-----------------------------------------------------------
// Create a DirectShow audio rendering filter that
// encapsulates the audio endpoint device that is currently
// assigned to the specified device role.
//-----------------------------------------------------------
#define EXIT_ON_ERROR(hres)  \
              if (FAILED(hres)) { goto Exit; }
#define SAFE_RELEASE(punk)  \
              if ((punk) != NULL)  \
                { (punk)->Release(); (punk) = NULL; }

// This application's audio session GUID
const GUID guidAudioSessionId = {
    0xb13ff52e, 0xa5cf, 0x4fca,
    {0x9f, 0xc3, 0x42, 0x26, 0x5b, 0x0b, 0x14, 0xfb}
};

HRESULT CreateAudioRenderer(ERole role, IBaseFilter** ppAudioRenderer)
{
    HRESULT hr = S_OK;
    IMMDeviceEnumerator *pEnumerator = NULL;
    IMMDevice *pDevice = NULL;

    if (ppAudioRenderer == NULL)
    {
        return E_POINTER;
    }

    // Activate the IBaseFilter interface on the
    // audio renderer with the specified role.
    hr = CoCreateInstance(CLSID_MMDeviceEnumerator,
                          NULL, CLSCTX_INPROC_SERVER,
                          __uuidof(IMMDeviceEnumerator),
                          (void**)&pEnumerator);
    EXIT_ON_ERROR(hr)

    hr = pEnumerator->GetDefaultAudioEndpoint(eRender, role,
                                              &pDevice);
    EXIT_ON_ERROR(hr)

    DIRECTX_AUDIO_ACTIVATION_PARAMS  daap;
    daap.cbDirectXAudioActivationParams = sizeof(daap);
    daap.guidAudioSession = guidAudioSessionId;
    daap.dwAudioStreamFlags = AUDCLNT_STREAMFLAGS_CROSSPROCESS;

    PROPVARIANT  var;
    PropVariantInit(&var);

    var.vt = VT_BLOB;
    var.blob.cbSize = sizeof(daap);
    var.blob.pBlobData = (BYTE*)&daap;

    hr = pDevice->Activate(__uuidof(IBaseFilter),
                           CLSCTX_ALL, &var,
                           (void**)ppAudioRenderer);
    EXIT_ON_ERROR(hr)

Exit:
    SAFE_RELEASE(pEnumerator);
    SAFE_RELEASE(pDevice);
    return hr;
}

前のコード例では、CreateAudioRenderer 関数は、デバイス ロール (eConsole、eMultimedia、または eCommunications) を入力パラメーターとして受け入れます。 2 つ目のパラメーターは、関数が IBaseFilter インターフェイス インスタンスのアドレスを書き込むポインターです。 さらに、この例は、IMMDevice::Activate メソッドを使用し、アプリケーション固有のセッション GUID (guidAudioSessionId 定数によって指定) によって、IBaseFilter インスタンス内のオーディオ ストリームをプロセス間オーディオ セッションに割り当てる方法を示しています。 Activate 呼び出しの 3 つ目のパラメーターは、セッション GUID とプロセス間フラグを含む構造を指します。 ユーザーがアプリケーションの複数のインスタンスを実行した場合、すべてのインスタンスのオーディオ ストリームは同じセッション GUID を使用するため、同じセッションに属します。

または、呼び出し元は Activate 呼び出しの 3 つ目のパラメーターとして NULL を指定して、セッション GUID 値 GUID_NULL を持つプロセス固有のセッションとして、ストリームを既定のセッションに割り当てることができます。 詳しくは、「IMMDevice::Activate」をご覧ください。

レガシ オーディオ API との相互運用性