====== Ubuntu 24.04 Desktop Env ====== ===== - Video Meetings ===== ==== - Bluetooth Headset ==== # Setup bluetooth on Ubuntu 24.04 with Piperwire (on Raspberry Pi 5) > I've had a hard time bringing bluetooth to work on a Raspberry Pi 5 with Ubuntu 24.04 using Pipewire as audio backend. > Maybe you run into the same situation and find this helpful. With the common tutorials on how to enable a bluetooth speaker connection on Ubuntu, there were the following problems for my combination of Ubuntu 24.04 on a Raspberry Pi 5 and using PipeWire (as of July 2024): - either the audio quality was fine but the connection automatically disconnects after a few seconds - or the connection does not disconnect, but the audio begins to stutter extremely after 60 to 90 seconds of audio played Since Ubuntu 22.10, PipeWire is the default soundserver on Ubuntu, so trying to use Bluetooth with PulseAudio as soundserver would mean to uninstall the recommended default and reconfigure the system. So PipeWire it is! After trying a lot of different stuff, the solution contains: - setup PipeWire correctly - compiling / installing a current version of bluez - setting the correct bluetooth parameters This gist is based on (Debian Wiki)[https://wiki.debian.org/PipeWire#Debian_12] and inspired by this [gist for Bluetooth on Ubuntu 22.04](https://gist.github.com/the-spyke/2de98b22ff4f978ebf0650c90e82027e?permalink_comment_id=4018512) # Installation ## PipeWire **Works out of the box** **WirePlumber** as session manager: ```bash # Install WirePlumber as session manager while removing pipewire-media-sessions as the old session manager sudo apt install wireplumber pipewire-media-session- # Enable WirePlumber in "systemd" (running as user, not as root) systemctl --user --now enable wireplumber.service ``` **Setting up Alsa and PipeWire as substitute for PulseAudio** ```bash # Configure PipeWire to activate its PulseAudio replacement daemon # Configure PipeWire to activate its ALSA Plugin # Also install pulseaudio and alsa utils sudo apt install pipewire-pulse pipewire-alsa pulseaudio-utils alsa-utils # Reboot and check, if pipewire-pulse is working correctly sudo reboot now # This should return something like: # "Server Name: PulseAudio (on PipeWire 1.X.XX)" LANG=C pactl info | grep '^Server Name' ``` ## Bluetooth / BlueZ ** TODO ** ```bash # Minimum requirement for bluetooth sudo apt install libspa-0.2-bluetooth # If still installed, remove pulseaudio-module-bluetooth sudo apt remove pulseaudio-module-bluetooth ``` We need to install `bluez` either by source or taking the available apt version. ### Trying the available version ```bash sudo apt install bluez ``` If this version is working, you're fine! At the time of writing, I had to install a newer version of bluez (upgrading from apt version 5.72 to 5.77) ### (Optional) Installing bluez by source Installation instructions taken from https://www.makeuseof.com/install-bluez-latest-version-on-ubuntu/ ```bash # If you have an old version installed, remove it first sudo apt autoremove bluez # Install necessary build packages sudo apt install build-essential libreadline-dev libical-dev libdbus-1-dev libudev-dev libglib2.0-dev python3-docutils # Set the current bluez version # Check https://github.com/bluez/bluez/releases for the most recent version BLUEZ_VERSION=5.77 wget http://www.kernel.org/pub/linux/bluetooth/bluez-$BLUEZ_VERSION.tar.xz # Download, unzip, build and install the bluez version tar -xf bluez-$BLUEZ_VERSION.tar.xz && cd bluez-$BLUEZ_VERSION ./configure make sudo make install ``` For me, this new version of bluez also solved a extremely verbous console output when being inside the `bluetoothctl` terminal. # Configure bluetooth If you have compiled a newer version of bluez, allowing experimental features might help. ```bash # Modify /lib/systemd/system/bluetooth.service, e.g. with nano sudo nano /lib/systemd/system/bluetooth.service # Search for the ExecStart line and add a "--experimental" at the end, so that you have the following: # ExecStart=/usr/local/libexec/bluetooth/bluetoothd --experimental ``` Set the correct controller mode: ```bash # Modify /etc/bluetooth/main.cfg sudo nano /etc/bluetooth/main.cfg # Uncomment / set both lines: # Name = BlueZ # ControllerMode = dual ``` Restart bluetooth / your system ```bash sudo systemctl restart bluetooth # or sudo reboot now ``` Sources for the bluetooth config: - https://askubuntu.com/questions/1240679/how-to-pairsetupconnect-airpod-pro-on-ubuntu-20-04 # Connect to your device These are the common bluetoothctl commands to find and connect to your device: ```bash bluetoothctl power on bluetoothctl agent on bluetoothctl discoverable on bluetoothctl pairable on bluetoothctl scan on bluetoothctl trust DEVICE:MAC bluetoothctl pair DEVICE:MAC bluetoothctl connect DEVICE:MAC ``` # Collection of further methods to tackle problems ## Check if bluetooth is blocked ``` sudo rfkill list # If bluetooth is marked as blocked, run: sudo rfkill unblock all ``` ## Check if bluetooth is even running ```bash # Check the status of bluetooth, there should be something like "running" / "active" systemctl status bluetooth # If not, start bluetooth with one of the following systemctl start bluetooth bluetoothctl power on # You can also check and unblock again rfkill unblock all ``` ## Choppy audio on systems with high load Based on https://wiki.debian.org/PipeWire PipeWire's lower latency compared to PulseAudio can lead to choppy audio on systems with high load. First view the quantum using the `pw-top` command and then increase the quantum value using this command, until the audio becomes smoother. ```bash # Call this while playling audio. # Experiment with different quantum values. pw-metadata -n settings 0 clock.force-quantum 2048 ``` Once you find the right quantum value for your situation, you can make the value permanent by creating a config file `~/.config/pipewire/pipewire.conf.d/choppy-under-load.conf` with the following content and restart pipewire related daemons. ``` context.properties = { default.clock.quantum = 2048 default.clock.min-quantum = 2048 } ``` ## Reduce Latency Based on this [gist for Ubuntu 22](https://gist.github.com/shakthizen/c943a07d3ef99f8f5b4004d77b358d2d). Find necessary info about the bluetooth device (while it is connected!) ``` pactl list | grep -Pzo '.*bluez_card(.*\n)*' ``` The output should be something like ``` Name: bluez_card.28_11_A5_84_B6_F9 Driver: module-bluez5-device.c ... Ports: speaker-output: Speaker (priority: 0, latency offset: 0 usec, available) Part of profile(s): a2dp_sink, headset_head_unit speaker-input: Bluetooth Input (priority: 0, latency offset: 0 usec, not available) Part of profile(s): headset_head_unit ``` We see that the buffers have currently 0 latency. In the next step, you will need the NAME and PORT of your output. In this example, these are bluez_card.28_11_A5_84_B6_F9 and speaker-output, respectively. Set the buffer size (latency) of your card to a suitable value with this command pattern: ``` pactl set-port-latency-offset ``` The latency unit of the following command is microseconds, so I'm using a 50 millisecond buffer for my command here: ``` pactl set-port-latency-offset bluez_card.28_11_A5_84_B6_F9 speaker-output 50000 ``` Restart your bluetooth service to apply your change ```bash sudo service bluetooth restart ``` As there is usually no documentation about this, you may have to experiment with higher or lower buffer values. Many people people posted their working latencies in the comments to this answer. Check them out for guidance on the latency value.