Logo

Home About Community Download Documentation Planet


Bluetooth

PulseAudio depends on BlueZ for all Bluetooth functionality, and additionally oFono is required for HFP support.

Profiles

The bluetooth standard specifies three audio profiles. Try not to confuse these with the "card profile" concept in PulseAudio. A bluetooth device shows up in PulseAudio as a card, and the card will have some set of profiles depending on what bluetooth profiles the device supports, but the "bluetooth profile" <-> "card profile" mapping is not one-to-one. The three bluetooth profiles are:

  • A2DP (Advanced Audio Distribution Profile) - high-quality audio playback, appropriate for e.g. listening to music.
  • HSP (HeadSet Profile) - phone-quality audio playback and recording, appropriate for phone calls.
  • HFP (Hands-Free Profile) - same as HSP, but with additional functionality for managing phone calls.

Each of the profiles are further divided into two roles:

  • A2DP:
    • Source role - the device that sends audio.
    • Sink role - the device that receives audio.
  • HSP:
    • Audio Gateway role - the device that the headset is connected to. The HSP profile is typically used in phone calls, and this is the device that is connected to the cellular network (for cellular phone calls) or to the internet (for VoIP calls). Typically a cellular phone or a PC.
    • Headset role - the headset, obviously. This is where the speakers and microphone are.
  • HFP:
    • Audio Gateway role - the device that the hands-free device is connected to. The HFP profile is typically used for cellular phone calls, and this is the device that is connected to the cellular network. Typically a cellular phone.
    • Hands-Free Unit role - the device with the speakers and microphone.

A2DP

PulseAudio supports A2DP in both source and sink roles. When PulseAudio acts in the source role, a sink is created where applications can play to. When PulseAudio acts in the sink role, a source is created where applications can record from.

A2DP works generally without a hassle. With PulseAudio versions older than 12.0 the audio can get badly out of sync when watching videos, however.

HSP/HFP

PulseAudio supports both HSP roles, and with oFono also both HFP roles. In the default configuration, if oFono isn't running, only HSP is enabled. If oFono is running, the audio gateway role of HSP is enabled plus both HFP roles. The headset role of HSP is disabled, because otherwise PulseAudio and oFono would conflict as both would try to listen for new connections from audio gateway devices.

It's possible to force PulseAudio to only enable HSP or HFP with the "headset" option of module-bluetooth-discover (configured in /etc/pulse/default.pa). By default the option is set to "auto", but if it's set to "native", then only HSP is enabled, and if the option is set to "ofono", then only HFP is enabled.

When connected to a HSP or HFP device, the bluetooth card in PulseAudio will have the "Headset Head Unit (HSP/HFP)" and/or "Headset Audio Gateway (HSP/HFP)" profiles available. When those profiles are activated, a sink and a source are created where applications can play and record audio.

When PulseAudio is acting as a headset or a hands-free unit, it's rarely necessary to manually change the card profile. When the audio gateway initiates audio streaming, module-bluetooth-policy will automatically change to the appropriate profile. module-bluetooth-policy will also load module-loopback instances to loop the audio from bluetooth to the local speakers and microphone.

Being able to use HFP headsets without oFono would be nice, and there are patches for implementing HFP support in PulseAudio here. Pali Rohár is pursuing a different approach, he wants to create a new "hsphfpd" daemon that handles the communication with the headset (including some non-audio bits that don't really fit in PulseAudio) and provides an API for PulseAudio (or some other sound server) for passing audio to and from the headset. You can read about hsphfpd here: https://lists.freedesktop.org/archives/pulseaudio-discuss/2019-December/031506.html

Supported codecs

The bluetooth standard allows using many different codecs with A2DP, and there are some options for HFP too. Currently PulseAudio supports only SBC with A2DP and CVSD with HSP and HFP. (Note that the CVSD encoding is done by the bluetooth adapter hardware, PulseAudio sends plain PCM audio to the hardware when using HSP or HFP.) Support for more codecs is being worked on.

Using bluetooth when running PulseAudio in the system mode

For some reason the bluetooth modules aren't included in /etc/pulse/system.pa by default, so if you want to use bluetooth, add this to /etc/pulse/system.pa:

load-module module-bluetooth-discover
load-module module-bluetooth-policy

It's generally recommended to disallow module loading when using PulseAudio in the system mode, because if the system administrator doesn't trust the users, allowing users to load modules may not be a good idea. However, bluetooth doesn't work if module loading is disallowed (this is a bug that somebody should fix), so if it's more important to have bluetooth support than to prevent users from loading (and unloading) modules, make sure you don't disallow module loading (by default module loading is allowed).

The D-Bus access policy doesn't allow pulseaudio to communicate with bluetoothd by default when running pulseaudio in the system mode. Add the user "pulse" to group "bluetooth" to grant the permission:

sudo useradd -g bluetooth pulse

The D-Bus access policy also doesn't allow pulseaudio to communicate with ofonod by default when running pulseaudio in the system mode. To grant the permission, add this to /etc/dbus-1/system.d/ofono.conf:

  <policy user="pulse">
    <allow send_destination="org.ofono"/>
  </policy>

Using HFP with oFono

Currently HFP support in pulseaudio is only available through oFono. The additional dependency makes device setup somewhat difficult because oFono is designed for mobile telephony and not for audio applications.

Within oFono, a mobile telephony device is represented as a modem. oFono will only work if there is at least one enabled modem in your system. To simplify modem control, you should download the source code of oFono (git://git.kernel.org/pub/scm/network/ofono/ofono.git), which contains a "test" directory with several useful python scripts. A list of available modems can be obtained by running

test/list-modems

A modem can be enabled with

test/enable-modem /modem_path

and disabled again with

test/disable-modem /modem_path

Headset Setup

The necessity to provide a modem to oFono makes the headset setup rather cumbersome. If you do not have a GSM/UMTS modem connected to your system (like in most desktop environments), you need a modem emulator. Unfortunately oFono does not allow to use a mobile (hfp modem, see below) as a modem to support headsets.

The best emulator choice is "phonesim" because there is a version that is maintained together with ofono. Most distributions contain a package ofono-phonesim or similar while the git version can be found at git://git.kernel.org/pub/scm/network/ofono/phonesim.git.

To set up phonesim, first create or edit the file phonesim.conf in /etc/ofono. It should contain the following lines:

[phonesim]
Driver=phonesim
Address=127.0.0.1
Port=12345

Restart oFono and check with list-modems if the phonesim modem was found. Start phonesim with

phonesim -p 12345 /usr/share/phonesim/default.xml&

The paths to phonesim.conf and default.xml might be different if you compiled ofono and/or phonesim from source. Now you can enable the modem either by using the enable-modem script or by issuing the following command:

dbus-send --print-reply --system --dest=org.ofono /phonesim org.ofono.Modem.SetProperty string:"Powered" variant:boolean:"true"

list-modems should show that the modem is powered and online. If you want to play with the modem emulator, you can add the -gui option to the phonesim command. Then a GUI will pop up as soon as you enable the modem.

Once the modem is set up properly, you can connect your headset and the "Headset Head Unit (HSP/HFP)" profile should be available in pulseaudio.

Mobile phone Setup

After connecting your mobile to the system, the phone should already be available without further configuration. Use list-modems to find it (there will be a modem with Type=hfp). If it is not online (Online=1 and Powered=1), you need to enable it first by running enable-modem with the appropriate path. While the device is enabled, you can test that audio works by calling someone using the phone. You can also try to command the phone to make the call from your computer with this command:

test/dial-number /hfp_path 12345

Similar to HSP, module-bluetooth-policy will load module-loopback instances to loop the audio from bluetooth to the local speakers and microphone. To hangup all ongoing calls, this command can be used:

test/hangup-all /hfp_path

History of bluetooth features in PulseAudio

13.0

  • Removed BlueZ 4 support.
  • Bluetooth card profile choices aren't persistent any more by default.

More details in the release notes.

12.0

  • More accurate latency reporting with A2DP, meaning improved A/V sync.
  • Recognize HSP support in devices that advertise their HSP capability using a different identifier than what PulseAudio has been using before.
  • Use A2DP by default with headsets rather than HSP.

More details in the release notes.

11.1

  • The default HSP MTU configuration was reverted to always use 48 bytes. Asking the kernel about the MTU size is still possible by passing "autodetect_mtu=yes" to module-bluetooth-discover.

11.0

  • HSP headset role implemented, which means that PulseAudio can act as a headset.
  • HFP audio gateway role implemented (via oFono), which means that PulseAudio can use bluetooth headsets via HFP instead of HSP (good especially for headsets that only support HFP).
  • The HSP audio gateway and HFP headset roles can be enabled simultaneously.
  • Bluetooth device priority got bumped higher than internal sound cards, which means that it's not any more necessary to set the bluetooth device as the default sink manually when connecting it.
  • The "auto_switch" option of module-bluetooth-policy got a new mode: mode "2" can be used to enable automatic profile switching from A2DP to HSP when a recording stream appears without any role set.
  • HSP MTU configuration changed from always using 48 bytes to asking the kernel for an appropriate packet size.

More details in the release notes.

10.0

  • module-bluetooth-policy got a new option: "auto_switch" can be used to enable automatic profile switches from A2DP to HSP when a recording stream appears with role "phone".
  • Separate volumes for A2DP and HSP.

More details in the release notes.

6.0

  • HSP audio gateway role implemented, so HSP headsets can again be used with PulseAudio.
  • HFP hands-free unit role implemented (via oFono), so PulseAudio can act as a headset or other hands-free device.

More details in the release notes.

5.0

  • Initial BlueZ 5 support added. Only A2DP is supported. (BlueZ 4 support is retained, though, so systems that still use BlueZ 4 keep working as before.)

More details in the release notes.

Troubleshooting

Check first that your version of PulseAudio supports the feature you're trying to use. Refer to the history section above to see when a particular bluetooth feature was added to PulseAudio.

HSP problem: audio is silent or skipping

The packet size (a.k.a. MTU, "maximum transmission unit") that PulseAudio uses with the bluetooth HSP profile might be bad. By default PulseAudio configures the packet size to 48 bytes, but the adapter might require something else. Try passing "autodetect_mtu=yes" to module-bluetooth-discover in /etc/pulse/default.pa. That will make PulseAudio ask the kernel what the correct packet size is. The option is not enabled by default, because the kernel gives bad advice too often, while the default size of 48 bytes works better.

HSP problem: the bluetooth sink and source are created, but no audio is being transmitted

This is often not PulseAudio's fault, and not specific to any particular headset. Instead, the problem tends to be in the bluetooth adapter. The bluetooth adapter may be missing firmware, or the adapter's SCO audio routing may be wrong (SCO is the audio protocol used by HSP and HFP, and SCO audio needs to be routed via the HCI interface in order to work with PulseAudio). Bug 97064 has discussion about this, and solutions for a couple of adapters. If you have different hardware and are suffering from this problem AND you find a working solution, please comment on the bug.

Here are the adapters with known solutions (these adapters/chipsets are probably used in multiple products under different brands, so use lsusb/lspci/etc to figure out the chipset of your bluetooth adapter):

TI WL1837: http://www.ti.com/product/WL1837MOD

This adapter may have wrong SCO audio routing. Use this command (as root) to route the SCO audio through HCI:

hcitool cmd 0x3F 0x0210 0x01 120 511 0xFF

Broadcom BCM20702

This adapter requires proprietary firmware. Installation instructions: http://plugable.com/2014/06/23/plugable-usb-bluetooth-adapter-solving-hfphsp-profile-issues-on-linux/

Broadcom BCM2835, BCM4354, and BCM43438

(BCM2835 and BCM43438 are notable for being used in Raspberry Pi Zero W and Raspberry Pi 3, respectively.) These adapters may have wrong SCO audio routing. Use this command (as root) to fix the routing:

hcitool cmd 0x3F 0x01C 0x01 0x02 0x00 0x01 0x01

Current Raspbian versions do this automatically: https://github.com/RPi-Distro/pi-bluetooth/commit/0dffacec9452b975ed7c17b530e4f230ea17b727

BCM2835 doesn't work properly even with the fixed routing. There's audio, but it's very bad.

HSP problem: "Protocol not supported"

There was some regression in the kernel that was introduced in 3.12 and fixed in 3.18 that caused failure when trying to activate HSP with some headsets. This problem can be identified by this error message in pulseaudio log:

backend-native.c: connect(): Protocol not supported

Getting a log from bluetoothd

Sometimes inspecting the bluetoothd log is helpful. Here are instructions for getting the log:

First, stop bluetoothd and preferably also prevent it from getting started automatically. Here's how to do that with systemd:

sudo systemctl disable bluetooth.service
sudo systemctl stop bluetooth.service

Then, run bluetoothd in a terminal with verbose logging:

sudo /usr/lib/bluetooth/bluetoothd -n -d

Now you can read the log, or copy it from the terminal for later reading.

When you want to stop bluetoothd, press ctrl-c. When you're done, you probably want to re-enable the bluetooth service. Here's how to do that with systemd:

sudo systemctl enable bluetooth.service
sudo systemctl start bluetooth.service

Sometimes it's useful to have both bluetoothd and pulseaudio logs interleaved, because that makes it easier to match events in the bluetoothd log with events in the pulseaudio log. To do this, add "&" to the end of the bluetoothd command, like this:

sudo /usr/lib/bluetooth/bluetoothd -n -d &

Now bluetoothd will run as a background process, but it will still print log messages to the terminal. You can now start pulseaudio in the same terminal. TODO: Write instructions for getting the log from pulseaudio.

When bluetoothd is running in the background, ctrl-c won't stop it, so use this command instead:

sudo killall bluetoothd

Specifications

Here are some links to relevant specifications: