背景
在平时用电脑时,因为就一个设备,没有想过声音是如何传输的。
这次连接了小爱同学和蓝牙耳机,发现网易云音乐有15个声音选项,令我来了兴趣:
DirectSound:Primary Sound Driver
DirectSound:扬声器(Realtek High Definition Audio)
DirectSound:耳机(小爱音箱-8825 stereo)
DirectSound:耳机(QCY T8 Stereo)
DirectSound:耳机(QCY T8 Hands-Free AG Audio)
WaveOut:Microsoft Sound Mapper
WaveOut:扬声器(Realtek High Definition Au)
WaveOut:耳机(小爱音箱-8825 Stereo)
WaveOut:耳机(QCY T8 Stereo)
WaveOut:耳机(QCY T8 Hands-Free AG Audio)
Wasapi:默认输出设备
Wasapi:耳机(小爱音箱-8825 Stereo)
Wasapi:扬声器(Realtek High Definition Audio)
Wasapi:耳机(QCY T8 Stereo)
Wasapi:耳机(QCY T8 Hands-Free AG Audio)
首先我们发现,网易云的15个选项实际上是3个xxx+5个设备的组合,不禁让我们思考原理。
设备传输
我们理清一下设备传输的过程。
- 网络层:从网易云音乐下载下来音乐文件,一般以临时文件存储。
- 应用层:文件被软件解码出声音数据流,软件选择设备选项输出,一般是默认设备为多。
- 系统层:操作系统给每个设备提供各API,用于调用硬件资源。
- 硬件层:通过驱动程序和系统衔接,处理数据流,发出声音。
所以这3个xxx应该是系统层的不同接口,把硬件各自弄了个 API。
其他5个则是硬件,硬件中有一个是默认设备,在点击Windows的🔈时可以选择。
但剩下4个中 QCY-T8 实际上重复了一次,应该是驱动程序识别出了两个设备,其中 QCY T8 Hands-Free AG Audio 的声音是单声道,而且是通话质量,音质估计在 20 kbps,基本上听不下去。
而且,耳机还自带一个麦克风,而且名字也叫 QCY T8 Hands-Free AG Audio (2) ,我估计麦克风和刚才的低质量耳机是一体的,之所以设计低质量输出,就是为了麦克风和耳机同时启用。
而识别了两个设备的原理,可以先了解一下「蓝牙」 ,然后看看驱动的知识。
系统 API
WASAPI与Waveout 与Directsound的区别 ,解释了系统API的区别,具体接口介绍可以在百度百科搜到。
WASAPI、DirectSound/DS、WaveOut、Kernel Streaming/KS :这个资料更全面
Windows应该有很多API可以玩,比如连点器,其实就是调用了光标操作API。
除了到 Microsoft Docs 查API,可以看看 <windws.h>
中有很多有趣的API。
现在软件开发都不用自己调用API了,很多IDE都支持自动调用API,比如window应用就经常用.NET来写,本质上他的API函数是封装多层后给你的。
腾讯会议
不过有趣的是,因为 QCY 有两个设备,当腾讯会议选择一个 QCY 的一个设备后,如果它恰好没检测到另一个设备,那电脑通过另一个设备发出的所有声音都无了,只有把 Windows 输出也选择 QCY 相同的设备才正常。
解决办法是断开耳机,重新连接,然后腾讯会议会重新检测设备,此时在 Windows 选择默认,然后腾讯会议会跟着 Windows 默认输出了。
但有时候,这个问题更加严重,两个设备不管选择那个都没有声音,居然只能用电脑扬声器,重启蓝牙没有用,重启耳机没有用,重启腾讯会议也没有用,逼得我把所有软件都关一遍,接近于重启电脑。然后一开腾讯会议,继续重复前面的问题!
以上这些原因还不清楚,但能推测到它应该修改了 API 的一些设置,类似于为了通信而进行的独占。某些软件那种固执己见的开发方式,总是搞的兼容性差,操作也不流畅,令人难受要命。
浏览器
我还发现一个现象,蓝牙音箱在驱动上似乎有问题。
电脑随便打开一个音频,比如用 potplayer 打开视频、打开网易云音乐,然后浏览器随便播放个音频,比如B站视频、网易云音乐。
这个时候,potplayer 的暂停不会影响浏览器或任何一个软件,但浏览器暂停后,所有软件的音频会全部没有声音。
这个问题另我很恼火,凭什么浏览器会控制整个电脑的音频输出呢?
我推测是浏览器连接的音频 API 是Waveout,因为这个 API 是软件独占的。而在不练蓝牙音箱时,可能用的是 DirectSound API。
于是我去搜了一下,发现浏览器的权限似乎确实很高。比如 「Internet 选项」,似乎是 Windows 专门给浏览器的 API,@ Windows Internet 、Internet Options
接着我尝试把浏览器输出选为「电脑扬声器」,其他软件选为「蓝牙音箱」,更离谱事情发生了,我暂停电脑的扬声器,音响也没声音了。
我用「开发人员工具」删掉了所有的「事件」,包括 Framework 侦听器,但依旧没有效果。我推测事件只是执行的条件,问题不是要不要执行,而是执行音频操作后会对系统 API 造成影响。
后续更新:询问 GPT4
目前我是手动切换音频源解决的。
首先把要听的音频换到电脑扬声器,然后再切换回蓝牙音箱,就好了。