Funções de dispositivo para aplicativos DirectSound

Observação

A API MMDevice oferece suporte a funções de dispositivo. No entanto, a interface do usuário no Windows Vista não implementa suporte para esse recurso. O suporte à interface do usuário para funções de dispositivo pode ser implementado em uma versão futura do Windows. Para obter mais informações, consulte Funções de dispositivo no Windows Vista.

 

A API DirectSound não fornece um meio para um aplicativo selecionar o dispositivo de ponto de extremidade de áudio que o usuário atribuiu a uma função de dispositivo específica. No entanto, no Windows Vista, as APIs de áudio principais podem ser usadas em conjunto com um aplicativo DirectSound para habilitar a seleção de dispositivo com base na função do dispositivo. Com a ajuda das APIs de áudio principais, o aplicativo pode identificar o dispositivo de ponto de extremidade de áudio atribuído a uma função específica, obter o GUID do dispositivo DirectSound para o dispositivo de ponto de extremidade e chamar a função DirectSoundCreate ou DirectSoundCaptureCreate para criar uma instância de interface IDirectSound ou IDirectSoundCapture que encapsula o dispositivo de ponto de extremidade. Para obter mais informações sobre o DirectSound, consulte a documentação do SDK do Windows.

O exemplo de código a seguir mostra como obter o GUID de dispositivo DirectSound para o dispositivo de renderização ou captura que está atualmente atribuído a uma função de dispositivo específica:

//-----------------------------------------------------------
// 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;
}

No exemplo de código anterior, a função GetDirectSoundGuid aceita uma direção de fluxo de dados (eRender ou eCapture) e uma função de dispositivo (eConsole, eMultimedia ou eCommunications) como parâmetros de entrada. O terceiro parâmetro é um ponteiro através do qual a função grava um GUID de dispositivo que o aplicativo pode fornecer como um parâmetro de entrada para a função DirectSoundCreate ou DirectSoundCaptureCreate .

O exemplo de código anterior obtém o GUID do dispositivo DirectSound por:

  • Criando uma instância de interface IMMDevice que representa o dispositivo de ponto de extremidade de áudio que tem a direção de fluxo de dados especificada e a função de dispositivo.
  • Abrindo o repositório de propriedades do dispositivo de ponto de extremidade de áudio.
  • Obter a propriedade PKEY_AudioEndpoint_GUID da loja de propriedades. O valor da propriedade é uma representação de cadeia de caracteres do GUID do dispositivo DirectSound para o dispositivo de ponto de extremidade de áudio.
  • Chamando a função CLSIDFromString para converter a representação de cadeia de caracteres do GUID do dispositivo em uma estrutura GUID. Para obter mais informações sobre CLSIDFromString, consulte a documentação do SDK do Windows.

Depois de obter um GUID de dispositivo da função GetDirectSoundGuid, o aplicativo pode chamar DirectSoundCreate ou DirectSoundCaptureCreate com esse GUID para criar o dispositivo de renderização ou captura DirectSound que encapsula o dispositivo de ponto de extremidade de áudio. Quando o DirectSound cria um dispositivo dessa maneira, ele sempre atribui o fluxo de áudio do dispositivo à sessão padrão — a sessão de áudio específica do processo que é identificada pelo valor GUID da sessão GUID_NULL.

Se o aplicativo exigir que o DirectSound atribua o fluxo a uma sessão de áudio de processo cruzado ou a uma sessão com um GUID de sessão não-NULL, ele deverá chamar o método IMMDevice::Activate para criar um objeto IDirectSound ou IDirectSoundCapture em vez de usar a técnica mostrada no exemplo de código anterior. Para obter um exemplo de código que mostra como usar o método Activate para especificar uma sessão de áudio entre processos ou um GUID de sessão não NULL para um fluxo, consulte Funções de dispositivo para aplicativos DirectShow. O exemplo de código nessa seção mostra como criar um filtro DirectShow, mas, com pequenas modificações, o código pode ser adaptado para criar um dispositivo DirectSound.

A função GetDirectSoundGuid no exemplo de código anterior chama a função CoCreateInstance para criar um enumerador para os dispositivos de ponto de extremidade de áudio no sistema. A menos que o programa de chamada tenha chamado anteriormente a função CoInitialize ou CoInitializeEx para inicializar a biblioteca COM, a chamada CoCreateInstance falhará. Para obter mais informações sobre CoCreateInstance, CoInitialize e CoInitializeEx, consulte a documentação do SDK do Windows.

Interoperabilidade com APIs de áudio herdadas