Partilhar via


Propriedades do dispositivo (principais APIs de áudio)

Durante o processo de enumeração de dispositivos de ponto de extremidade de áudio, um aplicativo cliente pode interrogar os objetos de ponto de extremidade para suas propriedades de dispositivo. As propriedades do dispositivo são expostas na implementação da interface IPropertyStore da API MMDevice. Dada uma referência à interface IMMDevice de um objeto de ponto de extremidade, um cliente pode obter uma referência ao armazenamento de propriedades do objeto de ponto de extremidade chamando o método IMMDevice::OpenPropertyStore.

Os clientes podem ler essas propriedades, mas não devem defini-las. Os valores de propriedade são armazenados como estruturas PROPVARIANT .

O gerenciador de ponto de extremidade define as propriedades básicas do dispositivo para pontos de extremidade. O gerenciador de ponto de extremidade é o componente do Windows responsável por detectar a presença de dispositivos de ponto de extremidade de áudio.

Cada identificador de propriedade PKEY_Xxx na lista a seguir é uma constante do tipo PROPERTYKEY definida no arquivo de cabeçalho Functiondiscoverykeys_devpkey.h. Todos os dispositivos de ponto de extremidade de áudio têm essas propriedades de dispositivo.

Propriedade Descrição
PKEY_DeviceInterface_FriendlyName O nome amigável do adaptador de áudio ao qual o dispositivo de ponto de extremidade está conectado (por exemplo, "Adaptador de áudio XYZ").
PKEY_Device_DeviceDesc A descrição do dispositivo do dispositivo de ponto de extremidade (por exemplo, "Alto-falantes").
PKEY_Device_FriendlyName O nome amigável do dispositivo de ponto de extremidade (por exemplo, "Alto-falantes (adaptador de áudio XYZ)").
PKEY_Device_InstanceId Armazena o identificador de instância do dispositivo de ponto de extremidade de áudio. O valor também pode ser adquirido por meio do método IMMDevice::GetId . Para obter mais informações sobre essa propriedade, consulte Cadeias de caracteres e DEVPKEY_Device_InstanceId de ID de ponto de extremidade.
PKEY_Device_ContainerId Armazena o identificador de contêiner do dispositivo PnP que implementa o ponto de extremidade de áudio. Para obter mais informações sobre essa propriedade, consulte DEVPKEY_Device_ContainerId.

Alguns dispositivos de ponto de extremidade de áudio podem ter propriedades adicionais que não aparecem na lista anterior. Para obter mais informações sobre propriedades adicionais, consulte Propriedades do ponto de extremidade de áudio.

Para obter mais informações sobre PROPERTYKEY, consulte a documentação do Sistema de Propriedades do Windows.

O exemplo de código a seguir imprime os nomes de exibição de todos os dispositivos de ponto de extremidade de renderização de áudio no sistema:

//-----------------------------------------------------------
// This function enumerates all active (plugged in) audio
// rendering endpoint devices. It prints the friendly name
// and endpoint ID string of each endpoint device.
//-----------------------------------------------------------
#define EXIT_ON_ERROR(hres)  \
              if (FAILED(hres)) { goto Exit; }
#define SAFE_RELEASE(punk)  \
              if ((punk) != NULL)  \
                { (punk)->Release(); (punk) = NULL; }

const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);

void PrintEndpointNames()
{
    HRESULT hr = S_OK;
    IMMDeviceEnumerator *pEnumerator = NULL;
    IMMDeviceCollection *pCollection = NULL;
    IMMDevice *pEndpoint = NULL;
    IPropertyStore *pProps = NULL;
    LPWSTR pwszID = NULL;

    hr = CoCreateInstance(
           CLSID_MMDeviceEnumerator, NULL,
           CLSCTX_ALL, IID_IMMDeviceEnumerator,
           (void**)&pEnumerator);
    EXIT_ON_ERROR(hr)

    hr = pEnumerator->EnumAudioEndpoints(
                        eRender, DEVICE_STATE_ACTIVE,
                        &pCollection);
    EXIT_ON_ERROR(hr)

    UINT  count;
    hr = pCollection->GetCount(&count);
    EXIT_ON_ERROR(hr)

    if (count == 0)
    {
        printf("No endpoints found.\n");
    }

    // Each loop prints the name of an endpoint device.
    for (ULONG i = 0; i < count; i++)
    {
        // Get pointer to endpoint number i.
        hr = pCollection->Item(i, &pEndpoint);
        EXIT_ON_ERROR(hr)

        // Get the endpoint ID string.
        hr = pEndpoint->GetId(&pwszID);
        EXIT_ON_ERROR(hr)
        
        hr = pEndpoint->OpenPropertyStore(
                          STGM_READ, &pProps);
        EXIT_ON_ERROR(hr)

        PROPVARIANT varName;
        // Initialize container for property value.
        PropVariantInit(&varName);

        // Get the endpoint's friendly-name property.
        hr = pProps->GetValue(
                       PKEY_Device_FriendlyName, &varName);
        EXIT_ON_ERROR(hr)

        // GetValue succeeds and returns S_OK if PKEY_Device_FriendlyName is not found.
        // In this case vartName.vt is set to VT_EMPTY.      
        if (varName.vt != VT_EMPTY)
        {
            // Print endpoint friendly name and endpoint ID.
            printf("Endpoint %d: \"%S\" (%S)\n", 
                    i, varName.pwszVal, pwszID);
        }

        CoTaskMemFree(pwszID);
        pwszID = NULL;
        PropVariantClear(&varName);
        SAFE_RELEASE(pProps)
        SAFE_RELEASE(pEndpoint)
    }
    SAFE_RELEASE(pEnumerator)
    SAFE_RELEASE(pCollection)
    return;

Exit:
    printf("Error!\n");
    CoTaskMemFree(pwszID);
    SAFE_RELEASE(pEnumerator)
    SAFE_RELEASE(pCollection)
    SAFE_RELEASE(pEndpoint)
    SAFE_RELEASE(pProps)
}

A macro FAILED no exemplo de código anterior é definida no arquivo de cabeçalho Winerror.h.

No exemplo de código anterior, o corpo for-loop na função PrintEndpointNames chama o método IMMDevice::GetId para obter a cadeia de caracteres de ID de ponto de extremidade para o dispositivo de ponto de extremidade de áudio que é representado pela instância de interface IMMDevice. A cadeia de caracteres identifica exclusivamente o dispositivo em relação a todos os outros dispositivos de ponto de extremidade de áudio no sistema. Um cliente pode usar a cadeia de caracteres de ID de ponto de extremidade para criar uma instância do dispositivo de ponto de extremidade de áudio posteriormente ou em um processo diferente chamando o método IMMDeviceEnumerator::GetDevice . Os clientes devem tratar o conteúdo da cadeia de caracteres de ID do ponto de extremidade como opaco. Ou seja, os clientes não devem tentar analisar o conteúdo da cadeia de caracteres para obter informações sobre o dispositivo. O motivo é que o formato da cadeia de caracteres é indefinido e pode mudar de uma implementação da API MMDevice para a próxima.

Os nomes de dispositivo amigáveis e as cadeias de caracteres de ID de ponto de extremidade obtidas pela função PrintEndpointNames no exemplo de código anterior são idênticos aos nomes de dispositivo amigáveis e cadeias de caracteres de ID de ponto de extremidade fornecidos pelo DirectSound durante a enumeração de dispositivos. Para obter mais informações, consulte Eventos de áudio para aplicativos de áudio herdados.

No exemplo de código anterior, a função PrintEndpointNames 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.

Para obter mais informações sobre as interfaces IMMDeviceEnumerator, IMMDeviceCollection e IMMDevice, consulte MMDevice API.

Dispositivos de ponto de extremidade de áudio