コード例 #1
0
ファイル: AudioCapture.cpp プロジェクト: kbinani/dxrip
//
//  Retrieves the device friendly name for a particular device in a device collection.  
//
//  The returned string was allocated using malloc() so it should be freed using free();
//
String GetDeviceName(IMMDeviceCollection *DeviceCollection, UINT DeviceIndex)
{
    IMMDevice *device;
    LPWSTR deviceId;
    HRESULT hr;

    hr = DeviceCollection->Item(DeviceIndex, &device);
    PersistentAssert(SUCCEEDED(hr), "DeviceCollection->Item failed");
    
    hr = device->GetId(&deviceId);
    PersistentAssert(SUCCEEDED(hr), "device->GetId failed");

    IPropertyStore *propertyStore;
    hr = device->OpenPropertyStore(STGM_READ, &propertyStore);
    SafeRelease(&device);
    PersistentAssert(SUCCEEDED(hr), "device->OpenPropertyStore failed");

    PROPVARIANT friendlyName;
    PropVariantInit(&friendlyName);
    hr = propertyStore->GetValue(PKEY_Device_FriendlyName, &friendlyName);
    SafeRelease(&propertyStore);
    PersistentAssert(SUCCEEDED(hr), "propertyStore->GetValue failed");

    String Result = String(UnicodeString(friendlyName.pwszVal)); // + String(" (") + String( UnicodeString(deviceId) ) + String(")")
    
    PropVariantClear(&friendlyName);
    CoTaskMemFree(deviceId);

    return Result;
}
コード例 #2
0
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInGuidStr(WCHAR deviceInStrBuffer[OVR_AUDIO_MAX_DEVICE_STR_SIZE])
{
	if (!deviceInStrBuffer)
		return ovrError_InvalidParameter;

	IMMDeviceEnumerator* pEnumerator;
	const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
	const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
	HRESULT hr = CoCreateInstance(
		CLSID_MMDeviceEnumerator, NULL,
		CLSCTX_ALL, IID_IMMDeviceEnumerator,
		(void**)&pEnumerator);
	if (FAILED(hr))
		return ovrError_RuntimeException;

	IMMDevice* pDevice;
	hr = pEnumerator->GetDefaultAudioEndpoint(eCapture, eConsole, &pDevice);
	if (FAILED(hr))
		return ovrError_RuntimeException;

	LPWSTR pGuid;
	hr = pDevice->GetId(&pGuid);
	if (FAILED(hr))
		return ovrError_RuntimeException;

	wcsncpy(deviceInStrBuffer, pGuid, OVR_AUDIO_MAX_DEVICE_STR_SIZE);

	// Cleanup
	pDevice->Release();
	pEnumerator->Release();
	return ovrSuccess;
}
コード例 #3
0
static HRESULT
DeviceIdStringGet(IMMDeviceCollection *dc, UINT id, wchar_t *deviceIdStr, size_t deviceIdStrBytes)
{
    HRESULT hr = 0;

    IMMDevice *device  = nullptr;
    LPWSTR    s        = nullptr;

    assert(dc);
    assert(deviceIdStr);
    assert(0 < deviceIdStrBytes);

    deviceIdStr[0] = 0;

    HRG(dc->Item(id, &device));
    HRG(device->GetId(&s));

    wcsncpy_s(deviceIdStr, deviceIdStrBytes/2, s, deviceIdStrBytes/2 -1);

end:
    CoTaskMemFree(s);
    s = nullptr;
    SafeRelease(&device);
    return hr;
}
コード例 #4
0
ファイル: WasapiWrap.cpp プロジェクト: kekyo/PlayPcmWin
static HRESULT
DeviceNameGet(
IMMDeviceCollection *dc, UINT id, wchar_t *name, size_t nameBytes)
{
    HRESULT hr = 0;

    IMMDevice *device = nullptr;
    LPWSTR deviceId = nullptr;
    IPropertyStore *ps = nullptr;
    PROPVARIANT pv;

    assert(dc);
    assert(name);

    name[0] = 0;

    assert(0 < nameBytes);

    PropVariantInit(&pv);

    HRR(dc->Item(id, &device));
    HRR(device->GetId(&deviceId));
    HRR(device->OpenPropertyStore(STGM_READ, &ps));

    HRG(ps->GetValue(PKEY_Device_FriendlyName, &pv));
    SafeRelease(&ps);

    wcsncpy_s(name, nameBytes / sizeof name[0], pv.pwszVal, _TRUNCATE);

end:
    PropVariantClear(&pv);
    CoTaskMemFree(deviceId);
    SafeRelease(&ps);
    return hr;
}
//
//  Retrieves the device friendly name for a particular device in a device collection.
//
LPWSTR GetDeviceName(IMMDeviceCollection *DeviceCollection, UINT DeviceIndex)
{
    IMMDevice *device;
    LPWSTR deviceId;
    HRESULT hr;

    hr = DeviceCollection->Item(DeviceIndex, &device);
    if (FAILED(hr))
    {
        printf("Unable to get device %d: %x\n", DeviceIndex, hr);
        return NULL;
    }
    hr = device->GetId(&deviceId);
    if (FAILED(hr))
    {
        printf("Unable to get device %d id: %x\n", DeviceIndex, hr);
        return NULL;
    }

    IPropertyStore *propertyStore;
    hr = device->OpenPropertyStore(STGM_READ, &propertyStore);
    SafeRelease(&device);
    if (FAILED(hr))
    {
        printf("Unable to open device %d property store: %x\n", DeviceIndex, hr);
        return NULL;
    }

    PROPVARIANT friendlyName;
    PropVariantInit(&friendlyName);
    hr = propertyStore->GetValue(PKEY_Device_FriendlyName, &friendlyName);
    SafeRelease(&propertyStore);

    if (FAILED(hr))
    {
        printf("Unable to retrieve friendly name for device %d : %x\n", DeviceIndex, hr);
        return NULL;
    }

    wchar_t deviceName[128];
    hr = StringCbPrintf(deviceName, sizeof(deviceName), L"%s (%s)", friendlyName.vt != VT_LPWSTR ? L"Unknown" : friendlyName.pwszVal, deviceId);
    if (FAILED(hr))
    {
        printf("Unable to format friendly name for device %d : %x\n", DeviceIndex, hr);
        return NULL;
    }

    PropVariantClear(&friendlyName);
    CoTaskMemFree(deviceId);

    wchar_t *returnValue = _wcsdup(deviceName);
    if (returnValue == NULL)
    {
        printf("Unable to allocate buffer for return\n");
        return NULL;
    }
    return returnValue;
}
コード例 #6
0
ファイル: WASAPI.cpp プロジェクト: arrai/mumble-record
const QHash<QString, QString> WASAPISystem::getDevices(EDataFlow dataflow) {
	QHash<QString, QString> devices;

	HRESULT hr;

	IMMDeviceEnumerator *pEnumerator = NULL;
	IMMDeviceCollection *pCollection = NULL;

	hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), reinterpret_cast<void **>(&pEnumerator));

	if (! pEnumerator || FAILED(hr)) {
		qWarning("WASAPI: Failed to instatiate enumerator");
	} else {
		hr = pEnumerator->EnumAudioEndpoints(dataflow, DEVICE_STATE_ACTIVE, &pCollection);
		if (! pCollection || FAILED(hr)) {
			qWarning("WASAPI: Failed to enumerate");
		} else {
			devices.insert(QString(), tr("Default Device"));

			UINT ndev = 0;
			pCollection->GetCount(&ndev);
			for (unsigned int idx=0;idx<ndev;++idx) {
				IMMDevice *pDevice = NULL;
				IPropertyStore *pStore = NULL;

				pCollection->Item(idx, &pDevice);
				pDevice->OpenPropertyStore(STGM_READ, &pStore);

				LPWSTR strid = NULL;
				pDevice->GetId(&strid);

				PROPVARIANT varName;
				PropVariantInit(&varName);

				pStore->GetValue(PKEY_Device_FriendlyName, &varName);

				devices.insert(QString::fromWCharArray(strid), QString::fromWCharArray(varName.pwszVal));

				PropVariantClear(&varName);
				CoTaskMemFree(strid);

				pStore->Release();
				pDevice->Release();
			}
			pCollection->Release();
		}
		pEnumerator->Release();
	}

	return devices;
}
コード例 #7
0
ファイル: TestAudio.cpp プロジェクト: CltKitakami/MyLib
LPWSTR GetDeviceName(IMMDeviceCollection *DeviceCollection, UINT DeviceIndex)
{
    IMMDevice *device;
    LPWSTR deviceId;
    HRESULT hr;

    hr = DeviceCollection->Item(DeviceIndex, &device);
    if (FAILED(hr))
    {
        printf("Unable to get device %d: %x\n", DeviceIndex, hr);
        return nullptr;
    }
    hr = device->GetId(&deviceId);
    if (FAILED(hr))
    {
        printf("Unable to get device %d id: %x\n", DeviceIndex, hr);
        return nullptr;
    }

    IPropertyStore *propertyStore;
    hr = device->OpenPropertyStore(STGM_READ, &propertyStore);
    if (FAILED(hr))
    {
        printf("Unable to open device %d property store: %x\n", DeviceIndex, hr);
        return nullptr;
    }

    PROPVARIANT friendlyName;
    PropVariantInit(&friendlyName);
    hr = propertyStore->GetValue(PKEY_Device_FriendlyName, &friendlyName);

    if (FAILED(hr))
    {
        printf("Unable to retrieve friendly name for device %d : %x\n", DeviceIndex, hr);
        return nullptr;
    }

    DVAR(friendlyName.vt);
    if (friendlyName.vt != VT_LPWSTR)
    	DVAR("Unknown");
    else
    	DVAR((const wchar_t *)friendlyName.pwszVal);

    PropVariantClear(&friendlyName);
    CoTaskMemFree(deviceId);

    return nullptr;
}
コード例 #8
0
HRESULT GetDefaultDeviceID(IMMDeviceEnumerator *pEnum, LPWSTR *ppOutID)
{
        IMMDevice *pDevice = NULL;
        HRESULT hr = pEnum->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
                                
        if(FAILED(hr))
        {
                *ppOutID = NULL;
                return hr;
        }

        hr = pDevice->GetId(ppOutID);
        pDevice->Release();

        return hr;
}
コード例 #9
0
std::wstring GetDefaultID()
{
	std::wstring id_default;
	IMMDevice * pEndpoint = 0;
	if (pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pEndpoint) == S_OK)
	{
		LPWSTR pwszID = 0;
		if (pEndpoint->GetId(&pwszID) == S_OK)
		{
			id_default = pwszID;
		}
		CoTaskMemFree(pwszID);
	}

	SAFE_RELEASE(pEndpoint)
	return id_default;
}
コード例 #10
0
ファイル: REV_CAPI_Audio.cpp プロジェクト: LibreVR/Revive
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutGuidStr(WCHAR deviceOutStrBuffer[OVR_AUDIO_MAX_DEVICE_STR_SIZE])
{
	REV_TRACE(ovr_GetAudioDeviceOutGuidStr);

	if (!deviceOutStrBuffer)
		return ovrError_InvalidParameter;

	// Query and cache the result
	static WCHAR cachedBuffer[OVR_AUDIO_MAX_DEVICE_STR_SIZE] = {};
	if (wcslen(cachedBuffer) == 0)
	{
		HRESULT com = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

		IMMDeviceEnumerator* pEnumerator;
		const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
		const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
		HRESULT hr = CoCreateInstance(
			CLSID_MMDeviceEnumerator, NULL,
			CLSCTX_ALL, IID_IMMDeviceEnumerator,
			(void**)&pEnumerator);
		if (FAILED(hr))
			return ovrError_AudioComError;

		IMMDevice* pDevice;
		hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
		if (FAILED(hr))
			return ovrError_AudioDeviceNotFound;

		LPWSTR pGuid;
		hr = pDevice->GetId(&pGuid);
		if (FAILED(hr))
			return ovrError_AudioComError;

		wcsncpy(cachedBuffer, pGuid, OVR_AUDIO_MAX_DEVICE_STR_SIZE);

		// Cleanup
		pDevice->Release();
		pEnumerator->Release();
		if (SUCCEEDED(com))
			CoUninitialize();
	}

	wcsncpy(deviceOutStrBuffer, cachedBuffer, OVR_AUDIO_MAX_DEVICE_STR_SIZE);
	return ovrSuccess;
}
コード例 #11
0
AudioEndpoint::AudioEndpoint(IMMDeviceEnumerator *aDeviceEnumerator)
{
	Set(L"\0");

	IMMDevice *pDevice;
	HRESULT hr = aDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
	if (SUCCEEDED(hr))
	{
		LPWSTR id;
		hr = pDevice->GetId(&id);
		if (SUCCEEDED(hr))
		{
			Set(id);
			CoTaskMemFree(id);
		}
		pDevice->Release();
	}
}
コード例 #12
0
ファイル: audio-device.cpp プロジェクト: AaronFae/VimProject
AUDIO_DEVICE_API void GetDefaultCaptureDeviceId(DeviceInfo *pDeviceInfo, LPWSTR szBuffer, int bufferLen)
{
	InternalDeviceInfo *pInternalDeviceInfo = (InternalDeviceInfo *) pDeviceInfo;

    HRESULT hr = S_OK;
    IMMDevice *pDevice = NULL;

	hr = pInternalDeviceInfo->pEnumerator->GetDefaultAudioEndpoint(eCapture, eMultimedia, &pDevice);

    // assert(hr == S_OK);

	// Copy and return the Id String.
	WCHAR *szTempId;
	pDevice->GetId(&szTempId);
    wcsncpy_s(szBuffer, bufferLen, szTempId, _TRUNCATE);

	SAFE_RELEASE(pDevice);

	return;
}
コード例 #13
0
ファイル: audio-device.cpp プロジェクト: AaronFae/VimProject
AUDIO_DEVICE_API void GetCaptureListDeviceId(DeviceInfo *pDeviceInfo, int index, LPWSTR szBuffer, int bufferLen)
{
	InternalDeviceInfo *pInternalDeviceInfo = (InternalDeviceInfo *) pDeviceInfo;

    HRESULT hr = S_OK;
    IMMDevice *pDevice = NULL;

    if (pInternalDeviceInfo->pCaptureCollection != NULL) {
        hr = pInternalDeviceInfo->pCaptureCollection->Item(index, &pDevice);
    }

    // assert(hr == S_OK);

	// Copy and return the Id String.
	WCHAR *szTempId;
	pDevice->GetId(&szTempId);
    wcsncpy_s(szBuffer, bufferLen, szTempId, _TRUNCATE);

	SAFE_RELEASE(pDevice);

	return;
}
コード例 #14
0
PLUGIN_EXPORT void Initialize(void** data, void* rm)
{
	if (!InitCom())
	{
		UnInitCom();
		return;
	}

	UINT count;
	if (!pCollection || (S_OK != pCollection->GetCount(&count)))
	{
		UnInitCom();
		return;
	}
	endpointIDs = std::vector<std::wstring>(count);

	for (UINT i = 0; i < count; ++i)
	{
		IMMDevice *pEndpoint = 0;

		// Get pointer to endpoint number i.
		if (pCollection->Item(i, &pEndpoint) == S_OK)
		{
			// Get the endpoint ID string.
			LPWSTR pwszID = 0;
			if (pEndpoint->GetId(&pwszID) == S_OK)
			{
				endpointIDs[i] = pwszID;
			}
			CoTaskMemFree(pwszID);
		}
		SAFE_RELEASE(pEndpoint)
	}
	UnInitCom();
	GetWin7AudioState(INIT);
}
コード例 #15
0
ファイル: GetAudioDevices.cpp プロジェクト: AaronMike/OBS
bool GetDefaultDevice(String &strVal, EDataFlow df )
{
    const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
    const IID IID_IMMDeviceEnumerator    = __uuidof(IMMDeviceEnumerator);
    IMMDeviceEnumerator *mmEnumerator;
    HRESULT err;

    err = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&mmEnumerator);
    if(FAILED(err))
        return false;

    //-------------------------------------------------------

    IMMDevice *defDevice;
    if(FAILED(mmEnumerator->GetDefaultAudioEndpoint(df, eCommunications, &defDevice)))
    {
        SafeRelease(mmEnumerator);
        return false;
    }

    CWSTR wstrDefaultID;
    if(FAILED(defDevice->GetId((LPWSTR*)&wstrDefaultID)))
    {
        SafeRelease(defDevice);
        SafeRelease(mmEnumerator);
        return false;
    }

    strVal = wstrDefaultID;

    CoTaskMemFree((LPVOID)wstrDefaultID);
    SafeRelease(defDevice);
    SafeRelease(mmEnumerator);

    return true;
}
コード例 #16
0
void MFAudioEndpointControl::updateEndpoints()
{
    m_defaultEndpoint = QString::fromLatin1("Default");
    m_devices.insert(m_defaultEndpoint, NULL);

    IMMDeviceEnumerator *pEnum = NULL;
    HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator),
                          NULL, CLSCTX_ALL,
                          __uuidof(IMMDeviceEnumerator),
                         (void**)&pEnum);
    if (SUCCEEDED(hr)) {
        IMMDeviceCollection *pDevices = NULL;
        hr = pEnum->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pDevices);
        if (SUCCEEDED(hr)) {
            UINT count;
            hr = pDevices->GetCount(&count);
            if (SUCCEEDED(hr)) {
                for (UINT i = 0; i < count; ++i) {
                    IMMDevice *pDevice = NULL;
                    hr = pDevices->Item(i, &pDevice);
                    if (SUCCEEDED(hr)) {
                        LPWSTR wstrID = NULL;
                        hr = pDevice->GetId(&wstrID);
                        if (SUCCEEDED(hr)) {
                            QString deviceId = QString::fromWCharArray(wstrID);
                            m_devices.insert(deviceId, wstrID);
                        }
                        pDevice->Release();
                    }
                }
            }
            pDevices->Release();
        }
        pEnum->Release();
    }
}
コード例 #17
0
TBool OhmSenderDriverWindows::FindEndpoint(const char* aManufacturer)
{
	bool uninitialise = true;

	HRESULT hr = CoInitialize(NULL);

	printf("CoInitialize %d\n", hr);

	if (hr == 0x80010106)
	{
		uninitialise = false;
	}
	else if (!SUCCEEDED(hr))
	{
		return (false);
	}

	// Create a multimedia device enumerator.
	hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&iDeviceEnumerator);
		
	printf("CoCreateInstance %d\n", hr);
	
	if (SUCCEEDED(hr))
	{
		IMMDeviceCollection *pDevices;
		
		// Enumerate the output devices.
			
		hr = iDeviceEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATEMASK_ALL | 0x10000000, &pDevices);
			
		printf("EnumAudioEndpoints %d\n", hr);

		if (SUCCEEDED(hr))
		{
			UINT count;
			
			pDevices->GetCount(&count);
            printf("count: %d\n", count);
				
			if (SUCCEEDED(hr))
			{
				for (unsigned i = 0; i < count; i++)
				{
					IMMDevice *pDevice;
				
					hr = pDevices->Item(i, &pDevice);
						
					if (SUCCEEDED(hr))
					{
						LPWSTR wstrID = NULL;
						
						hr = pDevice->GetId(&wstrID);
                            
                        wprintf(L"id: %s\n", wstrID);
							
						if (SUCCEEDED(hr))
						{
							IPropertyStore *pStore;
							
							hr = pDevice->OpenPropertyStore(STGM_READ, &pStore);
								
							if (SUCCEEDED(hr))
							{
                                PROPVARIANT var;
                                PropVariantInit(&var);
                                hr = pStore->GetValue(PKEY_AudioEndpoint_GUID, &var);
                                wprintf(L"%s\n", var.pwszVal);
                                
								PROPVARIANT friendlyName;
								
								PropVariantInit(&friendlyName);
									
								hr = pStore->GetValue(PKEY_DeviceInterface_FriendlyName, &friendlyName);
                                    
                                wprintf(L"friendlyName: %s\n", friendlyName.pwszVal);
									
								if (SUCCEEDED(hr))
								{
									wchar_t model[200];

									MultiByteToWideChar(CP_ACP, 0, aManufacturer, -1, model, sizeof(model));

									wcscpy(model + wcslen(model), L" Songcast");

									if (!wcscmp(friendlyName.pwszVal, model))
									{
										iSongcastEndpoint.Set(wstrID);
										PropVariantClear(&friendlyName);
										pStore->Release();
										pDevice->Release();
										pDevices->Release();
										if (uninitialise) {
											CoUninitialize();
										}
										return (true);
									}

									PropVariantClear(&friendlyName);
								}

								pStore->Release();
							}
                                
                            CoTaskMemFree(wstrID);
						}
						pDevice->Release();
					}
				}
			}
			pDevices->Release();
		}
		iDeviceEnumerator->Release();
	}

	if (uninitialise) {
		CoUninitialize();
	}

	return (false);
}
コード例 #18
0
ファイル: AESinkWASAPI.cpp プロジェクト: CaptainRewind/xbmc
void CAESinkWASAPI::EnumerateDevicesEx(AEDeviceInfoList &deviceInfoList, bool force)
{
  IMMDeviceEnumerator* pEnumerator = NULL;
  IMMDeviceCollection* pEnumDevices = NULL;
  IMMDevice*           pDefaultDevice = NULL;
  CAEDeviceInfo        deviceInfo;
  CAEChannelInfo       deviceChannels;
  LPWSTR               pwszID = NULL;
  std::wstring         wstrDDID;

  WAVEFORMATEXTENSIBLE wfxex = {0};
  HRESULT              hr;

  hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&pEnumerator);
  EXIT_ON_FAILURE(hr, __FUNCTION__": Could not allocate WASAPI device enumerator. CoCreateInstance error code: %li", hr)

  UINT uiCount = 0;

  // get the default audio endpoint
  if(pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDefaultDevice) == S_OK)
  {
    if(pDefaultDevice->GetId(&pwszID) == S_OK)
    {
      wstrDDID = pwszID;
      CoTaskMemFree(pwszID);
    }
    SAFE_RELEASE(pDefaultDevice);
  }

  // enumerate over all audio endpoints
  hr = pEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pEnumDevices);
  EXIT_ON_FAILURE(hr, __FUNCTION__": Retrieval of audio endpoint enumeration failed.")

  hr = pEnumDevices->GetCount(&uiCount);
  EXIT_ON_FAILURE(hr, __FUNCTION__": Retrieval of audio endpoint count failed.")

  for (UINT i = 0; i < uiCount; i++)
  {
    IMMDevice *pDevice = NULL;
    IPropertyStore *pProperty = NULL;
    PROPVARIANT varName;
    PropVariantInit(&varName);

    deviceInfo.m_channels.Reset();
    deviceInfo.m_dataFormats.clear();
    deviceInfo.m_sampleRates.clear();

    hr = pEnumDevices->Item(i, &pDevice);
    if (FAILED(hr))
    {
      CLog::Log(LOGERROR, __FUNCTION__": Retrieval of WASAPI endpoint failed.");
      goto failed;
    }

    hr = pDevice->OpenPropertyStore(STGM_READ, &pProperty);
    if (FAILED(hr))
    {
      CLog::Log(LOGERROR, __FUNCTION__": Retrieval of WASAPI endpoint properties failed.");
      SAFE_RELEASE(pDevice);
      goto failed;
    }

    hr = pProperty->GetValue(PKEY_Device_FriendlyName, &varName);
    if (FAILED(hr))
    {
      CLog::Log(LOGERROR, __FUNCTION__": Retrieval of WASAPI endpoint device name failed.");
      SAFE_RELEASE(pDevice);
      SAFE_RELEASE(pProperty);
      goto failed;
    }

    std::string strFriendlyName = localWideToUtf(varName.pwszVal);
    PropVariantClear(&varName);

    hr = pProperty->GetValue(PKEY_AudioEndpoint_GUID, &varName);
    if(FAILED(hr))
    {
      CLog::Log(LOGERROR, __FUNCTION__": Retrieval of WASAPI endpoint GUID failed.");
      SAFE_RELEASE(pDevice);
      SAFE_RELEASE(pProperty);
      goto failed;
    }

    std::string strDevName = localWideToUtf(varName.pwszVal);
    PropVariantClear(&varName);

    hr = pProperty->GetValue(PKEY_AudioEndpoint_FormFactor, &varName);
    if (FAILED(hr))
    {
      CLog::Log(LOGERROR, __FUNCTION__": Retrieval of WASAPI endpoint form factor failed.");
      SAFE_RELEASE(pDevice);
      SAFE_RELEASE(pProperty);
      goto failed;
    }
    std::string strWinDevType = winEndpoints[(EndpointFormFactor)varName.uiVal].winEndpointType;
    AEDeviceType aeDeviceType = winEndpoints[(EndpointFormFactor)varName.uiVal].aeDeviceType;

    PropVariantClear(&varName);

    hr = pProperty->GetValue(PKEY_AudioEndpoint_PhysicalSpeakers, &varName);
    if (FAILED(hr))
    {
      CLog::Log(LOGERROR, __FUNCTION__": Retrieval of WASAPI endpoint speaker layout failed.");
      SAFE_RELEASE(pDevice);
      SAFE_RELEASE(pProperty);
      goto failed;
    }
    unsigned int uiChannelMask = std::max(varName.uintVal, (unsigned int) KSAUDIO_SPEAKER_STEREO);

    deviceChannels.Reset();

    for (unsigned int c = 0; c < WASAPI_SPEAKER_COUNT; c++)
    {
      if (uiChannelMask & WASAPIChannelOrder[c])
        deviceChannels += AEChannelNames[c];
    }

    PropVariantClear(&varName);

    IAudioClient *pClient;
    hr = pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&pClient);
    if (SUCCEEDED(hr))
    {
      /* Test format DTS-HD */
      wfxex.Format.cbSize               = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
      wfxex.Format.nSamplesPerSec       = 192000;
      wfxex.dwChannelMask               = KSAUDIO_SPEAKER_7POINT1_SURROUND;
      wfxex.Format.wFormatTag           = WAVE_FORMAT_EXTENSIBLE;
      wfxex.SubFormat                   = KSDATAFORMAT_SUBTYPE_IEC61937_DTS_HD;
      wfxex.Format.wBitsPerSample       = 16;
      wfxex.Samples.wValidBitsPerSample = 16;
      wfxex.Format.nChannels            = 8;
      wfxex.Format.nBlockAlign          = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3);
      wfxex.Format.nAvgBytesPerSec      = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
      hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
      if (SUCCEEDED(hr))
        deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_DTSHD));

      /* Test format Dolby TrueHD */
      wfxex.SubFormat                   = KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MLP;
      hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
      if (SUCCEEDED(hr))
        deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_TRUEHD));

      /* Test format Dolby EAC3 */
      wfxex.SubFormat                   = KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL_PLUS;
      wfxex.Format.nChannels            = 2;
      wfxex.Format.nBlockAlign          = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3);
      wfxex.Format.nAvgBytesPerSec      = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
      hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
      if (SUCCEEDED(hr))
        deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_EAC3));

      /* Test format DTS */
      wfxex.Format.nSamplesPerSec       = 48000;
      wfxex.dwChannelMask               = KSAUDIO_SPEAKER_5POINT1;
      wfxex.SubFormat                   = KSDATAFORMAT_SUBTYPE_IEC61937_DTS;
      wfxex.Format.nBlockAlign          = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3);
      wfxex.Format.nAvgBytesPerSec      = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
      hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
      if (SUCCEEDED(hr))
        deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_DTS));

      /* Test format Dolby AC3 */
      wfxex.SubFormat                   = KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL;
      hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
      if (SUCCEEDED(hr))
        deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_AC3));

      /* Test format AAC */
      wfxex.SubFormat                   = KSDATAFORMAT_SUBTYPE_IEC61937_AAC;
      hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
      if (SUCCEEDED(hr))
        deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_AAC));

      /* Test format for PCM format iteration */
      wfxex.Format.cbSize               = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
      wfxex.dwChannelMask               = KSAUDIO_SPEAKER_STEREO;
      wfxex.Format.wFormatTag           = WAVE_FORMAT_EXTENSIBLE;
      wfxex.SubFormat                   = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;

      for (int p = AE_FMT_FLOAT; p > AE_FMT_INVALID; p--)
      {
        if (p < AE_FMT_FLOAT)
          wfxex.SubFormat               = KSDATAFORMAT_SUBTYPE_PCM;
        wfxex.Format.wBitsPerSample     = CAEUtil::DataFormatToBits((AEDataFormat) p);
        wfxex.Format.nBlockAlign        = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3);
        wfxex.Format.nAvgBytesPerSec    = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
        if (p <= AE_FMT_S24NE4 && p >= AE_FMT_S24BE4)
        {
          wfxex.Samples.wValidBitsPerSample = 24;
        }
        else
        {
          wfxex.Samples.wValidBitsPerSample = wfxex.Format.wBitsPerSample;
        }

        hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
        if (SUCCEEDED(hr))
          deviceInfo.m_dataFormats.push_back((AEDataFormat) p);
      }

      /* Test format for sample rate iteration */
      wfxex.Format.cbSize               = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
      wfxex.dwChannelMask               = KSAUDIO_SPEAKER_STEREO;
      wfxex.Format.wFormatTag           = WAVE_FORMAT_EXTENSIBLE;
      wfxex.SubFormat                   = KSDATAFORMAT_SUBTYPE_PCM;
      wfxex.Format.wBitsPerSample       = 16;
      wfxex.Samples.wValidBitsPerSample = 16;
      wfxex.Format.nChannels            = 2;
      wfxex.Format.nBlockAlign          = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3);
      wfxex.Format.nAvgBytesPerSec      = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;

      for (int j = 0; j < WASAPISampleRateCount; j++)
      {
        wfxex.Format.nSamplesPerSec     = WASAPISampleRates[j];
        wfxex.Format.nAvgBytesPerSec    = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
        hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
        if (SUCCEEDED(hr))
          deviceInfo.m_sampleRates.push_back(WASAPISampleRates[j]);
      }

      /* Test format for channels iteration */
      wfxex.Format.cbSize               = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
      wfxex.dwChannelMask               = KSAUDIO_SPEAKER_STEREO;
      wfxex.Format.wFormatTag           = WAVE_FORMAT_EXTENSIBLE;
      wfxex.SubFormat                   = KSDATAFORMAT_SUBTYPE_PCM;
      wfxex.Format.nSamplesPerSec       = 48000;
      wfxex.Format.wBitsPerSample       = 16;
      wfxex.Samples.wValidBitsPerSample = 16;
      wfxex.Format.nChannels            = 2;
      wfxex.Format.nBlockAlign          = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3);
      wfxex.Format.nAvgBytesPerSec      = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;

      bool hasLpcm = false;

      // Try with KSAUDIO_SPEAKER_DIRECTOUT
      for (unsigned int k = WASAPI_SPEAKER_COUNT; k > 0; k--)
      {
        wfxex.dwChannelMask             = KSAUDIO_SPEAKER_DIRECTOUT;
        wfxex.Format.nChannels          = k;
        wfxex.Format.nBlockAlign        = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3);
        wfxex.Format.nAvgBytesPerSec    = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
        hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
        if (SUCCEEDED(hr))
        {
          if (k > 3) // Add only multichannel LPCM
          {
            deviceInfo.m_dataFormats.push_back(AE_FMT_LPCM);
            hasLpcm = true;
          }
          break;
        }
      }

      /* Try with reported channel mask */
      for (unsigned int k = WASAPI_SPEAKER_COUNT; k > 0; k--)
      {
        wfxex.dwChannelMask             = uiChannelMask;
        wfxex.Format.nChannels          = k;
        wfxex.Format.nBlockAlign        = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3);
        wfxex.Format.nAvgBytesPerSec    = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
        hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
        if (SUCCEEDED(hr))
        {
          if ( !hasLpcm && k > 3) // Add only multichannel LPCM
          {
            deviceInfo.m_dataFormats.push_back(AE_FMT_LPCM);
            hasLpcm = true;
          }
          break;
        }
      }

      /* Try with specific speakers configurations */
      for (unsigned int i = 0; i < ARRAYSIZE(layoutsList); i++)
      {
        unsigned int nmbOfCh;
        wfxex.dwChannelMask             = ChLayoutToChMask(layoutsList[i], &nmbOfCh);
        wfxex.Format.nChannels          = nmbOfCh;
        wfxex.Format.nBlockAlign        = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3);
        wfxex.Format.nAvgBytesPerSec    = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
        hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
        if (SUCCEEDED(hr))
        {
          if ( deviceChannels.Count() < nmbOfCh)
            deviceChannels = layoutsList[i];
          if ( !hasLpcm && nmbOfCh > 3) // Add only multichannel LPCM
          {
            deviceInfo.m_dataFormats.push_back(AE_FMT_LPCM);
            hasLpcm = true;
          }
        }
      }
      pClient->Release();
    }
    else
    {
      CLog::Log(LOGDEBUG, __FUNCTION__": Failed to activate device for passthrough capability testing.");
    }

    deviceInfo.m_deviceName       = strDevName;
    deviceInfo.m_displayName      = strWinDevType.append(strFriendlyName);
    deviceInfo.m_displayNameExtra = std::string("WASAPI: ").append(strFriendlyName);
    deviceInfo.m_deviceType       = aeDeviceType;
    deviceInfo.m_channels         = deviceChannels;

    /* Store the device info */
    deviceInfoList.push_back(deviceInfo);

    if(pDevice->GetId(&pwszID) == S_OK)
    {
      if(wstrDDID.compare(pwszID) == 0)
      {
        deviceInfo.m_deviceName = std::string("default");
        deviceInfo.m_displayName = std::string("default");
        deviceInfo.m_displayNameExtra = std::string("");
        deviceInfoList.push_back(deviceInfo);
      }
      CoTaskMemFree(pwszID);
    }

    SAFE_RELEASE(pDevice);
    SAFE_RELEASE(pProperty);
  }
コード例 #19
0
ファイル: GetAudioDevices.cpp プロジェクト: AaronMike/OBS
void GetAudioDevices(AudioDeviceList &deviceList, AudioDeviceType deviceType)
{
    const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
    const IID IID_IMMDeviceEnumerator    = __uuidof(IMMDeviceEnumerator);
    IMMDeviceEnumerator *mmEnumerator;
    HRESULT err;

    err = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&mmEnumerator);
    if(FAILED(err))
    {
        AppWarning(TEXT("GetAudioDevices: Could not create IMMDeviceEnumerator"));
        return;
    }

    //-------------------------------------------------------

    AudioDeviceInfo *info;

    if(deviceType == ADT_RECORDING) {
      info = deviceList.devices.CreateNew();
      info->strID = TEXT("Disable");
      info->strName = Str("Disable");
    }

    info = deviceList.devices.CreateNew();
    info->strID = TEXT("Default");
    info->strName = Str("Default");

    //-------------------------------------------------------

    IMMDeviceCollection *collection;

    EDataFlow audioDeviceType;
    switch(deviceType)
    {
    case ADT_RECORDING:
        audioDeviceType = eCapture;
        break;
    case ADT_PLAYBACK:
        audioDeviceType = eRender;
        break;
    default:
        audioDeviceType = eAll;
        break;
    }

    err = mmEnumerator->EnumAudioEndpoints(audioDeviceType, DEVICE_STATE_ACTIVE | DEVICE_STATE_UNPLUGGED, &collection);
    if(FAILED(err))
    {
        AppWarning(TEXT("GetAudioDevices: Could not enumerate audio endpoints"));
        SafeRelease(mmEnumerator);
        return;
    }

    UINT count;
    if(SUCCEEDED(collection->GetCount(&count)))
    {
        for(UINT i=0; i<count; i++)
        {
            IMMDevice *device;
            if(SUCCEEDED(collection->Item(i, &device)))
            {
                CWSTR wstrID;
                if(SUCCEEDED(device->GetId((LPWSTR*)&wstrID)))
                {
                    IPropertyStore *store;
                    if(SUCCEEDED(device->OpenPropertyStore(STGM_READ, &store)))
                    {
                        PROPVARIANT varName;

                        PropVariantInit(&varName);
                        if(SUCCEEDED(store->GetValue(PKEY_Device_FriendlyName, &varName)))
                        {
                            CWSTR wstrName = varName.pwszVal;

                            AudioDeviceInfo *info = deviceList.devices.CreateNew();
                            info->strID = wstrID;
                            info->strName = wstrName;
                        }
                    }

                    CoTaskMemFree((LPVOID)wstrID);
                }

                SafeRelease(device);
            }
        }
    }

    //-------------------------------------------------------

    SafeRelease(collection);
    SafeRelease(mmEnumerator);
}
コード例 #20
0
ファイル: main.cpp プロジェクト: korha/SoundCardSwitch
//-------------------------------------------------------------------------------------------------
void FMain()
{
    if (const HWND hWnd = FindWindowW(g_wGuidClass, nullptr))
        PostMessageW(hWnd, WM_CLOSE, 0, 0);

    if (SUCCEEDED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED)))
    {
        IMMDeviceEnumerator *immDeviceEnumerator;
        if (CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), reinterpret_cast<LPVOID*>(&immDeviceEnumerator)) == S_OK)
        {
            IMMDevice *immDeviceDefault;
            if (immDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &immDeviceDefault) == S_OK)
            {
                wchar_t *wIdDefaultOld;
                HRESULT hr = immDeviceDefault->GetId(&wIdDefaultOld);
                immDeviceDefault->Release();
                if (hr == S_OK)
                {
                    IMMDeviceCollection *immDeviceCollection;
                    hr = immDeviceEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &immDeviceCollection);
                    immDeviceEnumerator->Release();
                    if (hr == S_OK)
                    {
                        UINT iCount;
                        if (immDeviceCollection->GetCount(&iCount) == S_OK)
                        {
                            bool bFail = true;
                            for (UINT i = 0; i < iCount; ++i)
                            {
                                IMMDevice *immDevice;
                                if (immDeviceCollection->Item(i, &immDevice) == S_OK)
                                {
                                    wchar_t *wIdEnum;
                                    hr = immDevice->GetId(&wIdEnum);
                                    immDevice->Release();
                                    if (hr == S_OK)
                                    {
                                        if (FCompareMemoryW(wIdDefaultOld, wIdEnum))
                                        {
                                            bFail = false;
                                            if (++i >= iCount)
                                                i = 0;
                                            hr = immDeviceCollection->Item(i, &immDevice);
                                            immDeviceCollection->Release();
                                            if (hr == S_OK)
                                            {
                                                wchar_t *wIdDefaultNew;
                                                if (immDevice->GetId(&wIdDefaultNew) == S_OK)
                                                {
                                                    IPropertyStore *ipStore;
                                                    hr = immDevice->OpenPropertyStore(STGM_READ, &ipStore);
                                                    immDevice->Release();
                                                    if (hr == S_OK)
                                                    {
                                                        PROPVARIANT propFriendlyName;
                                                        PropVariantInitFix(&propFriendlyName);
                                                        PROPERTYKEY propKeyFriendlyName;
                                                        propKeyFriendlyName.fmtid.Data1 = 0xA45C254E;
                                                        propKeyFriendlyName.fmtid.Data2 = 0xDF1C;
                                                        propKeyFriendlyName.fmtid.Data3 = 0x4EFD;
                                                        FCopyMemory(propKeyFriendlyName.fmtid.Data4);
                                                        propKeyFriendlyName.pid = 14;
                                                        hr = ipStore->GetValue(propKeyFriendlyName, &propFriendlyName);
                                                        ipStore->Release();
                                                        if (SUCCEEDED(hr))
                                                        {
                                                            IPolicyConfig *pPolicyConfig;
                                                            if (CoCreateInstance(__uuidof(CPolicyConfigClient), nullptr, CLSCTX_ALL, (GetVersion() & 0xFF) >= 10 ? __uuidof(IPolicyConfigWin10) : __uuidof(IPolicyConfig), reinterpret_cast<LPVOID*>(&pPolicyConfig)) == S_OK)
                                                            {
                                                                hr = pPolicyConfig->SetDefaultEndpoint(wIdDefaultNew, eConsole);
                                                                if (hr == S_OK)
                                                                {
                                                                    pPolicyConfig->SetDefaultEndpoint(wIdDefaultNew, eMultimedia);
                                                                    pPolicyConfig->SetDefaultEndpoint(wIdDefaultNew, eCommunications);
                                                                }
                                                                pPolicyConfig->Release();
                                                                if (hr == S_OK)
                                                                {
                                                                    WNDCLASSEX wndCl;
                                                                    wndCl.cbSize = sizeof(WNDCLASSEX);
                                                                    wndCl.style = 0;
                                                                    wndCl.lpfnWndProc = WindowProc;
                                                                    wndCl.cbClsExtra = 0;
                                                                    wndCl.cbWndExtra = 0;
                                                                    wndCl.hInstance = GetModuleHandleW(nullptr);
                                                                    wndCl.hIcon = nullptr;
                                                                    wndCl.hCursor = nullptr;
                                                                    wndCl.hbrBackground = nullptr;
                                                                    wndCl.lpszMenuName = nullptr;
                                                                    wndCl.lpszClassName = g_wGuidClass;
                                                                    wndCl.hIconSm = nullptr;

                                                                    if (RegisterClassExW(&wndCl))
                                                                    {
                                                                        if (CreateWindowExW(WS_EX_NOACTIVATE | WS_EX_LAYERED | WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST, g_wGuidClass, nullptr, WS_POPUP | WS_VISIBLE | WS_MAXIMIZE, 0, 0, 0, 0, nullptr, nullptr, wndCl.hInstance, propFriendlyName.pwszVal))
                                                                        {
                                                                            MSG msg;
                                                                            while (GetMessageW(&msg, nullptr, 0, 0) > 0)
                                                                                DispatchMessageW(&msg);
                                                                        }
                                                                        UnregisterClassW(g_wGuidClass, wndCl.hInstance);
                                                                    }
                                                                }
                                                            }
                                                        }
                                                        PropVariantClear(&propFriendlyName);
                                                    }
                                                    CoTaskMemFree(wIdDefaultNew);
                                                }
                                                else
                                                    immDevice->Release();
                                            }
                                            break;
                                        }
                                        CoTaskMemFree(wIdEnum);
                                    }
                                }
                            }
                            if (bFail)
                                immDeviceCollection->Release();
                        }
                        else
                            immDeviceCollection->Release();
                    }
                    CoTaskMemFree(wIdDefaultOld);
                }
                else
                    immDeviceEnumerator->Release();
            }
            else
                immDeviceEnumerator->Release();
        }
        CoUninitialize();
    }
}
コード例 #21
0
ファイル: main.cpp プロジェクト: RickSaada/blog
int __cdecl wmain(void) {
    HRESULT hr = CoInitialize(NULL);
    if (FAILED(hr)) {
        LOG(L"Failed CoInitializeEx: hr = 0x%08x", hr);
        return __LINE__;
    }
    CoUninitializeOnExit cuoe;

    // get active devices
    IMMDeviceEnumerator *pEnum = NULL;
    hr = CoCreateInstance(
        __uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator),
        (void**)&pEnum
    );
    if (FAILED(hr)) {
        LOG(L"Couldn't get device enumerator: hr = 0x%08x", hr);
        return __LINE__;
    }
    ReleaseOnExit releaseEnum(pEnum);
    
    IMMDeviceCollection *pDeviceCollection = NULL;
    hr = pEnum->EnumAudioEndpoints(eAll, DEVICE_STATE_ACTIVE | DEVICE_STATE_UNPLUGGED, &pDeviceCollection);
    if (FAILED(hr)) {
        LOG(L"Couldn't get device collection: hr = 0x%08x", hr);
        return __LINE__;
    }
    ReleaseOnExit releaseDeviceCollection(pDeviceCollection);
    
    UINT nDevices = 0;
    hr = pDeviceCollection->GetCount(&nDevices);
    if (FAILED(hr)) {
        LOG(L"Couldn't get device collection count: hr = 0x%08x", hr);
        return __LINE__;
    }
    
    for (UINT i = 0; i < nDevices; i++) {
        IMMDevice *pDevice = NULL;
        hr = pDeviceCollection->Item(i, &pDevice);
        if (FAILED(hr)) {
            LOG(L"Couldn't get device: hr = 0x%08x", hr);
            return __LINE__;
        }
        ReleaseOnExit releaseDevice(pDevice);

        IMMEndpoint *pEndpoint = NULL;
        hr = pDevice->QueryInterface(IID_PPV_ARGS(&pEndpoint));
        if (FAILED(hr)) {
            LOG(L"Couldn't get endpoint: hr = 0x%08x", hr);
            return __LINE__;
        }
        ReleaseOnExit releaseEndpoint(pEndpoint);

        EDataFlow eDirection = eAll;
        hr = pEndpoint->GetDataFlow(&eDirection);
        if (FAILED(hr)) {
            LOG(L"Couldn't get data flow: hr = 0x%08x", hr);
            return __LINE__;
        }

        LOG(L"%s endpoint", StringFromDataFlow(eDirection));

        IPropertyStore *pPropertyStore = NULL;
        hr = pDevice->OpenPropertyStore(STGM_READ, &pPropertyStore);
        if (FAILED(hr)) {
            LOG(L"Couldn't get property store: hr = 0x%08x", hr);
            return __LINE__;
        }
        ReleaseOnExit releasePropertyStore(pPropertyStore);

        // get the long name property
        PROPVARIANT pv; PropVariantInit(&pv);
        hr = pPropertyStore->GetValue(PKEY_Device_FriendlyName, &pv);
        if (FAILED(hr)) {
            LOG(L"Couldn't get friendly name: hr = 0x%08x", hr);
            return hr;
        }
        PropVariantClearOnExit clearPropVariant(&pv);

        LOG(L"Name: %s", pv.pwszVal);

        // get the ID
        WCHAR *wszId = NULL;
        hr = pDevice->GetId(&wszId);
        if (FAILED(hr)) {
            LOG(L"Couldn't get device ID: hr = 0x%08x", hr);
            return __LINE__;
        }
        CoTaskMemFreeOnExit releaseId(wszId);

        LOG(L"Endpoint ID: %s", wszId);

        // get device topology object for that endpoint
        IDeviceTopology *pDT = NULL;
        hr = pDevice->Activate(__uuidof(IDeviceTopology), CLSCTX_ALL, NULL, (void**)&pDT);
        if (FAILED(hr)) {
            LOG(L"Couldn't get device topology object: hr = 0x%08x", hr);
            return __LINE__;
        }
        ReleaseOnExit releaseDT(pDT);

        // get the single connector for that endpoint
        IConnector *pConnector = NULL;
        hr = pDT->GetConnector(0, &pConnector);
        if (FAILED(hr)) {
            LOG(L"Couldn't get the connector on the endpoint: hr = 0x%08x", hr);
            return __LINE__;
        }
        ReleaseOnExit releaseConnector(pConnector);

        // QI on the device's connector for IPart
        IPart *pPart = NULL;
        hr = pConnector->QueryInterface(IID_PPV_ARGS(&pPart));
        if (FAILED(hr)) {
            LOG(L"Couldn't get the part: hr = 0x%08x", hr);
            return __LINE__;
        }
        ReleaseOnExit releasePart(pPart);

        // all the real work is done in this function
        // follow the connector from this trivial endpoint topology
        // over to the rest of the topologies
        hr = WalkTreeFromPart(pPart, eDirection, true, 1);
        if (FAILED(hr)) {
            LOG(L"Couldn't walk the tree: hr = 0x%08x", hr);
            return __LINE__;
        }

        LOG(L"");
    }

    return 0;
}
コード例 #22
0
BOOL SetDefaultAudioDevice_Vista(LPCTSTR lpszHardwareId, LPCTSTR lpszName)
{
	HRESULT hr = S_FALSE;
	BOOL bSuccessful = FALSE;

	IMMDeviceEnumerator *pDeviceEnumerator = NULL;
	IMMDeviceCollection* pCollection = NULL;
	IPolicyConfigVista *pPolicyConfigVista = NULL;

	do {
		CElcAudioDeviceEnumerator enumerator;
		if (!enumerator.Enumerate(FALSE))
			break;
		CElcDeviceItem * pAudioItem = enumerator.FindItemByPnpId(lpszHardwareId, lpszName);
		if (!pAudioItem)
			break;

		if (FAILED(CoCreateInstance(
			__uuidof(MMDeviceEnumerator), 
			NULL, 
			CLSCTX_INPROC_SERVER, 
			__uuidof(IMMDeviceEnumerator), 
			(LPVOID *)&pDeviceEnumerator)))
		{
			break;
		}

		if (FAILED(pDeviceEnumerator->EnumAudioEndpoints(
			eRender, 
			DEVICE_STATE_ACTIVE, 
			&pCollection)))
		{
			break;
		}

		LPWSTR lpszId = NULL;
		UINT nCount = 0;
		pCollection->GetCount(&nCount);

		for (UINT i=0; i<nCount; i++) {
			IMMDevice* pDevice = NULL;
			if (SUCCEEDED(pCollection->Item(i, &pDevice))) {

				pDevice->GetId(&lpszId);
				SAFE_RELEASE(pDevice);

				LPCWSTR lpszIdDup = lpszId + 17;
				if (pAudioItem->m_strDeviceId.CompareNoCase(lpszIdDup) == 0)
					break;

				CoTaskMemFree(lpszId);
				lpszId = NULL;
			}
		}

		if (lpszId && SUCCEEDED(CoCreateInstance(
			__uuidof(CPolicyConfigVistaClient), 
			NULL, 
			CLSCTX_ALL, 
			__uuidof(IPolicyConfigVista), 
			(LPVOID *)&pPolicyConfigVista)))
		{
			if (SUCCEEDED(pPolicyConfigVista->SetDefaultEndpoint(lpszId, eMultimedia))
				&& SUCCEEDED(pPolicyConfigVista->SetDefaultEndpoint(lpszId, eCommunications)))
				bSuccessful = TRUE;
		}

		if (lpszId)
			CoTaskMemFree(lpszId);

	} while (0);

	SAFE_RELEASE(pPolicyConfigVista);
	SAFE_RELEASE(pCollection);
	SAFE_RELEASE(pDeviceEnumerator);

	return bSuccessful;
}
コード例 #23
0
ファイル: MFSound_WASAPI.cpp プロジェクト: TurkeyMan/fuji
void MFSound_InitWASAPI()
{
	gDevices.Init(sizeof(MFAudioDevice), 8, 8);
	gCaptureDevices.Init(sizeof(MFAudioCaptureDevice), 8, 8);

	HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&gpEnumerator);
	if(FAILED(hr))
	{
		MFDebug_Assert(false, "Couldn't create multimedia device enumerator!");
		return;
	}

	// enumerate audio devices...
	gpNotification = new MFAudioDeviceNotification;
	gpEnumerator->RegisterEndpointNotificationCallback(gpNotification);

	// enumerate render devices
	IMMDeviceCollection *pDevices;
	gpEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE | DEVICE_STATE_UNPLUGGED, &pDevices);
	if(pDevices)
	{
		UINT count;
		pDevices->GetCount(&count);

		for(UINT i=0; i<count; ++i)
		{
			IMMDevice *pDevice;
			pDevices->Item(i, &pDevice);

			MFDevice *pDev = MFDevice_AllocDevice(MFDT_AudioRender, NULL);
			pDev->pInternal = gDevices.AllocAndZero();
			MFAudioDevice &device = *(MFAudioDevice*)pDev->pInternal;

			GetDeviceInfo(pDevice, pDev);

			pDevice->Release();

			MFDebug_Log(0, MFStr("Found audio device: %s, %s - state: %d (%s)", pDev->strings[MFDS_DeviceName], pDev->strings[MFDS_Manufacturer], device.state, pDev->strings[MFDS_ID]));
		}
		pDevices->Release();
	}

	// enumerate capture devices
	gpEnumerator->EnumAudioEndpoints(eCapture, DEVICE_STATE_ACTIVE | DEVICE_STATE_UNPLUGGED, &pDevices);
	if(pDevices)
	{
		UINT count;
		pDevices->GetCount(&count);

		for(UINT i=0; i<count; ++i)
		{
			IMMDevice *pDevice;
			pDevices->Item(i, &pDevice);

			MFDevice *pDev = MFDevice_AllocDevice(MFDT_AudioCapture, NULL);
			pDev->pInternal = gCaptureDevices.AllocAndZero();
			MFAudioCaptureDevice &device = *(MFAudioCaptureDevice*)pDev->pInternal;

			GetDeviceInfo(pDevice, pDev);

			pDevice->Release();

			MFDebug_Log(0, MFStr("Found audio capture device: %s, %s - state: %d (%s)", pDev->strings[MFDS_DeviceName], pDev->strings[MFDS_Manufacturer], device.state, pDev->strings[MFDS_ID]));
		}
		pDevices->Release();
	}

	// set defaults (this is some awkward windows code!)
	for(int i=0; i<2; ++i)
	{
		for(int j=0; j<3; ++j)
		{
			IMMDevice *pDevice;
			gpEnumerator->GetDefaultAudioEndpoint(gDirection[i], gRole[j], &pDevice);
			if(pDevice)
			{
				wchar_t *pDefaultId;
				pDevice->GetId(&pDefaultId);
				char temp[128];
				MFString_CopyUTF16ToUTF8(temp, pDefaultId);
				MFDevice *pDev = MFDevice_GetDeviceById(temp);
				MFDevice_SetDefaultDevice(gDt[i], gDef[j], pDev);
				CoTaskMemFree(pDefaultId);
				pDevice->Release();
			}
		}
	}
}
コード例 #24
0
int _tmain(int argc, _TCHAR* argv[])
{
		// read the command line option, -1 indicates list devices.
	int option = -1;
	if (argc == 2) option = atoi((char*)argv[1]);
	std::wcout << "SoundSwitch Audio Interface Changer\r\n";
	bool setOutput = false;

	HRESULT hr = CoInitialize(NULL);
	if (SUCCEEDED(hr))
	{
		IMMDeviceEnumerator *pEnum = NULL;
		// Create a multimedia device enumerator.
		hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL,
			CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pEnum);
		if (SUCCEEDED(hr))
		{
            LPWSTR wstrDefaultID = NULL;
                                        
            hr = GetDefaultDeviceID(pEnum, &wstrDefaultID);
            if(FAILED(hr))
            {
                    wstrDefaultID = NULL;
            }

			IMMDeviceCollection *pDevices;

			// Get default device
			IMMDevice *pDevice = NULL;
			hr = pEnum->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);

			// Enumerate the output devices.
			hr = pEnum->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE | DEVICE_STATE_UNPLUGGED | DEVICE_STATE_DISABLED, &pDevices);
			if (SUCCEEDED(hr))
			{
				UINT count;
				pDevices->GetCount(&count);
				if (SUCCEEDED(hr))
				{
					for (int i = 0; i < count; i++)
					{
						IMMDevice *pDevice;
						hr = pDevices->Item(i, &pDevice);
						if (SUCCEEDED(hr))
						{
							LPWSTR wstrID = NULL;
							hr = pDevice->GetId(&wstrID);
							if (SUCCEEDED(hr))
							{
								IPropertyStore *pStore;
								hr = pDevice->OpenPropertyStore(STGM_READ, &pStore);
								if (SUCCEEDED(hr))
								{
									bool isDefault = false;
                                    if(wstrDefaultID != NULL)
                                    {
                                            LPWSTR wstrID = NULL;
                                            HRESULT hr = pDevice->GetId(&wstrID);

                                            if(!_wcsicmp(wstrID, wstrDefaultID))
                                            {
                                                    isDefault = true;
                                            }

                                            CoTaskMemFree(wstrID);
                                    }

									PROPVARIANT friendlyName;
									PropVariantInit(&friendlyName);
									hr = pStore->GetValue(PKEY_Device_FriendlyName, &friendlyName);
									if (SUCCEEDED(hr))
									{
										// if no options, print the device
										// otherwise, find the selected device and set it to be default
										if (option == -1) {
											//printf("Audio Device %d: %ws\n",i, friendlyName.pwszVal);
											std::wcout << i << ": " << friendlyName.pwszVal;
											if (isDefault == true)
											{
												std::wcout << " (default)";
											}
											std::wcout << "\r\n";
										}
										if (i == option) {
											std::wcout << "Setting output to: " << i << ": " << friendlyName.pwszVal << "\r\n";
											SetDefaultAudioPlaybackDevice(wstrID);
											setOutput = true;
										}
										PropVariantClear(&friendlyName);
									}
									pStore->Release();
								}
							}
							pDevice->Release();
						}
					}
				}
				pDevices->Release();
			}


			//WTF?  If Release() gets called, then redirecting this .exe's output stops working. No idea why.. 
			// pEnum->Release();
		}
	}

	if (option >= 0 && !setOutput) 
	{
		std::cout << "Failed to select device " << option << "\r\n";
		return 1;
	}
	
	return hr;
}
コード例 #25
0
	static bool UpdateAudioDucking(bool bDuckingOptOutChecked)
	{
		HRESULT hr = S_OK;

		//  Start with the default endpoint.
		IMMDeviceEnumerator* pDeviceEnumerator = NULL;
		hr = CoCreateInstance(__uuidof(MMDeviceEnumerator),
			NULL,
			CLSCTX_INPROC_SERVER,
			IID_PPV_ARGS(&pDeviceEnumerator));

		if (SUCCEEDED(hr))
		{
			{
				IMMDevice* pEndpoint = NULL;
				hr = pDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pEndpoint);
				if (SUCCEEDED(hr))
				{
					LPWSTR Desc;
					pEndpoint->GetId(&Desc);
					UE_LOG(LogVoiceCapture, Display, TEXT("%s ducking on audio device. Desc: %s"), bDuckingOptOutChecked ? TEXT("Disabling") : TEXT("Enabling"), Desc);
					CoTaskMemFree(Desc);

					FAudioDuckingWindows::EnableDuckingOptOut(pEndpoint, bDuckingOptOutChecked);
					pEndpoint->Release();
					pEndpoint = NULL;
				}
			}

			if (0) // reference for enumerating all endpoints in case its necessary
			{
				IMMDeviceCollection* pDeviceCollection = NULL;
				IMMDevice* pCollEndpoint = NULL;
				hr = pDeviceEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pDeviceCollection);
				if (SUCCEEDED(hr))
				{
					IPropertyStore *pProps = NULL;

					::UINT DeviceCount = 0;
					pDeviceCollection->GetCount(&DeviceCount);
					for (::UINT i = 0; i < DeviceCount; ++i)
					{
						hr = pDeviceCollection->Item(i, &pCollEndpoint);
						if (SUCCEEDED(hr) && pCollEndpoint)
						{
							LPWSTR Desc;
							pCollEndpoint->GetId(&Desc);

							hr = pCollEndpoint->OpenPropertyStore(STGM_READ, &pProps);
							if (SUCCEEDED(hr))
							{
								PROPVARIANT varName;
								// Initialize container for property value.
								PropVariantInit(&varName);

								// Get the endpoint's friendly-name property.
								hr = pProps->GetValue(
									PKEY_Device_FriendlyName, &varName);
								if (SUCCEEDED(hr))
								{
									// Print endpoint friendly name and endpoint ID.
									UE_LOG(LogVoiceCapture, Display, TEXT("%s ducking on audio device [%d]: \"%s\" (%s)"),
										bDuckingOptOutChecked ? TEXT("Disabling") : TEXT("Enabling"),
										i, varName.pwszVal, Desc);

									CoTaskMemFree(Desc);

									Desc = NULL;
									PropVariantClear(&varName);

									pProps->Release();
									pProps = NULL;
								}
							}

							FAudioDuckingWindows::EnableDuckingOptOut(pCollEndpoint, bDuckingOptOutChecked);

							pCollEndpoint->Release();
							pCollEndpoint = NULL;
						}
					}

					pDeviceCollection->Release();
					pDeviceCollection = NULL;
				}
			}

			pDeviceEnumerator->Release();
			pDeviceEnumerator = NULL;
		}

		if (FAILED(hr))
		{
			UE_LOG(LogVoiceCapture, Warning, TEXT("Failed to duck audio endpoint. Error: %0x08x"), hr);
		}

		return SUCCEEDED(hr);
	}
コード例 #26
0
ファイル: audio_driver_wasapi.cpp プロジェクト: 93i/godot
Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_capture, bool reinit) {

	WAVEFORMATEX *pwfex;
	IMMDeviceEnumerator *enumerator = NULL;
	IMMDevice *device = NULL;

	CoInitialize(NULL);

	HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void **)&enumerator);
	ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);

	if (p_device->device_name == "Default") {
		hr = enumerator->GetDefaultAudioEndpoint(p_capture ? eCapture : eRender, eConsole, &device);
	} else {
		IMMDeviceCollection *devices = NULL;

		hr = enumerator->EnumAudioEndpoints(p_capture ? eCapture : eRender, DEVICE_STATE_ACTIVE, &devices);
		ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);

		LPWSTR strId = NULL;
		bool found = false;

		UINT count = 0;
		hr = devices->GetCount(&count);
		ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);

		for (ULONG i = 0; i < count && !found; i++) {
			IMMDevice *device = NULL;

			hr = devices->Item(i, &device);
			ERR_BREAK(hr != S_OK);

			IPropertyStore *props = NULL;
			hr = device->OpenPropertyStore(STGM_READ, &props);
			ERR_BREAK(hr != S_OK);

			PROPVARIANT propvar;
			PropVariantInit(&propvar);

			hr = props->GetValue(PKEY_Device_FriendlyName, &propvar);
			ERR_BREAK(hr != S_OK);

			if (p_device->device_name == String(propvar.pwszVal)) {
				hr = device->GetId(&strId);
				ERR_BREAK(hr != S_OK);

				found = true;
			}

			PropVariantClear(&propvar);
			props->Release();
			device->Release();
		}

		if (found) {
			hr = enumerator->GetDevice(strId, &device);
		}

		if (strId) {
			CoTaskMemFree(strId);
		}

		if (device == NULL) {
			hr = enumerator->GetDefaultAudioEndpoint(p_capture ? eCapture : eRender, eConsole, &device);
		}
	}

	if (reinit) {
		// In case we're trying to re-initialize the device prevent throwing this error on the console,
		// otherwise if there is currently no device available this will spam the console.
		if (hr != S_OK) {
			return ERR_CANT_OPEN;
		}
	} else {
		ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
	}

	hr = enumerator->RegisterEndpointNotificationCallback(&notif_client);
	SAFE_RELEASE(enumerator)

	if (hr != S_OK) {
		ERR_PRINT("WASAPI: RegisterEndpointNotificationCallback error");
	}

	hr = device->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void **)&p_device->audio_client);
	SAFE_RELEASE(device)

	if (reinit) {
		if (hr != S_OK) {
			return ERR_CANT_OPEN;
		}
	} else {
		ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
	}

	hr = p_device->audio_client->GetMixFormat(&pwfex);
	ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);

	// Since we're using WASAPI Shared Mode we can't control any of these, we just tag along
	p_device->channels = pwfex->nChannels;
	p_device->format_tag = pwfex->wFormatTag;
	p_device->bits_per_sample = pwfex->wBitsPerSample;
	p_device->frame_size = (p_device->bits_per_sample / 8) * p_device->channels;

	if (p_device->format_tag == WAVE_FORMAT_EXTENSIBLE) {
		WAVEFORMATEXTENSIBLE *wfex = (WAVEFORMATEXTENSIBLE *)pwfex;

		if (wfex->SubFormat == KSDATAFORMAT_SUBTYPE_PCM) {
			p_device->format_tag = WAVE_FORMAT_PCM;
		} else if (wfex->SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) {
			p_device->format_tag = WAVE_FORMAT_IEEE_FLOAT;
		} else {
			ERR_PRINT("WASAPI: Format not supported");
			ERR_FAIL_V(ERR_CANT_OPEN);
		}
	} else {
		if (p_device->format_tag != WAVE_FORMAT_PCM && p_device->format_tag != WAVE_FORMAT_IEEE_FLOAT) {
			ERR_PRINT("WASAPI: Format not supported");
			ERR_FAIL_V(ERR_CANT_OPEN);
		}
	}

	DWORD streamflags = 0;
	if (mix_rate != pwfex->nSamplesPerSec) {
		streamflags |= AUDCLNT_STREAMFLAGS_RATEADJUST;
		pwfex->nSamplesPerSec = mix_rate;
		pwfex->nAvgBytesPerSec = pwfex->nSamplesPerSec * pwfex->nChannels * (pwfex->wBitsPerSample / 8);
	}

	hr = p_device->audio_client->Initialize(AUDCLNT_SHAREMODE_SHARED, streamflags, p_capture ? REFTIMES_PER_SEC : 0, 0, pwfex, NULL);
	ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);

	if (p_capture) {
		hr = p_device->audio_client->GetService(IID_IAudioCaptureClient, (void **)&p_device->capture_client);
	} else {
		hr = p_device->audio_client->GetService(IID_IAudioRenderClient, (void **)&p_device->render_client);
	}
	ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);

	// Free memory
	CoTaskMemFree(pwfex);
	SAFE_RELEASE(device)

	return OK;
}
コード例 #27
0
ファイル: MpcAudioRenderer.cpp プロジェクト: Samangan/mpc-hc
HRESULT CMpcAudioRenderer::GetAudioDevice(IMMDevice **ppMMDevice)
{
    TRACE(_T("CMpcAudioRenderer::GetAudioDevice\n"));

    CComPtr<IMMDeviceEnumerator> enumerator;
    IMMDeviceCollection* devices;
    IPropertyStore* pProps = NULL;
    HRESULT hr = enumerator.CoCreateInstance(__uuidof(MMDeviceEnumerator));

    if (hr != S_OK)
    {
        TRACE(_T("CMpcAudioRenderer::GetAudioDevice - failed to create MMDeviceEnumerator!\n"));
        return hr;
    }

    TRACE(_T("CMpcAudioRenderer::GetAudioDevice - Target end point: %s\n"), m_csSound_Device);

    if (GetAvailableAudioDevices(&devices) == S_OK && devices)
    {
        UINT count(0);
        hr = devices->GetCount(&count);
        if (hr != S_OK)
        {
            TRACE(_T("CMpcAudioRenderer::GetAudioDevice - devices->GetCount failed: (0x%08x)\n"), hr);
            return hr;
        }

        for (ULONG i = 0 ; i < count ; i++)
        {
            LPWSTR pwszID = NULL;
            IMMDevice *endpoint = NULL;
            hr = devices->Item(i, &endpoint);
            if (hr == S_OK)
            {
                hr = endpoint->GetId(&pwszID);
                if (hr == S_OK)
                {
                    if (endpoint->OpenPropertyStore(STGM_READ, &pProps) == S_OK)
                    {

                        PROPVARIANT varName;
                        PropVariantInit(&varName);

                        // Found the configured audio endpoint
                        if ((pProps->GetValue(PKEY_Device_FriendlyName, &varName) == S_OK) && (m_csSound_Device == varName.pwszVal))
                        {
                            TRACE(_T("CMpcAudioRenderer::GetAudioDevice - devices->GetId OK, num: (%d), pwszVal: %s, pwszID: %s\n"), i, varName.pwszVal, pwszID);
                            enumerator->GetDevice(pwszID, ppMMDevice);
                            SAFE_RELEASE(devices);
                            *(ppMMDevice) = endpoint;
                            CoTaskMemFree(pwszID);
                            pwszID = NULL;
                            PropVariantClear(&varName);
                            SAFE_RELEASE(pProps);
                            return S_OK;
                        }
                        else
                        {
                            PropVariantClear(&varName);
                            SAFE_RELEASE(pProps);
                            SAFE_RELEASE(endpoint);
                            CoTaskMemFree(pwszID);
                            pwszID = NULL;
                        }
                    }
                }
                else
                {
                    TRACE(_T("CMpcAudioRenderer::GetAudioDevice - devices->GetId failed: (0x%08x)\n"), hr);
                }
            }
            else
            {
                TRACE(_T("CMpcAudioRenderer::GetAudioDevice - devices->Item failed: (0x%08x)\n"), hr);
            }

            CoTaskMemFree(pwszID);
            pwszID = NULL;
        }
    }

    TRACE(_T("CMpcAudioRenderer::GetAudioDevice - Unable to find selected audio device, using the default end point!\n"));
    hr = enumerator->GetDefaultAudioEndpoint(eRender, eConsole, ppMMDevice);

    SAFE_RELEASE(devices);

    return hr;
}
コード例 #28
0
ファイル: Settings.cpp プロジェクト: elliottmc/MediaPortal-1
HRESULT AudioRendererSettings::GetAudioDevice(IMMDevice** ppMMDevice)
{
  Log("CWASAPIRenderFilter::GetAudioDevice");

  CComPtr<IMMDeviceEnumerator> enumerator;
  IMMDeviceCollection* devices;
  HRESULT hr = enumerator.CoCreateInstance(__uuidof(MMDeviceEnumerator));

  if (FAILED(hr))
  {
    Log("  failed to create MMDeviceEnumerator!");
    return hr;
  }

  Log("Target end point: %S", m_wWASAPIPreferredDeviceId);

  if (GetAvailableAudioDevices(&devices, NULL, false) == S_OK)
  {
    UINT count = 0;
    hr = devices->GetCount(&count);
    if (FAILED(hr))
    {
      Log("  devices->GetCount failed: (0x%08x)", hr);
      return hr;
    }
    
    for (UINT i = 0; i < count; i++)
    {
      LPWSTR pwszID = NULL;
      IMMDevice* endpoint = NULL;
      hr = devices->Item(i, &endpoint);
      if (SUCCEEDED(hr))
      {
        hr = endpoint->GetId(&pwszID);
        if (SUCCEEDED(hr))
        {
          // Found the configured audio endpoint
          if (wcscmp(pwszID, m_wWASAPIPreferredDeviceId) == 0)
          {
            enumerator->GetDevice(m_wWASAPIPreferredDeviceId, ppMMDevice);
            SAFE_RELEASE(devices);
            *ppMMDevice = endpoint;
            CoTaskMemFree(pwszID);
            pwszID = NULL;
            return S_OK;
          }
          else
          {
            SAFE_RELEASE(endpoint);
            CoTaskMemFree(pwszID);
            pwszID = NULL;
          }
        }
        else
          Log("  devices->GetId failed: (0x%08x)", hr);
      }
      else
        Log("  devices->Item failed: (0x%08x)", hr);

      CoTaskMemFree(pwszID);
      pwszID = NULL;
    }
  }

  Log("Unable to find selected audio device, using the default end point!");
  hr = enumerator->GetDefaultAudioEndpoint(eRender, eConsole, ppMMDevice);

  IPropertyStore* pProps = NULL;

  if (SUCCEEDED((*ppMMDevice)->OpenPropertyStore(STGM_READ, &pProps)))
  {
    LPWSTR pwszID = NULL;
    
    PROPVARIANT varName;
    PropVariantInit(&varName);

    PROPVARIANT eventDriven;
    PropVariantInit(&eventDriven);

    PROPVARIANT speakerMask;
    PropVariantInit(&speakerMask);

    if (SUCCEEDED(pProps->GetValue(PKEY_Device_FriendlyName, &varName)) &&
        SUCCEEDED(pProps->GetValue(PKEY_AudioEndpoint_Supports_EventDriven_Mode, &eventDriven)) &&
        SUCCEEDED((*ppMMDevice)->GetId(&pwszID)))
    {
      pProps->GetValue(PKEY_AudioEndpoint_PhysicalSpeakers, &speakerMask);
      Log("Default audio endpoint: \"%S\" (%S) - pull mode: %d sprk mask: %d" ,varName.pwszVal, pwszID, eventDriven.intVal, speakerMask.uintVal);
    }

    CoTaskMemFree(pwszID);
    pwszID = NULL;
    PropVariantClear(&varName);
    PropVariantClear(&eventDriven);
    PropVariantClear(&speakerMask);
    SAFE_RELEASE(pProps)
  }