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.
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 thousand dollar computers with thousand dollar SDR hardware. Where as this is made for $20 SDRs plugged into $20 computers.
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.
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.
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.
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 -W -f 89.1M | play -r 32k -t raw -e signed-integer -b 16 -c 1 -V1 -
This will tune to a broadcast FM station.
-f gives the frequency to tune in.
-W 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 -N -s 170k -o 4 -A -r 32k -l 0 -D | play -r 32k ...
- '-f ...' indicated the frequency to tune to
-Nmeans narrowband FM
-s 170kmeans to sample the radio at 170k/sec
-o 4indicated to sample at 4x the requested rate and downsample later
-Auses a fast polynominal approximation of arctangent
-r 32kmeans to lowpass/resample at 32kHz
-l 0disables squelch
-Dapplies a deemphesis filter
Needless to say, this is a lot just to listen to the local radio. So use
Operating police scanners is illegal in some countries, notably Germany.
rtl_fm -N -E -f 154.42M -f 154.75M -f 154.82M -f 154.89M -s 12k -o 4 -g 49.2 -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.
-Eedge tuning. This gets a whole paragraph of explanation below.
-f ...frequency to tune, use multiple times for scanning
-s 12ksample rate, about as narrow as possible for FM voice
-o 4same as above
-g 49.2set gain to maximum (use a value appropriate to your dongle)
-l 70set squelch to 70. The exact values varies a lot. Changing the gain or sample rate will require a change in the squelch to compensate.
The airband has a lot of channels to scan. Explicitly listing them all is not practical, so use a channel range.
rtl_fm -M -f 118M:137M:25k -s 12k -g 49.2 -l 280 | play -r 12k ...
-f start:stop:intervala range of frequencies to scan
-s 12ksame as above
-g 49.2same as above
-l 280squelch level, exact value varies a lot
Pagers are considered private communications in some areas and may be illegal to read.
rtl_fm -N -E -f 929.77M -s 22.5k -o 4 -g 11.5 -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 22.5k (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.
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
If you want to stream directly to a file, provide the file name as the final argument.
-N | -W | -M | -L | -U | -R
Selects a demodulator.
-Nnarrow band FM
-Wwide band FM
-Rraw 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.
Bandwidth of signal.
When using multiple dongles, this indicated which.
A floating point gain value. Find legal values with
Correct for the parts-per-million error in the crystal.
Enable a slightly higher quality downsampling FIR than the default boxcar filter.
Enable a polynomial approximation of arctan. Fast and integer based.
Enables deemphasis filter used in WBFM.
These kind of stink and are complicated and hard to explain.
Enables edge tuning. In the NBFM world, it is very common to specify the lower edge of the used bandwidth. For example, a NBFM transmitter operating with 20kHz bandwidth on 150MHz can be tuned with either
rtl_fm -E -f 150M -s 20k ... rtl_fm -f 150.010M -s 20k ...
By default this is disabled.
-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.
With FM demodulation it is common to sample much faster than the actual bandwidth and downsample later to improve sound quality. This sets an integer multiple to scale the bandwidth. Default is 1 (no oversampling) but
-o 4 is recommended. It has no effect on the output rate.
-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 stage. This is for that, but most of the time it is rarely needed. It will also change the output rate.