Skip to content
Oona Räisänen edited this page Nov 11, 2025 · 29 revisions

See also: Input formats

Note that you can exit Redsea in all of these cases using Ctrl+C.

Live decoding from RTL-SDR

To use Redsea with RTL-SDR you will need to first install the rtl-sdr package. It should include the FM decoder tool rtl_fm.

The full command to decode RDS live via rtl_fm, on an FM station at 87.9 MHz, is:

rtl_fm -s 171k -f 87.9M | redsea -r 171k

Redsea will run until Ctrl+C is pressed.

Experiment with rtl_fm options (e.g. -p, -g 20, -F 9) until you get the lowest error rate.

For Raspberry Pi 1 it's necessary to add -A fast to the rtl_fm options. This way more CPU cycles will be left to redsea.

Note that rtl_fm will tune the receiver a bit off-center; this is normal and is done to avoid the DC spike. See the rtl_fm FAQ for more about this behavior.

Beautifying the JSON output

You can get tidier json output using jq:

rtl_fm ... | redsea -r 171k | jq

It's also useful for extracting only certain fields, for instance the program type:

rtl_fm ... | redsea -r 171k | jq '.prog_type'

Or you can see which RT+ content-types the station is sending:

rtl_fm ... | redsea -r 171k | grep radiotext_plus | jq '.["radiotext_plus"]["tags"][]["content-type"]'

Decoding from AirSpy / HackRF / IQ

csdr can be used to demodulate streams from other radios on the command line, like AirSpy:

airspy_rx -f 87.9 -a 2500000 -g 9 -r /dev/stdout |\
  csdr convert_i16_f | csdr fir_decimate_cc 10 0.05 HAMMING |\
  csdr fmdemod_quadri_cf | csdr convert_f_i16 |\
  redsea -r 250k

Or HackRF:

hackrf_transfer -f 87900000 -s 10000000 |\
  csdr convert_i16_f | csdr fir_decimate_cc 40 0.0125 HAMMING |\
  csdr fmdemod_quadri_cf | csdr convert_f_i16 |\
  redsea -r 250k

Or any IQ file at baseband:

csdr convert_u8_f < iqfile.iq | csdr fir_decimate_cc 40 0.0125 HAMMING |\
  csdr fmdemod_quadri_cf | csdr convert_f_i16 |\
  redsea -r 250k

For the IQ file, make sure you choose the first conversion command according to the sample format of your IQ file. Also, make sure that the decimation ratio produces the correct sample rate.

You can even use csdr to shift another signal to baseband before decimation. The csdr readme has examples for frequency shifting.

Decoding MPX from a file or via sound card

It's easy to decode audio files containing a demodulated FM carrier. Note that the file must have around 128k samples per second or more. 171k will work fastest, because it doesn't require resampling internally.

redsea -f multiplex.wav

If your sound card supports recording at high sample rates (192 kHz) you can also decode the MPX output of an FM tuner or RDS encoder, for instance with this sox command:

rec -t .s16 -r 192k -c 1 - | redsea -r 192k

The raw PCM MPX input is assumed to be 16-bit signed-integer (.s16) single-channel (-c 1) samples.

Listening while decoding live

The --feed-through option echoes the input signal back to stdout. This lets you use both the original signal and the decoded RDS via different streams.

For example, the signal can be listened to using sox, while RDS groups are printed to stderr:

rtl_fm -M fm -l 0 -A std -p 0 -s 171k -g 20 -F 9 -f 87.9M |\
  redsea -r 171k --feed-through |\
  play -t .s16 -r 171k -c 1 -

Or you can use stereodemux to listen in stereo:

rtl_fm -M fm -l 0 -A std -p 0 -s 171k -g 20 -F 9 -f 87.9M |\
  redsea -r 171k --feed-through |\
  demux -r 171k |\
  play -t .s16 -r 171k -c 2 -

However, this only works with raw MPX input for now.

Writing RDS Spy compatible sample files

This command writes a hex-format outputfile with a timestamp in its file name.

rtl_fm -M fm -l 0 -A std -p 0 -s 171k -g 40 -F 9 $@ | \
  redsea -x -r 171k | tee `head -12l | tail -1l | \
  cut -d" " -f1`_`date +%F`_`date +%k`-`date +%M`-`date +%S`_$2Hz.spy

Receiving station logos (redsea 1.2+)

Some stations use RDS 2 to send the station logo.

This command waits for the picture and exits when the first one has been received.

rtl_fm ... | \
redsea --streams -r 171k |\
  grep file_contents |\
  head --lines=1 |\
  jq --raw-output .rft.file_contents |\
  base64 --decode > rft_file.bin &&\
  file --extension file.bin

Then rename file.bin appropriately so you can open it.

Clone this wiki locally