我正在尝试使用 WASAPI 捕获音频。我的代码主要基于ChatterBox VoIP 示例应用程序。我正在获取音频缓冲区,但它们都是无声的(标记为 AUDCLNT_BUFFERFLAGS_SILENT)。
我正在为 Windows Phone 使用 Visual Studio Express 2012。在模拟器上运行。
我正在尝试使用 WASAPI 捕获音频。我的代码主要基于ChatterBox VoIP 示例应用程序。我正在获取音频缓冲区,但它们都是无声的(标记为 AUDCLNT_BUFFERFLAGS_SILENT)。
我正在为 Windows Phone 使用 Visual Studio Express 2012。在模拟器上运行。
如果我将 Visual Studio 设置为本机调试并在任何时候单步执行代码,我遇到了完全相同的问题并设法在 ChatterBox 示例应用程序中重现它。
此外,在不经过“停止”程序的情况下关闭应用程序并停止 AudioClient 将要求您重新启动模拟器/设备,然后才能再次捕获音频数据。
在我弄清楚前面提到的问题之前,它几乎让我发疯,但我终于让它工作了。
所以.. 1. 一定不要做原生调试 2. 总是调用 IAudioClient->Stop(); 在终止应用程序之前。3. 确保将正确的参数传递给 IAudioClient->Initialize();
我已经包含了一段对我来说 100% 有效的代码。为了清楚起见,我省略了错误检查..
LPCWSTR pwstrDefaultCaptureDeviceId =
GetDefaultAudioCaptureId(AudioDeviceRole::Communications);
HRESULT hr = ActivateAudioInterface(pwstrDefaultCaptureDeviceId,
__uuidof(IAudioClient2), (void**)&m_pAudioClient);
hr = m_pAudioClient->GetMixFormat(&m_pwfx);
m_frameSizeInBytes = (m_pwfx->wBitsPerSample / 8) * m_pwfx->nChannels;
hr = m_pAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED,
AUDCLNT_STREAMFLAGS_NOPERSIST | AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
latency * 10000, 0, m_pwfx, NULL);
hr = m_pAudioClient->SetEventHandle(m_hCaptureEvent);
hr = m_pAudioClient->GetService(__uuidof(IAudioCaptureClient),
(void**)&m_pCaptureClient);
就是这样。在调用此代码之前,我已经启动了一个工作线程,它将监听 m_hCaptureEvent 并调用 IAudioCaptureClient->GetBuffer(); 每当触发捕获事件时。
当然,使用 Microsoft.XNA.Audio.Microphone 可以正常工作,但引用 XNA 框架并不总是一种选择.. :)
这是一个非常烦人的问题,浪费了我大约 2 天的时间。我的问题通过设置AudioClientProperties.eCatagory
为AudioCategory_Communications
而不是AudioCategory_Other
.
经过这么长的尝试和错误期后,我不确定这个问题将来是否会重复,因为 API 的行为不是很稳定,每次运行都可能返回不同的结果。
编辑:是的,我的猜测是正确的。重新启动 wp 模拟器会使缓冲区再次静音。但是将其更改AudioClientProperties.eCatagory
为AudioCategory_Other
再次解决它。我仍然不知道它有什么问题以及最终的解决方案是什么。
我再次遇到同样的问题,这次评论(删除)
properties.eCategory = AudioCategory_Communications;
解决了问题。
我可以添加我对 Windows Phone 8.1 的建议。我做了以下实验。
然后我用 AudioDeviceRole::Communications 打开捕获设备,捕获设备一直工作正常。
对于 Windows 10 捕获设备始终有效,无论您是否使用 AudioDeviceRole::Communications 打开它。
我有同样的问题。似乎您既可以使用 only ,也可以AudioCategory_Other
创建一个实例VoipPhoneCall
and use only AudioCategory_Communications
。
所以我的解决方案是使用AudioCategory_Communications
并创建一个传出的VoipPhoneCall
. 您应该像在Chatterbox VoIP 示例应用程序中那样实现后台代理VoipCallCoordinator
才能正常工作。