Propriétés de l’appareil (API audio principales)

Pendant le processus d’énumération des appareils de point de terminaison audio, une application cliente peut interroger les objets de point de terminaison pour leurs propriétés d’appareil. Les propriétés de l’appareil sont exposées dans l’implémentation par l’API MMDevice de l’interface IPropertyStore . Étant donné une référence à l’interface IMMDevice d’un objet de point de terminaison, un client peut obtenir une référence au magasin de propriétés de l’objet de point de terminaison en appelant la méthode IMMDevice::OpenPropertyStore .

Les clients peuvent lire ces propriétés, mais ne doivent pas les définir. Les valeurs de propriété sont stockées en tant que structures PROPVARIANT .

Le gestionnaire de points de terminaison définit les propriétés de base de l’appareil pour les points de terminaison. Le gestionnaire de points de terminaison est le composant Windows chargé de détecter la présence d’appareils de point de terminaison audio.

Chaque identificateur de propriété PKEY_Xxx dans la liste suivante est une constante de type PROPERTYKEY définie dans le fichier d’en-tête Functiondiscoverykeys_devpkey.h. Tous les appareils de point de terminaison audio ont ces propriétés d’appareil.

Propriété Description
PKEY_DeviceInterface_FriendlyName Nom convivial de l’adaptateur audio auquel le périphérique de point de terminaison est attaché (par exemple, « adaptateur audio XYZ »).
PKEY_Device_DeviceDesc Description de l’appareil de point de terminaison (par exemple, « Haut-parleurs »).
PKEY_Device_FriendlyName Nom convivial de l’appareil de point de terminaison (par exemple, « Haut-parleurs (adaptateur audio XYZ) »).
PKEY_Device_InstanceId Stocke l’identificateur instance de l’appareil de point de terminaison audio. La valeur peut également être requise via la méthode IMMDevice::GetId . Pour plus d’informations sur cette propriété, consultez Chaînes d’ID de point de terminaison et DEVPKEY_Device_InstanceId.
PKEY_Device_ContainerId Stocke l’identificateur de conteneur de l’appareil PnP qui implémente le point de terminaison audio. Pour plus d’informations sur cette propriété, consultez DEVPKEY_Device_ContainerId.

Certains appareils de point de terminaison audio peuvent avoir des propriétés supplémentaires qui n’apparaissent pas dans la liste précédente. Pour plus d’informations sur les propriétés supplémentaires, consultez Propriétés du point de terminaison audio.

Pour plus d’informations sur PROPERTYKEY, consultez la documentation du système de propriétés Windows.

L’exemple de code suivant imprime les noms complets de tous les appareils de point de terminaison de rendu audio dans le système :

//-----------------------------------------------------------
// 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 dans l’exemple de code précédent est définie dans le fichier d’en-tête Winerror.h.

Dans l’exemple de code précédent, le corps de la boucle for dans la fonction PrintEndpointNames appelle la méthode IMMDevice::GetId pour obtenir la chaîne d’ID de point de terminaison pour le périphérique de point de terminaison audio représenté par l’interface IMMDevice instance. La chaîne identifie de manière unique l’appareil par rapport à tous les autres appareils de point de terminaison audio du système. Un client peut utiliser la chaîne d’ID de point de terminaison pour créer une instance du périphérique de point de terminaison audio ultérieurement ou dans un autre processus en appelant la méthode IMMDeviceEnumerator::GetDevice. Les clients doivent traiter le contenu de la chaîne d’ID de point de terminaison comme opaque. Autrement dit, les clients ne doivent pas essayer d’analyser le contenu de la chaîne pour obtenir des informations sur l’appareil. La raison en est que le format de chaîne n’est pas défini et peut changer d’une implémentation de l’API MMDevice à la suivante.

Les noms d’appareils conviviaux et les chaînes d’ID de point de terminaison obtenus par la fonction PrintEndpointNames dans l’exemple de code précédent sont identiques aux noms d’appareils conviviaux et aux chaînes d’ID de point de terminaison fournies par DirectSound lors de l’énumération de l’appareil. Pour plus d’informations, consultez Événements audio pour les applications audio héritées.

Dans l’exemple de code précédent, la fonction PrintEndpointNames appelle la fonction CoCreateInstance pour créer un énumérateur pour les périphériques de point de terminaison audio dans le système. À moins que le programme appelant ait précédemment appelé la fonction CoInitialize ou CoInitializeEx pour initialiser la bibliothèque COM, l’appel CoCreateInstance échoue. Pour plus d’informations sur CoCreateInstance, CoInitialize et CoInitializeEx, consultez la documentation du Kit de développement logiciel (SDK) Windows.

Pour plus d’informations sur les interfaces IMMDeviceEnumerator, IMMDeviceCollection et IMMDevice , consultez API MMDevice.

Périphériques de point de terminaison audio