CLI tool
theori-io/nrsc5 avatar
theori-io/nrsc5

nrsc5 decodes HD Radio broadcasts from an RTL-SDR dongle

NRSC-5 receiver for rtl-sdr

971 stars119 forksCNOASSERTION

At a glance

What is it?
nrsc5 is a C program that receives NRSC-5 digital radio stations with an RTL-SDR dongle or from recorded IQ files, and it ships a libnrsc5 library so other applications can reuse the decoder. It suits Linux and Windows engineers who want the audio stream rather than the tuner, and it is not a general purpose SDR program.
Who is it for?
nrsc5 suits an engineer who wants the decoded audio program from an NRSC-5 station on a machine with an RTL-SDR dongle, or who needs to work on the decoder itself and can build a C project with CMake. It does not suit someone who wants a general purpose software defined radio, because the program is scoped to one broadcast standard, and it does not suit a reader hoping for a packaged binary on Windows, because the documented route there is MSYS2 or a cross compile.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 6 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A decoder for one broadcast standard, not a general SDR tool

nrsc5 does one thing: it receives NRSC-5 digital radio stations, the standard behind HD Radio in North America, and gives you the audio. The inputs are an RTL-SDR dongle or a file of recorded I/Q samples, and the outputs are audio you can play, save or pipe into another program.

The README is direct about the scope. It receives NRSC-5 digital radio stations using an RTL-SDR dongle, or by reading from I/Q files. That is the whole job. There is no spectrum scanning, no demodulation of other modulation types, and no generic receiver abstraction.

That narrowness is the reason the program is useful to engineers. A general SDR tool gives you raw samples and leaves the hard part to you. nrsc5 carries the entire NRSC-5 receive chain, from tuning through to audio program selection, and adds a command line interface and an API upon which other applications can be built.

Two output paths matter. You can play audio straight to the sound device, and you can write the decoded audio to a file, in wav or raw format. The distinction matters for anything you intend to process further, since the examples in the documentation show the audio being piped into an external media player rather than played locally.

The project is written in C, built with CMake, and the last push was on 2026-10-17. Releases are numbered up to v3.2.0, released on 2026-06-02, with v3.1.0 in December 2025 and v3.0.1 in June 2025.

libnrsc5 is the reusable part, and it ships its own DLL

The repository is not just a program. There is an `include/` directory, a `doc/` directory and a `src/` directory, and the Windows build instructions tell you to copy two files to run the program outside MSYS2: `libnrsc5.dll` and `nrsc5.exe`.

That DLL is the library half. The build options confirm it exists as a separate component with its own configuration, and the option `-DLIBRARY_DEBUG_LEVEL=1` is described as the debug logging level for libnrsc5, distinct from the program's own log level.

The API is documented rather than incidental. One build flag, `-DBUILD_DOC=ON`, generates html API documentation, and it is off by default, so a build does not produce it unless you ask. The home page for the project is not set, but the generated documentation is what a developer who wants to embed the decoder would look for.

For anyone building an application on top of nrsc5, the important consequence is that the decoder is separable from the command line front end. A media application can link the library, pick a program and consume audio without reimplementing the NRSC-5 receive chain. The Windows instructions demonstrate the split in practice, since the program and the DLL can be copied to a machine that has neither MSYS2 nor a compiler.

The library is licensed separately from nothing else in the repository, so its terms are whatever the LICENSE file at the repository root says.

Building on Debian, Fedora, openSUSE and macOS

The build instructions are complete and per-distribution, which is unusual for a project this small.

On Ubuntu, Debian or Raspbian the dependency list and build sequence are given in full:

bash
sudo apt install git build-essential cmake autoconf libtool libao-dev libfftw3-dev librtlsdr-dev
git clone https://github.com/theori-io/nrsc5.git
cd nrsc5
mkdir build
cd build
cmake [options] ..
make
sudo make install
sudo ldconfig

The `sudo ldconfig` at the end is not optional in practice, because the installed shared library has to be found by the dynamic linker. The build is a plain out-of-tree CMake build, and the `[options]` placeholder is where the feature flags go.

Fedora and openSUSE reuse the Ubuntu steps and replace only the package installation command. Fedora uses dnf with `fftw-devel`, `rtl-sdr-devel` and `libusb1-devel`, while openSUSE installs a devel pattern with zypper and then adds `fftw3-devel`, `rtl-sdr-devel` and `libusb-1_0-devel`. On macOS the route is Homebrew, using a formula script fetched from the repository:

bash
curl https://raw.githubusercontent.com/theori-io/nrsc5/master/nrsc5.rb > /tmp/nrsc5.rb
brew install --HEAD -s /tmp/nrsc5.rb

The `--HEAD` flag means the formula installs the current master rather than a tagged release, which is the right choice for a project where the release cadence is a few months.

The build flags are where SIMD and codec support get decided

Five options control what gets built, and each is a genuine fork in behaviour rather than a cosmetic setting.

bash
-DUSE_NEON=ON            Use NEON instructions. [ARM, default=OFF]
-DUSE_SSE=ON             Use SSSE3 instructions. [x86, default=OFF]
-DUSE_FAAD2=ON           AAC decoding with FAAD2. [default=ON]
-DLIBRARY_DEBUG_LEVEL=1  Debug logging level for libnrsc5. [default=5]
-DBUILD_DOC=ON           Generate html API documentation [default=OFF]

The two SIMD options are per-architecture and both default to off, which means a plain build gets the portable path. On an ARM machine such as a Raspberry Pi you would turn on `USE_NEON`, and on x86 you would turn on `USE_SSE` for SSSE3 instructions. The Windows cross-compile scripts show the flag being used deliberately:

bash
support/win-cross-compile 64 --cmake-args="-DUSE_SSE=ON" -j4

`USE_FAAD2` controls AAC decoding through FAAD2 and is on by default, so the AAC path is the standard build. Turning it off is a decision to drop that decoder, and the documentation does not say what replaces it.

`LIBRARY_DEBUG_LEVEL` defaults to 5 for libnrsc5, which is a library-wide setting separate from the program's own runtime log level. `BUILD_DOC` is off by default and produces html API documentation when enabled, which is what you want if you are reading the library interface before writing code against it.

The command line takes a frequency, a program number and a lot of optional knobs

The interface is positional first. The frequency is the centre frequency in MHz or Hz, and the second argument is the audio program to decode, given as 0, 1, 2 or 3. You do not provide a frequency when reading from a file.

The basic case is short:

bash
nrsc5 107.1 0

That tunes to 107.1 MHz and plays audio program 0. The examples show what the options are for. Gain is set with `-g`, and if you omit it the tool selects gain automatically. The RTL-SDR device index is `-d`, and `-p` sets the ppm error of the dongle. You can point at a remote `rtl_tcp` instance with `-H`, taking a host and optional port.

File handling has its own pair. `-r` reads IQ samples from an input file and `-w` writes IQ samples to an output file, which is how you capture a segment for later analysis. The input format is chosen with `--iq-input-format` from cu8, cs16 and cf32. The rates differ per format and per band: complex unsigned 8-bit runs at 1488375 SPS, complex signed 16-bit at 744188 SPS for FM or 46512 SPS for AM, and complex float 32-bit at the same two rates. The default is cu8, so a file recorded in another format will not be read correctly unless you say so.

Audio output goes to a file with `-o` and the format is set by `-t`, wav or raw, defaulting to wav. The `--am` switch switches from FM to AM. `-T` enables bias-T, which powers an external antenna over the coax, and `-D` enables direct sampling with a value of 1 for I-ADC input or 2 for Q-ADC input.

Two switches exist for working with the stream itself rather than listening to it: `--dump-aas-files dir-name` dumps AAS files and is marked WARNING: insecure in the documentation, and `--dump-hdc file-name` dumps HDC packets. The insecure warning is on the AAS dump and is not elaborated in the text available here.

At runtime, pressing 0 through 7 switches between audio programs and pressing Q quits.

Testing without a radio: the included sample capture

Before you point a dongle at an antenna, you can run the program against a bundled capture. The build tree includes a sample file under `support/`, and the documented test command pipes it in:

bash
xz -d < ../support/sample.xz | src/nrsc5 -r - 0

The `xz -d` step decompresses the sample and the `-` argument tells the program to read from standard input, which is why the file is piped rather than named. The trailing `0` is the audio program to decode.

This matters for two reasons. First, it separates the questions of whether the decoder works and whether your radio setup works, so a silent decode points at the hardware and software configuration rather than the code. Second, it demonstrates the standard-input path that the CLI options describe, where you do not provide a frequency at all.

The Windows build has the same test, written out in two steps instead of a pipe:

bash
cd ~/nrsc5/support
xz -d sample.xz
nrsc5.exe -r sample 0

The documentation is direct about what to do when the sample does not work. Make sure every instruction was followed, and if it still fails, file an issue with the error message and put "[Windows]" in the title. That is a useful signal that the Windows path is the one most likely to need support, since it depends on a MinGW toolchain and a driver change.

On Windows, driver problems show up as errors accessing the RTL-SDR device, and the fix is to use Zadig to change the USB driver.

A custom licence, a shared library, and a Windows caveat

The licence is the first thing to read and the last thing to guess about. The project is listed as using a custom licence that GitHub cannot classify, with the LICENSE file at the repository root as the authority. It is not MIT, not Apache and not GPL, so any assumption you carry over from another theori-io project or from the general category of small SDR utilities is worth checking against that file. Nothing in the documentation summarises its terms.

The dependency on librtlsdr and on the libao and FFTW development packages also has a consequence worth stating plainly. The program does not bundle a radio driver, so a working RTL-SDR on Linux means the operating system already knows the device. On Windows that assumption does not hold, which is why the README spends a paragraph on changing the USB driver with Zadig.

Two further operational notes. The Windows build route is either MSYS2 on Windows or a cross compiler on an Ubuntu, Debian or macOS machine, with scripts provided for both cases, and after a cross compile the artefacts are `*.dll` and `nrsc5.exe` from `build-win64/bin` or `build-win32/bin`. The MSYS2 route has its own update ritual, running `pacman -Syu` and being told to close the terminal and reopen it before continuing with `pacman -Su`.

Finally, the project is only licensed to the extent its LICENSE file says. Whether you can redistribute the binary, link the library in a commercial product, or ship a modified decoder is a question that file answers, and the documentation does not answer it for you.

Editorial conclusion

nrsc5 suits an engineer who wants the decoded audio program from an NRSC-5 station on a machine with an RTL-SDR dongle, or who needs to work on the decoder itself and can build a C project with CMake. It does not suit someone who wants a general purpose software defined radio, because the program is scoped to one broadcast standard, and it does not suit a reader hoping for a packaged binary on Windows, because the documented route there is MSYS2 or a cross compile. Verify three things before relying on it: that the licence file permits your intended use, since the project uses a custom licence rather than a standard one, that you have librtlsdr and the audio and FFT development packages installed before the build will link, and that your recorded IQ file uses one of the three supported sample formats, since the default cu8 assumes a specific sample rate.

Frequently asked questions

How do I build nrsc5 on Ubuntu or Debian?

Install the build dependencies with `sudo apt install git build-essential cmake autoconf libtool libao-dev libfftw3-dev librtlsdr-dev`, clone the repository, create a `build` directory, then run `cmake ..`, `make`, `sudo make install` and `sudo ldconfig` so the shared library is found.

How can I test nrsc5 without an RTL-SDR dongle?

The repository includes a sample capture under `support/`. Decompress and pipe it into the program with `xz -d < ../support/sample.xz | src/nrsc5 -r - 0`, where the `-` reads from standard input and `0` selects the audio program.

What IQ file formats does nrsc5 accept?

The `--iq-input-format` option takes cu8, cs16 or cf32. The default is cu8 at 1488375 SPS, while cs16 and cf32 run at 744188 SPS for FM or 46512 SPS for AM, so a capture in another format must be declared explicitly.

How do I build nrsc5 on Windows?

The documented options are MSYS2 on Windows, using the MSYS2 MinGW 64-bit terminal and the `nrsc5/support/msys2-build -j4` script, or a cross compile from Ubuntu, Debian or macOS with `support/win-cross-compile 64 --cmake-args="-DUSE_SSE=ON" -j4`. The resulting `*.dll` and `nrsc5.exe` files can then be copied to a Windows machine.

Can I use nrsc5 as a library in my own application?

Yes. The project offers an API upon which other applications can be built, built as libnrsc5 with headers under `include/` and documentation under `doc/`. You can enable generated html API documentation at build time with `-DBUILD_DOC=ON`.

Official sources

  1. Issues
  2. README
  3. Releases
  4. theori-io/nrsc5 on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/theori-io-nrsc5.svg)](https://hysenlabs.com/projects/theori-io-nrsc5)

Was this useful?