PI Bluetooth Audio Receiver
This short tutorial will show how the RPI can be used as a Bluetooth Audio Receiver, producing high quality audio output to a stereo receiver, especially in conjunction with a Digital Audio Card, as shown in the picture below:
Follow these steps:
I) Upgrade your system
Type:
pi@audiopi:~ $ sudo apt-get update
pi@audiopi:~ $ sudo apt-get upgrade
This operation may take some time. All Bluetooth related drivers should be installed with the latest Raspbian version. You can check your versions if you want:
pi@audiopi:~ $ uname -a
Linux audiopi 4.9.35-v7+ #1014 SMP Fri Jun 30 14:47:43 BST 2017 armv7l GNU/Linux
II) Edit your Bluetooth configuration:
pi@audiopi:~ $ sudo vi /etc/bluetooth/main.conf
Add the following line to the [General] section:
Enable=Source,Sink,Media
This will enable your Pi to work as a source and sink for audio media.
Change the class to:
Class = 0x00041C
This will change the default class of your Bluetooth device to audio and the headphone icon will pop up in the devices your pi will be pairing with…
Set the values for pairing and discovering times
DiscoverableTimeout = 0
PairableTimeout = 0
We want our pi to be discoverable and pairable forever.
Save the file, these should be your changes:
III) Configure the pi audio
We will use pulseaudio as the pi’s sound server, to which the audio media will be streamed over the Bluetooth connection and reroute the stream to the DAC sound card.
Type:
pi@audiopi:~ $ sudo vi /etc/pulse/daemon.conf
Change the resample method to trivial:
resample-method = trivial
The method trivial is the most basic algorithm implemented. It is supported by the pi.
Your file should look like this:
We need pulseaudio to run at system startup, as we will use the pi in headless mode without any user interaction.
Pulseaudio needs to be instantiated just once and hence we’re going to add a pulseaudio.sh script to the /etc/init.d directory where all startup scripts are located.
Type:
pi@audiopi:~ $ sudo vi /etc/init.d/pulseaudio.sh
and paste the following text into the file:
#! /bin/sh
#
# pulseaudio initscript
#
### BEGIN INIT INFO
# Provides: pulseaudio.sh
# Required-Start: $local_fs $remote_fs
# Required-Stop: $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts pulseaudio at startup
# Description: starts pulseaudio at startup
### END INIT INFO
# This is needed for bluetooth audio
pulseaudio -D
Save the file. Let’s now make the script executable
pi@audiopi:~ $ sudo chmod 755 /etc/init.d/pulseaudio.sh
Register script to be run at startup:
pi@audiopi:~ $ sudo update-rc.d pulseaudio.sh defaults
IV) Configure the DAC
Reconfigure your audio output if you’re using a digital audio card. My PiFi DAC+ v2.0 is compatible with the HiFiBerry drivers and the configuration is fairly trivial as shown below:
Type
pi@audiopi:~ $ sudo vi /boot/config.txt
Uncomment the appropriate dtparm setting and add the overlay parameter:
dtoverlay=hifiberry-dacplus
Comment the dtparam=audio=on line, as we’re not using the RPI’s native sound chip.
V) Activate the appropriate Bluetooth commands in the Bluetooth controller
You can conveniently interact with your Bluetooth controller through an interactive CLI as shown here:
pi@audiopi:~ $ sudo service bluetooth restart
pi@audiopi:~ $ bluetoothctl
[NEW] Controller B8:27:EB:AD:57:39 audiopi [default]
[bluetooth]# power on
[CHG] Controller B8:27:EB:AD:57:39 Class: 0x0c041c
Changing power on succeeded
[CHG] Controller B8:27:EB:AD:57:39 Powered: yes
[bluetooth]# show
Controller B8:27:EB:AD:57:39
Name: audiopi
Alias: audiopi
Class: 0x0c041c
Powered: yes
Discoverable: yes
Pairable: yes
UUID: PnP Information (00001200-0000-1000-8000-00805f9b34fb)
UUID: Generic Access Profile (00001800-0000-1000-8000-00805f9b34fb)
UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
UUID: A/V Remote Control (0000110e-0000-1000-8000-00805f9b34fb)
UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
UUID: Audio Source (0000110a-0000-1000-8000-00805f9b34fb)
UUID: Audio Sink (0000110b-0000-1000-8000-00805f9b34fb)
Modalias: usb:v1D6Bp0246d0517
Discovering: no
[bluetooth]#
The sequence of commands above show that the Bluetooth configuration parameters have taken effect: After Power on, the controller is powered, it has the right class (audio), it is discoverable and pairable and is defined as audio source and sink.
Take a mobile device or tablet and switch Bluetooth on, when your device starts scanning the environment your pi will be visible as an available device, and pairing will work.
However, you won’t be able to connect to your pi yet. It needs to trust your device first:
[bluetooth]# paired-devices
Device C0:EE:FB:47:1C:83 OnePlus2
[bluetooth]# trust C0:EE:FB:47:1C:83
[CHG] Device C0:EE:FB:47:1C:83 Trusted: yes
Changing C0:EE:FB:47:1C:83 trust succeeded
[bluetooth]#
If you connect now the magic happens… !
But does it, stream some music and … yes you will hear it, but here comes the bad news, if you are accessing your pi through WiFi you will hear stuttering audio and clicks, because of an interference between the Bluetooth and WiFi on the PI’s BCM43438 chip or possibly some driver error, the only way to solve this is through deactivation of your wlan0 interface.
VI) Finish the setup
Let’s put the missing pieces together, first of all, the pi will have to be run in headless mode, therefore it needs to boot automatically to the console.
Type:
pi@audiopi:~ $ sudo raspi-config
Select Boot Options and the right Option here:
Save these settings and reboot your pi.
We’ll now write a shell script that trusts all paired-devices, for them to be able to connect.
Type:
pi@audiopi:~ $ sudo vi trust_paired.sh
Copy the content of the file below.
#!/bin/bash
#bring down wireless lan driver as it interferes with bluetooth audio...
sudo ifdown wlan0
# Power on the bluetooth controller and make it discoverable and pairable
echo -e 'power on \nagent on\ndefault-agent\ndiscoverable on \npairable on\nquit' | bluetoothctl
while true
do
# List devices
echo -e 'paired-devices\nquit' | bluetoothctl | awk '/^Device/ {print $2 "\t" $3}' > devices.tmp
# Trust devices
while read p
do
echo "Device to trust is: $p"
mymac=$( echo $p | cut -d' ' -f 1 )
echo -e "trust $mymac \nquit" | bluetoothctl
done < devices.tmp
# Remove temporary file
rm devices.tmp
sleep 15
done
Make this file executable:
pi@audiopi:~ $ sudo chmod 755 trust_paired.sh
Add this file to pi’s bashrc file to execute it whenever pi logs on.
pi@audiopi:~ $ sudo vi .bashrc
And add this line at the bottom of the file:
/home/pi/trust_paired.sh
Now reboot your system and … tadaaaa!!!