-
Notifications
You must be signed in to change notification settings - Fork 189
ALSA devices with bluealsa‐aplay
Please consult the bluealsa-aplay manual page for bluealsa-aplay
usage instructions. The purpose of this article is to provide some additional context, particularly to help users who may have little previous experience of working directly with the ALSA audio layer.
bluealsa-aplay
plays the audio stream using ALSA, so the output device must be specified as an ALSA PCM device. If no device is specified on the command line bluealsa-aplay
will select the ALSA default
PCM, which on most systems will be the analogue output of the first sound card with automatic conversions, channel mapping and stream mixing enabled (assuming the user's ALSA config has not modified the definition of default
). The user can use bluealsa-aplay
command-line options to specify any alternative PCM device to use, and also to fine-tune some of the parameters of that device.
If the simple default
ALSA device is not on the correct sound card on your system, you can tell bluealsa-aplay
to use a different card, but still with all default settings. A card can be specified by index or by name. The index
of a card is allocated sequentially as it is "discovered" by the kernel, and is therefore dependent on the order in which the kernel probes for devices on boot, and also the order in which removable cards such as USB audio adapters are added or removed by the user. Cards are numbered from 0, and if the card is not specified ALSA will assume card 0. For example, the following will use the default device on card 0:
bluealsa-aplay --pcm=default
to use the default device on card number 1, use
bluealsa-aplay --pcm=default:CARD=1
It may be preferable to use the card name rather than its index number if removable cards such as USB are in use, to avoid the issue of index number varying from one boot to the next. To see a list of connected sound card names, use:
cat /proc/asound/cards
In the output of that command, the first digit is the card index number, and the string within square brackets [ ... ]
is the card name. The remaining text helps identify which card is which. So for example:
0 [IQaudIODAC ]: IQaudIODAC - IQaudIODAC
IQaudIODAC
1 [Device ]: USB-Audio - USB Audio Device
C-Media Electronics Inc. USB Audio Device at usb-3f980000.usb-1.2, full speed
In the above card 0 is called IQaudIODAC
and card 1 is called Device
. So the default PCM device on card 1 can also be specified with:
bluealsa-aplay --pcm=default:CARD=Device
Throughout this document we will use card numbers for simplicity, but in every example it is possible to use the card name instead of the number.
If default
does not give the desired result, even when a specific card is selected, then alternative PCM devices can be used. ALSA provides a standard set of simple PCM devices that generally cover all the common usage scenarios for bluealsa-aplay
. It is therefore unlikely that a user will need to define any complex PCM devices in their own ALSA config files. We consider each of these standard PCMs:
The hw
PCM device gives an application direct access to the sound card; alsa-lib does not apply any additional processing to the stream. Therefore, this PCM gives the highest possible fidelity and efficiency, but is also the least flexible. The stream configurations available are exactly those provided by the hardware so may not always be compatible with the bluealsa-aplay
audio output streams. hw
is the best choice when the sound card directly supports the bluetooth audio PCM formats and only one client connection at a time is required. Most sound cards will support only one client connection per PCM device, so with such cards bluealsa-aplay
will only be able to support one connected bluetooth client at a time when using the hw
PCM.
hw
allows to specify the desired sound card and the device on that card as arguments. By default the first card and first device on that card are selected, so hw
is equivalent to hw:0,0
. For example, to output audio directly to device number 2 on card number 1, with no conversions:
bluealsa-aplay --pcm=hw:1,2
or
bluealsa-aplay --pcm=hw:CARD=1,DEV=2
Note that the DEV argument is always a number, only the CARD argument will accept a name, not the DEV argument.
You can obtain a list of all available device numbers using
aplay -l
Example output:
**** List of PLAYBACK Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: ALC236 Analog [ALC236 Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 3: HDMI 0 [HDMI 0]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 7: HDMI 1 [HDMI 1]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 8: HDMI 2 [HDMI 2]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 9: HDMI 3 [HDMI 3]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 10: HDMI 4 [HDMI 4]
Subdevices: 1/1
Subdevice #0: subdevice #0
Here device 0 is the analog output and devices 3,7,8,9 and 10 are HDMI digital outputs.
The plughw
PCM device applies some conversions to the audio stream where necessary before passing it to the sound card. This PCM can modify:
-
access -
bluealsa-aplay
always opens its output PCM in interleaved read-write mode, if the card requires non-interleaved or memory-mapped modeplughw
will perform this conversion automatically. This conversion does not degrade the audio stream in any way. -
sample rate -
bluealsa-aplay
outputs audio at the sample rate sent by the bluetooth client;plughw
can re-sample the stream to a different rate, however any such conversion will inevitably result in some loss of information and some "artefacts" which may potentially result in a noticeable loss of fidelity. Also the conversion may be approximate in which case there may be dropouts in the sound caused by underruns or overruns of the PCM buffer. -
sample format -
bluealsa-aplay
outputs audio samples with the same PCM format as sent by the bluetooth client. Typically, this is signed 16-bit integer ("S16_LE").plughw
can re-sample to a different format if necessary; this can lead to some loss of fidelity, especially if the number of bits per sample is reduced. -
channels - A2DP streams are generally stereo (2 channels), HSP/HFP streams are always mono (1 channel). If the card supports more channels than the Bluetooth stream, then
plughw
will leave the additional channels of the card unused, except in the case of a mono stream feeding a stereo output device in which case it will copy the mono stream to channels 0 and 1 of the card, each at 50% volume. If the output PCM supports only one channel, then for a stereo streamplughw
will combine the two channels by averaging.
plughw
performs only those conversions that are necessary to make the stream compatible with the card. So it is a good general choice when support for only one Bluetooth device at a time is required. It accepts the same arguments, with the same defaults, as the hw
PCM to select card and device.
For example, to use plughw
with card 0, device 0:
bluealsa-aplay --pcm=plughw
... or with card 1, device 3:
bluealsa-aplay --pcm=plughw:CARD=1,DEV=3
The purpose of the ALSA default
PCM device is to ensure, as far as is possible, that there is always at least one PCM available that will just "work" with any stream. It will try to apply whatever converters and other plugins are required to permit multiple simultaneous client connections sending any stream format to some device on the selected card. It takes one argument, which specifies which card to use, and defaults to card 0. Note that the default
PCM device does not accept a DEV
argument: the default device for a card is pre-set in the ALSA configuration (it is almost always device 0).
It is common practice to re-define default
in user configurations to support some specific application. If for any reason you have found it necessary to re-define default
to support some other application, then bluealsa-aplay
will use this new definition.
default
is the best choice for initial testing, and in production for many budget or low-quality cards (e.g. the Raspberry Pi on-board jack-plug audio output). It is also a good choice in general, unless you require output to a card that has multiple devices (e.g. digital outputs) or multiple channels, and the output you require is not configured as default for the card.
Example:
bluealsa-aplay --pcm=default:CARD=1
The sysdefault
PCM device initially is an alias for default
in an out-of-the-box ALSA configuration. If default
has been re-defined in the user configuration then the original definition is still available by using sysdefault
.
bluealsa-aplay --pcm=sysdefault:CARD=1
The dmix
PCM device implements stream mixing in software before passing the resulting mixed stream directly to a hw
PCM device. This allows multiple clients to connect simultaneously to a card that would otherwise not allow this. This device requires that all clients use the same audio format and sample rate, and the same buffer and period sizes. All of the hardware parameters are set by the dmix
PCM device. It ignores the values requested by the clients for buffer and period. The default values used are:
- period size: 1024 frames
- buffer size: 16384 frames (i.e. 16 periods)
Channels, rate and format can be selected by the first client to open the dmix
device, but only by using arguments to the device name when it is opened. The default values are:
- channels: 2
- rate: 48000
- format: the default format of the underlying
hw
device
For example, to open the dmix
device on the default card, but with a rate of 44100 and format S16_LE, use:
bluealsa-aplay --pcm=dmix:RATE=44100,FORMAT=S16_LE
This will only succeed if the underlying hw
device natively supports those parameters, is not already opened (for example by a client using the hw
device directly) and this dmix
device is not already opened using a different set of parameters.
To use a different card (e.g. card 1), or different device on the card (e.g. device 2) the above example would be used as:
bluealsa-aplay --pcm=dmix:CARD=1,DEV=2,RATE=44100,FORMAT=S16_LE
The dmix
PCM device can be a good choice when the user knows that the all Bluetooth clients will use the same audio parameters (i.e. channels, rate and format). Note that a standard-compliant Bluetooth speaker must allow A2DP clients to use either 48000 or 44100 sample rate, so in general it is not guaranteed that all clients will use the same audio parameters. See the plug PCM device below for more information.
dsnoop
is for audio capture only, so is not relevant to bluealsa-aplay
.
The file
PCM device stores the output stream to a file or FIFO (it can also create a command pipeline and send the PCM stream to the pipeline standard input). It does not send the audio to any sound card or other audio device. The file path must be provided as a parameter. By default the file will contain raw PCM; if you wish to create a .wav
file, add wav
as a second parameter. For example:
bluealsa-aplay --pcm=file:/tmp/recording.wav,wav
or
bluealsa-aplay --pcm=file:FILE=/tmp/recording.wav,FORMAT=wav
The filename can contain placeholders which are substituted by the sample format (%f), sample rate (%r) and channels (%c). This can be especially useful when creating a raw PCM file, which otherwise would include no information about its contents. For example:
bluealsa-aplay --pcm=file:/tmp/recording-%f-%r-%c.pcm
The null
PCM device just discards all samples, so we mention it here only for completeness as on its own it has little practical use with bluealsa-aplay
For cards that are known to ALSA, the standard configuration also includes some PCM devices that map the stream to specific multi-channel layouts. These PCM devices do not apply any conversions to the audio. Since BlueALSA streams are either 1 or 2 channel only, these are of little practical use with bluealsa-aplay
. They are:
- surround21
- surround40
- surround41
- surround50
- surround51
- surround71
There is also a PCM device called front
that may be useful with a multi-channel card if the hw
device directs the audio to the rear or side speakers of a multi-channel card. Like the other multi-channel abstractions if performs no audio conversions.
If the card has digital audio outputs, and ALSA has a configuration for the card, then PCM devices are available for these outputs. These devices perform no audio conversions or channel mapping. There are two types:
hdmi
spdif
spdif
may also be called iec958
. Both types accept the card id and a device number as arguments. Note that some HDMI devices only enable the audio when there is also a video stream. Examples:
Use the S/PDIF output on the default card:
bluealsa-aplay --pcm=spdif
Use the default HDMI output:
bluealsa-aplay --pcm=hdmi
The hdmi
PCM has its own device numbering scheme. Looking at the example aplay -l
output above, we see on that particular card hw
device 3 is HDMI device 0, and hw
device 7 is HDMI device 1, etc. When using the hdmi
PCM the DEV argument is the HDMI number. Most HDMI devices will identify themselves when connected, and if so aplay -l
will indicate that device identity in its output. So for example, if an HDMI socket on the computer is connected to an LG TV, the output from aplay -l
may be:
**** List of PLAYBACK Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: ALC236 Analog [ALC236 Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 3: HDMI 0 [HDMI 0]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 7: HDMI 1 [LG TV]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 8: HDMI 2 [HDMI 2]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 9: HDMI 3 [HDMI 3]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 10: HDMI 4 [HDMI 4]
Subdevices: 1/1
Subdevice #0: subdevice #0
This tells us that HDMI device 1 is the connection to the TV. So we can use that with:
bluealsa-aplay --pcm=hdmi:CARD=0,DEV=1
Neither of these digital devices perform any audio conversions, so it may be necessary to use the plug PCM device to make them compatible with bluealsa-aplay
.
The standard ALSA PCM device set also includes two PCM devices that can be used in conjunction with the above devices to improve compatibility and allow recording while playing to a device. The actual output device must be specified as an argument, which may need careful quoting.
The plug
PCM device can be used to convert audio format for use with those devices above that do not do this themselves. The conversions it can do are the same as the plughw
device, please see that device for more details. For example, to use the dmix
PCM device on card 1 device 2 when the underlying hw device does not support the BlueALSA audio format:
bluealsa-aplay --pcm="plug:'dmix:CARD=1,DEV=2'"
The tee
PCM device copies the audio stream to a file (or fifo, or command pipeline) and also sends it to an output PCM device. See the file
PCM device description above for details of the file naming. It requires the output PCM device, file name, and optional file format as arguments. For example:
bluealsa-aplay --pcm="tee:SLAVE='plughw:CARD=1,DEV=2',FILE=/tmp/recording.wav,FORMAT=wav"
The ALSA configuration can be extended by defining new PCMs, and the default values for various parameters can be modified by defining special keys in the configuration or by setting some special environment variables.
To set configuration keys they should be defined in either /etc/asound.conf
(for all users, choose this if running bluealsa-aplay
as root or some service account) or ~/.asoundrc
(if running bluealsa-aplay
under your own account). Some useful configuration keys:
-
defaults.pcm.card
This key is used by all the above ALSA standard PCM devices to set the card number. Card names will not work here, so its usefulness is limited if removable cards are used. This key can be used instead of setting the card via the CARD argument when selecting the output device. If the CARD argument is used, the argument overrides this defaults key value. For example:defaults.pcm.card 1
-
defaults.ctl.card
Similarly, this key sets the default mixer card. -
defaults.pcm.device
Sets the default device number for all the above ALSA standard PCM devices. -
defaults.pcm.file_format
Sets the default file format for thefile
andtee
PCM devices. Takes the valuesraw
orwav
. The initial value israw
. -
defaults.pcm.file_truncate
If set totrue
, the file used by thefile
andtee
PCM devices will be overwritten, if set tofalse
then new audio data will be appended to the file. The initial value istrue
.
Defining your own PCMs is an advanced topic which is out of scope for this document, please consult your distribution's documentation or the ALSA documentation for more information.
bluealsa-aplay
needs to set the ALSA PCM device buffer time and period time (period time is the interval between interrupts from the device); and bluealsa-aplay
must ensure that there is always at least one period of audio frames available in the buffer when a device interrupt occurs. By default, bluealsa-aplay
sets the buffer time to 500000 µs, and the period time to 100000 µs. bluealsa-aplay
starts the PCM device when BlueALSA has delivered enough audio frames to reduce the space in the buffer to one period or less. Decreasing the buffer time will therefore decrease latency, but will also increase the risk of audio drop-outs. A drop-out occurs either when there is less than one period of audio frames in the buffer when the device requests it, or when the buffer is full and audio needs to be transferred from BlueALSA. The period time should be set such that there is a whole number of periods in the buffer, because some ALSA devices (especially those that involve sample rate changes) may otherwise suffer increased risk of audio drop-outs. Reducing the number of periods in the buffer (the default is five) may slightly reduce latency but will increase CPU load. For example, to set the buffer time to 320000 µs with 4 periods in the buffer:
bluealsa-aplay --buffer-time=320000 --period-time=80000
To avoid drop-outs when the sound card cannot natively support the BlueALSA audio sample rate, it is advisable to ensure that the period time represents a whole number of audio frames at both the BlueALSA rate and the sound card rate. See the bluealsa-aplay manual page for more details. In practice this can achieved by ensuring that the period time is a multiple of 10000 µs.
Note that, for A2DP at least, the default values of buffer time and period time used by bluealsa-aplay
work well and it is not normally necessary to set them explicitly.
dmix
is a special case worth mentioning here. As noted above, it ignores the buffer_time
and period_time
settings requested by the application and applies its own default values, which are not multiples of 10000µs. This can a problem when the Bluetooth audio is not sampled at the rate set by dmix
for the card, for example if the Bluetooth client sends audio sampled at 44100Hz.
To overcome this it is necessary to set new defaults for the dmix
PCM device. This is achieved by setting special configuration keys. The defaults are specific to a card name. So, to set a period time of 100000µs with buffer of 5 periods using the example system above with an i2s card and a USB card, for the IQaudio card we need to define:
defaults.dmix.IQaudIODAC.period_time 100000
defaults.dmix.IQaudIODAC.periods 5
and for the USB card:
defaults.dmix.Device.period_time 100000
defaults.dmix.Device.periods 5
Bluetooth allows an audio source (e.g. phone) to control the playback volume of the audio sink (e.g. headphones, speaker). This requires that both devices support the necessary protocols.
BlueALSA supports remote volume control for both A2DP and HSP/HFP, but enabling support for A2DP requires that the bluealsa
daemon is run with --a2dp-volume
. When this option is used the daemon will inform bluealsa-aplay
whenever a volume change request is received from the remote device, and bluealsa-aplay
will then apply the requested change to its configured ALSA mixer control.
bluealsa-aplay
by default will attempt to implement the volume change request by operating a control called Master
in a mixer called default
. Not all mixers have a control called Master
so it is often necessary to give the correct name on the command-line. This is generally the case when using USB or i2c sound cards. default
may not refer to the correct mixer if more than one sound card is attached, so it may also be necessary to specify the mixer device on the command line.
Note that the ALSA in-built digital PCM devices (hdmi
and s/pdif
,iec958
) do not normally have hardware volume controls, so without any advanced configuration only software volume control is available to bluealsa-aplay
with these devices.
In ALSA, a mixer is a CTL device. There are some standard pre-defined CTLs in ALSA, and it is also possible to define new CTL devices within the configuration. We will only consider the standard CTL devices here, use of bluealsa-aplay
does not normally require bespoke definitions. The CTL devices of interest here are:
The default
CTL device is normally defined to refer to the mixer that controls the card used by the default
PCM device. Like the default
PCM device it is often redefined in local configurations. This mixer takes its card number as an argument, so if you wish to use default
card number 1:
bluealsa-aplay --mixer-device=default:1
or
bluealsa-aplay --mixer-device=default:CARD=1
If the --mixer-device=
option is not given, bluealsa-aplay
assumes --mixer-device=default
.
The sysdefault
CTL device is the same as the ALSA standard configuration default
definition. Use this if you wish to use the original default
definition on an installation in which default
has been re-defined.
The hw
CTL device passes control requests directly to the sound card. In a standard installation sysdefault
is in practice the same as hw
.
ALSA documentation uses the word "control" to refer to different, but related, concepts depending on the abstraction layer being discussed. In this document we use "control" to refer to an object that the ALSA documentation calls "simple control" or "simple mixer control". Possibly the easiest way to see a list of these controls for a connected sound card is to use alsamixer
. If you have two cards connected, you can select the one you want with the --card=
option. For example, to see the controls for card 1
alsamixer --card=1
Controls that show Item: ... [dB gain: ... ]
in the top left when selected are volume controls of some kind that can be used by bluealsa-aplay
; however to be certain of which is the correct control for your chosen PCM device you should consult the documentation for your card. If the documentation is missing or unclear, you could try each of the dB gain
controls until you find one that works.
If Master
is not the correct control for your PCM device, then you can specify the one to use on the command line. For example, to use a control called Speaker
bluealsa-aplay --mixer-name=Speaker