677 lines
27 KiB
ReStructuredText
677 lines
27 KiB
ReStructuredText
.. SPDX-FileCopyrightText: 2021-2025 BlueALSA developers
|
|
.. SPDX-License-Identifier: MIT
|
|
|
|
================
|
|
bluealsa-plugins
|
|
================
|
|
|
|
----------------------------
|
|
Bluetooth Audio ALSA Plugins
|
|
----------------------------
|
|
|
|
:Date: December 2025
|
|
:Manual section: 7
|
|
:Manual group: Miscellaneous
|
|
:Version: $VERSION$
|
|
|
|
DESCRIPTION
|
|
===========
|
|
|
|
BlueALSA permits applications to access Bluetooth audio devices using the ALSA
|
|
alsa-lib API. Users of those applications can then use Bluetooth speakers,
|
|
headphones, headsets and hands-free devices much as if they were local devices.
|
|
This integration is achieved by two ALSA plugins, one for PCM audio streams and
|
|
one for CTL volume controls.
|
|
|
|
PCM PLUGIN
|
|
==========
|
|
|
|
The BlueALSA ALSA PCM plugin communicates with the ``bluealsad(8)`` service.
|
|
It can be used to define ALSA PCMs in your own configuration file (e.g.
|
|
~/.asoundrc), or you can use the predefined **bluealsa** PCM.
|
|
|
|
The Predefined **bluealsa** PCM
|
|
-------------------------------
|
|
|
|
The simplest way to use the PCM plugin is with the predefined ALSA PCM device
|
|
**bluealsa**. The definition of this PCM device is of type ``plug`` so audio
|
|
format conversion, if required, is done automatically by the PCM. It has
|
|
parameters DEV, PROFILE, CODEC, VOL, SOFTVOL, DELAY, and SRV. All these
|
|
parameters have defaults. Parameter values in an ALSA PCM name are specified
|
|
using the syntax:
|
|
|
|
::
|
|
|
|
bluealsa:DEV=01:23:45:67:89:AB,PROFILE=a2dp,CODEC=aac,VOL=60,SOFTVOL=no,DELAY=0,SRV=org.bluealsa
|
|
|
|
PCM Parameters
|
|
~~~~~~~~~~~~~~
|
|
|
|
DEV
|
|
The device Bluetooth address in the form *XX:XX:XX:XX:XX:XX*. Device names
|
|
or aliases are not valid here. The default value is **00:00:00:00:00:00**
|
|
which selects the most recently connected device of the chosen profile.
|
|
|
|
PROFILE
|
|
May be either **a2dp**, **asha** or **sco**. **sco** selects either
|
|
Hands-Free (HFP) or Headset (HSP) profile, whichever is connected on the
|
|
selected device.
|
|
The default is **a2dp**.
|
|
|
|
CODEC
|
|
Specifies the codec to be used by the profile. When a connection is
|
|
established between a device and a host, BlueALSA negotiates the best
|
|
available codec with the device; this parameter allows the ALSA
|
|
configuration to override that selection. The default value is
|
|
**unchanged** which causes the PCM to use its existing codec setting. The
|
|
codec name is case insensitive; so for example **aptX**, **aptx**, and
|
|
**APTX** are all accepted. If the specified codec is not available the
|
|
plugin issues a warning and uses the default value instead.
|
|
|
|
BlueALSA does not support changing the HFP codec from a HFP-HF node, only
|
|
the HFP-AG node can change the HFP codec.
|
|
|
|
oFono does not permit the audio agent to select the codec, so this
|
|
parameter has no effect when BlueALSA is used with oFono for HFP support.
|
|
|
|
For the A2DP profile it is possible to also specify a "configuration" for
|
|
the codec by appending the configuration as a hex string separated from the
|
|
codec name by a colon. The bits responsible for the number of channels and
|
|
the sample rate are set by the plugin with the respect to options
|
|
provided by the user (channel mode and sample rate bits act as a
|
|
mask). For example:
|
|
|
|
::
|
|
|
|
CODEC=SBC:FC450240
|
|
|
|
This SBC configuration limits the channel mode options to mono and dual
|
|
channel. So, in case of 2 channel audio stream, the plugin will negotiate
|
|
the dual channel mode instead of default (if supported) joint stereo mode.
|
|
|
|
VOL
|
|
Specifies the initial volume for the PCM when opened. The default value is
|
|
**unchanged** which causes the PCM to use its existing volume setting. The
|
|
value is an integer percentage of the maximum volume [0-100]. The mute
|
|
status can also be set by appending the character '-' to mute the sound or
|
|
'+' to unmute it. The volume is not restored to its original value when the
|
|
PCM is closed. For example to set the initial volume to 80% and ensure that
|
|
mute is disabled for this PCM:
|
|
|
|
::
|
|
|
|
VOL=80+
|
|
|
|
SOFTVOL
|
|
Enables or disables BlueALSA's software volume feature for this PCM. See
|
|
the ``bluealsad(8)`` manual page for more information on software volume.
|
|
This is a boolean option (values **on** or **off**), but also accepts the
|
|
special value **unchanged** which causes the PCM to use its existing
|
|
softvol value. The default value is **unchanged**.
|
|
|
|
HWCOMPAT
|
|
Modifies the behavior of the plugin when the remote device is connected
|
|
but not active in order to align better with the behavior of the ALSA
|
|
``hw`` plugin . This is a string option which takes the values **none**,
|
|
**busy** or **silence**.
|
|
See `Transport acquisition`_ in the **NOTES** section below for more
|
|
information.
|
|
|
|
DELAY
|
|
An integer number which is added to the reported delay (latency) value in
|
|
order to manually adjust the audio synchronization. It is not normally
|
|
required and defaults to **0**. See the **EXT** parameter of the CTL plugin
|
|
in the `CTL Parameters`_ section below for a more flexible and convenient
|
|
method of manually adjusting the reported delay by using a mixer control.
|
|
|
|
SRV
|
|
The D-Bus service name of the BlueALSA daemon. Defaults to
|
|
**org.bluealsa**. See ``bluealsad(8)`` for more information. Not normally
|
|
required.
|
|
|
|
Setting Different Defaults
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
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.codec "cvsd"
|
|
defaults.bluealsa.volume "50+"
|
|
defaults.bluealsa.softvol off
|
|
defaults.bluealsa.hwcompat "silence"
|
|
defaults.bluealsa.delay 5000
|
|
defaults.bluealsa.service "org.bluealsa.source"
|
|
|
|
Note that **volume** takes a string value and so the default must be enclosed
|
|
in quotation marks.
|
|
|
|
Positional Parameters
|
|
~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
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*, *CODEC*,
|
|
*VOL*, *SOFTVOL*, *HWCOMPAT*, *DELAY*, *SRV*. For example:
|
|
|
|
::
|
|
|
|
bluealsa:01:23:45:67:89:AB,a2dp,unchanged,unchanged,unchanged,none,0,org.bluealsa
|
|
|
|
When using positional parameters defaults can only be implied at the end of the
|
|
id string, so
|
|
|
|
::
|
|
|
|
bluealsa:01:23:45:67:89:AB
|
|
|
|
is equivalent to the full form above, but
|
|
|
|
::
|
|
|
|
bluealsa:01:23:45:67:89:AB,a2dp,,80+
|
|
|
|
is not permitted.
|
|
|
|
Defining BlueALSA PCMs
|
|
----------------------
|
|
|
|
You can define your own ALSA PCM in the ALSA configuration. To do this, create
|
|
an ALSA configuration node defining a PCM with type ``bluealsa``. 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, asha or sco)
|
|
[codec STR] # Preferred codec
|
|
[volume STR] # Initial volume for this PCM
|
|
[softvol BOOLEAN] # Enable/disable BlueALSA's software volume
|
|
[hwcompat STR] # HW compatibility mode (none, busy or silence)
|
|
[delay INT] # Extra delay (frames) to be reported (default 0)
|
|
[service STR] # DBus name of service (default org.bluealsa)
|
|
}
|
|
|
|
The **device** and **profile** fields must be specified so that the plugin can
|
|
select the correct Bluetooth transport; the other fields are optional. Note
|
|
that the default values for the optional fields are not overridden
|
|
automatically by the configuration ``defaults.bluealsa.*`` in a PCM defined
|
|
this way; however the configuration defaults can be referenced by use of
|
|
``@func refer`` (see the `ALSA configuration file syntax` documentation for
|
|
more information).
|
|
|
|
When choosing a name for your PCM definition, the name **pcm.bluealsa** is
|
|
predefined by the bluez-alsa installation (see section *The Predefined
|
|
bluealsa PCM* above), so it should not be used as a name for your own PCM
|
|
devices as doing so will most likely have unexpected or undesirable results.
|
|
|
|
Note that the **volume** field is of type **string**, so the value must be
|
|
enclosed in double-quotes. See the *PCM Parameters* section above for more
|
|
information on each field.
|
|
|
|
Do not confuse the PCM type **bluealsa** with the PCM named **bluealsa**. The
|
|
type does not perform any audio conversions, you will have to wrap your own
|
|
defined PCMs with type **plug** to achieve that; whereas the predefined PCM
|
|
**pcm.bluealsa** *is* of type **plug**.
|
|
|
|
Name Hints
|
|
----------
|
|
|
|
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"
|
|
}
|
|
}
|
|
|
|
Now using ``aplay -L`` will include the following in its output:
|
|
|
|
::
|
|
|
|
# aplay -L
|
|
bt-headphones
|
|
My Bluetooth headphones
|
|
#
|
|
|
|
If you are using the predefined **bluealsa** PCM, then you can create a
|
|
"namehint" entry in your ~/.asoundrc file like this:
|
|
|
|
::
|
|
|
|
namehint.pcm {
|
|
mybluealsadevice "bluealsa:DEV=00:11:22:33:44:55,PROFILE=a2dp|My Bluetooth headphones"
|
|
}
|
|
|
|
Then ``aplay -L`` shows
|
|
|
|
::
|
|
|
|
# aplay -L
|
|
bluealsa:DEV=00:11:22:33:44:55,PROFILE=a2dp
|
|
My Bluetooth headphones
|
|
|
|
For alsa-lib versions before v1.2.3.2, a bug in the namehint parser means that
|
|
a **namehint.pcm** entry has to be written as
|
|
|
|
::
|
|
|
|
namehint.pcm {
|
|
mybluealsadevice "bluealsa:DEV=00:11:22:33:44:55,PROFILE=a2dp|DESCMy Bluetooth headphones"
|
|
}
|
|
|
|
(note the keyword **DESC** after the pipe symbol and before the description
|
|
text.)
|
|
|
|
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 configuration 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|My 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, before the pipe | symbol, is the string that is to be passed to
|
|
ALSA applications to identify the PCM (e.g. with ``aplay -D ...``). The next
|
|
section, after the pipe symbol, is the description that will be presented to
|
|
the user. The optional **|IOID** section is not included in the description
|
|
given to the application.
|
|
|
|
CTL PLUGIN
|
|
==========
|
|
|
|
The BlueALSA ALSA CTL plugin can be used to define ALSA CTLs (mixer devices) in
|
|
your own configuration file (e.g. ~/.asoundrc), or you can use the predefined
|
|
configuration that is included in the bluez-alsa project.
|
|
|
|
A BlueALSA CTL device has no associated soundcard, so ``alsamixer`` will not
|
|
list it in its F6 menu. It can be selected either by starting ``alsamixer``
|
|
with
|
|
|
|
::
|
|
|
|
alsamixer -D bluealsa
|
|
|
|
or by selecting "enter device name .." on the F6 menu then typing out
|
|
"bluealsa" in the "Device Name" box.
|
|
|
|
|
|
The CTL has two operating modes, **Default** mode and **Single Device** mode.
|
|
|
|
Default Mode
|
|
------------
|
|
|
|
In this mode when a device connects, the mixer will create new controls for it,
|
|
and when a device disconnects, the mixer will remove its controls.
|
|
``alsamixer(1)`` will show these changes dynamically.
|
|
|
|
Control names are constructed by combining the device Bluetooth alias with
|
|
either the profile type ('A2DP' or 'SCO') of the controlled PCM or the word
|
|
"Battery" for battery level indicators. If two or more connected devices have
|
|
the same alias then an index number is added to the name to make it unique.
|
|
|
|
The Bluetooth "alias" of a device is by default the same as its "name". The
|
|
name is a string defined by the device manufacturer and embedded in its
|
|
firmware. Typically two identical devices will have identical names. The
|
|
"alias" is created by BlueZ and stored locally on the host computer. So the
|
|
alias can be changed using a tool such as ``bluetoothctl(1)`` to make it unique
|
|
if desired. As manufacturers tend to use long names for their devices the alias
|
|
can also be useful to give a short "nickname" to a device.
|
|
|
|
Although this default mode works well with ``alsamixer``, there are some
|
|
limitations that may make it unsuitable for some applications. In particular:
|
|
|
|
- If device aliases are not unique then the index number associated with
|
|
each is not easily predictable in advance; so it can be difficult to
|
|
programmatically associate a PCM with its volume control.
|
|
|
|
- A consequence of the alsa-lib implementation of controls is that when one
|
|
Bluetooth device connects or disconnects it is necessary to remove all
|
|
controls from all devices in the mixer and create a new set. This invalidates
|
|
pointers held by applications and can cause application crashes. (Hardware
|
|
sound cards do not have randomly appearing and disappearing controls, so
|
|
many, or even most, applications are not programmed correctly to deal with
|
|
it.)
|
|
|
|
Single Device Mode
|
|
------------------
|
|
|
|
The BlueALSA CTL also implements an alternative mode that presents controls
|
|
only for one specified device. In this case the control names are simply the
|
|
profile type of the controlled PCM ('A2DP' or 'SCO') or the word "Battery".
|
|
There is never any need for index suffixes or device alias. Immediately this
|
|
overcomes the two main issues of the default mode.
|
|
|
|
Single device mode is achieved by including the device Bluetooth address as an
|
|
argument to the ALSA device id, for example:
|
|
|
|
::
|
|
|
|
alsamixer -D bluealsa:00:11:22:33:44:55
|
|
|
|
A notable difference between single-device mode and the default mode is in the
|
|
cases of the device not being connected when the mixer is opened, and when the
|
|
device disconnects while the mixer is open.
|
|
|
|
For the default mode, the mixer will still open, even if no devices are
|
|
connected, but will display no controls. In single device mode the open request
|
|
will fail with an error message.
|
|
|
|
Similarly, in default mode when a device disconnects the mixer remains open but
|
|
removes the set of controls and creates a new control set without the
|
|
disconnected device. That new set will be empty if no devices remain. If the
|
|
device then re-connects the mixer will again create a new set of controls with
|
|
the newly connected device included.
|
|
|
|
In single device mode when its device disconnects then the mixer will close.
|
|
The ``alsamixer`` application will continue running with no associated device
|
|
or controls, but will not automatically re-open the mixer if the device
|
|
re-connects. The user can use F6 to open a new device.
|
|
|
|
As a special case, a single device mixer can be opened with the address
|
|
**00:00:00:00:00:00**. This will create a mixer with controls for the most
|
|
recently connected device at the time the mixer is opened. Once created, that
|
|
mixer behaves the same as if it had been opened with the actual address of the
|
|
device: it does not change to a new device if another is subsequently
|
|
connected.
|
|
|
|
The Predefined **bluealsa** CTL
|
|
-------------------------------
|
|
|
|
The **bluealsa** CTL has parameters DEV, EXT, BTT, DYN, and SRV. All the
|
|
parameters have defaults.
|
|
|
|
CTL Parameters
|
|
~~~~~~~~~~~~~~
|
|
|
|
DEV
|
|
The device Bluetooth address in the form XX:XX:XX:XX:XX:XX. Device names or
|
|
aliases are not valid here. The default value is **FF:FF:FF:FF:FF:FF**
|
|
which selects controls from all connected devices (see `Default Mode`_
|
|
above). Also accepts the special address **00:00:00:00:00:00** which
|
|
selects the most recently connected device.
|
|
|
|
EXT
|
|
Causes the plugin to include extra controls. These are the controls for
|
|
Bluetooth codec selection, volume mode selection, client delay (sync)
|
|
and/or battery level indicator.
|
|
If the value is **yes** then all of these additional controls are included;
|
|
if the value is **no** then none of them are included. The default is
|
|
**no**.
|
|
|
|
This parameter can also select individual controls by using a colon (':')
|
|
separated list of control names. The control names are **codec**, **mode**,
|
|
**sync** and **battery**. For example:
|
|
|
|
::
|
|
|
|
EXT=codec
|
|
EXT=mode:battery
|
|
|
|
See `Codec switching`_ in the **NOTES** section below for more information
|
|
on the codec selection control.
|
|
|
|
The volume mode controls take values "software" and "pass-through"; the
|
|
playback control has index 0 and capture control has index 1.
|
|
See the `Volume control` section in the ``bluealsad(8)`` for more
|
|
information on the software volume setting.
|
|
|
|
The client delay controls are called "Sync". They can be used to apply
|
|
a fixed adjustment to the delay reported by the associated PCM to the
|
|
application, and may be useful with applications that need to synchronize
|
|
the bluetooth audio stream with some some other stream, such as a video.
|
|
The values are in milliseconds from ``-3275 ms`` to ``+3275 ms`` in steps
|
|
of ``25 ms``. The playback control has index 0 and the capture control has
|
|
index 1. Each codec supported by a PCM has its own client delay value.
|
|
Note that this control changes only the delay value reported to the
|
|
application by ALSA, it does not affect the actual delay (latency) of the
|
|
PCM stream. Values set by this control type are saved in the BlueALSA
|
|
persistent state files, and so are remembered and automatically applied
|
|
each time the PCM is used.
|
|
|
|
The read-only battery level indicator will be shown only if the device
|
|
supports battery level reporting.
|
|
|
|
BTT
|
|
Appends Bluetooth transport type (e.g. "-SNK" or "-HFP-AG") to the control
|
|
element names. When using with the `Default Mode`_ this will reduce the
|
|
number of available characters for Bluetooth device name, so the default
|
|
value is **no**.
|
|
|
|
In some rare circumstances, when more than one A2DP or HFP/HSP profile is
|
|
connected with a single Bluetooth device, it might happen that the control
|
|
element names for such device will not be unique. This might be problematic
|
|
for control applications which use ALSA High Level Control Interface, e.g.
|
|
``amixer`` or ``alsamixer``. Such applications will report error or simply
|
|
crash. This can be avoided by setting the BTT parameter to **yes**.
|
|
|
|
DYN
|
|
Enables "dynamic" operation. The plugin will add and remove controls as
|
|
profiles are connected or disconnected. This is the normal behavior, so
|
|
the default value is "**yes**". This argument is ignored in default mode;
|
|
in that mode operation is always dynamic. There are some applications that
|
|
are not programmed to handle dynamic addition or removal of controls, and
|
|
can fail when such events occur. Setting this argument to **no** in single
|
|
device mode with such applications can protect them from such failures.
|
|
When dynamic operation is disabled, the plugin never adds or removes any
|
|
controls. If a single profile is disconnected, then its associated volume
|
|
control is put into an inactive state, i.e.: read-only with its value and
|
|
playback/capture switch set to 0.
|
|
|
|
SRV
|
|
The D-Bus service name of the BlueALSA daemon. Defaults to
|
|
**org.bluealsa**. See ``bluealsad(8)`` for more information.
|
|
|
|
The default values can be overridden in the ALSA configuration, for example:
|
|
|
|
::
|
|
|
|
defaults.bluealsa.ctl.device "00:11:22:33:44:55"
|
|
defaults.bluealsa.ctl.bttransport "no"
|
|
defaults.bluealsa.ctl.dynamic "yes"
|
|
defaults.bluealsa.ctl.extended "no"
|
|
|
|
Defining BlueALSA CTLs
|
|
----------------------
|
|
|
|
You can define your own ALSA CTL in the ALSA configuration. To do this, create
|
|
an ALSA configuration node defining a CTL with type ``bluealsa``. The
|
|
configuration node has the following fields:
|
|
|
|
::
|
|
|
|
ctl.name {
|
|
type bluealsa # Bluetooth PCM
|
|
[device STR] # Device address (default "FF:FF:FF:FF:FF:FF")
|
|
[extended STR] # Include additional controls (default no)
|
|
[bttransport STR] # Append BT transport to element names (yes/no, default no)
|
|
[dynamic STR] # Enable dynamic operation (yes/no, default yes)
|
|
[service STR] # D-Bus name of service (default "org.bluealsa")
|
|
}
|
|
|
|
All the fields (except **type**) are optional. See the `CTL Parameters`_
|
|
section above for more information on each field. As for PCM definitions above,
|
|
the default values for the optional fields are hard-coded into the plugin; they
|
|
are not overridden by the configuration ``defaults.bluealsa.`` settings.
|
|
|
|
NOTES
|
|
=====
|
|
|
|
Codec selection
|
|
---------------
|
|
|
|
When used on a HFP gateway node, there may be a brief delay with HFP PCMs
|
|
after connection until the codec is selected. This delay is typically less
|
|
than two seconds. During this time interval it is not possible to open the
|
|
PCM plugin, it will fail with "Resource temporarily unavailable" (EAGAIN).
|
|
|
|
Codec switching
|
|
---------------
|
|
|
|
Changing the codec used by a BlueALSA transport causes the PCM(s) running on
|
|
that transport to terminate. Therefore using a Codec control can have
|
|
undesirable consequences. Unfortunately the ``alsamixer(1)`` UI does not
|
|
present a separate pick-list for enumerated types, so merely browsing the list
|
|
of codecs using this control actually issues a Codec change request every time
|
|
a different codec is displayed. This is not ideal, so the use of this control
|
|
type with ``alsamixer(1)`` is not recommended. The control type does however
|
|
work well with other mixer applications such as ``amixer(1)``.
|
|
|
|
Note that BlueALSA does not support changing the HFP codec from a HFP-HF node,
|
|
only the HFP-AG node can change the HFP codec.
|
|
|
|
Transport acquisition
|
|
---------------------
|
|
|
|
The audio connection of a Bluetooth profile is not established immediately that
|
|
a device connects. The A2DP source device, or HFP/HSP gateway device, must
|
|
first "acquire" the profile transport.
|
|
|
|
When the BlueALSA PCM plugin is used on a source A2DP or gateway HFP/HSP node,
|
|
then **bluealsad(8)** will automatically acquire the transport and begin audio
|
|
transfer when the plugin starts the PCM.
|
|
|
|
When used on an A2DP sink or HFP/HSP HF/HS node then **bluealsad(8)** must wait
|
|
for the remote device to acquire the transport. The ALSA PCM plugin state model
|
|
does not define any state that can be directly mapped to this situation, so
|
|
the BlueALSA PCM plugin offers a choice of behaviors to suit various
|
|
application requirements. The choice is selected using the parameter
|
|
**hwcompat** (**HWCOMPAT** argument to the pre-defined `bluealsa` PCM) which
|
|
takes one of the following values:
|
|
|
|
- none
|
|
|
|
The streams are presented exactly as handled by Bluetooth. No adjustments
|
|
are made to align the PCM more to expected ALSA behavior. While waiting for
|
|
the transport to be acquired the PCM plugin behaves as if the device
|
|
timer is stopped; it does not generate any poll() events, and the
|
|
application will be blocked when writing or reading to/from the PCM. For
|
|
applications playing audio from a file or recording audio to a file this is
|
|
not normally an issue and has the advantage that the played or captured
|
|
stream does not contain any frames of silence artificially inserted by the
|
|
plugin. However when streaming between some other device and a
|
|
BlueALSA device this may lead to very large latency (delay) or trigger
|
|
underruns or overruns in the other device. Capture streams may also have
|
|
brief interruptions caused by Bluetooth radio link interference. Some
|
|
applications, particularly ones which attempt to manage latency such as
|
|
``alsaloop(1)``, may become unstable in this situation.
|
|
|
|
- busy
|
|
|
|
Causes snd_pcm_open() to return immediately with error code **-EBUSY**
|
|
("Device or resource busy") on A2DP sink, HFP-HF and HSP-HS nodes if the
|
|
transport is not yet acquired. This is analogous to a ``hw`` device PCM
|
|
that is temporarily unavailable (for example because it is in use by some
|
|
other application). With this option the plugin also stops the
|
|
PCM stream and enters the **SND_PCM_STATE_DISCONNECTED** state if the
|
|
remote device releases the transport while in use, which is analogous to a
|
|
removable ``hw`` device being unplugged. If a capture stream is interrupted
|
|
by temporary Bluetooth link instability then the plugin simply blocks
|
|
temporarily, which may cause issues for some applications as noted for the
|
|
**none** value above.
|
|
|
|
- silence
|
|
|
|
Inserts silence for capture streams, or simply drops frames for playback
|
|
streams, whenever the transport is not acquired. Short intervals of silence
|
|
may also be inserted into capture streams if there is a break in the
|
|
incoming stream (for example as a result Bluetooth link instability). By
|
|
this means a continuous stream is maintained as far as the application is
|
|
concerned. This is analogous to a soundcard device with no speakers or
|
|
microphone plugged in: only silence is captured and playback succeeds but
|
|
produces no sound.
|
|
|
|
The **silence** option can also be used with capture devices on HFP/HSP AG and
|
|
A2DP source nodes (e.g. when using the FastStream codec) because in those cases
|
|
it is possible that the remote device is not sending any audio even though the
|
|
transport has been acquired.
|
|
|
|
PCM drain and non-blocking operation
|
|
------------------------------------
|
|
|
|
The BlueALSA PCM plugin does not support draining of capture PCMs. For a
|
|
capture PCM `snd_pcm_drain()` has the same effect as `snd_pcm_drop()`. This is
|
|
a limitation of the ALSA `ioplug` external plugin API.
|
|
|
|
For playback PCMs, BlueALSA has support for the drain operation in both
|
|
blocking and non-blocking modes. In blocking mode the drain operation will wait
|
|
until the BlueALSA server has played out the final audio frame. In non-blocking
|
|
mode the plugin will inform the application of drain completion as soon as the
|
|
ALSA ring buffer has been flushed; this means that some audio frames at the end
|
|
of the stream may be lost in non-blocking mode as the PCM may stop before the
|
|
server has had time to encode and play out all the frames.
|
|
|
|
FILES
|
|
=====
|
|
|
|
/etc/alsa/conf.d/20-bluealsa.conf
|
|
BlueALSA device configuration file.
|
|
ALSA additional configuration, defines the ``bluealsa`` PCM and CTL
|
|
devices.
|
|
|
|
SEE ALSO
|
|
========
|
|
|
|
``alsamixer(1)``, ``amixer(1)``, ``aplay(1)``, ``bluetoothctl(1)``,
|
|
``bluealsad(8)``, ``bluetoothd(8)``
|
|
|
|
Project web site
|
|
https://github.com/arkq/bluez-alsa
|
|
|
|
ALSA configuration file syntax
|
|
https://www.alsa-project.org/alsa-doc/alsa-lib/conf.html
|
|
|
|
ALSA built-in PCM plugins reference
|
|
https://www.alsa-project.org/alsa-doc/alsa-lib/pcm_plugins.html
|