An implementation of a DAB (digital audio broadcasting) radio using software defined radio.
For a description of what software defined radio is refer to this link.
This repository contains applications that:
- Demodulate the OFDM (orthogonal frequency division multiplexed) raw IQ signals into a digital frame
- Decode DAB digital OFDM frames for use into a radio application
The code in this project is purely academic. It can be considerably improved and optimised. Examples of more polished DAB projects is listed in the inspirations section below.
For those who are interested only in parts of the implementation refer to the following directories:
Directory | Description |
---|---|
src/modules/ofdm | OFDM demodulation code |
src/modules/dab | DAB digital decoding core algorithms |
src/modules/basic_radio | Combines all of the DAB core algorithms into a cohesive example app |
src/modules/basic_scraper | Attaches itself via callbacks to a basic_radio instance to save audio/slideshow/MOT data to disk |
src/utility | Small helper template library for general purpose use |
src/audio | Audio player library for playing through sound device |
src/gui | ImGui code for application user interface |
src/*.cpp | All our sample applications |
Download the ZIP archive from the releases page. Use git-bash or a shell that supports redirecting stdout.
Run ./get_live_data.sh -c [your_dab_channel] | ./basic_radio_app.exe
Refer to the code inside ./get_live_data.sh
for the list of possible frequency blocks where your DAB ensemble exists in.
Inside the GUI app go to the subchannels tab and wait for the database to update. Your list of radio stations will pop up. Click on any of them to start playing them. You can play multiple radio stations simulataneously.
Wohnort has an excellent website for viewing the list of DAB ensembles across the work. In Australia where I am, the blocks being used in Sydney are [9A,9B,9C]
.
If you can't find any DAB ensembles in your area, then you can download binary files from the Releases page. These contain raw IQ values as well as pre-demodulated OFDM digital frames. You can read in these files with the applications described in the application list.
Clone the repository using the command
git clone https://github.com/FiendChain/DAB-Radio.git --recurse-submodules -j8
Build the applications using cmake.
cmake . -B build -DCMAKE_BUILD_TYPE=Release
NOTE that the application was written for Windows and will not work with other platforms.
But the core algorithms are platform independent. You just need to write code to support other platforms. This includes the imgui GUI code, and the 16bit PCM audio player.
Name | Description |
---|---|
radio_app | The complete radio app with controls for the tuner |
bin/rtl_sdr | Reads raw 8bit IQ values from your rtl-sdr dongle to stdout |
basic_radio_app | Complete app that reads raw 8bit IQ stream and demodulates and decodes it into a basic radio |
basic_radio_app_no_demod | Reads in a digital OFDM frame from ofdm_demod_gui or ofdm_demod_cli and decodes it for a basic radio |
ofdm_demod_cli | Demodulates a raw 8bit IQ stream into digital OFDM frames |
ofdm_demod_gui | Demodulates a raw 8bit IQ stream into digital OFDM frames with a GUI |
convert_viterbi | Decodes/encodes between a viterbi_bit_t array of soft decision bits to a packed byte |
basic_radio_scraper | Reads raw 8bit IQ stream, demodulates and decodes the data, then saves it to disk |
basic_radio_scraper_no_demod | Reads in a digital OFDM frame from ofdm_demod_gui or ofdm_demod_cli, decodes the data then saves it to disk |
simulate_transmitter | Simulates a OFDM signal with a defined transmission mode, but doesn't contain any meaningful digital data. Outputs an 8bit IQ stream to stdout. |
./radio_app.exe
./get_live_data.sh -c 9C | ./basic_radio_app.exe
./get_live_data.sh -c 9C | ./basic_radio_scraper.exe -o ./data/9C_2/
./get_live_data.sh -c 9C | ./ofdm_demod_gui.exe > ./data/frame_bits_9C.bin
./get_live_data.sh -c 9C | ./ofdm_demod_gui.exe | ./convert_viterbi.exe > ./data/frame_bytes_9C.bin
./convert_viterbi.exe -d -i ./data/frame_bytes_9C.bin | ./basic_radio_app_no_demod.exe
NOTE: This is useful for testing changes to your DAB decoding implementation by replaying packed byte OFDM frames that you recorded previously.
./get_live_data.sh -c 9C | ./ofdm_demod_gui.exe | ./convert_viterbi.exe | tee data/frame_bytes_9C.bin | ./convert_viterbi.exe -d | ./basic_radio_app_no_demod.exe
NOTE: tee
is a unix application that reads in stdin and outputs to stdout and the specified filepath.
./get_live_data.sh -c 9C | ./ofdm_demod_gui.exe | ./convert_viterbi.exe | tee data/frame_bytes_9C.bin | ./convert_viterbi.exe -d | ./basic_radio_scraper_no_demod.exe
- Make OFDM demodulator more performant
Replace use of cosf and sinf in phase locked loop for fine freq compensationAdded multithreading to improve performance- Reduce overhead due to complex multiplication
Make DAB frame decoder more performantReplace inefficient general viterbi decoder with the SPIRAL project's implementation found here.
- Profile other parts of the code that are excessively slow
- Error correction
Use soft decision Viterbi decoding to improve error correction at low SNRIncrease the traceback length of the Viterbi decoder (Not preferrable due to currently slow implementation)- Determine how to use the firecode CRC16 in the AAC super frame to correct errors
- Improve the basic radio GUI
- Make a user friendly interface that is less technically involved
- Replace imgui with a less GPU/CPU hungry GUI framework
Integrate the rtl_sdr.exe code from the librtlsdr libraryAdd in ensemble scanning across possible block frequenciesAdd support for basic radio to handle multiple ensembles- Automatically scan ensembles and persist data
- Support the rest of the DAB standard
- MPEG-II audio for DAB channels
Stream/packet data for slideshows and extra programme information
- Add TII (transmitter identificaton information) decoding
- Add SNR meter
- Add view for OFDM symbol magnitude spectrum
- Persist DAB database on the hard disk
- Save as JSON
- Load from JSON at runtime if specified
- Add as much comments to link specific pieces of code to parts of the standard that were heavily referenced. This includes the specific document number, the specific clause and specific table/chart used.
Conform to rule of 0/3/5 by using stl containersDelete move/copy constructors for objects which rely on callbacks that take in pointersUse smart pointers to manage memory instead of manually managing memory- Fix up parts of the codebase which may have security vulnerabilities due to improper bounds checking, etc... there are a lot of possibilities
-
The welle.io open source radio has an excellent implementation of DAB radio. Their implementation is much more featureful and optimised than mine. Their repository can be found here. They also have a youtube video showcasing their wonderful software here.
-
There is a large community of rtl-sdr projects which can be found at rtl-sdr.com. This link points to a webpage showcasing several open source community projects that aim to decode DAB signals.
- ETSI the non-for-profit standardisation organisation for making all of the standards free to access and view. Without their detailed documentation and specifications it would not be possible to build a rtl-sdr DAB radio.
- Phil Karn for his Reed Solomon and Viterbi decoding algorithms which can be found here
- tcbrindle for his C++ single header template library implementation of std::span which can be found here