Adding Additional Bluetooth Codec Support to Moode 7.1

Moode 7.1 includes Bluetooth support and can act both as a receiver for playback and a player to Bluetooth headphones or speakers. By default it supports the standard SBC codec, which essentially everything supports. This is fine as a minimum, but we want to add support for more advanced or high quality codecs, including AAC (used by Apple devices such iPhones), AptX and AptX HD (higher quality, common on android), and LDAC (claimed highest quality, with more support as time goes on).

Because of license restrictions on these proprietary codecs I don’t think any can be shipped by default with a packaged build of Moode. But we want support so we’ll replace the included bluez-alsa package with one we compile ourselves.

This guide is current as of April 6, 2021, and assumes a fresh installation of Moode 7.1 and some familiarity with the command line. And yes we’re building everything from the current github commits rather than a formal release. It should work, but I don’t take any responsibility for broken upstream code. I rarely use Bluetooth, and this may not be reliable at all.

Moode 7.1 already has a full build environment, so we only need a limited set of additional packages to build this. The instructions for each package assume starting from the same root directory (in this case, the default home directory, /home/pi).

Dependencies

Let’s start with dependencies, including libraries for AAC, AptX, and LDAC support. The prerequesites to build bluez-alsa with these codecs supported are summarized below:

We’ll build and install each dependency here. Note that these tend to default to placing files in /usr/local but we’ll override to /usr. I don’t think we’ll clobber anything we don’t want to clobber.

Build FDK-AAC

Documentation for this library is very limited, but this should work.

# download the current code
git clone https://github.com/mstorsjo/fdk-aac.git
cd fdk-aac

# configure build environment
# we will install in /usr rather than /usr/local
autoreconf --install --force
mkdir build
cd build
../configure --prefix="/usr" --disable-shared

# compile and install
make
sudo make install

Build openaptx

Documentation on this is slightly better, but still pretty light. The default configuration in the instructions depends on sndfile, so we’ll install the system version and headers first.

# install libsndfile and development headers
sudo apt install libsndfile1 libsndfile1-dev

Now we can download and compile the openaptx code. I had success using FFMPEG and less success using the ENABLE_APTX422 and APTXHD1000 switches.

# download the current code
git clone https://github.com/Arkq/openaptx.git
cd openaptx

# configure build environment
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr -DENABLE_DOC=OFF -DWITH_FFMPEG=ON -DWITH_SNDFILE=ON ..

# compile and install
make
sudo make install

Build LDAC library

The third codec we compile is for LDAC support. I believe this enables Moode to output LDAC (and I have confirmed that works), but not to receive it. This may be a Sony licensing issue, but I am not certain.

# download the current code
git clone https://github.com/EHfive/ldacBT.git
cd ldacBT
git submodule update --init

# configure build environment
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr -DINSTALL_LIBDIR=/usr/lib -DLDAC_SOFT_FLOAT=OFF ..

# compile and install
make
sudo make install

Build BlueZ-ALSA

These commands area adapted from the moode builder scripts, with flags for the additional codecs we just compiled enabled. Additional documentation can be found on the main BlueZ-ALSA page and the instructions for installing from source.

This needs to be compiled only after successful installation of the other codecs.

# download the current code
git clone https://github.com/Arkq/bluez-alsa.git
cd bluez-alsa

# configure build environment
# only after all dependencies are done
autoreconf --install --force
mkdir build
cd build

# based on existing Moode build scripts with aac, aptx, and ldac enabled
../configure --disable-hcitop --with-alsaplugindir=/usr/lib/arm-linux-gnueabihf/alsa-lib --enable-aac --enable-aptx --enable-aptx-hd --enable-ldac

# compile and install
make
sudo make install

# reboot and test
sudo reboot

That should take care of everything. Just in case I recommend a reboot. Additional codecs should now work, with no change to basic usage from the stock installation.

Test

We’ll do a basic test, asking the system which codecs are available.

# get general information
bluealsa -h

$ bluealsa -h
Usage:
  bluealsa [OPTION]...

Options:
  -h, --help            print this help and exit
  -V, --version         print version and exit
  -B, --dbus=NAME       D-Bus service name suffix
  -S, --syslog          send output to syslog
  -i, --device=hciX     HCI device(s) to use
  -p, --profile=NAME    enable BT profile
  --a2dp-force-mono     force monophonic sound
  --a2dp-force-audio-cd force 44.1 kHz sampling
  --a2dp-keep-alive=SEC keep A2DP transport alive
  --a2dp-volume         native volume control by default
  --sbc-quality=NB      set SBC encoder quality
  --aac-afterburner     enable FDK AAC afterburner
  --aac-latm-version=NB select LATM syntax version
  --aac-vbr-mode=NB     select FDK AAC encoder VBR mode
  --ldac-abr            enable LDAC adaptive bit rate
  --ldac-eqmid=NB       set LDAC encoder quality
  --xapl-resp-name=NAME set product name used by XAPL
  
Available BT profiles:
  - a2dp-source Advanced Audio Source (LDAC, aptX-HD, aptX, AAC, SBC)
  - a2dp-sink   Advanced Audio Sink (aptX-HD, aptX, AAC, SBC)
  - hfp-hf      Hands-Free (v1.7)
  - hfp-ag      Hands-Free Audio Gateway (v1.7)
  - hsp-hs      Headset (v1.2)
  - hsp-ag      Headset Audio Gateway (v1.2)
  
By default only output profiles are enabled, which includes A2DP Source and HSP/HFP Audio Gateways. If one wants to enable other set of profiles, it is required to explicitly specify all of them using `-p NAME` options.

So the a2dp source (player to bluetooth headphones or speakers) and sink (receiver from phone or computer) functions have aptx-HD, aptx, AAC, and SBC support. Additionally, the source function has LDAC support.

Receiver Test

Let’s connect an iPhone and test output. We use the standard BlueZ audio configuration settings in Moode for bluetooth receiver function: - Bluetooth: On - Pairing Agent: On

Pair the iPhone as usual, and let’s use Apple Music to play a track. We see the system is using AAC now.

$ bluealsa-aplay -L

[some warnings snipped]
    A2DP (AAC): S16_LE 2 channels 44100 Hz

Let’s do the same but on an older Android tablet. Pairing and playing music we see it’s using aptX now. I see the same result playing from a Windows 10 laptop.

$ bluealsa-aplay -L

[some warnings snipped]
    A2DP (aptX): S16_LE 2 channels 44100 Hz

Player Test

So that was input. We’ll connect Moode output to an inexpensive set of bluetooth headphones (don’t forget to change MPD Output to Bluetooth on the BlueZ configuration page). For some reason MPD defaults to 0 volume, so you’ll need to turn that up too.

So we’re connected using aptX again. Let’s try LDAC next.

$ bluealsa-aplay -L

[some warnings snipped]
    A2DP (aptX): S16_LE 2 channels 44100 Hz

I don’t have any headphones with LDAC support, but I can connect my Sony Walkman and use that as a receiver. And we see (and hear) LDAC working.

$ bluealsa-aplay -L

[some warnings snipped]
    A2DP (LDAC): S32_LE 2 channels 96000 Hz

Usage

Usage is the same as with a stock installation of Moode 7.1, the choice of protocol should be automatically negotiated by the player and receiver.

Posted on 06 April 2021