Random Quote Board

Demodulating Radio Broadcast Data System (RBDS) with Gnu Radio

Gary Schafer, August 2021

20 November 2020 marked the 100th anniversary of the first commercial radio broadcast of KDKA in Pittsburgh. That station used amplitude modulation (AM), specifically double sideband, full carrier AM.

The Federal Communications Commission (FCC) issued the first grant for a FM station (W2XMN in Alpine, NJ) to Edwin Armstrong in 1936, and a license in 1938. More stations followed. In 1945, the FCC stated that,

The Commission may grant experimental authority to an FM station for the multiplex transmission of facsimile or other signals and aural broadcast programs...

The idea was this. FM broadcast stations were primarily setup for audio broadcast. The FCC was saying, "You can also transmit other information on an experimental basis, so long as it does not interfere with your primary audio broadcast." That "other information" would be modulated onto low frequency (tens of kHz) carrier waves, added together with the main audio, then modulated onto the RF carrier. This would create a composite signal combining several signals together.

Thus began the idea of "subcarriers", or secondary channels of information transmitted on FM broadcast stations. Subcarriers became a way of multiplexing different information onto the same carrier.

The Federal Register of March 25th, 1955, stated that WTOP, an FM broadcast station in Washington, DC, had already tested this idea of "sub-channels" on their own station in the summer of 1953. Those tests showed that facsimile, teletype and voice communications could also be "impressed" (modulated) onto the main carrier without affecting the main carrier operation. This was their conclusion:

It is our conclusion, based on these reports and our knowledge of the multiplex facsimile operation, that multiplex operation by FM broadcast stations is feasible. Feasibility depends on satisfaction of two criteria: that the sub-channel operation not interfere with the main channel signal, and that the sub-channel signal be of usable quality.

The Radio Broadcasting Data System (RBDS)

Fast forward to 1984. European groups developed the Radio Data Service (RDS). It was a digital subcarrier designed to pass certain pieces of information. This included program type (jazz, rock, etc), program identification (identify the station, such as by call letters), and program service information (originally just static station information, but now generally station name, song artist, and song title).

The US adopted a similar system which it called "Radio Broadcasting Data System (RBDS)" in 1992. That system is now installed on many, if not most, FM broadcast stations here in the US.

Many, if not most, stations nowadays will carry several such "sub-channels" of information. Below is but one example. This one is from WETA, an FM broadcast station also in Washington, DC.

Baseband spectrum of a FM broadcast station, specifically WETA (90.9 MHz) in Washington, DC. This is a typical station transmitting stereo audio. The spectrum from 0 - 15 kHz is both left (L) and right (R) channels combined. At 19 kHz, there is a pilot tone. This tone serves multiple purposes. First, its appearance tells your radio that it is receiving a stereo signal. Its second purpose is to demodulate the "L-R Audio", also called the "stereo signal", at 38 kHz (second harmonic) followed by the "RBDS" signal at 57 kHz (third harmonic). The last signal is a "SCA" or "Subsidiary Communications Authority". It's purpose is typically to provide a secondary audio signal.

Before we get too far into the weeds, let's make certain we all understand some basics of digital signals. First, there is the encoding, or how the digital bit stream is put together. This refers to how the bit stream is created based on the information it contains (source coding) as well as how it is further altered based on randomization, channel coding (error correction, synchronization, framing), interleaving, line coding, and pulse shaping. The second aspect is the modulation, meaning how the signal is impressed onto the carrier in order to convey the information from point A to point B.

The RBDS starts as four groups, with a 16 bit block in each group. Those four groups of 16 bits represent a lot of information. RBDS provides information on the type of station (classical, rock, religion, etc), the name of the current song, the artist, the station identifier, and even the current date and time.

A 10 bit checkword is added to each block to create four groups of 26 bit blocks each. There's a fair amount of processing that goes along with the creation of these checkwords. The result is a fair amount of redundancy in the signal, such that the efficiency of the signal has dropped to just over 61%. The upside is that the information can be recovered even with a relatively low signal-to-noise ratio (SNR).

An RBDS signal starts with 10 bit information blocks, which are then padded with a 10 bit checkword for each block. This gives them a rough efficiency of 61% (16/26 x 100%). (Image source: "United States RBDS Standard", National Radio Systems Committee, April 1998)

The bit stream is then differentially encoded. At this point, it has a bit rate of 57000/48 = 1187.5 Hz. The bit stream is Manchester encoded. Manchester encoding is a dipolar line coding, which means it has no DC component. It does, however, double the bit rate (2375 Hz). It's pulsed shaped (filtered). (NOTE: In one of those "Well, actually..." moments, the original design has the pulse shaping and Manchester encoding occurring at the same time.) The modulation is two-level amplitude shift keyed (2ASK) suppressed carrier. This is identical to a 2-level phase shift keyed signal. The carrier center frequency is 57 kHz, or three times the pilot tone frequency of 19 kHz.

Time domain view of a RBDS signal. This is the RBDS from 90.9 MHz (WETA) in Washington, DC.

Demodulating RBDS

Demodulating and decoding a RBDS signal is the reverse of the above process.

NOTE: For this demonstration, I'm using Gnu Radio Companion 3.8 running on Linux Mint 20.2. I've also installed "gr-rds" from "Software Manager". I was able to make this work on Windows 3.7, but I had to disable all of the QT GUI displays and set the "Options" block to "WX GUI" for the RDS decoder. In other words, with Windows 10 and GRC 3.7, I can either have the various time and frequency displays or I can have the RDS display.

I'm just going to provide the whole Gnu Radio graph up front, then I'll walk through it a section at a time. I've made liberal use of virtual sinks and sources. That keeps down the number of lines, and makes the graph less scary. Each source / sink marks a new section. There are five sections in total. Let's go through them one at a time.

This is the full RBDS decoder. I've broken it down into five sections, with each section performing a distinct function.

FM Demodulator

Before we can demodulate the RBDS signal, we first need a RBDS signal. This requires finding a FM broadcast signal containing a RBDS signal. Most FM broadcast stations I've seen have such signals. I've outlined several, possible frequency demodulators that you can use to access the baseband of the FM station. For this post, I'm going to use a basic (and poorly named) "Quadrature Demod" block. This is a polar discriminator.

The first section is a basic frequency demodulator. It starts with the SDR source block (a RTL-SDR, in this case), passes through a lowpass filter to isolate the analog portion of a FM broadcast station, then is followed by a polar discriminator ("Quadrature Demod" block). The output is the full baseband signal of the FM broadcast station tuned to the center frequency of the SDR. The virtual sink will be used to send the baseband signal to the circuitry that will isolate, demodulate and decode the RBDS signal.
Baseband spectrum of FM broadcast station. This is WETA (90.9 MHz) in Washington, DC. A green box surrounds the RBDS signal centered at 57 kHz.
These are the properties of the lowpass filter used to isolate the analog FM broadcast signal.
Properties for the "Quadrature Demod" block used to frequency demodulate the FM broadcast signal.
Properties for the "QT GUI Frequency Sink" used to display the baseband spectrum of the FM broadcast signal.
Import properties showing how the value for "pi" is created. If this does not work (for whatever reason), then use a "Variable" block with the ID set to "pi" and the value set to "3.1415927".

RBDS Filter

The next step is to isolate the RBDS signal from all of the other baseband signals. I'm going to use a complex frequency shift so that I don't have to filter the signal first. I'm going to shift the signal down to 0 Hz, then use a single lowpass filter to isolate it. Shifting the RBDS signal to 0 Hz will also prepare it for demodulation.

This section complex frequency shifts the RBDS signal down to 0 Hz. It then uses a single lowpass filter to isolate it. The "Rational Resampler" block changes the signals sample rate to 57 kHz. RDS symbol rate is 57 kHz / 48 = 1187.5. By setting the sample rate to this value (57 kHz), we wind up with an integer number of samples per symbol (48).
The "Signal Source" block used to create the complex sinusoid that will frequency shift the RBDS signal to 0 Hz.
Properties for the baseband lowpass filter. This filter is used to isolate the RBDS signal. The symbol rate of the RBDS signal is twice the bit rate. The bit rate is 57 kHz / 48 = 1187.5 Hz. The symbol rate is thus 1187.5 x 2 = 2375 Hz.
This "Rational Resampler" block adjusts the sample rate to 57 kHz. This makes the follow-on processing easier as each symbol will be an integer number of samples.
The "AGC2" block uses the defaults. It simply ensures that the amplitude of the RBDS signal will be adequate for the follow-on processing.
Properties of the first constellation sink. This display will show the raw constellation of the RBDS signal before it has been frequency and phase synced.

RBDS Timing Sync

This section synchronizes the samples with the center of each bit. It performs a matched filtering using a root raised cosine (RRC) with an alpha value of 0.35, then performs the Manchester decoding. The Costas loop phase syncs the constellation. The output is a stable 2-point constellation. The nice thing about this circuit is that it does not rely on a 19 kHz pilot tone in order to properly lock to the RBDS signal. This is good because (a) not all stations have a 19 kHz pilot tone and (b) even those stations that do have such a pilot tone don't use it to sync with the RBDS signal. (NOTE: I discovered at least three stations here in the Washington, DC and Baltimore area that don't use the pilot tone to phase lock with the RBDS signal. That was an interesting discovery.)

This section takes the filtered, baseband RBDS signal and synchronizes the phase. The output will be a signal that varies between -1 and +1.
This is the "Polyphase Clock Sync" block properties. This block will sync to the optimum sample points for each bit. It will not actually phase sync to the RBDS signal.
This is the properties for the "RRC Filter Taps" block. This calculates the taps for the root raised cosine (RRC) filter used in the "Polyphase Clock Sync" block.
Properties for the Costas loop. This will frequency and phase sync the RBDS signal. The output will be the raw RBDS signal shifting along the real axis.
This is the same AGC2 as before. This AGC block ensures that the values of the RBDS signal vary between +1 and -1. This lines them up properly for the demodulation in the next section.

The short video below shows how the circuit syncs its timing to several, different RBDS signals.

RBDS Demodulation

Okay, we have the RBDS signal isolated, and we're synchronized to the bit stream. At this point, you should have a constellation diagram that shows two clusters, one at -1 and another at +1, both on the real line. The next step is to actually demodulate the signal. To do so, I'm going to use the fact that a two-level amplitude shift keyed (ASK) signal with suppressed carrier is identical to a binary phase shift keyed (BPSK) signal. After that, it's the process of stripping off the differential encoding. Here's the interesting thing about the differential encoding. While I have a Costas loop above, it's not needed for this circuit. The differential encoding means that the bit stream doesn't care about the absolute value of each bit, but only the transition between bits. So long as we have clear transitions, the signal will decode properly.

The demodulator section starts by demodulating the synced RBDS signal as BPSK, then decoding the differential encoding.
The constellation decoder simply uses the values as provided by the "Constellation Object" block.
The signal is a BPSK signal, and the "Constellation Object" block provides this as a drop-down choice.
The "Differential Decoder" block changes the bit stream such that the transitions determine the bits, not the actual bit levels themselves.
This is the time sink that shows the demodulated RBDS bit stream.
This is the raster that shows the time domain demodulated bit stream.

RBDS Decoder and Display

The last part is to actually decode the RBDS bit stream and display the actual information. For this, we need three, separate blocks in Gnu Radio. These are shown below.

These three blocks have no, real user settings. You're not adjusting a sample rate, or telling Gnu Radio how many samples per symbol, or setting the bit rate or bandwidth of the system in these blocks. Yet these three blocks are probably performing the vast majority of the processing in this entire graph. These blocks have to ensure that the bits were properly received using the checkword, which itself requires a fair amount of processing. Then it has to parse out what the bits mean which, again, means a bit of processing. The point is that the people who put together the "gr-rds" branch of Gnu Radio deserve a lot of praise for making this plug-in.

The first two blocks actually decode the bit stream and turn it into text that the RDS panel displays.

RBDS Display Examples

I chose four, different stations as demonstrations for my demodulating and decoding circuit. These are shown below.

This is from WETA (90.9 MHz in Washington, DC). Along with the RBDS, the baseband spectrum has both a standard, stereo audio signal plus a SCA subcarrier at 67 kHz.
This is the graph when applied to WRBS (95.1 MHz in Baltimore, MD). Of note is that this RBDS signal provides a date / time string.
This is the display from WDCH (99.1 MHz in Washington, DC). Of note with this signal is the lack of a 19 kHz pilot tone and stereo signal. This is an all-talk radio station.
This is the display from WTOP (103.5 MHz in Washington, DC). It, too, lacks a 19 kHz pilot one and stereo signal. Of interest with this signal is that it is the one that takes the longest to phase lock and achieve a 2-point constellation. It probably takes a full minute typically for that to occur. However, due to the differential encoding, the graph is still able to recover the display text within seconds of being tuned to this station. Also, this is the same station that tested subcarriers back in 1953, or 68 years ago, though it was at a different frequency (96.3 MHz, H/T TMW).


This was another fun post to put together. Who am I kidding? They're all fun. If they weren't, I wouldn't be doing this. Regardless, I enjoyed putting this post together due to the combination of analog and digital techniques this type of signal combines. We'll see where it takes me for my next post.

Here's a Random Fact...