Standard Soundausgabe-Gerät bekommen

Hunter

Erfahrenes Mitglied
Hallo,

ich habe derzeit ein kleines Problem, mit der Sound-API. Wie man weiß ist diese so super dokumentiert und ich finde einfach keine Lösung.
Mein Problem ist, dass ich das Standard Soundausgabe-Gerät nicht bekomme. Soll heißen, ich weiß nicht welche Funktion ich noch aufrufen kann/welche Parameter ich noch übergeben sollte.
Momentan hab ich es mit der Funktion GetDefaultAudioEndpoint() versucht, jedoch bekomme ich dort nur den Status des Gerätes (aktiviert, deaktivert, nicht angeschlossen, ..), jedoch nicht, ob es das Standard-Gerät ist.
 
Laut Doku liefert die Funktion das Standard-Audio-Gerät zurück (Standard = Default). Wenn du da kein Gerät bekommst, hast du kein Standard-Gerät. Die zusätzlichen Informationen liefern nur den Zustand über das Standard-Gerät, so kannst du entscheiden, ob du es verwenden willst oder nicht.
 
Also die Funktion schreibt ja in das struct IMMDevice, dieses Struct ist schonmal ungleich NULL, was heißt, dass es keine Fehler oä. gab. Wüsste ich nicht wie ich dessen Wert auslesen kann. Ich könnte mit dem Struct dann zwar ein Audio-Gerät aktivieren, jedoch bekomme ich keine direkte Information welches Gerät als Standard-Gerät ausgewählt ist. Auch die Debug-Console sagt mit, dass es die Werte nicht auslesen kann.
 
IMMDevice ist kein struct sondern ein Interface. Und biete bspw. die Methode GetId() an. Damit kannst du einen Zeiger auf einen LPWSTR übergeben und bekommst dann S_OK im Gut-Fall oder einen Fehlercode zurück. Wenn S_OK zurück kommt, kannst du den String auswerten und musst ihn anschließend mit der Funktion CoTaskMemFree() wieder freigeben.

Die Dokumentation ist sehr gut, ich weiß gar nicht, warum du anderer Meinung bist :)
 
Hoppla ja, es ist ein Interface.
GetId() kannte ich auch schon, denn das benötige ich um das Standard-Ausgabegerät zu setzten. Und genau dort ist die API nicht dokumentiert. Ich musste erst mal Google bemühen um herauszufinden, wie man das Standard-Ausgabegerät setzt.
Jedoch habe ich bisher immer noch keinen Weg gefunden das momentane Standard-Gerät herauszufinden. Auch mittels IPropertyStore::GetValue habe ich keine Möglichkeit gefunden.
 
Und dieses Code-Beispiel hat dir dabei nicht geholfen?

C++:
// enumaudio.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//

#include "stdafx.h"

#include <mmdeviceapi.h>
#include <stdio.h>
#include <objbase.h>
#include <FunctionDiscoveryKeys_devpkey.h>

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

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


   /**** HIER WIRD DER DEFAULT ENDPOINT AUSGELESEN ****/
   hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eMultimedia, &pEndpoint);

   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)

  // Print endpoint friendly name and endpoint ID.
  printf("Endpoint (DEFAULT = STANDARD): \"%S\" (%S)\n",
  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)
}

int _tmain(int argc, _TCHAR* argv[])
{
   CoInitialize(NULL);
   PrintEndpointNames();
   getchar();
   return 0;
}
 
An diesen Wert hab ich ja auch gedacht, jedoch bekomme ich immer nur den Anfangsbuchstaben des Geräts, deshalb konnte ich es nicht herausfinden. Ich hab mir das Beispiel auch ein paar mal durchgeschaut, bin da aber nicht wirklich schlauer geworden. Naja, vielen Dank an Dich für deine Geduld. :)
 
Wie meinst du das, du bekommst nur den Anfangsbuchstaben? Hier mal ein aufgeräumtes Beispiel ohne den Loop:

C++:
// enumaudio.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//

#include "stdafx.h"

#include <mmdeviceapi.h>
#include <stdio.h>
#include <objbase.h>
#include <FunctionDiscoveryKeys_devpkey.h>

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

	/**** HIER WIRD DER DEFAULT ENDPOINT AUSGELESEN ****/
	hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eMultimedia, &pEndpoint);

	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)

    // Print endpoint friendly name and endpoint ID.
    printf("Endpoint (DEFAULT = STANDARD): \"%S\" (%S)\n",
            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)
}

int _tmain(int argc, _TCHAR* argv[])
{
	CoInitialize(NULL);
	PrintEndpointNames();
	getchar();
	return 0;
}

Wenn du mal Code zeigen würdest, könnte man mit dem arbeiten, was du hast.
 
Funktioniert jetzt. Ich habe warscheinlich irgendwo einen kleinen Fehler gemacht.
Sorry, bin heute irgendwie nicht ganz bei der Sache... :)

Thema kann als abgehackt gekenzeichnet werden. Danke nochmal @saftmeister. :)
 

Neue Beiträge

Zurück