Description

This page contains audio service usage examples. The API description is available at audio service.

Note that there are a few approaches for a2dp (alsa, gstreamer, pulse?), maybe two for sco (alsa, pulse?). Alsa is the simplest and should support the greater variety of audio clients directly.

Basic steps

(these are valid for bluez-utils-3.16 or newer)

Note: you will not need bluetooth-alsa, plugz, btsco or the like for audio to work. They are obsolete.

  1. Make sure the audio service is installed
  2. modify your ~/.asoundrc to contain
    pcm.bluetooth {
       type bluetooth
       device 00:11:22:33:44:55
    }
    
    where 00:11:22:33:44:55 is the Bluetooth address of your headset (use for example hcitool scan to find it)
  3. configure your audio application to use the alsa device "bluetooth". See Supported Players for some examples.
  4. start playing :)

Tips

  • There's a tool called dbus-viewer (apt-get install dbus-viewer; dbus-viewer --system) which is very helpful in using D-Bus interfaces as long as there are no convenient scripts or GUIs available for them. A newer similar tool for GTK+ is called D-Feet.

Known issues

  • You may get choppiness with a2dp. An hcid.conf with "lm accept,master;" and "lp hold,sniff,park;" will be more robust.
  • If you get messages in the kernel log like "sco packet for unknown connection" then you may need to apply a kernel patch (several versions of the fix are circulating around bluez-dev but no one solution seems right)
  • xmms with broadcom based headsets produces choppy sound at times (actually xmms in general seems to have a little bit buggy alsa usage). We recommend using some other player, e.g. audacious.
    • e.g. the Logitech freepulse and Etymotic Research ety8 headphones are broadcom based
  • vlc pause/unpause doesn't work (no sound after unpause)

Alsa Plugin

Configuration

Append this lines to ~/.asoundrc:

pcm.bluetooth {
	type bluetooth
        device "XX:XX:XX:XX:XX:XX" #optional, connects to specific device instead the default one
        profile "auto"             #optional, supported profiles are: auto, hifi and voice 
}

Supported Players

aplay and arecord

arecord -D bluetooth -f S16_LE | aplay -D bluetooth -f S16_LE

gst-launch

gst-launch -v alsasrc device=bluetooth ! audioconvert ! audioresample ! alsasink device=bluetooth sync=false

audacious

options->preferences->Audio->Current Output Plugin->ALSA
Output Plugin Preferences->Device Settings->audio device: "bluetooth"

if you can't see the audio device form there, you can force the bluetooth output by modifying your audacious property file

~/.config/audacious/config. Modify the "pcm_device" value by "pcm_device=bluetooth"

xmms

xmms is known to have some issues, please use its successor audacious instead

options->preferences->Output Plugin->Configure: "bluetooth"

beep-media-player

preferences->Plugins->Output->Select ALSA->Preferences->Audio device: "bluetooth"->Advanced->disable mmap mode

mplayer

mplayer -ao alsa:device=bluetooth

play

play --device=bluetooth file.mp3

amarok

Amarok configuration -> Engine -> Select: "alsa"

then

replace "default" with "bluetooth" in either "mono" or "stereo" field

banshee, rhythmbox and totem

to route the sound to bluetooth:

gconftool -t string -s /system/gstreamer/0.10/default/musicaudiosink "alsasink device=bluetooth"

to route the sound to normal speakers:

gconftool -t string -s /system/gstreamer/0.10/default/musicaudiosink "autoaudiosink"

Kaffeine

Menu Settings -> xine Engine Parameters -> audio -> Expert Options tab
Change "device.alsa_default_device" (mono) and "device.alsa_front_device" (stereo) from "default" to "bluetooth"

GStreamer Plugin

Currently only available for a2dp.

Configuration

It is not necessary to create a virtual device as in alsa, configuration can be change via element properties:

a2dpsink

Element Properties:
  name                : The name of the object
                        flags: readable, writable
                        String. Default: null Current: "a2dpsink0"
  preroll-queue-len   : Number of buffers to queue during preroll
                        flags: readable, writable
                        Unsigned Integer. Range: 0 - 4294967295 Default: 0 Current: 0
  sync                : Sync on the clock
                        flags: readable, writable
                        Boolean. Default: true Current: true
  max-lateness        : Maximum number of nanoseconds that a buffer can be late before it is dropped (-1 unlimited)
                        flags: readable, writable
                        Integer64. Range: -1 - 9223372036854775807 Default: -1 Current: -1
  qos                 : Generate Quality-of-Service events upstream
                        flags: readable, writable
                        Boolean. Default: false Current: false
  device              : Bluetooth remote device address
                        flags: readable, writable
                        String. Default: null Current: null

sbcenc

Element Properties:
  name                : The name of the object
                        flags: readable, writable
                        String. Default: null Current: "sbcenc0"
  mode                : Encoding mode
                        flags: readable, writable
                        Enum "GstSbcMode" Current: 0, "auto"
                           (0): auto             - Auto
                           (1): mono             - Mono
                           (2): dual             - Dual Channel
                           (3): stereo           - Stereo
                           (4): joint            - Joint Stereo
  allocation          : Allocation mode
                        flags: readable, writable
                        Enum "GstSbcAllocation" Current: 0, "auto"
                           (0): auto             - Auto
                           (1): loudness         - Loudness
                           (2): snr              - SNR
  blocks              : Blocks
                        flags: readable, writable
                        Integer. Range: 0 - 2147483647 Default: 0 Current: 0
  subbands            : Sub Bands
                        flags: readable, writable
                        Integer. Range: 0 - 2147483647 Default: 0 Current: 0

Supported Players

gst-launch

gst-launch -v ... ! decodebin ! audioconvert ! audioresample ! sbcenc ! a2dpsink device=XX:XX:XX:XX:XX:XX

banshee, rhythmbox and totem

to route the sound to bluetooth:

gconftool -t string -s /system/gstreamer/0.10/default/musicaudiosink "sbcenc ! a2dpsink device=XX:XX:XX:XX:XX:XX"

to route the sound to normal speakers:

gconftool -t string -s /system/gstreamer/0.10/default/musicaudiosink "autoaudiosink"

Trying pulse

This is unproven but might not be far off.(it´s work)

Make audio service autostart. (Autostart=true in /etc/bluetooth/audio.service)

.asoundrc:

pcm.headset {
       type bluetooth
       device "XX:XX:XX:XX:XX:XX"
       profile "voice"
}

Manually run:

pactl load-module module-alsa-sink device=headset
pactl load-module module-alsa-source device=headset

Then use pavucontrol to make the headset sink/source the default

Advanced examples for programatically setting up audio devices

The examples from here to the end of the page are only for programmers who need to automate device creation, service startup, etc. Stop reading now if you're just trying to get the basics working.

Service Activation

When a client wants to start the audio service or discover the audio service bus "id", the ActivateService method should be called.

import dbus
bus = dbus.SystemBus()
bmgr = dbus.Interface(bus.get_object('org.bluez', '/org/bluez'), 'org.bluez.Manager')
bus_id = bmgr.ActivateService('audio')

# All serial service messages should be sent to this address
print bus_id

Service activation from command line:

$dbus-send --system --type=method_call --print-reply --dest=org.bluez \
/org/bluez org.bluez.Manager.ActivateService string:audio

A2DP

A2DP (Advanced Audio Distribution Profile) is intended for high quality stereo audio applications.

For A2DP there is no need to specifically request a "playing" state. The bluetooth alsa plugin will automatically do this when some application tries to use it. If no device is connected, the default device will be connected to, otherwise the first found connected device will be used.

python

import dbus
bus = dbus.SystemBus()
manager = dbus.Interface(bus.get_object('org.bluez', '/org/bluez'), 'org.bluez.Manager')
bus_id = manager.ActivateService('audio')
audio = dbus.Interface(bus.get_object(bus_id, '/org/bluez/audio'), 'org.bluez.audio.Manager')

path = audio.CreateDevice('00:11:22:33:44:55')
#audio.ChangeDefaultDevice(path) #change the device to be used by default
sink = dbus.Interface (bus.get_object(bus_id, path), 'org.bluez.audio.Sink')
sink.Connect()

Command line

The ":X.Y" in the following examples is the unique bus name of the audio service. You get it in the reply to the ActivateService method call:

$dbus-send --system --print-reply --dest=org.bluez /org/bluez org.bluez.Manager.ActivateService string:audio

* CreateDevice:

$dbus-send --system --type=method_call --print-reply --dest=":X.Y" \
/org/bluez/audio org.bluez.audio.Manager.CreateDevice string:00:11:22:33:44:55

* Connect (replace device_object_path with return value from last call):

$dbus-send --system --type=method_call --print-reply --dest=":X.Y" \
"device_object_path" org.bluez.audio.Sink.Connect

Headset Profile

The Headset Profile is intended for two-way low-latency audio applications such as VoIP.

python

import dbus
bus = dbus.SystemBus()
manager = dbus.Interface(bus.get_object('org.bluez', '/org/bluez'), 'org.bluez.Manager')
bus_id = manager.ActivateService('audio')
audio = dbus.Interface(bus.get_object(bus_id, '/org/bluez/audio'), 'org.bluez.audio.Manager')

path = audio.CreateHeadset('00:11:22:33:44:55')
#audio.ChangeDefaultHeadset(path) #change the device to be used by default
headset = dbus.Interface (bus.get_object(bus_id, path), 'org.bluez.audio.Headset')
#Connect and Play are not required in PCM mode
headset.Connect()
headset.Play()

Command line

* CreateHeadset:

$dbus-send --system --type=method_call --print-reply --dest=":X.Y" \
/org/bluez/audio org.bluez.audio.Manager.CreateHeadset string:00:11:22:33:44:55

* Connect:

$dbus-send --system --type=method_call --print-reply --dest=":X.Y" \
"device_object_path" org.bluez.audio.Headset.Connect

* Play:

$dbus-send --system --type=method_call --print-reply --dest=":X.Y" \
"device_object_path" org.bluez.audio.Headset.Play