//-----------------------------------------------------------
// This function enumerates all active (plugged in) audio
// rendering endpoint devices. It prints the friendly name
// and endpoint ID string of each endpoint device.
//-----------------------------------------------------------
//#include "stdafx.h"
#include <MMDeviceAPI.h>
#include <AudioClient.h>
#include <Functiondiscoverykeys_devpkey.h>
#include <iostream>
#include <stdio.h>
#include <typeinfo>
using namespace std;
#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);
//char* GetWideCharToMultiByte(wchar_t* varName) {
// int bufSize = WideCharToMultiByte(CP_ACP, NULL, varName, -1, NULL, 0, NULL, FALSE);
// char* varName_str = new char[bufSize];
// WideCharToMultiByte(CP_ACP, NULL, varName, -1, varName_str, bufSize, NULL, FALSE);
// return varName_str;
//}
void PrintEndpointNames()
{
HRESULT hr = S_OK;
IMMDeviceEnumerator* pEnumerator = NULL;
IMMDeviceCollection* pCollection = NULL;
IMMDevice* pEndpoint = NULL;
IPropertyStore* pProps = NULL;
LPWSTR pwszID = NULL;
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
EXIT_ON_ERROR(hr)
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)
printf("count = %d:\n", count);
if (count == 0)
{
printf("No endpoints found.\n");
}
// Each loop prints the name of an endpoint device.
for (ULONG i = 0; i < count; i++)
{
cout << "\ni = " << i << " --- " << endl;
// Get pointer to endpoint number i.
// 获取集合中第i个端点对象的IMMDevice接口的引用
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)
wcout.imbue(locale("", LC_CTYPE));
wcout << "wcout varName.pwszVal:" << varName.pwszVal << endl;
//宽字符串转换为多字节字符串
int bufSize = WideCharToMultiByte(CP_ACP, NULL, varName.pwszVal, -1, NULL, 0, NULL, FALSE);
char* varName_pwszVal_str = new char[bufSize];
WideCharToMultiByte(CP_ACP, NULL, varName.pwszVal, -1, varName_pwszVal_str, bufSize, NULL, FALSE);
const char* HDMI_str = "HDMI (英特尔(R) 显示器音频)";
const char* system_speaker_str = "扬声器 (Realtek(R) Audio)";
if (strcmp(HDMI_str, varName_pwszVal_str) == 0)
cout << "This is HDMI, it's index is " << i << endl;
else if (strcmp(system_speaker_str, varName_pwszVal_str) == 0)
{
cout << "This is system Speaker, it's index is " << i << endl;
}
else {
cout << "Not found specified device." << endl;
}
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 main() {
PrintEndpointNames();
return 0;
}