DEV Community

Cover image for A simple Broadcast Audio Source
Lars Knudsen 🇩🇰
Lars Knudsen 🇩🇰

Posted on • Edited on

A simple Broadcast Audio Source

Broadcast Audio Transmitters and Receivers

A simple BAP broadcast source (transmitter) that will be compatible with LE Audio broadcast receivers (e.g. some high-end earbuds available now) should advertise, including a field containing service data for the Broadcast Audio Announcement Service (0x1852) with a Broadcast ID as the data.
It also needs to provide LC3 encoded audio (the actual data) in isochronous channels which the periodic advertising train provides a pointer to.

LC3 is the new improved audio codec providing better quality with lower bandwidth.

Information about the source stream(s) is also provided through periodic advertising:

  • BIGinfo: Provides information needed by receivers to understand the stream (e.g. timings, possible encryption, etc.)
  • BASE (Broadcast Audio Source Endpoint): Contains information about the streams provided by the broadcast source, e.g. left/right channels, meta data like language and more

When a receiver is instructed to "tune in" to the broadcast (given Bluetooth LE address, Broadcast ID and Advertising Set ID), it will then be able to discover the correct broadcast source and synchronize to the broadcasted periodic advertising and eventually, decode and playback the audio broadcasted from the selected broadcast source (transmitter).

NOTE: This section only contains a very high level overview of the transmitter. For more details, Nick Hunn wrote an excellent book on LE Audio: Introducing Bluetooth LE Audio, 2nd Edition

Zephyr and LE Audio Broadcasting

The Zephyr RTOS contains some great Bluetooth LE Audio related samples. One of them is the Basic Audio Profile (BAP) Broadcast Source sample.

By default, this sample functions as a very simple broadcast transmitter, either transmitting (mock) sine wave audio or - if available and configured - functions as a USB sound card, transmitting audio provided through a USB interface (e.g. from a connected PC or phone).

Although this works well for some setups, for some test and development scenarios, it would be practical to have an array of broadcast sources, broadcasting (audible) different audio with minimal configuration and hardware needed.

nRF52840 Dongle and pre-encoded audio

As the sample already compiles and runs on the Nordic Semiconductor nRF52840 Dongle, it seemed reasonable to investigate if this dongle could be used for the purpose.

When building the bap_broadcast_source sample for the nRF52840 (with 1024 kB flash), memory usage is the following:

Memory region         Used Size  Region Size  %age Used
           FLASH:      260908 B      1020 KB     24.98%
             RAM:       62284 B       256 KB     23.76%
        IDT_LIST:          0 GB        32 KB      0.00%
Enter fullscreen mode Exit fullscreen mode

This should leave around 750 kB of flash memory, which could be used to contain audio data.

The bap_broadcast_source sample supports on-the-fly encoding of uncompressed PCM audio samples to LC3 encoded packets for broadcasting. But if we pre-encode the audio in LC3 format and store it in flash memory, we can eliminate the encoding step while also saving memory.

Taking a closer look at the liblc3 module used to encode/decode audio in Zephyr, originating from https://github.com/google/liblc3, shows that it also contains practical command line tools to encode and decode *.wav files to/from LC3 format.

Encoding a *.wav file, containing just above 2 minutes of 16 kHz, mono audio (input16KHz.wav at 4016868 bytes):

.../liblc3/bin$ ./elc3 -b 32000 input16KHz.wav output16KHz.lc3
Enter fullscreen mode Exit fullscreen mode

(32000 is the bitrate for 16 kHz LC3)

The result in output16KHz.lc3 is 527202 bytes of LC3 encoded audio data (including file and data packet headers), which is well below the limit of the 750 kB flash available.

For more information and full source code, look here

Capture with blueSpy

In an earlier post, I wrote about using the RFcreations mini-moreph together with the blueSpy software.

This time, it could be interesting to see what data it is able to capture from the nRF52840 Dongle, broadcasting 16 kHz (mono channel) audio.

Connecting the mini-moreph and starting capturing with the blueSpy software immediately finds the broadcast source with BT name Music and Broadcast name Hold on a Sec, which is chosen in the Filter Devices tab to focus on the advertising sent from the broadcast source dongle.

Looking at the timeline in the bottom, it's also possible to see the 16 kHz mono audio stream captured and correctly detected

blueSpy

full size

Now, if we select one of the entries in the summary pane, containing periodic advertising data and check out the Details pane, it's very easy to inspect both the BIGinfo:

BIGinfo

full size

And the BASE, which correctly shows a single subgroup with a single mono-channel 16 kHz BIS:

BASE

full size

Another cool feature is in the Audio Export panel, where it's both possible to listen to a selected BIS through the PC speaker and exporting to a file.

Audio Export

full size

Here I noticed yet another very nice feature. By right-clicking on the entries of captured source streams in the Audio Export panel, it's possible to generate a Broadcast Audio URI (with QR code):

Broadcast Audio URI

full size

By using the simple web test page, described in another post, I was able to verify the code:

QR scan

full size

Conclusion

In this post, we've covered how to create a simple, affordable standalone BAP Broadcast Source, broadcasting music in a loop from a tiny nRF52840 Dongle and how to capture audio and verifying BIGinfo and BASE with the RFcreations mini-moreph.

The full source code for the simple BAP broadcast source is available here.

Enjoy ;)

Top comments (0)