2023-03-14
md
Bluetooth®, PulseAudio, and BlueALSA in Raspberry Pi OS Lite (March 2022)
<-Bluetooth and BlueALSA in Raspberry Pi OS Lite (November 2021)
<-Baby Bluetooth Steps on Raspberry Pi 3 - Raspbian (Stretch)
 About another breaking change in Raspberry Pi OS (Bullseye) based on Debian 11 

At the end of 2020, BlueALSA (the Bluetooth Audio ALSA Backend aka bluez-alsa) was ejected and replaced with PulseAudio in the desktop version of Raspberry Pi OS (see the 2020-12-02 release notes). I feared then that there would be problems with the solutions I described as recently as November 4, 2021, to connect Bluetooth® sound devices to the Raspberry Pi running the Lite version of the OS. I did not test with the November 8 version of the OS, but yesterday, I confirmed that an update of my post about sound over Bluetooth® in Raspberry Pi OS (Bullseye) based on Debian 11 was needed.

Table of Content

  1. Raspberry Pi OS Lite
  2. Modifying the Bluetooth Service File
  3. Decision Time
  4. Installing PulseAudio
  5. Installing BlueALSA 1.4.0
  6. Installing BlueALSA 3.0.0
  7. Best Decision

Raspberry Pi OS Lite toc

First, let's look at the state of things when booting the Raspberry Pi after installing the January 28, 2022, version of Raspberry Pi OS Lite and doing an update and upgrade on the 15th of March.

michel@hp:~$ ssh pi@tarte.local Opening an ssh session from the desktop computer ... pi@tarte:~ $ sudo apt update && sudo apt upgrade -y ... The following packages will be upgraded: libcamera-apps-lite libcamera0 libcryptsetup12 libexpat1 libsasl2-2 libsasl2-modules-db libssl1.1 libwbclient0 linux-libc-dev openssl raspberrypi-bootloader raspberrypi-kernel raspberrypi-sys-mods raspi-config rpi-eeprom vcdbg 16 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. Need to get 91.3 MB of archives. After this operation, 3,829 kB of additional disk space will be used. ...

Let's check on the Linux kernel version and verify that the bluealsa package is not available in the Raspbian Bullseye repository.

pi@tarte:~ $ uname -a Linux tarte 5.10.92-v7+ #1514 SMP Mon Jan 17 17:36:39 GMT 2022 armv7l GNU/Linux pi@tarte:~ $ apt-cache policy bluealsa bluealsa: Installed: (none) Candidate: (none) Version table:

We can also confirm that, as before, the default user is not a member of the bluetooth group, and take care of that problem.

pi@tarte:~ $ groups pi adm dialout cdrom sudo audio video plugdev games users input render netdev gpio i2c spi pi@tarte:~ $ cat /etc/group | grep bluetooth bluetooth:x:112: the group exists but pi is not a member pi@tarte:~ $ sudo adduser pi bluetooth Adding user `pi' to group `bluetooth' ... Adding user pi to group bluetooth Done.

I prefer to reboot ($ sudo reboot) and open a new session after a major system upgrade. This also ensures that membership in the bluetooth group will take effect.

Modifying the bluetooth.service Unit File toc

Let's look at the bluetooth service which should be running on any Raspberry Pi equipped with the Wi-Fi/Bluetooth chip. Hopefully, a USB Bluetooth® dongle can be used with older Pi models with equivalent results.

pi@tarte:~ $ sudo systemctl status blue* ● bluetooth.target - Bluetooth Loaded: loaded (/lib/systemd/system/bluetooth.target; static) Active: active since Tue 2022-03-15 18:12:05 ADT; 2min 45s ago Docs: man:systemd.special(7) Mar 15 18:12:05 tarte systemd[1]: Reached target Bluetooth. ● bluetooth.service - Bluetooth service Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2022-03-15 18:12:05 ADT; 2min 46s ago Docs: man:bluetoothd(8) Main PID: 541 (bluetoothd) Status: "Running" Tasks: 1 (limit: 1597) CPU: 94ms CGroup: /system.slice/bluetooth.service └─541 /usr/libexec/bluetooth/bluetoothd Mar 15 18:12:05 tarte systemd[1]: Starting Bluetooth service... Mar 15 18:12:05 tarte bluetoothd[541]: Bluetooth daemon 5.55 Mar 15 18:12:05 tarte systemd[1]: Started Bluetooth service. Mar 15 18:12:06 tarte bluetoothd[541]: Starting SDP server Mar 15 18:12:06 tarte bluetoothd[541]: Bluetooth management interface 1.18 initialized Mar 15 18:12:06 tarte bluetoothd[541]: profiles/sap/server.c:sap_server_register() Sap driver initialization failed. Mar 15 18:12:06 tarte bluetoothd[541]: sap-server: Operation not permitted (1) Mar 15 18:12:06 tarte bluetoothd[541]: Failed to set privacy: Rejected (0x0b)

As can be seen, the version of BlueZ the "Official Linux Bluetooth protocol stack" has been bumped up from 5.50 to 5.55 which, again, is not the most recent version (now 5.63). As before those errors are not important and it would be possible to connect to a Bluetooth® device such as a keyboard at this point. As expected, it is not possible to connect to a Bluetooth® speaker.

pi@tarte:~ $ bluetoothctl Agent registered [bluetooth]# scan on Discovery started ... [NEW] Device 30:21:5C:00:01:02 AUDIOPOD2 [bluetooth]# connect 30:21:5C:00:01:02 Attempting to connect to 30:21:5C:00:01:02 [CHG] Device 30:21:5C:00:01:02 Connected: yes [CHG] Device 30:21:5C:00:01:02 UUIDs: 00001108-0000-1000-8000-00805f9b34fb [CHG] Device 30:21:5C:00:01:02 UUIDs: 0000110b-0000-1000-8000-00805f9b34fb [CHG] Device 30:21:5C:00:01:02 UUIDs: 0000110c-0000-1000-8000-00805f9b34fb [CHG] Device 30:21:5C:00:01:02 UUIDs: 0000110e-0000-1000-8000-00805f9b34fb [CHG] Device 30:21:5C:00:01:02 UUIDs: 0000111e-0000-1000-8000-00805f9b34fb [CHG] Device 30:21:5C:00:01:02 ServicesResolved: yes Failed to connect: org.bluez.Error.Failed [CHG] Device 30:21:5C:00:01:02 ServicesResolved: no [CHG] Device 30:21:5C:00:01:02 Connected: no

If the red error messages are irksome, it is possible to get rid of those related to the missing SAP server by editing the service file.

pi@tarte:~ $ sudo -E systemctl edit --full bluetooth

Change the ExecStart line from

ExecStart=/usr/libexec/bluetooth/bluetoothd

to

ExecStart=/usr/libexec/bluetooth/bluetoothd --noplugin=sap

Once the change to the service file is made, the service must be restarted.

pi@tarte:~ $ sudo systemctl daemon-reload pi@tarte:~ $ sudo systemctl restart bluetooth pi@tarte:~ $ sudo systemctl status bluetooth ● bluetooth.service - Bluetooth service Loaded: loaded (/etc/systemd/system/bluetooth.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2022-03-16 15:51:23 ADT; 17s ago Docs: man:bluetoothd(8) Main PID: 856 (bluetoothd) Status: "Running" Tasks: 1 (limit: 1597) CPU: 81ms CGroup: /system.slice/bluetooth.service └─856 /usr/libexec/bluetooth/bluetoothd --noplugin=sap Mar 16 15:51:22 tarte systemd[1]: Starting Bluetooth service... Mar 16 15:51:23 tarte bluetoothd[856]: Bluetooth daemon 5.55 Mar 16 15:51:23 tarte systemd[1]: Started Bluetooth service. Mar 16 15:51:23 tarte bluetoothd[856]: Starting SDP server Mar 16 15:51:23 tarte bluetoothd[856]: Excluding (cli) sap Mar 16 15:51:23 tarte bluetoothd[856]: Bluetooth management interface 1.18 initialized Mar 16 15:51:23 tarte bluetoothd[856]: Failed to set privacy: Rejected (0x0b)

As can be seen, I still do not know how to get rid of the last error message.

Decision Time toc

Now that the system is updated, and that a few Bluetooth loose ends have been tidied, a decision must be made if streaming sound over Bluetooth is desired. As far as I can tell, these are the available choices.

  1. Do not update to Raspberry Pi OS Bullseye (Debian 11). These options amount to the same thing since the Legacy version is the Debian 10 - Buster edition of the operating system.
  2. Update to Raspberry Pi OS Bullseye (Debian 11).
    • Install PulseAudio in the Lite version of the OS.
    • Compile BlueALSA from source.
    • Install BlueALSA from the older Buster repository or from another repository.

No matter how Buster is installed, if that's the route taken then the instructions in the older Bluetooth and BlueALSA in Raspberry Pi OS Lite (November 2021) post should remain valid and there's not much of interest below.

Moving on to PulseAudio may be the correct solution in the long term, although it does come at a cost as shown in the next section. Compiling and installing bluealsa from source is something I have done in the past Compiling BlueALSA in ALSA and Bluetooth on the Orange Pi PC 2 with Armbian Bionic. I tried it on the Raspberry Pi following the Installation from source Wiki page in the bluez-alsa GitHub repository. On the whole it worked but I did run into problems with using Alsamixer which I think were associated with the SystemD service file. I did not investigate at all, because right now, I think the better solution is to install BlueALSA from the "oldstable" Buster repository if there is an absolute need to use BlueALSA. For the more daring, there are indications at the end about installing a newer version of the package from a "testing" respository.

Installing PulseAudio toc

Eventhough PulseAudio is installed on my desktop Linux Mint computer, I know next to nothing about the package. Thankfully, I was able to find very helpful Web resources.

The first step is to install the PulseAudio BlueTooth module which is not included in the Lite version of Raspberry Pi OS but which is probably present in the desktop versions. Initially I tried the typical command.

pi@tarte:~ $ sudo apt install pulseaudio-module-bluetooth Reading package lists... Done Building dependency tree... Done Reading state information... Done The following additional packages will be installed: dbus-user-session fontconfig libaom0 libasound2-plugins libasyncns0 libavcodec58 libavresample4 libavutil56 libcairo-gobject2 libcairo2 libcodec2-0.9 libdatrie1 libdav1d4 libdrm-amdgpu1 libdrm-nouveau2 libdrm-radeon1 libgdk-pixbuf-2.0-0 libgdk-pixbuf2.0-bin libgdk-pixbuf2.0-common libgl1 libgl1-mesa-dri libglapi-mesa libglvnd0 libglx-mesa0 libglx0 libgraphite2-3 libgsm1 libharfbuzz0b libice6 libjack-jackd2-0 libllvm11 libltdl7 libmp3lame0 libopenjp2-7 libopus0 libpango-1.0-0 libpangocairo-1.0-0 libpangoft2-1.0-0 libpixman-1-0 libpulse0 libpulsedsp librsvg2-2 librsvg2-common libsensors-config libsensors5 libshine3 libsm6 libsnappy1v5 libsndfile1 libsoxr0 libspeex1 libspeexdsp1 libswresample3 libtdb1 libthai-data libthai0 libtheora0 libtwolame0 libva-drm2 libva-x11-2 libva2 libvdpau-va-gl1 libvdpau1 libvorbisenc2 libvpx6 libvulkan1 libwavpack1 libwayland-client0 libwebpmux3 libwebrtc-audio-processing1 libx11-xcb1 libx264-160 libx265-192 libxcb-dri2-0 libxcb-dri3-0 libxcb-glx0 libxcb-present0 libxcb-randr0 libxcb-render0 libxcb-shm0 libxcb-sync1 libxcb-xfixes0 libxdamage1 libxfixes3 libxi6 libxrender1 libxshmfence1 libxtst6 libxvidcore4 libxxf86vm1 libz3-4 libzvbi-common libzvbi0 mesa-va-drivers mesa-vdpau-drivers mesa-vulkan-drivers ocl-icd-libopencl1 pulseaudio pulseaudio-utils rtkit shared-mime-info va-driver-all vdpau-driver-all x11-common Suggested packages: jackd2 opus-tools librsvg2-bin lm-sensors speex opencl-icd pavumeter pavucontrol paprefs nvidia-legacy-390xx-vdpau-driver nvidia-legacy-340xx-vdpau-driver The following NEW packages will be installed: dbus-user-session fontconfig libaom0 libasound2-plugins libasyncns0 libavcodec58 libavresample4 libavutil56 libcairo-gobject2 libcairo2 libcodec2-0.9 libdatrie1 libdav1d4 libdrm-amdgpu1 libdrm-nouveau2 libdrm-radeon1 libgdk-pixbuf-2.0-0 libgdk-pixbuf2.0-bin libgdk-pixbuf2.0-common libgl1 libgl1-mesa-dri libglapi-mesa libglvnd0 libglx-mesa0 libglx0 libgraphite2-3 libgsm1 libharfbuzz0b libice6 libjack-jackd2-0 libllvm11 libltdl7 libmp3lame0 libopenjp2-7 libopus0 libpango-1.0-0 libpangocairo-1.0-0 libpangoft2-1.0-0 libpixman-1-0 libpulse0 libpulsedsp librsvg2-2 librsvg2-common libsensors-config libsensors5 libshine3 libsm6 libsnappy1v5 libsndfile1 libsoxr0 libspeex1 libspeexdsp1 libswresample3 libtdb1 libthai-data libthai0 libtheora0 libtwolame0 libva-drm2 libva-x11-2 libva2 libvdpau-va-gl1 libvdpau1 libvorbisenc2 libvpx6 libvulkan1 libwavpack1 libwayland-client0 libwebpmux3 libwebrtc-audio-processing1 libx11-xcb1 libx264-160 libx265-192 libxcb-dri2-0 libxcb-dri3-0 libxcb-glx0 libxcb-present0 libxcb-randr0 libxcb-render0 libxcb-shm0 libxcb-sync1 libxcb-xfixes0 libxdamage1 libxfixes3 libxi6 libxrender1 libxshmfence1 libxtst6 libxvidcore4 libxxf86vm1 libz3-4 libzvbi-common libzvbi0 mesa-va-drivers mesa-vdpau-drivers mesa-vulkan-drivers ocl-icd-libopencl1 pulseaudio pulseaudio-module-bluetooth pulseaudio-utils rtkit shared-mime-info va-driver-all vdpau-driver-all x11-common 0 upgraded, 105 newly installed, 0 to remove and 0 not upgraded. Need to get 69.2 MB of archives. After this operation, 244 MB of additional disk space will be used. Do you want to continue? [Y/n]  n 

I railed about the surprising number of packages that would be added with this install: 105 which require a 69.2 MB download and 244 MB of additional disk space once installed. Nevertheless, I went ahead and did complete the installation. However last week, almost exactly a year after the original version of this post was made public, Steffen Mietk suggested adding the --no-install-recommends option to the apt install command to avoid loading unneeded X11, Wayland and Messa packages into the Lite version of Raspberry Pi OS. So this is now the recommended install.

pi@tarte:~ $ sudo apt install --no-install-recommends pulseaudio-module-bluetooth

Unfortunately, I no longer have the Jan. 28, 2022, version of Raspberry Pi OS Lite on a Raspberry Pi, so I cannot report the exact amount of disk space this modified version would take. What can be said is that using the option reduced the require disk space from 240 MB to 80 MB in the February 21, 2023, version of the OS. I have yet to look at the details of how things work in the newest version of Raspberry Pi OS, but already I feel that this part of the post needs to be rewritten even if my preliminary findings indicate that not much has changed in the intervening year. Until a rewrite is available, this post continues with the discussion in the context of the Jan 2022 version of Raspberry Pi OS.

pi@tarte:~ $ systemctl --user status pulseaudio ● pulseaudio.service - Sound Service Loaded: loaded (/usr/lib/systemd/user/pulseaudio.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2022-03-16 21:50:32 ADT; 3min 46s ago TriggeredBy: ● pulseaudio.socket Main PID: 713 (pulseaudio) Tasks: 2 (limit: 1597) CPU: 455ms CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/pulseaudio.service └─713 /usr/bin/pulseaudio --daemonize=no --log-target=journal Mar 16 21:50:27 tarte systemd[693]: Starting Sound Service... Mar 16 21:50:32 tarte pulseaudio[713]: Failed to find a working profile. Mar 16 21:50:32 tarte pulseaudio[713]: Failed to load module "module-alsa-card" (argument: "device_id="1" name="platform-3f902000.hdmi" card_name="alsa_card.platform-3f902000.hdm> Mar 16 21:50:32 tarte systemd[693]: Started Sound Service.

The service is running, so I connected to a Bluetooth® speaker and then used the PulseAudio play utility to listen to a sound file on the Raspberry Pi previously copied onto the device.

pi@tarte:~ $ bluetoothctl connect 30:21:5C:00:01:02 Attempting to connect to 30:21:5C:00:01:02 [CHG] Device 30:21:5C:00:01:02 Connected: yes Connection successful pi@tarte:~ $ paplay -v sound/sound-01.wav Opening a playback stream with sample specification 's16le 2ch 44100Hz' and channel map 'front-left,front-right'. Connection established. Stream successfully created. Buffer metrics: maxlength=4194304, tlength=352800, prebuf=349276, minreq=3528 Using sample spec 's16le 2ch 44100Hz', channel map 'front-left,front-right'. Connected to device bluez_sink.30_21_5C_00_01_02.a2dp_sink (index: 2, suspended: no). Stream started. ^CGot signal, exiting.cy: 2025893 usec.

I must admit that was impressive. No command-line options to define the sound card was needed, it just worked. The volume can be adjusted in an another session.

pi@tarte:~ $ pactl list short sinks 0 alsa_output.platform-bcm2835_audio.analog-stereo module-alsa-card.c s16le 2ch 44100Hz SUSPENDED 1 bluez_sink.30_21_5C_00_01_02.a2dp_sink module-bluez5-device.c s16le 2ch 44100Hz RUNNING pi@tarte:~ $ pactl set-sink-volume 1 -30%

More info at How to control your Pulseaudio sound volume using the command line by John Cartwright July 22, 2020 . A web search with the "pulseaudio tui mixer" phrase turns up possible equivalents to alsamixer. But the fact is that ALSA is still the sound back end of the Pi and its utilities, such as aplay, alsamixer and so on, work without having to specify the device.

The Pi can be a "sink" meaning that another Bluetooth® device such as a tablet or phone can send an audio stream to the Pi which can in turn play it on a speaker connected to the 3.1 mm audio jack or the HDMI port. Again, it was surprisingly easy to do that. It turns out that this was just as easy to set up. I connected a powered speaker to the 3.1 mm audio jack on the Pi, disconnected the Bluetooth® speaker with bluetoothctl, and then paired and connected to an Android telephone with the same utility. Once the Pi and the phone were connected, the sound from the phone was routed over the air to the Pi and then send out to the speaker. There was no need to run a utility on the Pi similar to bluealsa-play. I should also point out that the latency problem was not anywhere as bad as that encountered with bluealsa. I only did a cursory test, but I could look at a YouTube video on the phone with sound send by Bluetooth® to the Pi while the latter was performing a fruitless find command over the complete file system and sending the listing out to a session connected through Wi-Fi.

All in all, PulseAudio is very impressive and I can see why it was brought back into the OS. It is, however, very heavy, especially for the Lite version.

Installing BlueALSA 1.4.0 toc

By adding a new list containing the Buster repository to the apt utility sources directory , it will be possible to install the bluealsa package as before.

pi@tarte:~ $ echo "deb http://archive.raspberrypi.org/debian/ buster main" | sudo tee /etc/apt/sources.list.d/raspberrypi.list deb http://archive.raspberrypi.org/debian/ buster main pi@tarte:~ $ ls -l /etc/apt/sources.list.d/ total 8 -rw-r--r-- 1 root root 55 Mar 16 15:20 raspberrypi.list -rw-r--r-- 1 root root 191 Jan 27 21:03 raspi.list

Let's check that the package is now available.

pi@tarte:~ $ sudo apt update ... pi@tarte:~ $ apt-cache policy bluealsa bluealsa: Installed: (none) Candidate: 0.13 Version table: 0.13 500 500 http://archive.raspberrypi.org/debian buster/main armhf Packages

That is the same version of bluealsa that I installed in Buster in November 2021. There is something that is not appropriate with adding the old distribution's repository.

pi@tarte:~ $ apt-cache policy Package files: 100 /var/lib/dpkg/status release a=now 500 http://archive.raspberrypi.org/debian bullseye/main armhf Packages release o=Raspberry Pi Foundation,a=stable,n=bullseye,l=Raspberry Pi Foundation,c=main,b=armhf origin archive.raspberrypi.org 500 http://archive.raspberrypi.org/debian buster/main armhf Packages release o=Raspberry Pi Foundation,a=oldstable,n=buster,l=Raspberry Pi Foundation,c=main,b=armhf origin archive.raspberrypi.org 500 http://raspbian.raspberrypi.org/raspbian bullseye/rpi armhf Packages release o=Raspbian,a=stable,n=bullseye,l=Raspbian,c=rpi,b=armhf origin raspbian.raspberrypi.org 500 http://raspbian.raspberrypi.org/raspbian bullseye/non-free armhf Packages release o=Raspbian,a=stable,n=bullseye,l=Raspbian,c=non-free,b=armhf origin raspbian.raspberrypi.org 500 http://raspbian.raspberrypi.org/raspbian bullseye/contrib armhf Packages release o=Raspbian,a=stable,n=bullseye,l=Raspbian,c=contrib,b=armhf origin raspbian.raspberrypi.org 500 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf Packages release o=Raspbian,a=stable,n=bullseye,l=Raspbian,c=main,b=armhf origin raspbian.raspberrypi.org Pinned packages:

The packages in the old Buster repository have the same priority as the packages in the newer repository. It is better to change that.

pi@tarte:~ $ printf 'Package: *\nPin: release n=buster\nPin-Priority: 50\n' | sudo tee --append /etc/apt/preferences.d/limit-buster Package: * Pin: release a=buster Pin-Priority: 50 pi@tarte:~ $ sudo apt update Hit:1 http://raspbian.raspberrypi.org/raspbian bullseye InRelease Hit:2 http://archive.raspberrypi.org/debian buster InRelease Hit:3 http://archive.raspberrypi.org/debian bullseye InRelease Reading package lists... Done Building dependency tree... Done Reading state information... Done All packages are up to date. pi@tarte:~ $ apt-cache policy Package files: 100 /var/lib/dpkg/status release a=now 500 http://archive.raspberrypi.org/debian bullseye/main armhf Packages release o=Raspberry Pi Foundation,a=stable,n=bullseye,l=Raspberry Pi Foundation,c=main,b=armhf origin archive.raspberrypi.org 50 http://archive.raspberrypi.org/debian buster/main armhf Packages release o=Raspberry Pi Foundation,a=oldstable,n=buster,l=Raspberry Pi Foundation,c=main,b=armhf origin archive.raspberrypi.org 500 http://raspbian.raspberrypi.org/raspbian bullseye/rpi armhf Packages release o=Raspbian,a=stable,n=bullseye,l=Raspbian,c=rpi,b=armhf origin raspbian.raspberrypi.org ...

Installation now proceeds much as before.

pi@tarte:~ $ sudo apt install bluealsa -y ... The following NEW packages will be installed: bluealsa libbluetooth3 libsbc1 0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded. Need to get 189 kB of archives. After this operation, 604 kB of additional disk space will be used. ... bluealsa.service is a disabled or a static unit, not starting it. Processing triggers for dbus (1.12.20-2) ... Processing triggers for libc-bin (2.31-13+rpt2+rpi1+deb11u2) ... pi@tarte:~ $ bluealsa --version 1.4.0 pi@tarte:~ $ sudo systemctl status bluealsa.service ● bluealsa.service - BluezALSA proxy Loaded: loaded (/lib/systemd/system/bluealsa.service; static) Active: inactive (dead) pi@tarte:~ $ sudo systemctl start bluealsa.service pi@tarte:~ $ sudo systemctl status bluealsa.service ● bluealsa.service - BluezALSA proxy Loaded: loaded (/lib/systemd/system/bluealsa.service; static) Active: active (running) since Wed 2022-03-16 17:09:04 ADT; 4s ago Main PID: 1330 (bluealsa) Tasks: 3 (limit: 1597) CPU: 42ms CGroup: /system.slice/bluealsa.service └─1330 /usr/bin/bluealsa Mar 16 17:09:04 tarte systemd[1]: Started BluezALSA proxy.

As hoped, this works.

pi@tarte:~ $ bluetoothctl connect 30:21:5C:00:01:02 Attempting to connect to 30:21:5C:00:01:02 [CHG] Device 30:21:5C:00:01:02 Connected: yes Connection successful pi@tarte:~ $ aplay -vv -D bluealsa:DEV=30:21:5C:00:01:02 sound/sound-01.wav Playing WAVE 'sound/sound-01.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo Plug PCM: Rate conversion PCM (48000, sformat=S16_LE) Converter: linear-interpolation Protocol version: 10002 Its setup is: stream : PLAYBACK access : RW_INTERLEAVED format : S16_LE subformat : STD channels : 2 rate : 44100 exact rate : 44100 (44100/1) msbits : 16 buffer_size : 22574 period_size : 3763 period_time : 85333 tstamp_mode : NONE tstamp_type : GETTIMEOFDAY period_step : 1 avail_min : 3763 period_event : 0 start_threshold : 22574 stop_threshold : 22574 silence_threshold: 0 silence_size : 0 boundary : 1479409664 Slave: BlueALSA PCM: /org/bluealsa/hci0/dev_30_21_5C_00_01_02/a2dp BlueALSA BlueZ device: /org/bluez/hci0/dev_30_21_5C_00_01_02 BlueALSA Bluetooth codec: 0 ########### + | 39%^C Aborted by signal Interrupt... ## + | 39%

The volume could be controlled in an other session with the alsamixer utility.

pi@tarte:~ $ alsamixer -D bluealsa

By default, bluealsa is only a "source" meaning that the Pi can be used to send an audio stream to a Bluetooth® device such as a speaker as shown above. But the Pi can be a "sink" meaning that another Bluetooth® device such as a tablet or phone can send an audio stream to the Pi which can in turn play it on a speaker connected to the 3.1 mm audio jack or the HDMI port. The bluealsa configuration has to be changed for that to take effect.

First we will create a default configuration file for the package. This is done by creating a one-line text file named /etc/default/bluealsa. Its content is

OPTIONS="-p a2dp-source -p a2dp-sink"

Then the service file needs to be edited.

pi@tarte:~ $ sudo -E systemctl edit --full bluealsa
[Unit] Description=BluezALSA proxy Requires=bluetooth.service After=bluetooth.service [Service] Type=simple User=root EnvironmentFile=-/etc/default/bluealsa ExecStart=/usr/bin/bluealsa $OPTIONS

There is a side effect of editing the service file in this fashion. Because it is copied to the /etc/systemd/system/ directory, the service is enabled. If the system is rebooted, the service will be started automatically. Here are the statuses of the services after a reboot.

pi@tarte:~ $ sudo systemctl status bluetooth* ● bluetooth.service - Bluetooth service Loaded: loaded (/etc/systemd/system/bluetooth.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2022-03-16 18:19:34 ADT; 1min 7s ago Docs: man:bluetoothd(8) Main PID: 529 (bluetoothd) Status: "Running" Tasks: 1 (limit: 1597) CPU: 209ms CGroup: /system.slice/bluetooth.service └─529 /usr/libexec/bluetooth/bluetoothd --noplugin=sap Mar 16 18:19:33 tarte systemd[1]: Starting Bluetooth service... Mar 16 18:19:34 tarte bluetoothd[529]: Bluetooth daemon 5.55 Mar 16 18:19:34 tarte systemd[1]: Started Bluetooth service. Mar 16 18:19:34 tarte bluetoothd[529]: Starting SDP server Mar 16 18:19:34 tarte bluetoothd[529]: Excluding (cli) sap Mar 16 18:19:34 tarte bluetoothd[529]: Bluetooth management interface 1.18 initialized Mar 16 18:19:34 tarte bluetoothd[529]: Endpoint registered: sender=:1.8 path=/org/bluez/hci0/A2DP/SBC/Source/1 Mar 16 18:19:34 tarte bluetoothd[529]: Endpoint registered: sender=:1.8 path=/org/bluez/hci0/A2DP/SBC/Source/2 Mar 16 18:19:34 tarte bluetoothd[529]: Failed to set privacy: Rejected (0x0b) ● bluetooth.target - Bluetooth Loaded: loaded (/lib/systemd/system/bluetooth.target; static) Active: active since Wed 2022-03-16 18:19:34 ADT; 1min 7s ago Docs: man:systemd.special(7) Mar 16 18:19:34 tarte systemd[1]: Reached target Bluetooth. pi@tarte:~ $ sudo systemctl status bluealsa* ● bluealsa.service - BluezALSA proxy Loaded: loaded (/etc/systemd/system/bluealsa.service; static) Active: active (running) since Wed 2022-03-16 18:19:34 ADT; 1min 12s ago Main PID: 530 (bluealsa) Tasks: 3 (limit: 1597) CPU: 56ms CGroup: /system.slice/bluealsa.service └─530 /usr/bin/bluealsa Mar 16 18:19:34 tarte systemd[1]: Started BluezALSA proxy.

I was then able to pair and connect an Android phone and the Pi over Bluetooth®. The Pi showed up as a headset, so that the sound generated by the phone was no longer played on its speakers but it was instead streamed to the Pi. The bleualsa-aplay utility could then play that audio stream to connected speakers.

pi@tarte:~ $ sudo bluealsa-aplay 04:92:26:00:01:02

The simpler address 00:00:00:00:00:00 will work.

Installing BlueALSA 3.0.0 toc

While the Raspberry Pi Foundation may be rejecting BlueALSA, its development continues unabated; there have been 19 commits to the source code since the start of the year. Therefore, continuing on with the old bluealsa package from the Buster repository is not a good long-term strategy. That package contained version 1.4.0 which was released in March 2019 which is rather out of date. The current release is version 3.1.0 dated June 2021. The best way to keep up with changes in BlueALSA would be to compile and install from the source code as explained above. As I said, this should work but it does involve a lot of work.

Lazyness being one my better character traits, I investigated a simpler approach. It turns out that BlueALSA is available in the very newest Bookworm version of Raspbian over at Raspbian.org. For whatever reason it has a different name: bluez-alsa-utils. Here is a quick rundown on how to proceed to install that package. There is no real need to go into details, this is pretty much what was done to install the package from the Buster repository in the previous section.

pi@tarte:~ $ echo "deb http://archive.raspbian.org/raspbian/ bookworm main" | sudo tee /etc/apt/sources.list.d/armbian.list pi@tarte:~ $ printf 'Package: *\nPin: release n=bookworm\nPin-Priority: 100\n' | sudo tee --append /etc/apt/preferences.d/limit-bookworm pi@tarte:~ $ sudo apt install bluez-alsa-utils

Do not forget to change the priority of the Bookworm repository or else you will update 365 packages or so with the next sudo apt upgrage -y command. And do not forget to edit /etc/default/bluez-alsa to set the OPTIONS="-p a2dp-source -p a2dp-sink" if the Pi is to receive a sound stream over Bluetooth®. I'll mention that it appears that latency is not as bad with this newer version of BlueALSA although maybe not as reduced as with PulseAudio. This is hard to quantify and very subjective, but in a pinch I would watch a YouTube video with the sound streamed to a Pi via Bluetooth®.

Best Decision toc

So should BlueALSA be abandonned? There's no doubt that PulseAudio is both more powerful and easier to use, at first blush anyway. But it is heavy, which is irksome for users wanting to run light servers on small single-board computers.

Number of packagesDownload Size KBDisk Space (KB)
PulseAudio72  28600  80000  
bluez-alsa6  242  708  

Since BlueALSA was sufficient for my needs in the past, I would be inclined to forego PulseAudio at least for as long the package remains in Raspbian (or, more accurately, in Debian). Others may need the greater capabilities of PulseAudio. Regardless, it is a welcomed addition.

<-Bluetooth and BlueALSA in Raspberry Pi OS Lite (November 2021)
<-Baby Bluetooth Steps on Raspberry Pi 3 - Raspbian (Stretch)