Updates for rtl_fm overhaul

Original The long lost documentation Updates for rtl_fm overhaul Editable
version 2 of 2

Rtl_fm is a little utility I wrote for the rtl-sdr project. The program was made to fill a gap in software defined radio: all the computers weaker than a Pentium 4. Basically, an Atom processor processor does not have enough oomph to demodulate something as simple as narrow band FM using the standard tools. (Recently a high performance FM demodulator was released, Simple FM but it works only passably on newer Atoms.) So rtl_fm was written with one goal, efficiency, in mind.

Fernando (2016-06-02-01-55-00-432)

"Atom processor processor"

The very first version ran with plenty of cycles to space. As an unexpected bonus, it ended up being efficient enough to easily run on small ARM boards such as the Raspberry Pi. GnuRadio is a really great program easily worth a thousand bucks. But it was designed to run on $500 computers with $500 SDR hardware. Where as this is made for $20 SDRs plugged into $20 computers. More powerful windows and OSX machines can easily handle several instances of rtl_fm at once.

Herb (2015-10-30-13-37-52-340)

cycles to space should be cycles to spare.

Rtl_fm is a general purpose analog demodulator. It can handle FM, AM and SSB. It can scan more than a hundred frequencies a second. For digital modes, piping the audio into multimon-ng works very well. On a Raspberry Pi, rtl_fm + multimon uses just over half of the CPU. If you are interested in ADS-B decoding, check out the rtl_adsb utility. It uses only 6% CPU on a Raspberry Pi and can run on targets as small and adorable as a 16MB TL-R703N. If you are using Arch Linux, I've already packaged these tools for you and you can install them with pacman -S rtl-sdr. If you need something more specific, feel free to send me an email.

bcfh (2015-01-20-04-02-41-366)

Throughout this guide, I'll be using Sox's play command to play the audio. This is because Sox works on Linux, OSX, Windows and pretty much anything else you can run a compiler on. (If you are using Windows, rename the sox binary to play first.) Sox will automatically resample the audio to keep your soundcard happy and can apply denoising filters to keep your ears happy. If you want to run closer to the metal, feel free to use the utilities provided by Alsa or OSS or Pulse. But I won't be talking about them in this guide.

hsk (2017-01-11-05-00-03-941)

My configuration (R820T) is ..

/usr/local/bin/rtl_fm -f $freq -g 50 -M fm -s 200k -A std -l 0 -E deemp -r 75k | /usr/bin/lame -r -s 75 -V 5 --lowpass 15 --resample 44.1 -m m -b 64 - -

..and it works great!!

Before starting, make sure your dongle works.
rtl_test should return a list of supported gain values and not produce error messages. Make sure you are using a USB 2.0 port as well, otherwise you get really weird errors.

Kevi_test n Groce (2014-02-01-07-25-59-003)

Issues using this on a Pi under Arch. Doing rtl_test does nothing just returns back to command line. I hear that the default dvb-t drivers wont work so i went in and lsmod and

blacklist dvb_usb_rtl28xxu blacklist rtl2832 blacklist rtl2830

Reboot and still nothing.

John (2015-03-31-21-41-45-954)

Note the gain values here are essentially in dB. Trying to find the sweet spot for POCSAG decoding but it's not easy :/

Jack (2016-12-17-03-52-24-241)

I want two have two RTL usb dongles one for DVB and one for FM how can I blacklist the kernel driver for just one of the devices. P.S. They are identical thanks

It is also very important to always make sure rtl_fm and Sox are both set to use the same data rate. This is probably the most common problem people run into.

Music on the Radio

rtl_fm -M wbfm -f 89.1M | play -r 32k -t raw -e s -b 16 -c 1 -V1 -
Daniel (2014-09-18-10-25-15-007)

I have a big problem with tuning the range will always be off by a matter of tens to hundreds of K how can i solve this problem?

for fm stations this is not really a problem but for narrow band this is a pain i cannot tune into any other bands correctly besides fm.

JOJOPI (2015-03-31-14-39-45-352)

Because the bandwith of the modulation of a stereo WBFM signal is 75kHz and the HF-bandwith of the signal is 150kHz you should type in: rtl_fm -M wbfm -f 89.1M -s 150k -r 75k | play -r 75k -t raw -e s -b 16 -c 1 -V1 -

Alan Corey (2016-07-17-17-45-00-888)

You can probably set your ppm error correction close enough for most purposes by using something like gqrx where you have a GUI. In the US there are narrowband FM stations continuously transmitting weather forecast loops around 162.4 MHz. If you listen they announce the frequency in the broadcast. With gqrx (or maybe hdsdr over a connection to rtl_tcp) click on a peak and zoom in until you get it centered, meanwhile listen for the frequency. Adjust the ppm until the displayed frequency matches what they announce. Write that on a sticker on the dongle, it won't change. You'll always have the same error no matter what mode or what program. I have 2 dongles with 59 and 102 ppm errors, those have been constant for years.

chibill (2017-02-26-20-28-34-430)

No longer works sox spits out an error about not enough input file names.

Igmu (2018-02-18-22-37-40-734)

I tried using your example

rtl_fm -M wbfm -f 89.1M | play -r 32k -t raw -e s -b 16 -c 1 -V1 -

but I get an error,

`Found 1 device(s): 0: Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM Found Rafael Micro R820T tuner Tuner gain set to automatic. rtl_fm: symbol lookup error: rtl_fm: undefined symbol: rtlsdr_set_bias_tee `

This will tune to a broadcast FM station.
-f gives the frequency to tune in.
-M wbfm says to use wideband FM mode, but this is really a shortcut for a tweaked narrowband FM mode. It expands fully into

rtl_fm -f 89.1M -M fm -s 170k -A fast -r 32k -l 0 -E deemp | play -r 32k ...
  • '-f ...' indicated the frequency to tune to
  • -M fm means narrowband FM
  • -s 170k means to sample the radio at 170k/sec
  • -A fast uses a fast polynominal approximation of arctangent
  • -r 32k means to lowpass/resample at 32kHz
  • -l 0 disables squelch
  • -E deemp applies a deemphesis filter
Max Santos (2018-06-14-19-48-28-980)

-E deemp applies a deemphesis filter, deemphesis shoul be spelled deemphasis

Max Santos (2018-06-15-09-42-13-384)

-E deemp applies a deemphesis filter, deemphesis should be spelled deemphasis

Needless to say, this is a lot just to listen to the local radio. So use -M wbfm instead. If conditions are poor you might need to manually add some gain with -g 20 or so.

kk (2014-02-03-14-15-35-780)

But if you want it to sound nice, you'll need the following incatation:

rtl_fm -g GAIN -f FREQ -M fm -s 200k -E deemp | play -r 200k -t raw -e s -b 16 -c 1 -V1 - lowpass 16k

Andre F (2014-05-02-03-37-59-334)

What about Miroslav's -X option

ref: http://permalink.gmane.org/gmane.comp.mobile.osmocom.sdr/299

Police Scanner

Operating police scanners is illegal in some countries, notably Germany.

rtl_fm -M fm -f 154.42M -f 154.75M -f 154.82M -f 154.89M -s 12k -g 50 -l 70 | play -r 12k ...

This one will take a lot more fiddling to work properly. First, you of course need channels used by your municipality. And this will only work if your local services have not upgraded to P25 or some other trunked system.

  • -M fm narrowband FM
  • -f ... frequency to tune, use multiple times for scanning
  • -s 12k sample rate, about as narrow as possible for FM voice
  • -g 50 set gain to maximum (use a value appropriate to your dongle)
  • -l 70 set squelch to 70. The exact values varies a lot. Changing the gain or sample rate will require a change in the squelch to compensate.
kk (2014-01-25-19-36-01-539)

Add -F 0

Airband Scanner

The airband has a lot of channels to scan. Explicitly listing them all is not practical, so use a channel range.

rtl_fm -M am -f 118M:137M:25k -s 12k -g 50 -l 280 | play -r 12k ...
Paul (2017-08-16-14-03-17-179)

Airband should be wideband FM, not AM

Dave (2017-11-10-19-45-53-458)

Aircraft radio 108-136 MHz is and has always been AM.

  • -M am AM demodulation
  • -f start:stop:interval a range of frequencies to scan
  • -s 12k same as above
  • -g 50 same as above
  • -l 280 squelch level, exact value varies a lot

Pager Decoder

Pagers are considered private communications in some areas (notably the US) and may be illegal to read.

rtl_fm -M fm -f 929.77M -s 22050 -g 10 -l 250 | multimon -t raw /dev/stdin

Exact frequency and gain depends on your area. Most of these options should be familiar by now. The only new thing is -s 22050 (the only sample rate multimon supports) and the rather peculiar incantation multimon needs to use standard input. Frequency scanning also works in conjunction with multimon.

kk (2014-01-25-18-52-17-511)

Probably should use -E dc because multimon requires good zero crossings.

kk (2014-01-25-19-36-32-012)

-F 0 here too

Network Streaming

Maybe you have a poor quality wifi link and don't want to send a full 1MS/s data stream around. Here is how to make a quick and dirty mp3 stream that will average 4KB-8KB/sec for voice channels. Other codecs may be swapped in as desired.

On the dongle side:

rtl_fm ..... | sox -traw -r24k -es -b16 -c1 -V1 - -tmp3 - | socat -u - TCP-LISTEN:8080

On the loudspeaker side:

netcat don.gle.ip.adr 8080 | play -t mp3 -
Paul (2015-01-25-04-45-15-828)

Client side (Mint) reports:

play FAIL formats: can't open input '-':

Any ideas?

Paul (2015-01-25-06-04-47-627)

On further investigation, the port 8080 was the issue. Moving this command to port 18080 got rid of this error.

Suggest maybe sudo to run on port 8080?


kk (2015-02-18-06-37-39-173)

Q: start/stop rtl_fm automatically based on time

A: cron and timeout

Q: Rtl_fm says it tunes to some other frequency instead of mine.

This is normal behavior, to dodge the DC spike present in E4000 tuners. The software tunes slightly off center and then corrects for the offset during demodulation.

Q: How to do skip channels when providing a range?

You don't. Use multiple ranges instead.

Q: How do I filter noise?

That is really hard. But Sox provides filters for it and you can use these filters in your play command.

Complete Reference

If you want to stream directly to a file, provide the file name as the final argument.

-M fm | wbfm | am | usb | lsb | raw

Selects a demodulator.

  • -M fm narrow band FM
  • -M wbfm wide band FM
  • -M am amplitude modulation
  • -M lsb lower sideband
  • -M usb upper sideband
  • -M raw raw output, 2x16 bit IQ pairs. Purely debugging and no sane person has any use for this.

-f <freq> | <start:stop:step>

Tune to a frequency. Value can be specified as an integer (89100000), a float (89.1e6) or as a metric suffix (89.1M). Multiple values or ranges will be scanned.

Scanning requires a non-zero squelch level.

-s <sample_rate>

Mark S (2021-06-16-15-56-31-240)

I am confused with the use of "sample rate" and "bandwidth" here. Which is it?

Using sdr# I can set the sample rate and bandwidth independently. For example, the sample rate can be set to .25MSPS and the bandwidth can be set to 43hZ. The bandwidth is represented in sdr# by a highlight region in the ttf window.

Can you please wow each are set using rtl_fm. Thanks

Bandwidth of signal.

Evgeny (2020-07-05-16-42-13-005)

Why does sdr# produce 37k samples at 12.5k bandwidth (nfm mode)? How do I make this using rtl_fm?

-d <index>

When using multiple dongles, this indicated which. You can also identify dongles by the text in the serial number field of the EEPROM.

-g <gain>

A floating point gain value. The dongle will use the closest gain setting available.

-p <error>

Correct for the parts-per-million error in the crystal.

hs (2016-12-14-06-16-32-536)

Thanks for the great work! Hope rtl_fm has AFC feature in it (for wfm reception)

-F 0 | 9

Enable a higher quality downsampling FIR than the default boxcar filter.
-F 0 is okay to use while -F 9 is still a work in progress.

-A std | fast | lut

Choose how arctan is computed. Options select between the standard (floating) lib, a fast polynomial integer approximation and a precomputed look-up-table.

-E dc | deemp | direct | offset

  • -E dc dc blocking filter
  • -E deemp de-emphasis filter for WBFM
  • -E direct direct sampling mode
  • -E offset offset tuning mode (E4000 only)
Bernie McIntosh (2015-06-18-00-40-53-786)

What happened to the "-E pad" option ? This would be handy. Thanks

Use multiple -E option to enable multiple features.

Confusing Options

These kind of stink and are complicated and hard to explain.

-l <squelch level>

Squelch is required for scanning multiple frequencies, to indicated when a frequency should be skipped. When used with a single frequency the output will be muted instead. Default value is 0/off.

Squelch values are extremely sensitive to external conditions (noise and antenna) as well as the other options used. For example, squelch should be halved when the sample rate is doubled. When in doubt, start at zero and work upwards.

-t <squelch delay>

The number of squelch hits to count up to. Default value is 20. So the squelch must be trigger 20 times consecutively before rtl_fm moves on to the next channel.

Negative delay values cause rtl_fm to exit instead of hopping to another channel or muting the output. This is useful for scripts or trunked systems.

-r <output rate>

In some odd circumstances you might want to apply an extra low pass downsampling/resampling stage. This is for that, but most of the time it is rarely needed. It will also change the output rate. It is also a very poor quality resampler. Use sox for resampling.