Geräteeigenschaften (Core-Audio-APIs)

Während des Auflistens von Audioendpunktgeräten kann eine Clientanwendung die Endpunktobjekte nach ihren Geräteeigenschaften abfragen. Die Geräteeigenschaften werden in der Implementierung der IPropertyStore-Schnittstelle der MMDevice-API verfügbar gemacht. Bei einem Verweis auf die IMMDevice-Schnittstelle eines Endpunktobjekts kann ein Client einen Verweis auf den Eigenschaftenspeicher des Endpunktobjekts abrufen, indem er die IMMDevice::OpenPropertyStore-Methode aufruft .

Clients können diese Eigenschaften lesen, sollten sie jedoch nicht festlegen. Eigenschaftswerte werden als PROPVARIANT-Strukturen gespeichert.

Der Endpunkt-Manager legt die grundlegenden Geräteeigenschaften für Endpunkte fest. Der Endpunkt-Manager ist die Windows-Komponente, die für die Erkennung des Vorhandenseins von Audioendpunktgeräten zuständig ist.

Jeder PKEY_Xxx Eigenschaftenbezeichner in der folgenden Liste ist eine Konstante vom Typ PROPERTYKEY , die in der Headerdatei Functiondiscoverykeys_devpkey.h definiert ist. Alle Audioendpunktgeräte verfügen über diese Geräteeigenschaften.

Eigenschaft BESCHREIBUNG
PKEY_DeviceInterface_FriendlyName Der Anzeigename des Audioadapters, an den das Endpunktgerät angefügt ist (z. B. "XYZ-Audioadapter").
PKEY_Device_DeviceDesc Die Gerätebeschreibung des Endpunktgeräts (z. B. "Lautsprecher").
PKEY_Device_FriendlyName Der Anzeigename des Endpunktgeräts (z. B. "Lautsprecher (XYZ-Audioadapter)").
PKEY_Device_InstanceId Speichert das Audioendpunktgerät instance Bezeichner. Der Wert kann auch über die IMMDevice::GetId-Methode abgerufen werden. Weitere Informationen zu dieser Eigenschaft finden Sie unter Endpunkt-ID-Zeichenfolgen und DEVPKEY_Device_InstanceId.
PKEY_Device_ContainerId Speichert den Containerbezeichner des PnP-Geräts, das den Audioendpunkt implementiert. Weitere Informationen zu dieser Eigenschaft finden Sie unter DEVPKEY_Device_ContainerId.

Einige Audioendpunktgeräte verfügen möglicherweise über zusätzliche Eigenschaften, die in der vorherigen Liste nicht angezeigt werden. Weitere Informationen zu zusätzlichen Eigenschaften finden Sie unter Audioendpunkteigenschaften.

Weitere Informationen zu PROPERTYKEY finden Sie in der Dokumentation zum Windows-Eigenschaftensystem.

Im folgenden Codebeispiel werden die Anzeigenamen aller Audiorenderingendpunkte im System ausgegeben:

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

Das Makro FAILED im vorherigen Codebeispiel ist in der Headerdatei Winerror.h definiert.

Im vorherigen Codebeispiel ruft der For-Schleifentext in der PrintEndpointNames-Funktion die IMMDevice::GetId-Methode auf, um die Endpunkt-ID-Zeichenfolge für das Audioendpunktgerät abzurufen, das durch die IMMDevice-Schnittstelle instance dargestellt wird. Die Zeichenfolge identifiziert das Gerät eindeutig in Bezug auf alle anderen Audioendpunktgeräte im System. Ein Client kann die Endpunkt-ID-Zeichenfolge verwenden, um eine instance des Audioendpunktgeräts zu einem späteren Zeitpunkt oder in einem anderen Prozess zu erstellen, indem die IMMDeviceEnumerator::GetDevice-Methode aufgerufen wird. Clients sollten den Inhalt der Endpunkt-ID-Zeichenfolge als undurchsichtig behandeln. Das heißt, Clients sollten nicht versuchen, den Inhalt der Zeichenfolge zu analysieren, um Informationen über das Gerät zu erhalten. Der Grund dafür ist, dass das Zeichenfolgenformat nicht definiert ist und sich möglicherweise von einer Implementierung der MMDevice-API zur nächsten ändert.

Die Anzeigegerätenamen und Endpunkt-ID-Zeichenfolgen, die von der PrintEndpointNames-Funktion im vorherigen Codebeispiel abgerufen werden, sind identisch mit den Anzeigegerätenamen und Endpunkt-ID-Zeichenfolgen, die von DirectSound während der Geräteenumeration bereitgestellt werden. Weitere Informationen finden Sie unter Audioereignisse für Legacyaudioanwendungen.

Im vorherigen Codebeispiel ruft die PrintEndpointNames-Funktion die CoCreateInstance-Funktion auf, um einen Enumerator für die Audioendpunktgeräte im System zu erstellen. Wenn das aufrufende Programm zuvor entweder die CoInitialize - oder CoInitializeEx-Funktion aufgerufen hat, um die COM-Bibliothek zu initialisieren, schlägt der CoCreateInstance-Aufruf fehl. Weitere Informationen zu CoCreateInstance, CoInitialize und CoInitializeEx finden Sie in der Windows SDK-Dokumentation.

Weitere Informationen zu den Schnittstellen IMMDeviceEnumerator, IMMDeviceCollection und IMMDevice finden Sie unter MMDevice-API.

Audioendpunktgeräte