airspy-fmradion
Software decoder for FM/AM broadcast radio with AirSpy R2 / Mini, Airspy HF+, and RTL-SDR
C++★ 167⑂ 19 forksGPL-3.0updated 3 days ago
git clone https://github.com/jj1bdx/airspy-fmradion.gitjj1bdx/airspy-fmradionREADME.mdfork it — it’s yours
airspy-fmradion
- Version 20260725-0
- For macOS (Apple Silicon) and Linux
Contributing
See CONTRIBUTING.md for the details.
Known issues and changes
- Please read CHANGES.md before using the software.
- Refer to doc/old-README-until-2023.md for the other miscellaneous technical details.
What is airspy-fmradion?
- airspy-fmradion is software-defined radio receiver (SDR) software with command-line interface.
What does airspy-fmradion provide?
- Supported SDR frontends: Airspy R2/Mini, Airspy HF+, and RTL-SDR
- Playing back from I/Q WAV files
- Monaural/stereo decoding of FM broadcasting stations
- Monaural decoding of AM stations
- Decoding NBFM/DSB/USB/LSB/CW/WSPR station audio
- Playback to soundcard through PortAudio or saving to file through libsndfile
- Command-line interface
Usage
# Portaudio output
airspy-fmradion -t airspy -q \
-c freq=82500k,srate=1000k,lgain=2,mgain=0,vgain=10 \
-P -
# 16-bit signed integer WAV output (pipe is not supported)
airspy-fmradion -t airspyhf -q \
-c freq=82500000,srate=384000 \
-W output_s16_le.wav
# 32-bit float WAV output (pipe is not supported)
airspy-fmradion -m am -t airspyhf -q \
-c freq=666k \
-G output_f32_le.wav
airspy-fmradion requirements
- Linux / macOS
- C++20 (gcc, clang/llvm)
Required libraries:
The following repository is fetched as a git submodule:
- r8brain-free-src, a sample rate converter designed by Aleksey Vaneev of Voxengo
Repositories in the following list are automatically fetched from CMake during the build process:
Git branches and tags
- Official releases are tagged
- main is the "production" branch with the most stable release (often ahead of the latest release though)
- dev is the development branch that contains current developments that will be eventually released in the main branch
- Other branches are experimental (and presumably abandoned)
Prerequisites
Debian/Ubuntu Linux
sudo apt-get install cmake pkg-config \
libusb-1.0-0-dev \
libasound2-dev \
libairspy-dev \
libairspyhf-dev \
librtlsdr-dev \
libsndfile1-dev \
portaudio19-dev \
libvolk2-dev
macOS
- Install HomeBrew libraries as in the following shell script
- Use HEAD for
airspyandairspyhf
brew update brew install portaudio brew install libsndfile brew install rtl-sdr brew install airspy --HEAD brew install airspyhf --HEAD brew install volk brew install fmt
Install the supported libvolk
- Install libvolk as described in libvolk.md.
- Run
volk_profileand save the configuration data for speed optimization.
Install the supported libsndfile for MP3 capability
- You may need to install libsndfile as described in libsndfile.md.
Installation
/bin/rm -rf build mkdir build git submodule update --init --recursive cmake -S . -B build cmake --build build --target all
Basic command options
-m devtypeis modulation type, one offm,nbfm,am,dsb,usb,lsb,cw,wspr(default fm)-t devtypeis mandatory and must beairspyfor Airspy R2 / Airspy Mini,airspyhffor Airspy HF+,rtlsdrfor RTL-SDR, andfilesourcefor the File Source driver.-qQuiet mode.-c configComma separated list of configuration options as key=value pairs or just key for switches. Depends on device type (see next paragraph).-d devidxDevice index, 'list' to show device list (default 0)-MDisable stereo decoding-R filenameWrite audio data as rawS16_LEsamples. Use filename-to write to stdout-F filenameWrite audio data as rawFLOAT_LEsamples. Use filename-to write to stdout-W filenameWrite audio data as RF64/WAVS16_LEsamples. Use filename-to write to stdout (pipe is not supported)-G filenameWrite audio data as RF64/WAVFLOAT_LEsamples. Use filename-to write to stdout (pipe is not supported)-C filenameWrite audio data to MP3 file of VBR -V 1. Use filename '-' to write to stdout. (This function is available when linked with supported libsndfile only.)-P device_numPlay audio via PortAudio device index number. Use string-to specify the default PortAudio device-L msSet PortAudio output suggested latency in milliseconds. Valid range: 1 to 40 (default: floored at 40 milliseconds) (-Lis ignored unless PortAudio output (-P) is used). See Output latency and the-Loption for the measured delays-T filenameWrite pulse-per-second timestamps. Use filename '-' to write to stdout-XShift pilot phase (for Quadrature Multipath Monitor) (-X is ignored under mono mode (-M))-USet deemphasis to 75 microseconds (default: 50)-fSet Filter type- for FM: wide and default: none, medium: +-156kHz, narrow: +-121kHz
- for AM: wide: +-9kHz, default: +-6kHz, medium: +-4.5kHz, narrow: +-3kHz
- for NBFM: wide: +-20kHz, default: +-10kHz, medium: +-8kHz, narrow: +-6.25kHz
-l dBEnable IF squelch, set the level to minus given value of dB-E stagesEnable multipath filter for FM. Size this to the echo delay spread (For stable reception only: turn off if reception becomes unstable). The value is between 1 to 1024.-r ppmSet IF offset in ppm (range: +-1000000ppm) (Note: this option affects output pitch and timing: use for the output timing compensation only!
Timestamp file format
- For FM:
pps_index sample_index unix_time if_level - For the other modes:
block unix_time if_level - if_level is in dB
Output audio specification
- Output maximum level is nominally -6dB (0.5) but may increase up to 0dB (1.0)
- Output audio sample rate is fixed to 48000Hz
FM multipath filter
- A blind constant-modulus (CMA) multipath filter with Normalized LMS step normalization can be enabled after IF AGC
- IF sample stages is defined by
-Eoptions - Each stage adds 4 taps spanning 10.4 microseconds, allocated 3:1 before/after the reference point
- Size
-Eto the echo delay spread. More stages is not safer. Taps beyond the delay spread carry no signal, add gradient noise, and slow the per-tap adaptation rate. Measured against a synthesized channel with a 3 microsecond echo,-E200decodes 6.9 dB worse than switching the filter off, while the optimum for that channel is around-E12; for an 8 microsecond echo the optimum moves up to-E36. On shallow echoes the filter is a net loss at any setting - Start low and raise
-Eonly while it keeps helping - Practical upper limit of
-Evalue: 200 - Practical
-Evalue for CPU load: up to 50 for Raspberry Pi 4, approx. 100 for a modern computer - See doc/MULTIPATH_FILTER_DESIGN_20260724.md for the design notes and measurements
Output latency and the -L option
Measured end-to-end, from the antenna to the analog output of a FiiO K7
USB DAC, against an analog FM radio receiving the same broadcast (macOS
26.5, Mac mini 2023, Airspy HF+, FM stereo with -E 100):
-L |
Granted by CoreAudio | Measured delay |
|---|---|---|
| 3 | 13.7 ms | 34 to 46 ms, never settles |
| 5 | 26.3 ms | 37 ms |
| 10 | 52.7 ms | 54 ms |
| 20 | 105.3 ms | 92 ms |
| 30 | 200.7 ms | 133 ms |
| 40 (default) | 210.7 ms | 151 ms |
- The output stage is nearly the whole delay. The Airspy HF+ and the entire decode chain contribute only 6 to 7 milliseconds, and the USB DAC itself at most 1.3 milliseconds
-L 10is the recommended low-latency setting: about a third of the default delay, while keeping a usable buffer margin.-L 5reaches 37 milliseconds but runs with almost no margin and can drop out under host load- Do not use
-L 3or below. The delay never settles and grows by about 1 millisecond per second - The delay also creeps upward by roughly 13 milliseconds per hour, because nothing disciplines the SDR sample clock against the DAC clock
- These figures are host-specific and were taken with one run per setting; treat them as a ladder, not as absolute constants
- See doc/LATENCY_MEASUREMENT_20260725.md for the method and the measurements, and doc/LATENCY_CHECK_20260719.md for the output stage alone
Airspy R2 / Mini configuration options
freq=<int>Desired tune frequency in Hz. Valid range from 1M to 1.8G. (default 100M:100000000)srate=<int>Device sample rate.listlists valid values and exits. (default10000000). Valid values depend on the Airspy firmware. Airspy firmware and library must support dynamic sample rate query.lgain=<x>LNA gain in dB. Valid values are:0, 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10, 11 12, 13, 14, list.listlists valid values and exits. (default8)mgain=<x>Mixer gain in dB. Valid values are:0, 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10, 11 12, 13, 14, 15, list.listlists valid values and exits. (default8)vgain=<x>VGA gain in dB. Valid values are:0, 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10, 11 12, 13, 14, 15, list.listlists valid values and exits. (default0)antbiasTurn on the antenna bias for remote LNA (default off)lagcTurn on the LNA AGC (default off)magcTurn on the mixer AGC (default off)
Airspy HF+ configuration options
freq=<int>Desired tune frequency in Hz. Valid range from 0 to 31M, and from 60M to 240M. (default 100M:100000000)srate=<int>Device sample rate.listlists valid values and exits. (default384000). Valid values depend on the Airspy HF firmware. Airspy HF firmware and library must support dynamic sample rate query.hf_att=<int>HF attenuation level and AGC control.- 0: enable AGC, no attenuation
- 1 - 8: disable AGC, apply attenuation of value * 6dB
RTL*SDR configuration options
freq=<int>Desired tune frequency in Hz. Accepted range from 10M to 2.2G. (default 100M:100000000)gain=<x>(defaultauto)autoSelects gain automaticallylistLists available gains and exit<float>gain in dB. Possible gains in dB are:0.0, 0.9, 1.4, 2.7, 3.7, 7.7, 8.7, 12.5, 14.4, 15.7, 16.6, 19.7, 20.7, 22.9, 25.4, 28.0, 29.7, 32.8, 33.8 , 36.4, 37.2, 38.6, 40.2, 42.1, 43.4, 43.9, 44.5, 48.0, 49.6
srate=<int>Device sample rate. valid values in the [900001, 3200000] range. (default1152000)blklen=<int>Device block length in bytes (default RTL-SDR default i.e. 64k)agcActivates device AGC (default off)antbiasTurn on the antenna bias for remote LNA (default off)
File Source driver configuration options
freq=<int>Frequency of radio station in Hz.srate=<int>IF sample rate in Hz.filename=<string>Source file name. Supported encodings:FLOAT,S24_LE,S16_LEzero_offsetSet if the source file is in zero offset, which requires Fs/4 IF shifting.blklen=<int>Set block length in samples.rawSet if the file is raw binary.format=<string>Set the file format for the raw binary file. Supported formats:U8_LE,S8_LE,S16_LE,S24_LE,FLOAT
Authors and contributors
- Joris van Rantwijk, primary author of SoftFM
- Edouard Griffiths, F4EXB, primary author of NGSoftFM (no longer involving in maintaining NGSoftFM)
- Kenji Rikitake, JJ1BDX, maintainer/developer/experimenter
- András Retzler, HA7ILM, for the former AF/IF AGC code in csdr
- Youssef Touil, Airspy Founder, aka Twitter @lambdaprog, for the intriguing exchange of Airspy product design details and the technical support
- Iowa Hills Software, for their FIR and IIR filter design tools
- Brian Beezley, K6STI, for his comprehensive Web site of FM broadcasting reception expertise and the idea of Quadrature Multipath Monitor
- Ryuji Suzuki, for reviewing the FM multipath filter coefficients and suggesting putting more weight on picking up more previous samples from the reference point than the samples after
- Teruhiko Hayashi, JA2SVZ, the creator of FM FPGA Tuner popular in Japan, for reviewing the measurement results of FM broadcast reception of airspy-fmradion, and various constructive suggestions
- Takehiro Sekine, for suggesting using GNU Radio's VOLK for faster calculation, and implementing Filesource device driver
- Takeru Ohta, for his Rust implementation of Tisserand-Berviller AGC algorithm
- Cameron Desrochers, for his readerwriterqueue implementation of a single-producer-single-consumer lock-free queue for C++
- Clayton Smith, for a bugfix pull request to airspy-fmradion to find an uninitialized variable and his help during bug tracking in VOLK.
- Andrew Hardin, for cmake-git-version-tracking
License
- As a whole package: GPLv3 (and later). See LICENSE.
- Each source code file might state a GPLv3-compatible license.
Usage of AI
- Claude Code is used to verify and fix the vulnerabilities of the code, and to improve the overall SDR design.
- Past bugfixes include GitHub Copilot suggestions.
[End of README.md]
more like this
gns3theme
Custom color themes for GNS3 GUI. Built-in schemes, custom JSON themes, device symbols. Supports Linux and macOS.
Python★ 50