Propiedades del dispositivo (API de audio principales)

Durante el proceso de enumeración de dispositivos de punto de conexión de audio, una aplicación cliente puede interrogar los objetos de punto de conexión para sus propiedades de dispositivo. Las propiedades del dispositivo se exponen en la implementación de la API MMDevice de la interfaz IPropertyStore . Dada una referencia a la interfaz IMMDevice de un objeto de punto de conexión, un cliente puede obtener una referencia al almacén de propiedades del objeto de punto de conexión llamando al método IMMDevice::OpenPropertyStore .

Los clientes pueden leer estas propiedades, pero no deben establecerlas. Los valores de propiedad se almacenan como estructuras PROPVARIANT .

El administrador de puntos de conexión establece las propiedades básicas del dispositivo para los puntos de conexión. El administrador de puntos de conexión es el componente de Windows responsable de detectar la presencia de dispositivos de punto de conexión de audio.

Cada PKEY_Xxx identificador de propiedad de la lista siguiente es una constante de tipo PROPERTYKEY que se define en el archivo de encabezado Functiondiscoverykeys_devpkey.h. Todos los dispositivos de punto de conexión de audio tienen estas propiedades de dispositivo.

Propiedad Descripción
PKEY_DeviceInterface_FriendlyName Nombre descriptivo del adaptador de audio al que está conectado el dispositivo de punto de conexión (por ejemplo, "Adaptador de audio XYZ").
PKEY_Device_DeviceDesc Descripción del dispositivo del punto de conexión (por ejemplo, "Altavoces").
PKEY_Device_FriendlyName Nombre descriptivo del dispositivo de punto de conexión (por ejemplo, "Altavoces (adaptador de audio XYZ)").
PKEY_Device_InstanceId Almacena el identificador de instancia de dispositivo de punto de conexión de audio. El valor también se puede consultar a través del método IMMDevice::GetId . Para obtener más información sobre esta propiedad, vea Cadenas de identificador de punto de conexión y DEVPKEY_Device_InstanceId.
PKEY_Device_ContainerId Almacena el identificador de contenedor del dispositivo PnP que implementa el punto de conexión de audio. Para obtener más información sobre esta propiedad, vea DEVPKEY_Device_ContainerId.

Algunos dispositivos de punto de conexión de audio pueden tener propiedades adicionales que no aparecen en la lista anterior. Para obtener más información sobre las propiedades adicionales, vea Propiedades de punto de conexión de audio.

Para obtener más información sobre PROPERTYKEY, vea la documentación del sistema de propiedades de Windows.

En el ejemplo de código siguiente se imprimen los nombres para mostrar de todos los dispositivos de punto de conexión de representación de audio en el 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)
}

La macro FAILED del ejemplo de código anterior se define en el archivo de encabezado Winerror.h.

En el ejemplo de código anterior, el cuerpo del bucle for en la función PrintEndpointNames llama al método IMMDevice::GetId para obtener la cadena de identificador de punto de conexión para el dispositivo de punto de conexión de audio representado por la instancia de interfaz IMMDevice . La cadena identifica de forma única el dispositivo con respecto a todos los demás dispositivos de punto de conexión de audio del sistema. Un cliente puede usar la cadena de identificador de punto de conexión para crear una instancia del dispositivo de punto de conexión de audio más adelante o en un proceso diferente llamando al método IMMDeviceEnumerator::GetDevice . Los clientes deben tratar el contenido de la cadena de identificador de punto de conexión como opaco. Es decir, los clientes no deben intentar analizar el contenido de la cadena para obtener información sobre el dispositivo. El motivo es que el formato de cadena no está definido y podría cambiar de una implementación de la API MMDevice a la siguiente.

Los nombres de dispositivo descriptivos y las cadenas de identificador de punto de conexión que obtiene la función PrintEndpointNames en el ejemplo de código anterior son idénticas a los nombres de dispositivo descriptivos y las cadenas de identificador de punto de conexión que proporciona DirectSound durante la enumeración del dispositivo. Para obtener más información, vea Eventos de audio para aplicaciones de audio heredadas.

En el ejemplo de código anterior, la función PrintEndpointNames llama a la función CoCreateInstance para crear un enumerador para los dispositivos de punto de conexión de audio del sistema. A menos que el programa de llamada anteriormente llamara a la función CoInitialize o CoInitializeEx para inicializar la biblioteca COM, se producirá un error en la llamada a CoCreateInstance . Para obtener más información sobre CoCreateInstance, CoInitialize y CoInitializeEx, consulte la documentación de Windows SDK.

Para obtener más información sobre las interfaces IMMDeviceEnumerator, IMMDeviceCollection e IMMDevice , consulte MMDevice API.

Dispositivos de punto de conexión de audio