I tried to use wasapi to record system's playout audio, but if the audio device has 8 channels, I always get the error (AUDCLNT_E_UNSUPPORTED_FORMAT) "m_captureClient->Initialize" would return AUDCLNT_E_UNSUPPORTED_FORMAT. But if the device is 48khz, 2 channels, then everything is OK.
The code is as below:
do {
HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL,
__uuidof(IMMDeviceEnumerator), (void**)&m_deviceEnumerator);
if (FAILED(hr)) {
err = ERROR_CODE_COM_CREATE_INSTANCE_FAILED;
break;
}
hr = m_deviceEnumerator->GetDevice(HELPER::StringConverter::convertUtf8ToUnicode(m_deviceId).c_str(), &m_endpointDevice);
if (FAILED(hr)) {
err = ERROR_CODE_COM_GET_AUDIO_ENDPOINT_FAILED;
break;
}
hr = m_endpointDevice->Activate(__uuidof(IAudioClient), CLSCTX_ALL, nullptr, (void**)&m_captureClient);
if (FAILED(hr)) {
err = ERROR_CODE_COM_ACTIVE_DEVICE_FAILED;
break;
}
hr = m_captureClient->GetMixFormat(&m_waveFmt);
if (FAILED(hr)) {
err = ERROR_CODE_COM_GET_MIX_FORMAT_FAILED;
break;
}
initFromMixFormat(m_waveFmt);
DWORD streamFlags = AUDCLNT_STREAMFLAGS_EVENTCALLBACK;
if (!m_isMic) {
streamFlags |= AUDCLNT_STREAMFLAGS_LOOPBACK;
}
hr = m_captureClient->Initialize(AUDCLNT_SHAREMODE_SHARED, streamFlags, WASAPI_CAPTOR_REF_TIME_PER_SEC, 0, m_waveFmt, nullptr);
if (FAILED(hr)) {
err = ERROR_CODE_COM_INIT_AUDIO_CLIENT_FAILED;
break;
}
// For ouotput mode, capture event will not signal when there is nothing rendering,
// so we run a render thread and rendering silent pcm data all the time.
if (!m_isMic) {
err = initRenderer();
HCMDR_ERROR_CODE_BREAK(err);
}
hr = m_captureClient->GetBufferSize(&m_captureSampleCount);
if (FAILED(hr)) {
err = ERROR_CODE_COM_GET_BUFFER_SIZE_FAILED;
break;
}
hr = m_captureClient->GetService(__uuidof(IAudioCaptureClient), (void**)&m_captor);
if (FAILED(hr)) {
err = ERROR_CODE_COM_GET_CAPTOR_FAILED;
break;
}
m_captureEvent = CreateEventA(nullptr, FALSE, FALSE, nullptr);
if (m_captureEvent == nullptr) {
err = ERROR_CODE_COM_CREATE_EVENT_FAILED;
break;
}
m_stopEvent = CreateEventA(nullptr, TRUE, FALSE, nullptr);
if (m_stopEvent == nullptr) {
err = ERROR_CODE_COM_CREATE_EVENT_FAILED;
break;
}
hr = m_captureClient->SetEventHandle(m_captureEvent);
if (FAILED(hr)) {
err = ERROR_CODE_COM_SET_EVENT_FAILED;
break;
}
m_inited = true;
} while (0);