一、注意事项
1、获取音频设备需要调用CoInitialize以及CoUninitialize。
2、由于C++没有finally关键字,代码中的CUSTOM_FINALLY为自定义宏,是为了实现类似try...catch...finally的效果,本身没有什么意义:
//定义空宏,处理finally
#ifndef CUSTOM_FINALLY
#define CUSTOM_FINALLY
#endif // CUSTOM_FINALLY
3、打印日志宏:
#define PNTLOG(format, ...) wprintf(format L"\n", __VA_ARGS__)
#define PNTERR(format, ...) PNTLOG(L"Error: " format, __VA_ARGS__)
#define PNTERRMSG(msg) wprintf(L"Error: %s \n", msg)
4、PKEY_Device_FriendlyName需要引用相应的头文件:
#include <functiondiscoverykeys_devpkey.h>
5、获取扬声器设备使用eRender枚举类型,获取麦克风设备使用eCapture枚举类型。
二、代码
1、获取默认扬声器
(1)获取设备指针
bool GetDefaultDevice(IMMDevice **ppMMDevice)
{
bool ret = false;
IMMDeviceEnumerator *pMMDeviceEnumerator = nullptr;
wchar_t wszErrMsg[MAX_PATH] = { 0 };
try
{
HRESULT hr = CoCreateInstance(
__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL,
__uuidof(IMMDeviceEnumerator),
reinterpret_cast<void**>(&pMMDeviceEnumerator)
);
if (FAILED(hr))
{
wsprintf(wszErrMsg, L"CoCreateInstance(IMMDeviceEnumerator) failed: hr = 0x%08x", hr);
throw std::exception();
}
// get the default render endpoint
hr = pMMDeviceEnumerator->GetDefaultAudioEndpoint(
eRender, eConsole, ppMMDevice
);
if (FAILED(hr))
{
wsprintf(wszErrMsg, L"IMMDeviceEnumerator::GetDefaultAudioEndpoint failed: hr = 0x%08x", hr);
throw std::exception();
}
ret = true;
}
catch(std::exception&)
{
PNTERRMSG(wszErrMsg);
}
//释放资源
CUSTOM_FINALLY
{
if (pMMDeviceEnumerator != nullptr)
{
pMMDeviceEnumerator->Release();
}
}
return ret;
}
(2)获取设备Id和名称
bool GetDefaultDevice(wstring& deviceId, wstring& deviceName)
{
IMMDevice* pMMDevice = nullptr;
if (!GetDefaultDevice(&pMMDevice))
{
return false;
}
bool ret = true;
wchar_t ws