Veracious Network More than just a game, it's a community!

Bluetooth Headphones & A2DP/AAC w/ Pipewire on Debian 12

I've had a pair of Anker Soundcore Life 2 bluetooth headphones with active noise-cancelling for a while, but generally used them with either my phone or laptop running PopOS. Recently decided to try to use them with my desktop running Debian Bookworm 12 (currently in beta), and had less than a pleasant time, despite learning far more than I wanted to about bluetooth.

First Issue, No Discoverability

I bought a cheap USB-BT adapter from Microcenter for under $10 and expected it to "just work" like most devices on Linux. Unfortunately despite being detected correctly by the OS, it refused to detect any discoverable devices. Despite having bluez package installed, the headset would not get detected until I installed blueman.

bash sudo apt install blueman sudo systemctl restart bluetooth

Once blueman was installed and the bluetooth daemon was restarted, the headset was detected and was able to connect to the desktop. Unfortunately it was only being detected as HFP/HSP and no audio would be sent to the headset.

HFP vs A2DP

After some research, I learned that the HFP/HSP profile is only for headsets with 2-way audio, but only mono in either direction, presumably due to bandwidth limitations in the bluetooth protocol. While poor audio would not have been the end of the world, I was getting no audio at all.

The correct profile for this headphone, (seeing as it did not offer 2-way audio), should have been A2DP which supports stereo audio and better codecs. Sadly Gnome was not showing any A2DP profiles in the list of profiles when the headphones were selected. The blueman manager blueman-manager had the same issue where only HFP/HSP was displaying as valid profiles.

Pipewire, Debian, and Copyright

The first suggestion I came across for this issue was talking about how AAC encoding is not enabled in Debian due to AAC being non-free software. I wasn't sure if this was affecting the profile issue, but figured it was worth investigating.

Unfortunately I was not able to find any working package with AAC support, so I partied like it was 1998 and grabbed the source for Pipewire and started package hunting.

Party Like it's 1998 and Compile from Source

Following official instructions from Pipewire, I performed the following work to compile Pipewire from source code with support for AAC and other various codecs.

```bash

Enable deb-multimedia for the "bad" codecs

echo 'deb https://www.deb-multimedia.org bookworm main non-free' \ | sudo tee /etc/apt/sources.list.d/deb-multimedia.list sudo apt update -oAcquire::AllowInsecureRepositories=true sudo apt-get install deb-multimedia-keyring

Install a bunch of dev libraries

sudo apt install libgstreamer1.0-dev meson libgstreamer-plugins-base1.0-dev \ libsystemd-dev liblilv-dev libsdl2-dev libopus-dev libsndfile1-dev \ libusb-dev libusb-1.0-0-dev libbluetooth-dev libcamera-dev cmake \ libmysofa-dev libavahi-client-dev libcanberra-dev libcap-dev \ libwebrtc-audio-processing-dev libopenal-dev libavcodec-dev \ libavdevice-dev openal-info sbc-tools libsbc-dev libdvdcss2 fdkaac \ gstreamer1.0-plugins-bad libfdk-aac-dev libldacbt-enc-dev libldacbt-abr-dev \ libfreeaptx-dev modemmanager-dev

Grab pipewire source code and configure

git clone https://gitlab.freedesktop.org/pipewire/pipewire.git cd pipewire meson setup --wipe builddir

If everything looks good, compile and install

meson compile -C builddir sudo meson install -C builddir ```

This will install the package into /usr/local but systemd is still starting the service from /usr. To resolve this, I edited /usr/lib/systemd/user/pipewire.service (as sudo) and changed ExecStart=/usr/bin/pipewire to ExecStart=/usr/local/bin/pipewire.

A quick reload and restart of the daemon got the new compiled verson working:

bash systemctl --user daemon-reload systemctl --user restart pipewire

This got Pipewire working with new codec support, but still no luck on the Bluetooth profile. Next step down the stack is to Bluetooth. Following instructions from the BlueZ project is straight forward and quick.

bash git clone https://github.com/bluez/bluez.git cd bluez ./configure make sudo make install sudo systemctl daemon-reload sudo systemctl restart bluetooth

Again, straight forward process and it worked with the restart, but still no profile.

System Default Configuration

One item I ran across during my research which I dismissed was "uncomment the name = bluez from your etc", (among other tweaks to that file). As a last ditch effort, that's what I did.

``` [General]

Defaults to 'BlueZ X.YZ', if Name is not set here and plugin 'hostname' is not loaded.

The plugin 'hostname' is loaded by default and overides the Name set here so

consider modifying /etc/machine-info with variable PRETTY_HOSTNAME= instead.

Name = BlueZ ```

At the top of /etc/bluetooth/main.conf, I uncommented Name = BlueZ to enable that directive (despite supposedly being default), and one final restart of Bluetooth.

Correct Profiles for Bluetooth

Lo and behold that did the trick! Well, some combination of the 3 steps worked... But if nothing else, I now have crystal clear AAC audio on my bluetooth headphones!

[HFP]: Hands-Free Profile [HSP]: Headset Profile *[A2DP]: Advanced Audio Distribution Profile