DirectSound 应用程序的设备角色

注意

MMDevice API 支持设备角色。 但是,Windows Vista 中的用户界面不支持此功能。 在将来的 Windows 版本中,可能会实现对设备角色的用户界面支持。 有关详细信息,请参阅 Windows Vista 中的设备角色。

 

DirectSound API 不提供应用程序选择用户分配给特定 设备角色音频终结点设备 的方法。 但是,在 Windows Vista 中,核心音频 API 可与 DirectSound 应用程序结合使用,以基于设备角色启用设备选择。 在核心音频 API 的帮助下, 应用程序可以标识分配给特定角色的音频终结点设备,获取终结点设备的 DirectSound 设备 GUID,并调用 DirectSoundCreateDirectSoundCaptureCreate 函数来创建 IDirectSoundIDirectSoundCapture 封装终结点设备的接口实例。 有关 DirectSound 的详细信息,请参阅 Windows SDK 文档。

以下代码示例演示如何获取当前分配给特定设备角色的呈现或捕获设备的 DirectSound 设备 GUID:

//-----------------------------------------------------------
// Get the DirectSound or DirectSoundCapture device GUID for
// an audio endpoint device. If flow = eRender, the function
// gets the DirectSound device GUID for the rendering device
// with the specified device role. If flow = eCapture, the
// function gets the DirectSoundCapture device GUID for the
// capture device with the specified device role.
//-----------------------------------------------------------
#define EXIT_ON_ERROR(hr)  \
              if (FAILED(hr)) { goto Exit; }
#define SAFE_RELEASE(punk)  \
              if ((punk) != NULL)  \
                { (punk)->Release(); (punk) = NULL; }

HRESULT GetDirectSoundGuid(EDataFlow flow, ERole role, GUID* pDevGuid)
{
    HRESULT hr = S_OK;
    IMMDeviceEnumerator *pEnumerator = NULL;
    IMMDevice *pDevice = NULL;
    IPropertyStore *pProps = NULL;

    PROPVARIANT var;
    PropVariantInit(&var);

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

    // Get a device enumerator for the audio endpoint
    // devices in the system.
    hr = CoCreateInstance(__uuidof(MMDeviceEnumerator),
                          NULL, CLSCTX_INPROC_SERVER,
                          __uuidof(IMMDeviceEnumerator),
                          (void**)&pEnumerator);
    EXIT_ON_ERROR(hr)

    // Get the endpoint device with the specified dataflow
    // direction (eRender or eCapture) and device role.
    hr = pEnumerator->GetDefaultAudioEndpoint(flow, role,
                                              &pDevice);
    EXIT_ON_ERROR(hr)

    hr = pDevice->OpenPropertyStore(STGM_READ, &pProps);
    EXIT_ON_ERROR(hr)

    // Get the DirectSound or DirectSoundCapture device GUID
    // (in WCHAR string format) for the endpoint device.
    hr = pProps->GetValue(PKEY_AudioEndpoint_GUID, &var);
    EXIT_ON_ERROR(hr)

    // Convert the WCHAR string to a GUID structure.
    hr = CLSIDFromString(var.pwszVal, pDevGuid);
    EXIT_ON_ERROR(hr)

Exit:
    PropVariantClear(&var);
    SAFE_RELEASE(pEnumerator);
    SAFE_RELEASE(pDevice);
    SAFE_RELEASE(pProps);
    return hr;
}

在前面的代码示例中,GetDirectSoundGuid 函数接受数据流方向(eRender 或 eCapture)和设备角色(eConsole、eMultimedia 或 eCommunications)作为输入参数。 第三个参数是一个指针,函数通过该指针将应用程序可以作为输入参数提供给 DirectSoundCreateDirectSoundCaptureCreate 函数的设备 GUID。

前面的代码示例通过以下方法获取 DirectSound 设备 GUID:

  • 创建 IMMDevice 接口实例,该实例表示具有指定数据流方向和设备角色的音频终结点设备。
  • 打开音频终结点设备的属性存储。
  • 从属性存储中获取 PKEY_AudioEndpoint_GUID 属性。 属性值是音频终结点设备的 DirectSound 设备 GUID 的字符串表示形式。
  • 调用 CLSIDFromString 函数,将设备 GUID 的字符串表示形式转换为 GUID 结构。 有关 CLSIDFromString的详细信息,请参阅 Windows SDK 文档。

从 GetDirectSoundGuid 函数获取设备 GUID 后,应用程序可以使用此 GUID 调用 DirectSoundCreateDirectSoundCaptureCreate 来创建封装音频终结点设备的 DirectSound 呈现或捕获设备。 当 DirectSound 以这种方式创建设备时,它始终将设备的音频流分配给默认会话,即由会话 GUID 值GUID_NULL标识的进程特定的音频会话。

如果应用程序要求 DirectSound 将流分配给跨进程音频会话或非NULL 会话 GUID 的会话,则应调用 IMMDevice::Activate 方法来创建 IDirectSoundIDirectSoundCapture 对象,而不是使用上述代码示例所示的技术。 有关演示如何使用 Activate 方法为流指定跨进程音频会话或非NULL 会话 GUID 的代码示例,请参阅 directShow 应用程序 设备角色。 该部分中的代码示例演示如何创建 DirectShow 筛选器,但通过轻微修改,可以调整代码以创建 DirectSound 设备。

前面的代码示例中的 GetDirectSoundGuid 函数调用 CoCreateInstance 函数,为系统中的音频终结点设备创建枚举器。 除非调用程序之前调用 CoInitializeCoInitializeEx 函数来初始化 COM 库,否则 CoCreateInstance 调用将失败。 有关 CoCreateInstanceCoInitializeCoInitializeEx的详细信息,请参阅 Windows SDK 文档。

与旧版音频 API 的互作性