我正在构建一个应用程序来使用WASAPI从设备捕获音频,其中使用的所有API都支持Windows vista及以上设备。
最初,我使用 WASAPI Capture 作为共享计时器驱动模式从设备捕获音频,其中将有一个线程每 0 毫秒从设备捕获音频。它在 Windows Vista 及以上设备中工作。
由于上述方法在 CPU 消耗方面效率不高,并且并非全部经过优化,因此我尝试使用 WASAPI Capture 作为共享事件驱动模式从设备捕获音频,其中仅当事件触发时才会捕获音频当数据可用时系统。此方法确实完全降低了 CPU 消耗,但不适用于 Windows VISTA 到 Windows Server 2016 设备。
Initialization of audio client interface
音频接口使用共享模式初始化,并且给出的流标志用于 AUDCLNT_STREAMFLAGS_EVENTCALLBACK,因为我使用的是事件驱动模式。 GetExtensibleMixFormat 方法给出了使用 Windows 的 GetMixFormat() 获取的默认混合格式。
int enginelatency = 20;
HRESULT hr = _AudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_LOOPBACK , enginelatency * 10000, 0, (WAVEFORMATEX*)mix_format_wasapicap_ptr->GetExtensibleMixFormat(), NULL);
Initializing the event
其中 _AudioSamplesReadyEvent 是提供给 SetEventHandle 方法的句柄。当音频缓冲区准备好由客户端处理时,系统将触发此事件。
hr = _AudioClient->SetEventHandle(_AudioSamplesReadyEvent);
虽然所有使用的 API 均受 Windows VISTA 及以上设备支持,但无法弄清楚为什么在 Windows VISTA 到 Windows Server 2016 设备中未触发事件。
我已经正确处理了错误,但无法捕获任何错误。另请注意,我使用了 WASAPI 捕获代码,通过将 GetDefaultAudioEndpoint 中使用的 dataFlow 更改为 eRender,进行了一些细微的更改,以便我可以从输出设备而不是麦克风捕获音频,因为 eCapture 捕获输入设备。
在调试时,我发现在 Windows Vista 到 Windows Server 2016 设备中,使用 eCapture 事件时正确触发,但使用 eRender _AudioSamplesReadyEvent 事件时未触发。
如有任何建议,我们将不胜感激。
根据Initialize文档,提到EVENT回调在Windows 10以下操作系统版本中不适用于环回流标志。
我使用渲染客户端触发事件来捕获客户端,其中我使用环回标志初始化捕获客户端,并使用事件回调初始化渲染客户端。
触发渲染客户端事件后,我使用捕获客户端从设备捕获音频缓冲区。
这就是我们需要在 Windows 10 以下操作系统中从输出设备捕获音频的方式。