直接渲染到 WASAPI 时,两个流之一没有音频输出

Posted

技术标签:

【中文标题】直接渲染到 WASAPI 时,两个流之一没有音频输出【英文标题】:No audio output from one of two streams when rendering directly to WASAPI 【发布时间】:2019-11-14 00:31:42 【问题描述】:

我已经被这个问题困扰了好几个星期了,谷歌也帮不上什么忙,所以希望这里的一些人可以帮助我。

我正在用 C++ 编写软件混音器,从网络和 Windows 麦克风获取音频数据包,将它们混合为 PCM,然后通过网络将它们发送回扬声器/USB 耳机。这行得通。我有一个使用 PortAudio 库来处理与 Windows 的接口的工作设置。但是,我的主管认为可以减少此软件和我们的系统之间的延迟,因此为了降低延迟(并更好地处理 USB 耳机断开连接),我现在正在重写 Windows 接口层以直接使用 WASAPI。我可以消除一些缓冲区和回调这样做,理论上使用超低延迟接口,如果这仍然不够快的话。

我现在只有部分工作,而部分部分就是在这里杀死我的原因。我们的系统将扬声器和耳机作为三个独立的单声道音频流。扬声器是单声道的,耳机由两个流组合成立体声。我将其作为两个流输出到 Windows,一个用于用户选择的扬声器设备,另一个用于用户选择的耳机设备。为了进行测试,它们都输出到我系统上的默认常规立体声混音。

我可以很好地听到扬声器的声音,但无论我尝试什么,我都无法听到耳机的声音。它们都使用相同的代码路径,它们都通过 WMF 重采样器以 Windows 所需的采样率转换为 2 通道音频。但我可以听到扬声器,但听不到耳机流。

这不是独占模式问题:我在所有流上都使用共享模式,我什至专门尝试将流减少到仅耳机,以防一个人踩到另一个或其他东西,但仍然是耳机没有音频输出。

这不是上游的混音器问题,因为我没有修改任何与 PortAudio 流一起使用时的代码。我可以看到音频通过混音器并通过我的调试可视化器输出。

当系统回调请求音频时,我可以看到数据进入了我从系统获取的缓冲区。我应该听到 something,甚至是静态的,但我什么也没得到。 (有一次,我完全绕过了环形缓冲区,在回调中直接将随机数放入缓冲区,但仍然没有声音。)

我在这里做错了什么?似乎 Windows 本身就是问题或其他问题,但我没有 Windows API 方面的专业知识来知道什么,而且我显然是我公司中最擅长这方面的专家。我什至还没有弄清楚为什么麦克风输入不起作用,而且我已经坚持了好几个星期了。如果有人有任何建议,将不胜感激。

【问题讨论】:

【参考方案1】:

检查重新采样的流:将立体声流输出到扬声器,将单声道流输出到听筒。

使用IAudioClient::IsFormatSupported 检查手机支持的格式。

使用 mp3 文件验证您的代码。使用两个媒体播放器在不同的设备上同时播放不同的文件。

【讨论】:

这些对我的问题没有特别帮助。但是,您提到IsFormatSupported 让我想起了扬声器流总是会因为单声道而被拒绝其格式,因此我询问系统该设备是否支持其自己的默认格式并转换为该格式。我用耳机实现了同样的特技,现在它可以工作了。这意味着耳机从IsFormatSupported IS A FLAT-OUT LIE 获得的“最接近”格式,因为它不支持它本身建议的格式。谢谢,微软。

以上是关于直接渲染到 WASAPI 时,两个流之一没有音频输出的主要内容,如果未能解决你的问题,请参考以下文章

使用 WASAPI 录制音频流

使用 wasapi 渲染音频的问题

WASAPI 音频设备的同步

尝试使用 Win32 WASAPI C++ 中的“捕获流”创建 wav 文件

Core Audio (WASAPI) 缓冲区事件计时

WebRTC Native M96 SDK接口封装--enableLoopbackRecording启用声卡采集,声卡播放的声音合到本地音频流发送远端