-
Notifications
You must be signed in to change notification settings - Fork 189
| ARCHIVE: Using the BlueALSA ALSA pcm plugin
This article documents the use of the BlueALSA PCM plugin for BlueALSA release 3.1.0 and earlier. Newer releases have additional features for the plugin, and also include documentation as a manual page (https://github.com/Arkq/bluez-alsa/blob/master/doc/bluealsa-plugins.7.rst).
The BlueALSA ALSA PCM plugin communicates directly with the bluealsa
service.
It is a raw PCM communication without any conversions. It can be used to define
ALSA PCMs in your own configuration file (e.g. ~/.asoundrc), or you can use the
pre-defined configuration that is included in the bluez-alsa project. This
wiki article gives an overview of both approaches.
Possibly the most common use-case of BlueALSA is to connect one bluetooth A2DP
speaker (or headphones) and send audio to it from an ALSA application. A
default BlueALSA installation allows you to do this by simply using an ALSA
device called bluealsa
. For example:
aplay -D bluealsa music.wav
or
vlc --alsa-audio-device=bluealsa
Similarly, if you have one 'phone connected with A2DP profile, you can record from it with:
arecord -D bluealsa -f s16_le -c 2 -r 48000 recording.wav
The need to specify an audio format is a requirement of arecord
, otherwise it
will convert the stream to mono, 8-bit samples at 8000Hz.
To use the last connected HFP/HSP device, you will need
aplay -D bluealsa:PROFILE=sco music.wav
and similarly for capture.
In the above scenarios the PCM device bluealsa
refers to the last connected
bluetooth A2DP device. It uses the pre-defined bluealsa
PCM, and takes
advantage of the default behavior which is to use the most recently connected
device. This default was introduced in bluez-alsa release 3.1.0.
If you have more than one device connected, and the one you want to use is not
the last one connected (or you are using an older release of bluez-alsa), then
you need to specify the device, which you can do by either defining your own
PCM or by passing parameters to the predefined bluealsa
PCM. See the
following sections for details.
If you need to refer to specific bluetooth devices rather than just the most
recently connected, or if your version of bluez-alsa is older than 3.1.0, then
you can define your own ALSA PCM. To do this, create an ALSA
configuration node defining a pcm with type bluealsa
. See below for a
predefined parameterized pcm, also called "bluealsa", that can avoid the need
for writing ALSA configurations.
The configuration node has the following fields:
pcm.name {
type bluealsa # Bluetooth PCM
device STR # Device address in format XX:XX:XX:XX:XX:XX
profile STR # Profile type (a2dp or sco)
[delay INT] # Extra delay (in frames) to be reported to the application (default 0)
[service STR] # D-Bus name of bluealsa service (default org.bluealsa)
}
The device
and profile
fields must be specified so that the plugin can
select the correct bluetooth transport; delay
and service
are optional.
The value for device
must be an actual bluetooth MAC address, device names
and aliases are not valid. The "special" address 00:00:00:00:00:00
can be
used here to select the most recently connected device.
Use profile "a2dp"
for A2DP streams, and profile "sco"
for HSP or HFP
streams.
The delay
option specifies a number of frames to be added to the delay value
reported by the plugin to the application. It is sometimes needed when trying
to synchronize the sound, for example with a video or another sound system.
This is because not all bluetooth audio devices accurately report the delay
(latency) from the time a frame is sent to the bluetooth controller to the time
it is actually played out by the loudspeaker (or vice-versa for capture streams
from microphones). The user must determine this delay by experience. Most
bluetooth devices do however report a delay that is acceptable in most
applications, so normally this option can be omitted - in that case no
adjustment will be applied.
The service
option specifies the D-Bus name used by the bluealsa service. It
defaults to "org.bluealsa", which is the default used by the server, so only
needs to be specified in special cases.
A simple, typical, example is to add the following to your ~/.asoundrc
file
(where 00:11:22:33:44:55 is the example bluetooth device address and
bt-headphones
is the name you have chosen to use for the pcm)
pcm.bt-headphones {
type plug
slave.pcm {
type bluealsa
device "00:11:22:33:44:55"
profile "a2dp"
}
}
With that definition in your ~/.asoundrc
file, you can then play audio to the
headphones by sending to device bt-headphones
; for example:
aplay -D bt-headphones music.wav
A note on choosing a name for your pcm definition: The name
pcm.bluealsa
is pre-defined by the bluez-alsa installation (see next section), so should not be used as a name for your own pcm devices as doing so will most likely have unexpected or undesirable results.
As a convenience for users, the bluez-alsa project also installs a global ALSA configuration file which defines a parameterized pcm device named "bluealsa".
pcm.bluealsa
is of type plug, so that it automatically converts the audio
stream from/to the format required by the bluetooth device. If we compare the
bluealsa
plugin type with the hw
plugin type, then pcm.bluealsa
is
analogous to pcm.plughw
. You can see the bluealsa ALSA configuration file
here:
20-bluealsa.conf
The pcm.bluealsa
arguments map to the bluealsa plugin parameters as follows:
plugin parameter | pcm.bluealsa argument name | default |
---|---|---|
device | DEV | defaults.bluealsa.device |
profile | PROFILE | defaults.bluealsa.profile |
delay | DELAY | defaults.bluealsa.delay |
service | SRV | defaults.bluealsa.service |
You can refer to a bluealsa pcm without needing to create a configuration in
~/.asoundrc
with:
bluealsa:DEV=00:11:22:33:44:55,PROFILE=a2dp,DELAY=0,SRV=org.bluealsa
The pre-defined configuration also provides values for all the defaults in the above table, so the above example could more simply be written as
bluealsa:DEV=00:11:22:33:44:55
The default value for device is "00:00:00:00:00:00" which selects the most recently connected device.
ALSA permits arguments to be given as positional parameters as an alternative to explicitly naming them. When using positional parameters it is important that the values are given in the correct sequence - DEV,PROFILE,DELAY,SRV.
Note - before bluez-alsa release 3.0.0, the sequence of the arguments was SRV,DEV,PROFILE,DELAY so the following positional parameter examples will not work with releases 2.1.0 and earlier.
Using positional parameters, we could also write our example as:
bluealsa:00:11:22:33:44:55,a2dp,0,org.bluealsa
or, taking advantage of the default definitions again:
bluealsa:00:11:22:33:44:55
So, without needing to create a ~/asoundrc
file at all, we can send audio to
the same headphones as in the example above with:
aplay -D bluealsa:00:11:22:33:44:55 music.wav
The defaults can be overridden by defining the ones you want to change in your
own configuration (e.g in ~/.asoundrc.conf
) for example:
defaults.bluealsa.device "00:11:22:33:44:55"
defaults.bluealsa.profile "sco"
defaults.bluealsa.delay 50
defaults.bluealsa.service "org.bluealsa"
Applications that follow ALSA guidelines will obtain the list of defined PCMs by using the alsa-lib "namehints" API. To make bluealsa PCMs visible via that API it is necessary to add a "hint" section to the ALSA configuration. If you have defined a new PCM, then the hint goes into the PCM configuration entry as follows:
pcm.bt-headphones {
type plug
slave.pcm {
type bluealsa
device "00:11:22:33:44:55"
profile "a2dp"
}
hint {
show on
description "My Bluetooth headphones"
}
}
If you are using the pre-defined bluealsa PCM, then you will need to create a "namehint" entry in your ~/.asoundrc file like this:
namehint.pcm {
mybluealsadevice "bluealsa:DEV=00:11:22:33:44:55,PROFILE=a2dp|DESCMy Bluetooth headphones"
}
Now using aplay -L
will include the following in its output:
# aplay -L
bt-headphones
My Bluetooth headphones
#
With that hint in place, the pcm will be listed as both a Capture and Playback
device. So arecord -L
will also list it. That is generally OK for HFP/HSP
devices, but an A2DP device most often offers only Capture (e.g. a mobile phone)
or only Playback (e.g. a bluetooth speaker). It is possible to use the hint
description to limit the listing to only one direction using an undocumented
syntax of ALSA config files.
If the hint.description value ends with |IOIDInput
the pcm will only show in
listings of Capture devices; if it ends with |IOIDOutput
the pcm will only
show in listings of Playback devices.
So we can modify our example above to:
pcm.bt-headphones {
type plug
slave.pcm {
type bluealsa
device "00:11:22:33:44:55"
profile "a2dp"
}
hint {
show on
description "My Bluetooth headphones|IOIDOutput"
}
}
or
namehint.pcm {
mybluealsadevice "bluealsa:DEV=00:11:22:33:44:55,PROFILE=a2dp|DESCMy Bluetooth headphones|IOIDOutput"
}
Now the aplay -L
output will be exactly the same as before, but arecord -L
will not include bt-headphones in its output.
When using the namehint.pcm
method, the key (mybluealsadevice
in the above
example) must be unique but otherwise is not used. The first part of the value
string, up to the pipe |
symbol, is the string that is to be passed to ALSA
applications to identify the PCM (eg with aplay -D ...
). The next section,
after the tag |DESC
, is the description that will be presented to the user.
The optional |IOID
section is as described above.