bluetooth:raspberry4b play audio

环境介绍:

1
2
3
4
5
6
# 硬件信息
树莓派4B 8GB

# 系统信息
uname -a
Linux caojun-desktop 6.8.0-1010-raspi #11-Ubuntu SMP PREEMPT_DYNAMIC Thu Aug 8 23:22:41 UTC 2024 aarch64 aarch64 aarch64 GNU/Linux

缘起

{% post_link 'bluetoothctl client tool' %} 介绍了为什么要写一个蓝牙应用库,既然选择了在树莓派上开发,那么就需要在树莓派上验证蓝牙应用库的可用性。通过树莓派运行蓝牙应用库连接蓝牙音响设备播放音频文件,我就可以证明蓝牙应用库的可用性。

在购入树莓派之前,我有查询过树莓派可以实现多媒体应用:视频和音频。树莓派硬件自带了一个3.5mm的音频输出口,以及两个micro hdmi接口。

验证

查看树莓派4B有哪些音频播放接口,可以通过一下两种方式:

  • 方式1:执行命令 cat /proc/asound/cards

    1
    2
    3
    4
    5
    6
    0 [Headphones     ]: bcm2835_headpho - bcm2835 Headphones
    bcm2835 Headphones
    1 [vc4hdmi0 ]: vc4-hdmi - vc4-hdmi-0
    vc4-hdmi-0
    2 [vc4hdmi1 ]: vc4-hdmi - vc4-hdmi-1
    vc4-hdmi-1
  • 方式2:执行命令 sudo apaly -l

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    **** List of PLAYBACK Hardware Devices ****
    card 0: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones]
    Subdevices: 8/8
    Subdevice #0: subdevice #0
    Subdevice #1: subdevice #1
    Subdevice #2: subdevice #2
    Subdevice #3: subdevice #3
    Subdevice #4: subdevice #4
    Subdevice #5: subdevice #5
    Subdevice #6: subdevice #6
    Subdevice #7: subdevice #7
    card 1: vc4hdmi0 [vc4-hdmi-0], device 0: MAI PCM i2s-hifi-0 [MAI PCM i2s-hifi-0]
    Subdevices: 1/1
    Subdevice #0: subdevice #0
    card 2: vc4hdmi1 [vc4-hdmi-1], device 0: MAI PCM i2s-hifi-0 [MAI PCM i2s-hifi-0]
    Subdevices: 1/1
    Subdevice #0: subdevice #0

通过上述查询接口,树莓派4B提供了3个音频接口:bcm2835 Headphones(即3.5mm耳机口)、vc4-hdmi-0、vc4-hdmi-1

耳机口播放音频

准备工作:

  • 3.5mm耳机线插入树莓派
  • 树莓派中下载alsa-utils工具

可以通过命令查询alsa-utils是否安装:dpkg -l | grep alsa-utils,若没有安装,则通过命令安装:sudo apt install alsa-utils

alsa-utils工具包含了:aplay(播放音频) 、 arecord(录制音频) 、 alsamixer(基于文本界面的音频设备管理) 、 amixer(调整设备音量),而且在 /usr/share/soudns/alsa 目录下会提供多个wav音频文件。

1
2
3
4
5
6
7
8
9
10
$ ll /usr/share/sounds/alsa/
-rw-r--r-- 1 root root 137134 4月 7 15:09 Front_Center.wav
-rw-r--r-- 1 root root 142128 4月 7 15:09 Front_Left.wav
-rw-r--r-- 1 root root 146990 4月 7 15:09 Front_Right.wav
-rw-r--r-- 1 root root 135202 4月 7 15:09 Noise.wav
-rw-r--r-- 1 root root 130096 4月 7 15:09 Rear_Center.wav
-rw-r--r-- 1 root root 126064 4月 7 15:09 Rear_Left.wav
-rw-r--r-- 1 root root 146480 4月 7 15:09 Rear_Right.wav
-rw-r--r-- 1 root root 134868 4月 7 15:09 Side_Left.wav
-rw-r--r-- 1 root root 129966 4月 7 15:09 Side_Right.wav

可以先通过alsamixer选择默认音频设备,并调节音量。接着通过aplay播放wav音频文件

1
2
3
4
5
# 播放方式1
sudo aplay /usr/share/sounds/alsa/Front_Center.wav

# 播放方式2, 指定CARD和DEV
sudo aplay /usr/share/sounds/alsa/Front_Center.wav -D plughw:CARD=0,DEV=0

若一切正常,则会从耳机中听到英文声音:Frong Center

调节设备音量:

1
2
3
4
5
# 音量调节至90%
amixer sset Master 90%

# 音量调节至20%
amixer sset Master 20%

再次播放wav音频文件,验证音量设备是否成功。

注意:这里发现一个奇怪的现象:对于alsa-utils工具包的软件都需要使用管理员权限执行,即sudo,否则就会有问题。

蓝牙音响播放音频

树莓派通过蓝牙适配器连接蓝牙音响,然后播放音频文件。其中主要解决的问题是:蓝牙连接成功后,如何将将音频文件传输到蓝牙音响,并输出音频?

通过互联网上的资料,我可以确认有两种解决方案:

  • bluez+bluealsa

    bluealsa 是一个用于将 ALSA(Advanced Linux Sound Architecture,高级Linux音频架构)与 Bluetooth 低功耗(即 BLE)音频协议相结合的解决方案。它使得 Linux 系统能够通过 BLE 连接蓝牙音频设备,并让蓝牙音频设备播放音频文件。

    bluealsa 的核心是bluealsa与 BlueZ 蓝牙守护进程bluetoothd和本地蓝牙适配器交互的守护进程。它处理 A2DP、HFP 和 HSP 的配置文件(即Profile)连接和配置逻辑,并通过 D-Bus 将生成的音频流呈现给应用程序。

  • bluez+pulseaudio

编译安装bluealsa

Github 开源项目:bluez-alsa

该开源项目README.md文件给出了一个提示:

警告:

从tag 4.3.1版本最新的源文件为核心组件使用了新的名字:

  • bluealsa daemon现在改为了 bluealsad daemon
  • bluealsa-cli utility现在改为了 bluealsactl utility

由于安装Ubuntu 24.04的树莓派目前不支持通过apt安装bluealsa,故这里通过编译安装,以下是详细过程。

  • 对于如何通过源码编译构建,该项目也很贴心的给出了指引文件INSTALL.md。更加详细的编译安装教程可以查看Installation from source,甚至不同的操作系统也都给出了,例如:Debain/Raspberry Pi OS/Ubuntu、Fedora、Arch。这里选择Ubuntu的安装过程即可。

    1
    2
    3
    4
    # 安装编译环境
    sudo apt update
    sudo apt-get install git automake build-essential libtool pkg-config python3-docutils
    sudo apt-get install libasound2-dev libbluetooth-dev libdbus-1-dev libglib2.0-dev libsbc-dev
  • 通过git克隆blue-alsa仓库到本地

    1
    2
    3
    4
    # 克隆仓库
    cd ~
    git clone https://github.com/arkq/bluez-alsa.git
    cd blue-alsa
  • 准备编译构建

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # 使用自动配置工具适配当前开发环境,最后生成configure配置文件
    autoreconf --install --force

    # 创建build目录,存放编译过程文件
    mkdir build
    cd build

    # 在build目录下,运行配置文件(这里没有增加额外的参数)
    ../configure

    # 编译和安装
    make
    sudo make install

运行bluealsa

在连接蓝牙音频设备之前,确保 hciconfig -a 可以查询到hci接口,确保 bluetoothd 已经运行。然后运行 bluealsa ,执行命令:

1
2
3
4
5
6
7
8
# 运行方式1,以root权限运行,注意:这里有bluealsa后台打印信息输出 
sudo bluealsa --profile=a2dp-source &

# 运行方式2,以root权限运行,禁止bluealsa后台打印信息输出
sudo bluealsa --profile=a2dp-source > /dev/null 2>&1 &

# 运行方式3,通过systemd运行bluealsa
sudo systemctl start bluealsa.service

使用 bluetoothctl 搜索、配对、连接蓝牙音频设备(此部分不做说明),修改asoundrc.conf,最后使用 aplay 播放wav音频文件

1
2
3
4
# 修改asoundrc.conf
pcm.!default "bluealsa"
ctl.!default "bluealsa"

1
2
# aplay播放wav文件
sudo aplay /usr/share/sounds/alsa/Front_Center.wav

asoundrc.conf

ALSA 正常工作不需要用户端文件.asoundrcasound.conf配置文件。asoundrc.conf 文件用于通过 alsa-lib 层实现额外的功能,例如路由和采样率转换。

alsa-lib 软件包提供了 /usr/share/alsa/alsa.conf 文件作为主入口点。该文件负责包含系统上所有可能的 .asoundrc 格式文件。alsa.conf 会加载系统全局自定义设置文件 /etc/asound.conf 和每个用户的自定义设置文件 ~/.asoundrc。

用户自定义的 ~/.asoundrd.conf 文件需要用户手动创建,并且文件该作用域大于全局自定义的 /etc/asoundrc.conf

参考

1、树莓派笔记:使用ALSA+A2DP+PulseAudio自制蓝牙音箱

2、Asoundrc