IAudioClient::Initialize
初始化音频流的时候发生报错AUDCLNT_E_UNSUPPORTED_FORMAT(0x88890008),先上产生了错误的代码:
WAVEFORMATEX* wfex;
HRESULT res;
DWORD flags = AUDCLNT_STREAMFLAGS_NOPERSIST;
flags |= AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM;
res = Device->Activate(__uuidof(IAudioClient), CLSCTX_ALL, nullptr,
(void**)&ac);
if (FAILED(res))
throw HRError("Failed to activate client context",res);
res = AudioClient->GetMixFormat(&wfex);
if (FAILED(res))
throw HRError("Failed to get mix format",res);
InitFormat(wfex);
CoTaskMemFree(wfex);
if (!m_isInputDevice)
flags |= AUDCLNT_STREAMFLAGS_LOOPBACK;
else
flags |= AUDCLNT_STREAMFLAGS_EVENTCALLBACK;
res = ac->Initialize(AUDCLNT_SHAREMODE_SHARED, flags,
BUFFER_TIME_100NS, 0, wfex, nullptr);
if (FAILED(res))
throw HRError("Failed to get initialize audio client",res);
解决思路:
首先查阅微软官方文档对该错误的解释:
AUDCLNT_E_UNSUPPORTED_FORMAT | The audio engine (shared mode) or audio endpoint device (exclusive mode) does not support the specified format. |
并尝试使用IAudioClient::IsFormatSupported排查问题:
WAVEFORMATEX* wfex2;
res = ac->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, wfex, &wfex2);
发现上述代码的报错相同,开始排查WAVEFORMATEX的输入参数是否正确
通过跟代码发现wfex在GetMixFormat()赋值后,wFormatTag被CoTaskMemFree()修改了
应该把CoTaskMemFree()放到Initialize()之后,程序正常。
最后贴上正常的代码:
WAVEFORMATEX* wfex;
HRESULT res;
DWORD flags = AUDCLNT_STREAMFLAGS_NOPERSIST;
flags |= AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM;
res = Device->Activate(__uuidof(IAudioClient), CLSCTX_ALL, nullptr,
(void**)&ac);
if (FAILED(res))
throw HRError("Failed to activate client context",res);
res = AudioClient->GetMixFormat(&wfex);
if (FAILED(res))
throw HRError("Failed to get mix format",res);
InitFormat(wfex);
if (!m_isInputDevice)
flags |= AUDCLNT_STREAMFLAGS_LOOPBACK;
else
flags |= AUDCLNT_STREAMFLAGS_EVENTCALLBACK;
WAVEFORMATEX* wfex2;
res = ac->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, wfex, &wfex2);
res = ac->Initialize(AUDCLNT_SHAREMODE_SHARED, flags,
BUFFER_TIME_100NS, 0, wfex, nullptr);
if (FAILED(res))
throw HRError("Failed to get initialize audio client",res);
CoTaskMemFree(wfex);