This post will show you how to connect a Bluetooth headset (microphone/speakers) to your Raspberry Pi, it is a sum up of several weeks I’ve spent trying to find a stable solution.
I took time to mention relevant and exhaustive information, so you don’t need to go through all Google results and workarounds that I already read and tested with no success.
If you are here for curiosity, know that the post is quite long, so make yourself comfortable.
Let’s start first with some important information:
- Raspbian uses BlueZ as Bluetooth stack.
- BlueZ deals with pure Bluetooth tasks (pairing/connection/…)
- So, BlueZ needs additional SW components for audio management
- First Linux audio manager that comes to mind is ALSA
- But, BlueZ (>= v5.0) doesn’t support ALSA anymore
- Instead, BlueZ is now using PulseAudio (>= 5.0)
- And, PulseAudio still uses ALSA
Before: BlueZ → ALSA
Now: BlueZ → PulseAudio → ALSA
Q: What does this mean in command-line?
All BlueZ tutorials and tips where you see ALSA commands (aplay, arecord,…) are now useless.
That’s not all the story:
- PulseAudio (5.0) supported only A2DP profile
- Later, it added also a native support of HSP profile (>=v6.0)
- And for HFP, you have to use another module: oFono
A2DP: BlueZ → PulseAudio (5+) → ALSA
HSP: BlueZ → PulseAudio (6+) → ALSA
HFP: BlueZ → oFono → PulseAudio (6+) → ALSA
For those who don’t know the difference between A2DP/HSP/HFP:
A2DP, Advanced Audio Distribution Profile, for high audio quality, as normal speakers.
E.g. Music streaming
HSP, Headset Profile, the device exchanges in/out audio and some basic AT commands.
E.g. VoIP call
HFP, Hands-Free Profile, the device acts as a phone, so it exchanges audio in/out and telephony commands.
E.g. Hands-Free mode in car
I’ll do it in that incremental order, A2DP, then HSP, and last HFP.
After this long synopsis, let’s put the pieces together.
Step 0: Start with a clean base
I recommend starting with a fresh Raspbian Jessie, in order to avoid any existing configuration files, the need to purge packages, …etc.
sudo apt-get update
sudo apt-get upgrade
sudo apt-get autoremove
Check the versions of packages:
dpkg -l pulseaudio
WARNING: Raspbian repository is still using PulseAudio 5
dpkg -l bluez
WARNING: Raspbian repository is now using Bluez 5
These small details can save you lot of time.
Raspbian Jessie out-of-box supports only A2DP with PulseAudio.
Bluez/PulseAudio link is done by the module pulseaudio-module-bluetooth (apt-get it if needed)
sudo apt-get install pulseaudio-module-bluetooth
At this line we have everything to set up A2DP profile connection.
Step 1: Connect the Bluetooth headset (A2DP)
Most of the time GUI Bluetooth tools will do it, but regarding all the core changes I mentioned above for each layer, I personally don’t advice you to use anyone , I tested Blueman, BlueDevil… not only it will not work, but you will not get any information or logs about the errors.
So I will show you how to do it using bluetoothctl (part of BlueZ)
Tip: Use dedicated console for Bluetooth and keep it open.
Turn on Bluetooth controller:
Start the agent:
Request default agent:
Turn on the headset, for mine I press and hold till I see the white blinking LED.
Start the scan:
After some seconds, you will see the headset name and MAC address
If, at this stage, the headset is still connected, you are very lucky.
If the headset is disconnected right after connection, this is the “normal problem”.
Q: How to know that the headset is disconnected:
Mine emits 2 short beeps. You can also see it in the console:
[CHG] Device xx:xx:xx:xx:xx:xx Connected: no
Check current processes running PA instances
ps aux | grep pulseaudio
pi 924 0.0 0.0 1912 92 ? S 09:35 0:00 /bin/sh /usr/bin/start-pulseaudio-x11
pi 27871 0.0 0.1 4280 1848 pts/0 S+ 11:02 0:00 grep –color=auto pulseaudio
Great, the problem is that no PulseAudio daemon is running, so start one:
(In other cases, the problem can be the opposite, you will find that PulseAudio was started and monopolized by other services. I’ll talk about this later at the end of the post)
Now try again to connect the headset, it should work this time.
Let’s go back to PulseAudio, display current sound cards.
You’ll find two, the built-in one of Raspberry Pi, and the headset one:
Two things to know about PulseAudio:
- Sinks: The audio outputs.
- Sources: The audio inputs.
To see them:
We want that the headset becomes default sink:
pacmd set-default-sink bluez_sink.xx_xx_xx_xx_xx_xx
Download and play a sound, you will hear it from the headphone!
wget http://youness.net/wp-content/uploads/2016/08/h2g2.ogg -P /tmp/
“In the beginning, the Universe was created. This made a lot of people very angry, and has been widely regarded as a bad move.”
– The Hitchhiker’s Guide to the Galaxy
Step 2 (Ongoing): Connect the Bluetooth headset (HSP)
As said before, HSP profile is supported with PulseAudio 6 and newer.
The only solution that I see here is to build PulseAudio from Git sources.
I’m currently trying to build PulseAudio by following official instructions here:
As soon as I do it properly, I’ll post it.
If you did it, please share your steps 🙂
I’m able to build PulseAudio from sources with some limitations, see below instructions:
FYI, I tried Arch Linux ARM, don’t waste your time, Bluetooth support is NOK too..
I choose to build the version 6 to avoid unwanted new features that may need extra work and dependencies.
This method was done with the latest Raspbian Jessie Lite (2016-09-23). This version comes without pre-installed PulseAudio, but if you are using the default Raspbian image or the one installed with NOOBS, purge it:
sudo apt-get purge pulseaudio
Start as usual by updating/upgrading the system:
sudo apt-get update
sudo apt-get upgrade
Download the sources from Freedesktop.org:
Unzip and go to the directory:
tar xvf pulseaudio-6.0.tar.xz
Run bootstrap script:
I will sum up here all errors I encountered (in case people search them by copy/paste):
./bootstrap.sh: line 46: intltoolize: command not found
configure: error: Unable to find libltdl version 2. Makes sure you have libtool 2.4 or later installed.
configure: error: *** sys/capability.h not found. Use --without-caps to disable capabilities support
No package 'json-c' found
No package 'sndfile' found
So install all above libraries:
sudo apt-get install intltool libtool libcap-dev libjson0-dev libsndfile1-dev
The script should now ends correctly, and in the command line you can see a table of the configuration done, with enabled/disabled parts. On my side: udev, bluez5, ofono, native-headset, alsa, X11, systemd, … were not enabled, so I installed additional libraries:
sudo apt-get install libudev-dev libsbc-dev libbluetooth-dev libx11-xcb-dev libasound2-dev libsystemd-dev libsamplerate0-dev
Re-do the ./ bootstrap, now missing parts are enabled.
Then, make and install PA6 (this will take some time, take a coffee).
sudo make install
The last command to avoid some errors of shared libs not found.
After this you can start PA daemon:
Check if it is running:
ps aux | grep pulse
Start another command line window and connect your headset like explained for A2DP before.
Go back to the first command line and window check existing audio cards:
Your headset should be here as second card (bluez_card.xx_xx_xx_xx_xx_xx)
You can see all information, including supported profiles (a2dp_sink, headset_head_unit)
You can see also that now your headset has a source (microphone)
One annoying bug is that pulseaudio daemon will be terminated some seconds after connecting the headset, to avoid this, change the daemon configuration:
sudo nano /etc/pulse/daemon.config
Uncomment (remove the ; in) the line and put negative value (-1):
exit-idle-time = -1
Ctrl+X, y, Enter.
Start again Pulseaudio daemon.
At this step, I can listen to audio with A2DP profile, meaning Pulse Audio is well installed.
However, when I switch to HSP, I hear nothing, here I’m still searching for the rootcause.
If you find the solution before me, please post it.
~To be completed~
Step 3 (Not yet started): Connect the Bluetooth headset (HFP)
To be done after step 2.
Good news is that oFono will be compatible.
sudo apt-get install ofono
dpkg -l ofono
~To be completed~
Step 4 (Not yet): Create autorun script
It will be very useful to create a script that make all above things, to be done.
~To be completed~
- I didn’t edit any configuration file, like default.pa of PulseAudio…etc.
- I didn’t enable any module, but maybe you will have to, if they are not auto-loaded by PulseAudio.
- I didn’t stop any PulseAudio instance, but maybe depending on your distribution, you will have to
pulseaudio --start(I saw a problem with GDM), and sometimes disable the autospawn:yes that creates PulseAudio daemon if no one is started.
- This tutorial will work for many other Linux distributions that have the same Bluetooth issue.
- Raspberry Pi 3
- Phillips SHB5600
If you have any question or remark, feel free to comment.
Audio sound from :http://www.moviesoundclips.net/sound.php?id=96