Bluetooth Speakers

Overview

I often find myself wanting to use my Raspberry Pi with Bluetooth audio. As I normally run my RPi without a desktop environment the graphical tools are not available to me easily. I have been wondering if I could use Bluetooth audio from the command-line. I have started some investigation into how this works and this HowTo is me capturing my notes as I go. I will hopefully be improving this over time and maybe even extend it to include how to configure things with Python.

The hardware uses the Bluetooth Advance Audio Distribution Profile (A2DP) which has a Source and Sink option.

Understanding UUID's

Bluetooth profiles and services are referred to by Universally Unique Identifier (UUID). These take the form of 128-bit hexadecimal numbers and are normally formatted as sequence of 32 hex digits grouped in groups of 8-4-4-4-12 e.g. 00000000-0000-1000-8000-00805F9B34FB

This can be rather cumbersome when documenting things so for officially adopted UUIDs they can be documented is a short form (16-bit UUIDs).

The 16-bit UUID is placed with the base 128-bit UUID 0000xxxx-0000-1000-8000-00805F9B34FB
In this HowTo you will see UUIDs in both their 128-bit and 16-bit form.

As a side note, this means if you are creating your own services or characteristics then you should avoid the reserved range of xxxxxxxx-0000-1000-8000-00805F9B34FB but I digress...

Sending Audio (Audio Source - 0x110A)

The first experiment I did was to use a Raspberry Pi 3 as a source connecting to a Jabra Solemate Bluetooth speaker.

Transcript of session

    pi@RPi3:~ $ bluetoothctl 
    [bluetooth]# agent on
    Agent registered
    [bluetooth]# scan on
    Discovery started
    [CHG] Controller B8:27:EB:22:57:E0 Discovering: yes
    [NEW] Device 50:C9:71:67:41:CD Jabra SOLEMATE v1.27.0
    [bluetooth]# scan off
    [CHG] Controller B8:27:EB:22:57:E0 Discovering: no
    Discovery stopped
    [bluetooth]# pair 50:C9:71:67:41:CD
    Attempting to pair with 50:C9:71:67:41:CD
    [CHG] Device 50:C9:71:67:41:CD Connected: yes
    [CHG] Device 50:C9:71:67:41:CD Modalias: usb:v0B0EpABCDd011B
    [CHG] Device 50:C9:71:67:41:CD UUIDs: 00001108-0000-1000-8000-00805f9b34fb
    [CHG] Device 50:C9:71:67:41:CD UUIDs: 0000110b-0000-1000-8000-00805f9b34fb
    [CHG] Device 50:C9:71:67:41:CD UUIDs: 0000110c-0000-1000-8000-00805f9b34fb
    [CHG] Device 50:C9:71:67:41:CD UUIDs: 0000110e-0000-1000-8000-00805f9b34fb
    [CHG] Device 50:C9:71:67:41:CD UUIDs: 0000111e-0000-1000-8000-00805f9b34fb
    [CHG] Device 50:C9:71:67:41:CD UUIDs: 00001200-0000-1000-8000-00805f9b34fb
    [CHG] Device 50:C9:71:67:41:CD ServicesResolved: yes
    [CHG] Device 50:C9:71:67:41:CD Paired: yes
    Pairing successful
    [CHG] Device 50:C9:71:67:41:CD ServicesResolved: no
    [CHG] Device 50:C9:71:67:41:CD Connected: no
    [bluetooth]# trust 50:C9:71:67:41:CD
    [CHG] Device 50:C9:71:67:41:CD Trusted: yes
    Changing 50:C9:71:67:41:CD trust succeeded
    [bluetooth]# connect 50:C9:71:67:41:CD 
    Attempting to connect to 50:C9:71:67:41:CD
    [CHG] Device 50:C9:71:67:41:CD Connected: yes
    Connection successful
    [CHG] Device 50:C9:71:67:41:CD ServicesResolved: yes

Now we have paired and said that we trust the device, just turning on the Bluetooth speaker means it will automatically connect to the Raspberry Pi.

To access the audio device we need to put the details in a file called ".asoundrc" in your home directory. e.g. ~/.asoundrc
More detailed documentation on asoundrc is available at: https://www.alsa-project.org/main/index.php/Asoundrc
For my example the .asoundrc need to have:

    defaults.bluealsa.interface "hci0"
    defaults.bluealsa.device "50:C9:71:67:41:CD"
    defaults.bluealsa.profile "a2dp"
    defaults.bluealsa.delay 10000

We can play a sound over Bluetooth from the commandline with:

    aplay -D bluealsa /usr/share/scratch/Media/Sounds/Animal/Crickets.wav

I only tested this with these short sound files. This may have been an oversight because as we will see with the audio sink example there maybe issues with longer files.

Receiving Audio (Audio Sink - 0x110B)

The second experiment I did was to use a Raspberry Pi 3 as a Bluetooth speaker. For this I connected a speaker to the 3.5mm audio connector on the RPi and used an Android phone as the audio source at the other end of the Bluetooth link.

Transcript of Session

    pi@RPi3:~ $ bluetoothctl 
    [bluetooth]# agent NoInputNoOutput
    Agent registered
    [bluetooth]# discoverable on
    Changing discoverable on succeeded
    [CHG] Controller B8:27:EB:22:57:E0 Discoverable: yes

Now we have made the Raspberry Pi discoverable we can pair with it from the mobile phone

    [NEW] Device 64:BC:0C:F6:22:F8 Nexus 5X
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 0000111f-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 Modalias: bluetooth:v000Fp1200d1436
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 00001105-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 0000110a-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 0000110c-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 0000110e-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 00001112-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 00001115-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 00001116-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 0000111f-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 0000112d-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 0000112f-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 00001132-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 00001200-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 00001800-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 00001801-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 ServicesResolved: yes
    [CHG] Device 64:BC:0C:F6:22:F8 Paired: yes
    [CHG] Device 64:BC:0C:F6:22:F8 ServicesResolved: no
    [CHG] Device 64:BC:0C:F6:22:F8 Connected: no
    [CHG] Device 64:BC:0C:F6:22:F8 Connected: yes
    [Nexus 5X]# trust 64:BC:0C:F6:22:F8 
    [CHG] Device 64:BC:0C:F6:22:F8 Trusted: yes
    Changing 64:BC:0C:F6:22:F8 trust succeeded

We can now connect to the Raspberry Pi from the mobile phone and start playing the audio

    [CHG] Device 64:BC:0C:F6:22:F8 Connected: no
    [CHG] Device 64:BC:0C:F6:22:F8 Connected: yes
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 00001105-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 0000110a-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 0000110c-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 0000110d-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 0000110e-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 00001112-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 00001115-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 00001116-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 0000111f-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 0000112d-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 0000112f-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 00001132-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 00001200-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 00001800-0000-1000-8000-00805f9b34fb
    [CHG] Device 64:BC:0C:F6:22:F8 UUIDs: 00001801-0000-1000-8000-00805f9b34fb
    [CHG] Controller B8:27:EB:22:57:E0 Discoverable: no
    [CHG] Device 64:BC:0C:F6:22:F8 Connected: no
    [CHG] Device 64:BC:0C:F6:22:F8 Connected: yes

Finally the Bluetooth audio-in needs to be routed to the speaker that is attached. This can be done with the following command:

    bluealsa-aplay 64:BC:0C:F6:22:F8

The results of this were... disappointing. The audio was cutting out very frequently. A little bit of research shows this is a known issue which you can find more detail about at:

For those that do not want to read the long threads on the issues then the summary seems to be:

it is a problem with Raspberry Pi firmware. Wifi and BT do not coexist very well

Summary

This was not the exciting result I had hoped for coming into this. Time to park this for a while and see if it gets sorted out in the meantime...

license