-
Notifications
You must be signed in to change notification settings - Fork 189
Using BlueALSA with the JACK Audio Connection Kit
A BlueALSA PCM can be used with JACK in the same way as any other ALSA PCM, so long as the constraints imposed by Bluetooth Audio are taken into consideration:
-
Bluetooth Audio is high-latency. There is nothing that BlueALSA or JACK can do to change that. So you need to resist the instinct of JACK users and general JACK advice to use very small period sizes and buffers. You will not succeed. At best you will waste CPU cycles and at worst experience constant underruns/overruns. Similarly, there is generally no need to run the jackd service with real-time priority unless that is also required by the jack client (for example zita-j2a and zita-a2j require real-time priority), it will not reduce latency.
-
BlueALSA PCMs are transient. They can connect and disconnect at random intervals. JACK clients and servers always assume that PCMs are permanent; there is no provision in the JACK model for removal of a sound device while in use.
jackd
,alsa_out
and other clients will fail if playing to a BlueALSA PCM that disconnects. -
A2DP transports may become "idle". The source may keep the transport open but not send any audio frames. Jack source clients such as
zita-a2j
andalsa_in
will generate errors and possibly fail completely when this happens, so it is important to ensure the audio stream is running before starting the Jack source client, and that the stream continues to run as long as the Jack source is running. This issue applies only to BlueALSA capture devices.
There have been a number of bluez-alsa issues raised in respect of using BlueALSA with JACK. Athough those issues, and the recommendations and workarounds mentioned in them, were valid when written, there have been many improvements to both BlueALSA and JACK recently. So much so that by using the latest bluez-alsa release and recent JACK releases it now quite straightforward to use them together, within the constraints described above.
BlueALSA can be used without any need to create ~/.asoundrc
entries, using
either zita-j2a
or alsa_out
, and can even be used as the backend device
of a jackd
service.
Possibly the simplest example is to create a jack sink using the bluealsa
default PCM:
zita-j2a -j bluealsa -d bluealsa -p 1024 -n 3 -c 2 -L
The command line arguments are as follows:
-j bluealsa
Use the name "bluealsa" for the sink. This is the name that jack
clients use to send audio to the sink.
-d bluealsa
Use the alsa device "bluealsa". This device name is predefined by
the bluez-alsa installation, and used in this way will select the most
recently connected A2DP playback device.
-p 1024
Use an ALSA period size of 1024 frames.
-n 3
Use an ALSA buffer of 3 periods. A smaller buffer will almost certainly
result in constant underruns.
-c 2
Use 2 channels. `zita-j2a` will create 2 jack ports, called
`bluealsa:playback_1` and `bluealsa:playback_2`.
-L
Use S16_LE samples. Without this option `zita-j2a` may convert to
32-bit samples only for the ALSA `plug` plugin to convert them back
to 16-bit.
To use a specific bluetooth device rather than the default, specify its MAC address in the device name, and give it a unique jack name:
zita-a2j -j bt_headphones -d bluealsa:XX:XX:XX:XX:XX:XX -p 4096 -n 3 -c 2 -L
We can now play to the headphones from any jack client. For example:
mpg123 -o jack -a bt_headphones:playback_1,bt_headphones:playback_2 MyFavouriteMusic.mp3
or
JACK_PLAY_CONNECT_TO=bt_headphones:playback_%d jack-play test_sounds.wav
The command line arguments for alsa_out
are the same as for zita-j2a
except that -L
is
not supported. For example:
alsa_out -j bt_headphones -d bluealsa:XX:XX:XX:XX:XX:XX -c 2 -p 4096 -n 3
There is still a bug in alsa_out
that causes a buffer overflow if the device
name is too long. It appears the longest device name allowed is 29 characters.
Fortunately the form used here is only 26 characters.
BlueALSA can also be used as a backend for a jackd service
jackd -r -d alsa -P bluealsa -n 3 -S -o 2
-r
Do not request real-time scheduling (optional - will also work without
this)
-d alsa
Use the ALSA backend
-P bluealsa
Use the most recently connected BlueALSA playback device. You can also
choose a specific device with `-P bluealsa:XX:XX:XX:XX:XX:XX`
-n 3
Use an ALSA buffer of 3 periods. A smaller buffer is sure to produce
underruns.
-o 2
Create 2 output channels
-S
Use S16_LE sample format
Clients can then send to the BlueALSA device with
JACK_PLAY_CONNECT_TO=system:playback_%d jack-play test_sounds.wav
It is possible to remove the ALSA plug
plugin from the audio processing chain,
and instead rely on JACK's own audio processing features. To do this we have to
define our PCMs in our ~/.asoundrc file. For example:
pcm.bt-headphones {
type bluealsa
device XX:XX:XX:XX:XX:XX
profile a2dp
}
ctl.bt-headphones {
type bluealsa
}
Remember here the limit of 29 characters for the PCM name when using
alsa_out
With ALSA plug
removed, we no longer need to force a sample format, so the
-L
or -S
argument is no longer needed.
Then we can use this with JACK as:
zita-j2a -j bt-headphones -d bt-headphones -p 4096 -n 3 -c 2
or
jackd -r -d alsa -P bt-headphones -n 3 -o 2