Having Bluetooth connectivity and enabling Raspberry Pi to behave as A2DP source is nothing new (see a general tutorial on Instructables), but the problem I had thus far was making that work on my media center Pi which was running Raspbmc. As I found out through numerous attempts to make it work, the problem was with Raspbmc suffering a bit too much from "weight loss" it forced upon itself, so the modules that work as expected on Raspbian were failing on Raspbmc:
$ pactl list sources short Assertion 'l' failed at pulsecore/flist.c:168, function pa_flist_pop(). Aborting.Aborted
When I learned that Raspbmc was not going to be developed any longer and that its successor -- OSMC -- will be based on Debian distro that was not butchered to fit on 2 GB SD card, I immediately planned to give that a try :-)
What I found out when I started setting up A2DP on OSMC on my Raspberry Pi 2 is that OSMC is no longer based (as its predecessor was and as Raspbian is) on Debian Wheezy, but that it is based on Debian Jessie. That means bye-bye SysVinit and hello Systemd. And that change of service manager (making all "A2DP on Rasberry Pi" available tutorials obsolete or at least not easily replicable by novice users) is the real reason for this tutorial.
Step 1: Requirements
- Raspberry Pi
- 4GB+ SD card with installed OSMC (Release Candidate or newer)
- Bluetooth v4.0+ USB adapter
- a headphones or speaker system connected to 3.5 mm phones port
- an Internet connection (for package updates)
- either LAN connection for SSH or an USB keyboard
A note regarding the Bluetooth v4.0+ USB adapter:
Even though I've used IOGEAR GBU521, any similar adapter should sufice, but best check the verified/supported hardware list before buying!
Step 2: Log in to a Terminal
Boot the Pi.
1) Variant: Remote terminal (SSH)
If you've a LAN connection to the Pi, the easiest way to go through this tutorial is to use SSH -- they you can copy/paste commands instead of typing them :-)
Find what your Pis IP address is and SSH into it with your favorite telnet client.
2) Variant: Local terminal
In this case, connect your keyboard, go to Power menu in XBMC and choose Exit. XMBC will close in a few seconds, but will restart immediately again. To enter the terminal, make sure you press the ESC key after you've choosen the Exit and while the OSMC screen is still showing. That will stop XBMC from staring again ad you'll have a terminal prompt with login in front of you.
Either way, the default credentials for OSMC are:
Step 3: Install the Necessary Packages
To get the state of repositories up-to-date, first execute:
sudo apt-get update
Optional: if you want, you can upgrade the outdated packages with:
sudo apt-get upgrade
Note: OSMC uses its own apt-get repository (http://apt.osmc.tv) for updating the system, which is a welcome change from Raspbmc, so not only does 'upgrade' upgrades the linux distro and installed 3rd party packages, it also upgrades the OSMC (media center and its packages).
After it finishes, execute this to install the necessary packages:
sudo apt-get install alsa-utils bluez bluez-tools pulseaudio-module-bluetooth python-gobject python-gobject-2
Image courtesy of: Keep Calm Network Ltd.
Step 4: Audio Configuration
Enable and load the sound module:
echo 'snd_bcm2835' | sudo tee -a /etc/modules echo 'snd-bcm2835' | sudo tee -a /etc/modules sudo modprobe snd_bcm2835 snd-bcm2835
Add users to pulse audio groups:
sudo usermod -a -G lp osmc
sudo usermod -a -G pulse-access,audio root sudo adduser osmc pulse-access
Heads-up: from this point forward, the tutorial uses GNU nano as terminal text editor, but you can easily use the one you prefer.
Open the configuration file for the PulseAudio daemon:
sudo nano /etc/pulse/daemon.conf
And find (press Ctrl+W, then type 'float') the line that reads:
resample-method = speex-float-1
and change it so:
; resample-method = speex-float-1 resample-method = trivial
Because we'll be running PulseAudio deamon in system mode, loading additional modules will not be possible once the deamon is started, so we need to configure their inclusion in the PulseAudio startup script for system mode:
sudo nano /etc/pulse/system.pa
and add the following lines (which check for existance and enable various modules):
.ifexists module-bluetooth-policy.so load-module module-bluetooth-policy .endif
.ifexists module-bluetooth-discover.so load-module module-bluetooth-discover .endif
.ifexists module-bluez5-device.so load-module module-bluez5-device .endif
.ifexists module-bluez5-discover.so load-module module-bluez5-discover .endif
We also need to create the service starting script:
sudo nano /etc/systemd/system/pulseaudio.service
and edit it like so:
[Unit] Description=Pulse Audio [Service] Type=simple ExecStart=/usr/bin/pulseaudio --system --disallow-exit --disallow-module-loading --disable-shm --daemonize [Install] WantedBy=multi-user.target
Execute these two commands to scan for new/changed units and to restart the PulseAudio service:
sudo systemctl daemon-reload sudo systemctl enable pulseaudio.service sudo systemctl start pulseaudio.service
All that is left to do for audio is to enable output to a prefered connector (0=auto,1=headphones,2=hdmi):
amixer cset numid=3 1
and, as volume will be controlled by the client, to set the volume level on the server side to 100 percent:
amixer set Master 100% pacmd set-sink-volume 0 65535
Step 5: Bluetooth Configuration
To make sure A2DP audio sinks are allowed, open the config file:
sudo nano /etc/bluetooth/audio.conf
and place these three lines under [General] heading:
[General] Enable=Source,Sink,Media,Socket HFP=true Class=0x20041C
Next, open another config file:
sudo nano /etc/bluetooth/main.conf
and place these lines under [General] heading:
[General] Name = osmc Class = 0x20041C
Next, list the BT adapter config:
sudo hciconfig -a
and note the MAC address (in form of XX:XX:XX:XX:XX:XX). You will need to specify it here:
sudo nano /var/lib/bluetooth/XX:XX:XX:XX:XX:XX/settings
where you should paste these lines:
[General] Discoverable=true Alias=osmc Class=0x20041C
Bring up the BT:
connmanctl enable bluetooth sudo hciconfig hci0 up
and in the BT control shell:
Then, execute the following commands to enable the agent and start the scan:
agent on default-agent discoverable on scan on
That should display a list of visible BT clients (if not, execute 'devices' command). Next, execute the following to pair/trust your client device(s):
pair XX:XX:XX:XX:XX:XX Request confirmation [agent] Confirm passkey 503116 (yes/no): yes trust XX:XX:XX:XX:XX:XX
Note: repeat the pair & trust commands for each device you want to allow to connect.
With this the Bluetooth part of the configuration is done.
Step 6: Fix for Automatic Audio After Reboot
When the past steps in the tutorial are all done, we can immediately see the effect -- the client and the Pi are connected and the client can stream audio via BT.
Woohoo! That's it!...Or, is it?
The problem comes when the Pi is restarted. Then, until someone is logged into console, PulseAudio will not work.
One solution is to enable auto-login into console.
sudo cp /lib/systemd/system/getty@.service /etc/systemd/system/autologin@.service
Next, we symlink that autologin@.service to the getty service for the tty on which we want to autologin, for example for tty1:
sudo mkdir /etc/systemd/system/getty.target.wants sudo ln -s /etc/systemd/system/autologin@.service /firstname.lastname@example.org
Up to now, this is still the same as the usual getty@.service file, but the most important part is to modify the autologin@.service to actually log you in automatically. To do that, you only need to change the ExecStart line to read:
ExecStart=-/sbin/agetty -a osmc %I 38400
That's it. After this you'll briefly see the login prompt when the OSMC boots up, but it will allow PulseAudio to run even without you logged in.
Step 7: Conclusion and Tips
My main goal was to reuse the always-on devices (media centar Raspberry Pi and Android phones/tablets) to stream online subscription music (namely Google Play Music) without needing to have PC turned on or the client device jacked in.
Naturally, the setup can be used to stream all sorts of audio through Pi. For example, gaming on tablet sounds pretty sweet when played on home stereo :)
- What I encountered occasionally on the phone was that sometimes it doesn't automatically reconnect to the Pi and that, when Pi (osmc) is pressed in BT phone settings, it immediately disconnects. The solution for this seems to be to turn BT on the phone off and then back on. After that (BT "reset") the phone again automatically connects to the Pi.
- I was writing down each step I applied while I was investigating how goal in this tutorial can be achieved, but when I started to verify the tutorial (on a clean OSMC install) some weeks later, the version of the OSMC was incremented and I didn't manage to reproduce it exactly step by step, so if you find some parts are off, feel free to suggest improvements in the comments (and I will hopefully update the tutorial).
Principal source of information: ArchLinux Wiki.
Honorable mention: inspired by a tutorial from dantheman_213.