树莓派3 音频配置及其应用场景(录音、VoIP 电话等)

从网上看到一本关于树莓派的电子书 Raspberry Pi for Secret Agents,利用树莓派打造“特工装备”。
其中有一章讲到音频设备的配置和几个相关的应用场景(比如录音监听、搭建电话系统等),感觉比较有意思。

一、音频系统简单配置

1. ALSA

ALSA (Advanced Linux Sound Architecture) 是一个承载树莓派上音频系统的底层框架,为树莓派及其外接的播放或录制设备提供内核驱动程序。同时该框架也包含用于制作音频应用的程序代码,和一些方便的命令行实用程序。

在 ALSA 的定义里,系统中的每一个音频设备都称作“声卡”。可以使用如下命令列出所有已连接的音频设备:

1
2
3
$ cat /proc/asound/cards
0 [ALSA ]: bcm2835_alsa - bcm2835 ALSA
bcm2835 ALSA

可以看到此时系统中只有树莓派默认的声卡 0 bcm2835 ALSA

2. 调节音量大小

可以使用 alsamixer 命令打开 AlsaMixer 实用程序,对音量等声音系统参数进行调节:
alsamixer

界面中 View 选项后面的 PlaybackCaptureAll 分别对应播放录制全部
可以按键盘上的 TAB 键切换到对应的界面。按下 fn+F6S 键切换声卡设备(此时只有一个声卡)

使用 ↑ ↓ 方向键调节音量,设置完成后按 ESC 键退出 AlsaMixer。

3. 切换音频输出

树莓派提供两种音频输出接口:3.5mm 模拟音频接口HDMI
可以通过 $sudo raspi-config 命令(选择 Advanced Options - Audio)配置音频输出方向,使音频输出固定使用 3.5mm 接口或 HDMI:
raspi-config

类似的操作也可以直接通过 amixer 命令完成:
$ amixer cset numid=3 1 :指定音频输出接口为 3.5mm 耳机接口
$ amixer cset numid=3 2 :指定音频输出接口为 HDMI

1
2
3
4
$ amixer cset numid=3 1
numid=3,iface=MIXER,name='PCM Playback Route'
; type=INTEGER,access=rw------,values=1,min=0,max=2,step=0
: values=1

4. 播放测试

可以使用 $ speaker-test -c2 -t wav 命令测试音频播放是否正常。
如一切顺利,则会依次从左耳耳机(或音箱)听到 Front Left,从右耳耳机听到 Front Right 的女声语音,直到按下 Ctrl + C 终止测试。

二、音频录制设备

1. USB声卡

树莓派提供的音频接口是不支持语音输入的。
使用 alsamixer 命令进入 AlsaMixer 程序,按下 TAB 键切换到 Caputre 界面,可以看到此设备无音频采集控制的提示:
bcm2835 ALSA Capture

为了录制音频,需要使用外接的音频输入设备。可以从网上购买一个便携式的 USB 免驱动声卡。
USB声卡及线控耳机
插入USB声卡后,通过 $ cat /proc/asound/cards 命令查看当前系统检测到的音频设备:

1
2
3
4
5
$ cat /proc/asound/cards
0 [ALSA ]: bcm2835_alsa - bcm2835 ALSA
bcm2835 ALSA
1 [Device ]: USB-Audio - USB Audio Device
GeneralPlus USB Audio Device at usb-3f980000.usb-1.3, full speed

此时输出信息中多了一个序号为 1 的声卡设备 USB-Audio
可以使用 $ speaker-test -D plughw:1 -c2 -t wav 测试 USB 声卡的音频播放是否正常(注意命令中的 -D plughw:1)。

使用 alsamixer -c1 命令调节新声卡的具体参数。其中 -c1 选项用于指定编号为 1 的声卡设备,即新插入的 USB 声卡。
alsamixer -c1

按下 fn+F4TAB 键将视图切换到 Capture 界面,确保 Mic 上方有出现 CAPTURE 字样(说明已开启录制功能,可以使用空格键切换开关状态):
Capture

2. 麦克风测试

首先安装 SoX 工具及其 mp3 格式支持:$sudo apt-get install sox libsox-fmt-mp3
SoX 是 Linux 系统上一个强大的音频处理工具,详细使用方法可以参考这篇文章:SoX — 音频处理工具里的瑞士军刀

sox 命令的基本格式为 sox <input> <output> 。其中的 <input><output> 既可以是某个具体的音频文件,也可以是某个特定的音频设备
所以可以简单的理解为,sox 工具就是对音频进行“传导”

  • 从文件到设备即为播放 sox music.mp3 <device>
  • 从设备到文件即为录制 sox <device> myrec.wav
  • 从文件到文件即为转码 sox input.wav output.mp3

可以使用 $ sox -t alsa plughw:1 -t alsa plughw:1 命令对麦克风进行测试。
其中 -t alsa plughw:1 表示 ALSA 声卡设备 1(即USB声卡)。
上述命令表示既使用USB声卡(麦克风) 作为音频输入,又用它(耳机)作为音频输出。

如一切正常,此时可以通过耳机听到自己对着麦克风讲话的声音。

3. 切换默认的音频设备

可以通过修改配置文件,将树莓派默认用于播放和录制的音频设备(即树莓派内置声卡),改为当前插入的USB声卡。
编辑 ~/.asoundrc 文件,改为如下内容:

1
2
3
4
5
6
7
8
9
pcm.!default {
type hw
card 1
}

ctl.!default {
type hw
card 1
}

其实就是将配置文件中的 card 0 改为 card 1

此时可直接使用 $ sox -d -d 命令测试USB声卡上连接的麦克风和耳机,无需再通过 -t alsa plughw:1 选项手动指定USB声卡(-d 选项表示默认音频设备,即已配置成默认的USB声卡)。

4. 录制与播放

默认音频设备切换为USB声卡后,可以使用以下命令录制一段音频并将其保存在 myrec.mp3 文件中:
$ sox -d myrec.mp3$ rec myrec.mp3

播放前面录制的音频文件可使用如下命令:
$ sox myrec.mp3 -d$ play myrec.mp3

未能配置USB声卡为默认音频设备或配置不成功,也可以使用如下命令进行录制与播放:
录制:$ sox -t alsa plughw:1 myrec.mp3
播放:$ sox myrec.mp3 -t alsa plughw:1

录制固定长度的音频片段(如 30 分钟)并保存在指定文件中:
$ sox -t alsa plughw:1 myrec.wav trim 0 00:30:00

持续录制很长时间的音频,保存在几个不同的文件中,每隔一小时保存一次:
$ sox -t alsa plughw:1 myrec.wav trim 0 01:00:00 : newfile : restart

三、远程监听

可以通过树莓派的 SSH 服务,在另一台电脑上远程收听树莓派通过USB声卡收集到的音频数据。
也就是说,用树莓派的麦克风录制周围环境的声音,同时在远程的另一台电脑上实时地(有短暂延迟)收听录制的内容,达到监听的效果。

在电脑端(也需要安装 sox 程序)执行如下命令即可:
$ ssh pi@[IP address] sox -t alsa plughw:1 -t sox - | sox -q -t sox - -d
sox

对于 Windows 系统,除安装 SoX 工具外,还需要先下载完整版 PuTTY 工具,并确保这两个工具的安装路径都已添加至 PATH 环境变量。

则可以使用如下命令通过树莓派进行远程监听:
plink pi@[IP address] -pw [password] sox -t alsa plughw:1 -t sox - | sox -q -t sox - -t waveaudio default

可以使用如下命令,将远程树莓派收集到的音频数据直接保存在本地文件中:
$ ssh pi@[IP address] sox -t alsa plughw:1 -t mp3 - > ~/Desktop/myrec.mp3
plink pi@[IP address] sox -t alsa plughw:1 -t mp3 - > D:\myrec.mp3 (Windows 系统)

使用如下命令,让本地电脑作为音频输入源,将其麦克风收集到的音频数据,通过 SSH 发送到远程树莓派上进行播放。
也就是将自己对着本地电脑讲的话通过树莓派进行远程广播
$ sox -d -t sox - | ssh pi@[IP address] sox -q -t sox - -d
sox -t waveaudio default -t sox - | plink pi@[IP address] -pw [password] sox -q -t sox - -d (Windows 系统)

同样的原理,也可以将本地磁盘上的音频文件直接发送到远程的树莓派上进行播放:
$ cat ~/Desktop/media/audios/Faded.wav | ssh pi@[IP address] sox -t wav - -d
type D:\myrec.mp3 | plink pi@[IP address] -pw [password] sox -t mp3 - -d (Windows 系统)

四、蓝牙耳机

树莓派 3 代 B+ 自带了 WIFI 和蓝牙功能,可以直接通过蓝牙连接音频设备。

1. 使用 hciconfig 命令获取蓝牙模块的相关信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ hciconfig -a
hci0: Type: Primary Bus: UART
BD Address: B8:27:EB:C3:38:31 ACL MTU: 1021:8 SCO MTU: 64:1
UP RUNNING
RX bytes:4181 acl:136 sco:0 events:135 errors:0
TX bytes:5065 acl:128 sco:0 commands:60 errors:0
Features: 0xbf 0xfe 0xcf 0xfe 0xdb 0xff 0x7b 0x87
Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
Link policy: RSWITCH SNIFF
Link mode: SLAVE ACCEPT
Name: 'raspberrypi'
Class: 0x480000
Service Classes: Capturing, Telephony
Device Class: Miscellaneous,
HCI Version: 4.2 (0x8) Revision: 0xfc
LMP Version: 4.2 (0x8) Subversion: 0x6119
Manufacturer: Broadcom Corporation (15)
2. 使用 hcitool scan 命令扫描附近可供连接的蓝牙设备,并记下蓝牙耳机对应的 MAC 地址
1
2
3
4
$ hcitool scan
Scanning ...
FC:58:FA:F4:67:33 A2
50:8F:4C:0D:31:3A Starky
3. 通过 MAC 地址与蓝牙耳机进行配对

使用 bluetoothctl 命令进入蓝牙控制台,依次通过 power onagent onscan onpairtrustconnect 等命令连接蓝牙设备。

注意此处连接蓝牙使用的是蓝牙设备的 MAC 地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ bluetoothctl
[NEW] Controller B8:27:EB:C3:38:31 raspberrypi [default]
[NEW] Device 50:8F:4C:0D:31:3A Starky
...
[bluetooth]# power on
Changing power on succeeded
[bluetooth]# agent on
Agent registered
[bluetooth]# scan on
Discovery started
[bluetooth]# pair FC:58:FA:F4:67:33
Attempting to pair with FC:58:FA:F4:67:33
Pairing successful
[bluetooth]# trust FC:58:FA:F4:67:33
[CHG] Device FC:58:FA:F4:67:33 Trusted: yes
Changing FC:58:FA:F4:67:33 trust succeeded
[bluetooth]# connect FC:58:FA:F4:67:33
Attempting to connect to FC:58:FA:F4:67:33
[CHG] Device FC:58:FA:F4:67:33 Connected: yes
Connection successful
[A2]#

退出蓝牙控制台,使用 hcitool con 命令查看当前已连接的蓝牙设备,确认连接成功:

1
2
3
$ hcitool con
Connections:
> ACL FC:58:FA:F4:67:33 handle 11 state 1 lm SLAVE AUTH ENCRYPT

4. 将音频输出设备切换为蓝牙耳机

首先安装 PulseAudio 软件包:
$ sudo apt-get install pulseaudio pulseaudio-module-bluetooth

启动 PulseAudio 守护进程:
$ pulseaudio --start

列出 PulseAudio 检测到的音频设备名称:

1
2
3
4
$ pacmd list-sinks short | grep -e 'name:'

name: <alsa_output.platform-soc_audio.analog-mono>
name: <bluez_sink.FC_58_FA_F4_67_33.headset_head_unit>

使用 pactl 命令将蓝牙耳机作为默认的音频设备:
$ pactl set-default-sink bluez_sink.FC_58_FA_F4_67_33.headset_head_unit

此时,即可直接使用 play 命令通过蓝牙耳机播放音频文件:
image.png

如果需要将音频输出切换回系统默认,运行如下命令即可:
$ pactl set-default-sink alsa_output.platform-soc_audio.analog-mono

或者自己对当前的音频配置有点混乱了。。。可以使用如下命令重置:
$ sudo /etc/init.d/alsa-utils reset

5. 注意事项

经过测试,发现蓝牙耳机连接后音质相差太大,播放速度明显放缓,未确定是哪里的问题。

同时我的蓝牙耳机开启后会自动连接至树莓派,如无法自动连接或者连接以后并没有被 PulseAudio 检测到,可以先使用 bluetoothctl 命令进入蓝牙控制台:
依次输入 power offpower on 命令重启蓝牙,使用 connect <MAC address> 命令重新连接蓝牙耳机(无需再配对和信任,直接连接)。

蓝牙耳机为默认音频设备后,之前配置 USB 声卡为默认的操作不再生效(除非断开蓝牙或关闭蓝牙耳机)。
可以在播放或录制时通过 -t alsa plughw:1 选项手动指定 USB 声卡。
$ sox -t alsa plughw:1 -d :使用 USB 声卡作为音频输入源,再将采集到的音频输出到默认设备(蓝牙耳机)

这一章的蓝牙介绍只供参考,推荐使用 USB 声卡进行音频的录制和播放。

五、配置 VoIP 服务器

VoIP 即 Voice over Internet Protocol ,就是将声音信号经过压缩与封包之后,以数据封包的形式在IP网络间进行传输。通俗地说也就是互联网电话或IP电话。

这里使用 Linux 平台上的 SIP Witch 软件作为 VoIP 系统的服务端。

1. 安装 SIP Witch

$ sudo apt-get install sipwitch

2. 编辑配置文件

/etc/default/sipwtich :找到 PLUGINS 选项,删除该行前面的注释

/etc/sipwitch.conf :编辑文件内容,在 <provision> 标签下添加用户注册信息:

1
2
3
4
5
6
7
8
9
10
<user id="phone1">
<extension>201</extension>
<secret>SecretSauce201</secret>
<display>Agent 201</display>
</user>
<user id="phone2">
<extension>202</extension>
<secret>SecretSauce202</secret>
<display>Agent 202</display>
</user>

其中的 id 表示注册用户登录时需要输入的用户名,<secret> 表示登录时使用的密码。

找到 <stack> 标签,并在其后添加如下一行配置,用于指定 VoIP 服务器的IP地址:
<localnames>[Your Pi's IP address]</localnames>

编辑完成后,重启 sipwitch 服务:
$ sudo systemctl restart sipwitch

3. 客户端配置

Windows 系统“软电话”可使用 MicroSIP 软件,Android 客户端可使用 CSipSimple,Mac 客户端有 Telephone

使用 /etc/sipwitch.conf 文件中定义的用户ID、密码以及服务器地址完成用户注册,各客户端之间即可直接拨打语音电话。
MicroSIP

参考资料

Raspberry Pi for Secret Agents - Third Edition