GBD and BlueALSA Playback - andy3471/GBD GitHub Wiki

Preliminaries

The instructions on this page assume that a GBD server instance is already up and running and listening for GBD client connections, e.g.:

$ ./gbdserver -p 7777
>> Authenticating... (Success)
>> Listening for incoming gbdclient connections on port: 7777

This was already discussed in section GBD Quick Start.

BT Audio Sources and the RPi BT Audio Sink

RPi Bluetooth Audio Sink

To turn the RPi into a Bluetooth audio sink, the Bluetooth A2DP connection is established from the host of the audio player.

RPi as a BT audio sink applies to either:

  • Economy GBD setups where the source of the audio is a player executing on the Desktop/laptop host. This is not to be confused with economy GBD setups where the source of the audio is an external BT device. In this latter case, the Desktop/laptop will have to be configured as the BT audio sink; its BlueALSA PCM framework will then route PCM signals to the GBD client (PCM plugin) which will, in turn, route them to the remote RPi GBD server via TCP/IP.

  • Standalone RPi GBD models. The source of the audio is an external BT device that streams directly to the RPi device.

Since an RPi setup is typically headless, it's BT configuration should be such that it works "out-of-the-box" upon RPi boot. Getting RPi BT settings right can be a bit tricky. The following configuration requirements may or may not be necessary (or may even be inaccurate!), and by no means are complete:

GNU/Linux PC Bluetooth Audio Source

This section discusses an economy GBD setup where the source of the audio is an application running on a GNU/Linux OS. This is not to be confused with economy GBD setups where the source of the audio is some external bluetooth device e.g. smart-phone or tablet.

Before proceeding, make sure that PulseAudio Bluetooth modules (if any) have been disabled/unloaded. See section Disabling PulseAudio Bluetooth for details.

It is also assumed that the bluetoothd and bluealsa daemons are up and running (with bluealsa configured for the CD Audio PCM params -- see section A2DP), e.g.:

user@ubuntu:~ $ ps ax | egrep '(bluetoothd|bluealsa)'
1658 ?        Ss     0:00 /usr/lib/bluetooth/bluetoothd
1665 ?        Ssl    0:00 /usr/bin/bluealsa --a2dp-force-audio-cd

The bluetoothctl utility will be used to stablish a connection to the RPi. Note that during the pairing process, a PIN may be requested. See section Disabling PIN Requirements for Pairing for tips on disabling this behavior.

To establish a BT connection with the RPi from the PC/laptop GNU/Linux host:

user@ubuntu: ~$ bluetoothctl 
[NEW] Controller 43:29:12:DF:78:CD ubuntu [default]
[NEW] Device 11:22:33:68:BC:15 raspberrypi
[bluetooth]# power on
[CHG] Controller 43:29:12:DF:78:CD Class: 0x48010c
Changing power on succeeded
[CHG] Controller 43:29:12:DF:78:CD Powered: yes

At this point, if the BT MAC address of the RPi machine was not displayed, try scanning. Recall that the RPi BT device should have been set to "discoverable". See Making RPi BT Device Discoverable:

[bluetooth]# scan on
Discovery started
[CHG] Controller 43:29:12:DF:78:CD Discovering: yes
[NEW] Device 11:22:33:68:BC:15 raspberrypi

... continuing ...

[bluetooth]# connect 11:22:33:68:BC:15
Attempting to connect to 11:22:33:68:BC:15
[CHG] Device 11:22:33:68:BC:15 Connected: yes
Connection successful
[raspberrypi]# quit
[DEL] Controller 43:29:12:DF:78:CD ubuntu [default]
user@ubuntu: ~$

Now, define an ALSA virtual PCM device for the bluealsa PCM plugin e.g.:

user@ubuntu: ~$ cat ~/.asoundrc
...
pcm.btdev {
  type plug
  slave.pcm {
    type bluealsa
    device "11:22:33:68:BC:15"
    profile "a2dp"
  }
  hint {
    show on
    description "Remote Raspberry BT"
  }
}

This configuration may be tested via:

user@ubuntu: ~$ aplay -D btdev foo.wav	
user@ubuntu: ~$ mplayer -ao alsa:device=btdev bar.mp3

At this juncture, while PCM signals are being routed to the remote RPi, an additional utility is required on the RPi host which will read the PCM from the BlueALSA PCM framework and route it to the GBD client (PCM plugin). This is discussed in section Playback via bluealsa-aplay.

Tablet/SmartPhone Bluetooth Audio Source

Note that this setup applies to both the economy GBD and standalone RPi models with the following main differences:

  • With the economy GBD setup, the BT audio source first streams to a PC/laptop running BlueALSA instead of directly to an RPi device as is the case with the standalone RPi model.

  • With both models, the BlueALSA framework streams the PCM signals to the GBD client (PCM plugin). However, since the economy GBD setup has to route the PCM to the GBD server on the remote RPi, it requires the ipaddr parameter in the GBD virtual PCM device to point to RPi machine. On the other hand, the standalone RPi model sets ipaddr to a loopback address since the GBD server now runs on the same host.

Playback via bluealsa-aplay

bluealsa-aplay is a utility that obtains PCM from the BlueALSA PCM plugin and routes it to the "standard" ALSA PCM pipeline. It is used here to route BlueALSA's PCM to the GBD framework via the gbd ALSA virtual PCM device defined in section ALSA Period Size.

  • In economy GBD setups where the source of the audio is an external BT device, bluealsa-aplay will run on the GNU/Linux PC/laptop. The ipaddr parameter of the gbd virtual PCM device will point to the Rpi machine.

  • Otherwise, in economy GBD setups where the source of the audio is an application running locally on the PC/laptop, or in standalone RPi setups where the source of the audio is an external BT device, bluealsa-aplay executes on the RPi machine. Here, the ipaddr parameter points to the loopback IP address.

bluealsa-aplay accepts a number of options. Use the -h|--help switch to view them. It accepts a BT MAC address for a specific BT device or the empty MAC address 00:00:00:00:00:00 which instructs it to accept connections from any BT device.

Execute bluealsa-aplay with:

pi@raspberrypi:~ $ bluealsa-aplay 00:00:00:00:00:00 -d gbd -vv [--pcm-period-time 23219]
Selected configuration:
  HCI device: hci0
  PCM device: gbd
  PCM buffer time: 500000 us
  PCM period time: 23219 us
  Bluetooth device(s): ANY
  Profile: A2DP
Used configuration for 43:29:12:DF:78:CD:
  PCM buffer time: 500000 us (88200 bytes)
  PCM period time: 23219 us (4096 bytes)
  Sampling rate: 44100 Hz
  Channels: 2

where:

  • -d tells bluealsa-aplay to redirect the PCM read from BlueALSA PCM plugin to the gbd PCM device.

  • -vv is used to dump the ALSA PCM parameters. A single -v will only display the PCM parameters associated with BlueALSA PCM plugin side. Double -vv is used to also allow viewing the PCM parameters for the GBD framework.

  • The optional --pcm-period-time 23219 parameter specifies the ALSA output latency. This switch will be required if using the plughw based gbd PCM device definition.

    The ALSA output latency is related to the ALSA period size via:

    period_time = period_size / sample_rate
    

    In this case:

    23219 us = 1024 (ALSA frames) / 44100 Hz
    

    Recall that the bluealsa daemon was launched with the --a2dp-force-audio-cd switch (see section A2DP). This results in the 44100 Hz sample rate, stereo channel count and 16-bit PCM. Therefore for 1024 ALSA period frames, the number of bytes in the signal will be given by:

    1024 (frames) * 2 (channels) * 2 (bytes per channel) = 4096 bytes
    

    Thus the 4096 bytes value printed against the PCM period time: 23219 us entry.

So, to be sure that bluealsa-aplay is actually sending 1024 ALSA period frames (16-bit PCM per channel for a stereo channel count), always check for the 4096 bytes value. Especially with the plughw based gbd PCM device definition, mistyping (or omitting) the right value for --pcm-period-time could result in, say,

PCM period time: 21333 us (3760 bytes)

... which will either not work well with GBD, or not even work at all.