我正在尝试学习如何使用WASAPI通过我的默认播放设备播放音频。我的测试是从默认设备捕获音频并将其发送到播放设备进行渲染,以便我可以通过扬声器听到自己的声音。
出现我从捕获设备获取的数据工作正常,但是当我将其发送到IAudioRenderClient缓冲区时,有时我会得到纯静态,有时我只是得到沉默。
如果您认为需要查看我的捕获设备逻辑,请询问。我没有发布它,因为在我看来它是一个播放设备问题。
我的设备在其他应用中正常运行。所以它不是设备问题。
谁能告诉我我做错了什么?
播放设备初始化
#define REFTIMES_PER_SEC 48000
bool AudioManager::InitPlaybackDevice()
{
HRESULT hr;
WAVEFORMATEX* pWfx = nullptr;
BYTE* pData = nullptr;
UINT32 nNumFramesPadding = 0;
// Query the Enumerator for the default playback device
hr = m_pEnumerator->GetDefaultAudioEndpoint(eRender, eCommunications, &m_pPlaybackDevice);
EXIT_ON_ERROR_SHUTDOWN(hr);
hr = m_pPlaybackDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&m_pAudioRenderClient);
EXIT_ON_ERROR_SHUTDOWN(hr);
hr = m_pAudioRenderClient->GetMixFormat(&pWfx);
EXIT_ON_ERROR_SHUTDOWN(hr);
hr = m_pAudioRenderClient->Initialize(AUDCLNT_SHAREMODE_SHARED, 0, REFTIMES_PER_SEC, 0, pWfx, NULL);
EXIT_ON_ERROR_SHUTDOWN(hr);
hr = m_pAudioRenderClient->GetBufferSize(&m_nPlaybackBufferFrameCount);
EXIT_ON_ERROR_SHUTDOWN(hr);
hr = m_pAudioRenderClient->GetService(IID_IAudioRenderClient, (void**)&m_pAudioRenderClientObj);
EXIT_ON_ERROR_SHUTDOWN(hr);
hr = m_pAudioRenderClient->GetCurrentPadding(&nNumFramesPadding);
EXIT_ON_ERROR_SHUTDOWN(hr);
hr = m_pAudioRenderClientObj->GetBuffer(m_nPlaybackBufferFrameCount - nNumFramesPadding, &pData);
EXIT_ON_ERROR_SHUTDOWN(hr);
hr = m_pAudioRenderClientObj->ReleaseBuffer(m_nPlaybackBufferFrameCount - nNumFramesPadding, AUDCLNT_BUFFERFLAGS_SILENT);
EXIT_ON_ERROR_SHUTDOWN(hr);
hr = m_pAudioRenderClient->Start();
EXIT_ON_ERROR(hr);
return true;
}
将音频数据发送到播放设备
bool AudioManager::SendSampleToPlaybackDevice(BYTE * i_pData, UINT32 i_nSize)
{
if (m_pAudioRenderClientObj != nullptr)
{
HRESULT hr;
BYTE* pData = nullptr;
UINT32 nNumFramesPadding = 0;
int nNumFrames = 0;
hr = m_pAudioRenderClient->GetCurrentPadding(&nNumFramesPadding);
EXIT_ON_ERROR(hr);
nNumFrames = min(i_nSize, m_nPlaybackBufferFrameCount - nNumFramesPadding);
hr = m_pAudioRenderClientObj->GetBuffer(nNumFrames, &pData);
EXIT_ON_ERROR(hr);
if(pData != nullptr)
memcpy(pData, i_pData, nNumFrames);
hr = m_pAudioRenderClientObj->ReleaseBuffer(nNumFrames, 0);
EXIT_ON_ERROR(hr);
return true;
}
return false;
}