I have a raspberry pi zero W and I would like to stream sound over bluetooth to a bluetooth-enabled speaker / headphone.
So how to achieve this with alsa
?
I have a raspberry pi zero W and I would like to stream sound over bluetooth to a bluetooth-enabled speaker / headphone.
So how to achieve this with alsa
?
I did manage to play sound and record using my Marshall MID headphones using a Raspberry Pi Zero W, which has a builtin WiFi + Bluetooth adapter, but no audio jack.
Please note that there are different approaches using different tools such as bluez
alsa
and pulseaudio
, hcitool
, bluetoothctl
.
Bluez Alsa let's you play sound on a bluetooth speaker like so:
aplay -D bluealsa:DEV=AA:BB:CC:DD:EE:FF,PROFILE=a2dp,HCI=hci0 ~/piano.wav
You'll have to install the bluealsa
client from source.
cd && git clone https://github.com/Arkq/bluez-alsa.git
cd bluez-alsa
# git checkout tags/v1.3.1 -b v1.3.1
sudo apt install bluez bluez-tools -y
sudo apt install libglib2.0-dev -y
sudo apt install libasound2-dev -y
sudo apt install build-essential autoconf -y
sudo apt install libbluetooth-dev -y
sudo apt install libtool -y
sudo apt install libsbc-dev -y
# sudo apt install libbsd-dev libfdk-aac-dev libncurses5-dev libreadline-dev -y
mkdir -p m4
autoreconf --install
mkdir build && cd build
# ../configure --enable-aac --enable-debug
#../configure --enable-debug
../configure CFLAGS="-g -O0" LDFLAGS="-g" --enable-debug
make && sudo make install
Now you can run sudo bluealsa -S
in a seperate terminal. You can startup bluealsa
by it to /etc/rc.local
before the exit
line:
sudo nano /etc/rc.local
Now add
# Start bluealsa as root <https://github.com/Arkq/bluez-alsa>
export LIBASOUND_THREAD_SAFE=0
/usr/bin/bluealsa -S &
Reboot and make sure that it's running: ps -ef | grep bluealsa
Add the pi user to the audio and the bluetooth group
sudo adduser pi bluetooth
sudo adduser pi audio
bluetoothd
with a2dp pluginThere is a a2dp
plugin for our bluetooth agent. So we'll change the services' ExecStart
parameter like so:
sudo nano /etc/systemd/system/bluetooth.target.wants/bluetooth.service
And while we're here we'll disable sap
since this may cause some errors:
ExecStart=/usr/lib/bluetooth/bluetoothd --noplugin=sap --plugin=a2dp
Now reload and restart the agent:
sudo systemctl daemon-reload
systemctl restart bluetooth
I run bluetoothctl
and issue the following commands:
sudo bluetoothctl
list
# Controller XXXXXX mydevice [default]
power on
agent on
default-agent
scan on
# [NEW] Device AA:BB:CC:DD:EE:FF XYZ
# Now I Press the pairing button on the device (disabling bluetooth on any nearby devices)
connect AA:BB:CC:DD:EE:FF
trust AA:BB:CC:DD:EE:FF
exit
The trust
command will enable to auto-pair the device again later on.
If auto-connecting does not work after reboot you may add the following line to /etc/rc.local
:
echo -e "power up\nconnect AA:BB:CC:DD:EE:FF\n quit"|bluetoothctl
Now let's create a config for our bluetooth device and add it either to /etc/asound.conf
(global) or ~/.asoundrc
(per-user basis).
pcm.mid {
type plug
slave {
pcm {
type bluealsa
device AA:BB:CC:DD:EE:FF
profile "a2dp"
}
}
hint {
show on
description "Marshall MID"
}
}
Now that the devices is connected you should be able to playback like so:
aplay -D mid ~/piano.wav
Alternatively you can specify the address and profile like so:
aplay -D bluealsa:DEV=2C:4D:79:0D:17:F9,PROFILE=a2dp,HCI=hci0 ~/piano.wav
For recording you'll need a different profile:
arecord -D bluealsa:DEV=2C:4D:79:0D:17:F9,PROFILE=sco ~/test.wav
This may result in poor sound quality.
There are a few things that can go wrong so here some troubleshooting pointers.
list
lists the interfaces. Use select XX:XX:XX...
to select another interfacedevices
list the devices. Use scan on
, scan off
to find new devices.info XX:XX:XX...
show information about the given deviceremove XX:XX:XX...
to remove a pairing and connection use remove. This can be helpful for starting over, when there are problems with the pairing process.Often the bluetooth devices may be connected to other computers, smartphones tablets. These devices can block a new pairing so make sure to switch those devices off or remove the pairing.
I encountered an error when starting bluealsa
which was :
bluealsa: Couldn't initialize controller thread: Bad file descriptor
In this case I had to delete the hci*
file in the /run
directory:
sudo rm /run/bluealsa/hci*
I would also get this message when running bluealsa
without sudo
.
You can get some logs by running
journalctl | grep blue
The status of the bluetooth service will also show some possible errors (Such as the SAP
server error from above):
GFP> service bluetooth status
● bluetooth.service - Bluetooth service
Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2018-10-24 08:59:08 UTC; 4s ago
Docs: man:bluetoothd(8)
Main PID: 566 (bluetoothd)
Status: "Running"
CGroup: /system.slice/bluetooth.service
└─566 /usr/lib/bluetooth/bluetoothd
Oct 24 08:59:08 godfatherphone systemd[1]: Stopped Bluetooth service.
Oct 24 08:59:08 godfatherphone systemd[1]: Starting Bluetooth service...
Oct 24 08:59:08 godfatherphone bluetoothd[566]: Bluetooth daemon 5.43
Oct 24 08:59:08 godfatherphone systemd[1]: Started Bluetooth service.
Oct 24 08:59:08 godfatherphone bluetoothd[566]: Starting SDP server
Oct 24 08:59:09 godfatherphone bluetoothd[566]: Bluetooth management interface 1.14 initialized
Oct 24 08:59:09 godfatherphone bluetoothd[566]: Failed to obtain handles for "Service Changed" characteristic
Oct 24 08:59:09 godfatherphone bluetoothd[566]: Sap driver initialization failed.
Oct 24 08:59:09 godfatherphone bluetoothd[566]: sap-server: Operation not permitted (1)
Oct 24 08:59:09 godfatherphone bluetoothd[566]: Endpoint registered: sender=:1.6 path=/A2DP/SBC/Source/1
The following lines are in red:
sudo apt install blueman xauth -y
sudo apt install -y obex-data-server
Logs to check during debugging
dmesg | egrep -i 'blue|firm'
tail -f /var/log/syslog
journalctl -u bluetooth
At some point I got the following error message:
ALSA lib ../../../src/asound/bluealsa-pcm.c:666:(_snd_pcm_bluealsa_open) Couldn't get BlueALSA transport: No such device
aplay: main:788: audio open error: No such device
This message won't come if the device is connected and paired.
$ busctl tree org.bluez
└─/org
└─/org/bluez
└─/org/bluez/hci0
├─/org/bluez/hci0/dev_XX_XX_79_0D_17_F9
└─/org/bluez/hci0/dev_XX_XX_26_AF_79_03
The System D status command will give you the status and errors of the bluetooth agent.
sudo systemctl status bluetooth
● bluetooth.service - Bluetooth service
Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2018-10-24 18:21:16 UTC; 14min ago
Docs: man:bluetoothd(8)
Main PID: 615 (bluetoothd)
Status: "Running"
CGroup: /system.slice/bluetooth.service
└─615 /usr/lib/bluetooth/bluetoothd --noplugin=sap
Oct 24 18:21:16 mypi systemd[1]: Starting Bluetooth service...
Oct 24 18:21:16 mypi bluetoothd[615]: Bluetooth daemon 5.43
Oct 24 18:21:16 mypi systemd[1]: Started Bluetooth service.
Oct 24 18:21:16 mypi bluetoothd[615]: Starting SDP server
Oct 24 18:21:16 mypi bluetoothd[615]: Excluding (cli) sap
Oct 24 18:21:16 mypi bluetoothd[615]: Bluetooth management interface 1.14 initialized
Oct 24 18:21:16 mypi bluetoothd[615]: Failed to obtain handles for "Service Changed" characteristic
Oct 24 18:23:29 mypi bluetoothd[615]: Endpoint registered: sender=:1.12 path=/A2DP/SBC/Source/1
Oct 24 18:23:29 mypi bluetoothd[615]: Endpoint unregistered: sender=:1.12 path=/A2DP/SBC/Source/1
Oct 24 18:23:43 mypi bluetoothd[615]: Endpoint registered: sender=:1.13 path=/A2DP/SBC/Source/1
According to wiki.archlinux.org:
Edit the file
/etc/dbus-1/system.d/bluetooth.conf
and add these lines to the bottom, just before the closing</busconfig>
.<policy user="bluealsa"> <allow send_destination="org.bluez"/> </policy>
On my mac I hit ⌥
while pressing the bluetooth icon in the status bar.
Note: When setting up /etc/asound.conf or .asoundrc if you set it as "default" then you don't need to specify the device when calling aplay. ie:
aplay ~/piano.wav
instead of
aplay -D mid ~/piano.wav
To do this the asoundrc should appear like so
pcm.!default {
type plug
slave.pcm {
type bluealsa
device "MAC address"
profile "a2dp"
}
}
ctl.!default {
type bluealsa
}