pyaudio高级玩法4:使用不同的声音设备
在这个系列的第一篇中,介绍了pyaudio的非阻塞模式,不过这个词还是有点生僻的,所以很多人没有明白代码的意义,为了让使用者少走弯路,所以在开始今天的正题之前,在这里补充说明一下。

pyaudio录音时,经常会有一边录音,一边做其他事情的需求。
比如一边录音一边保存,一边录音一边处理?
你大概会想一些其他解决方案,比如使用多线程完成这样的任务。
不过pyaudio是原生支持非阻塞模式记录声音的。
什么是非阻塞模式?
假设你使用一句编程代码来实现记录一秒钟声音这样的工作,
这种时候程序的运行一般有两种情况:
第一种,在这个代码执行的1秒钟时间内,程序就卡在这里等待其执行完毕后,再处理后面的内容。显然,对于一台计算机来说,这样的处理模式效率不高。如果需要循环记录声音,那么在处理其他内容的时候,也会造成声音记录这项工作被撕裂,导致记录的声音断断续续。
第二种情况,程序一旦启动录音,剩下的工作都放在后台运行,程序则不会等待其执行完毕,而是直接去执行后面的语句。当然,为了方便对声音的处理,我们可以随时去查看已经录到的内容,或者查询是否已经录制完毕。这样充分解决了
网上一般给出的pyaudio代码都是第一种情况,而实际上pyaudio可以直接支持第二种处理方式。而且设计非常完善,你所需要的只是添加一个回调函数。
具体怎么做?欢迎查看本系列的第一篇文章。

现在回过头来,pyaudio的功能可不仅仅局限于使用阻塞和非阻塞的方式去记录声音,作为python管理声音输入输出的主力库,其也可以管理你计算机上的声音输入输出设备。
以windows系统为例,我看先看一下在windows系统上如何管理这些设备。

这里可以管理windows的默认音频设备,它会影响到pyaudio的使用,当然pyaudio也可以直接调用非默认的音频设备。
我们可以查看当前计算机的音频设备和编号。先看代码:

import pyaudio
p = pyaudio.PyAudio()
print(p)
for i in range(p.get_device_count()):
print(p.get_device_info_by_index(i))

b站对代码的支持不太好,所以如果你复制粘贴这段代码,需要将其中的空格替换会正常的空格。代码本身还能更简单么?我认为不能啦。
然后,看看我们能获得什么。

返回的列表列出了本机上的所有音频设备,包括实际上可用的和不可用的,还有一些实际上重复的。除了编号,名称,还包括了输入和输出的声道数等信息。
一些设备从名称上就可以分辨其到底是输入设备,还是输出设备,不过更保险的方式是查看后面的maxinputchannel(最大输入声道数)和maxoutputchannel(最大输出声道数)。
列表可以看到,还是挺复杂的,如果不是有特殊需求(比如同时控制若然个不同的声音设备),我建议你还是直接忽略这些,不指定设备参数时,pyaudio会贴心的为你调用系统默认的声音设备。
知道了这些编号,我们只需要在pyaudio中设置对应的参数就可以啦。可以参考上一篇代码中的参数。
这里我直接把用到的部分搬过来。

是不是说的很详细了呢?
虽然忘了提,上篇内容其实也用到了pyaudio的输出功能。
综合这4篇文章,现在你应该可以使用pyaudio彻底玩转你计算机上的音频功能啦。剩下的应该只有用来处理声音的各种算法了。