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:

https://lh6.googleusercontent.com/0q7sLidAEGE5IweD6euBBdTx1PCdhv7Zo2ZOigMLUql1cHfd5gZLEjDFRA2lMpIREoB-hpLaiNzSTZ3GHKJ44PKJULnxKag2eA3jC-CtasSHnZ4i4GQcPLkoZjzNCogtiSP9KxXW     https://lh3.googleusercontent.com/058CM77KKeofJCJtTCPcHK6uRHsmU6L_JW-R3rBsjWAh3iUwr6WSRcBX1t2ZxnH8zh78b37hrrf8zhOUgSbnjXKZth2Z0xuSadC8sTJ9BSYr-pVOIPPTdHhVKGInkT9mpzDjBrO9

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:

Machine generated alternative text:
# resample-method defaults to speex- float-I on most architectures, 
# speex-fixed-l on ARM 
res ample - method 
— speex-float-l 
resample-method 
— trivial 
enable - remixing 
yes 
enable - fe - remi Xing 
flat-volumes = yes 
r limit-data 
r limit- 
core 
r limit-as 
• default-script-file 
, log-target 
— auto 
, log-level 
— notice 
, log-meta 
, log-time 
, log-backtrace = € 
r limit- fs ize 
r limit-stack 
r limit-rss — 
/etc/pulse/default.pa

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.

https://scontent.fbru2-1.fna.fbcdn.net/v/t34.0-12/26940897_10213310369886566_215132886_n.png?oh=ce1d7f9d494f77e7df713ac107d950e6&oe=5A62E60E                           https://scontent.fbru2-1.fna.fbcdn.net/v/t34.0-12/26940735_10213309391782114_96259426_n.png?oh=f4acf4f2d8aceb56b8d9bd838dd609c7&oe=5A63B55D

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… !

https://scontent.fbru2-1.fna.fbcdn.net/v/t34.0-12/26940524_10213310429208049_1963037057_n.png?oh=c50e5cfd9960b8131028499a30cfa3fe&oe=5A63CE68

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:

Machine generated alternative text:
Raspberry pi Softi*are Tool (raspz-conf-_g) 
Bl 
82 
Console 
Text console, 
Console Autolo z n Text console, 
Desktop 
Desktop GUI, 
Desktop Autologin Desktop GUI, 
re ulrln user to 10 in 
automaticall 10 ed in es 
requiring user to login 
automatically logged in as •pi' 
user

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!!!