github musithang/sdrtop v0.4.1
v0.4.1 - Lab Signal & crates.io

latest releases: v0.6.6, v0.6.5, v0.6.4...
one month ago

Every instrument so far described a signal from the outside: how strong, how wide, how clean. Lab Signal opens the channel and reads what is actually inside it. There is still no audio in sdrtop and there is not going to be, so go listen to the station on something else. This is a bench. ❤️

One new preset carries this release: Lab Signal (8), with two focus modes answering two questions. What is this signal, and what is it carrying?

📻 FM MPX and Demod (focus m)

  • Deviation, peak and RMS, measured about the carrier, so a mistuned radio reports its error as offset instead of inflating the modulation figure. Drawn against 75 kHz broadcast or 5 kHz narrowband.
  • MPX baseband from 0 to 60 kHz as a live profile, with the 19 k pilot, the 38 k stereo difference and the 57 k RDS subcarrier visible where they live.
  • Pilot and stereo: STEREO / MARGINAL / MONO, plus injection percentage against the 8 to 10 % norm. That reads the transmitter's health, not your reception.
  • RDS: station name, PI code, programme type, traffic flags and RadioText, nothing shown until it has been confirmed twice. No character appears and then gets corrected in front of you.
  • CTCSS out of the standard 40 tone table, with the margin it won by and an honest "searching" while its window fills.
  • AM depth, positive and negative peaks separately, because a negative peak near 100 % pinches the carrier off and splatters.
  • Tune the demodulated channel inside the capture with ←/→. P snaps to the strongest carrier and ignores your own LO leakage, T overrides the classifier.

📊 Signal Characterization (focus x)

  • Occupied bandwidth by the 99 % method, bounded to the carrier. It used to be bounded to the capture, so a broadcast station at 10 Msps politely reported 7.49 MHz. That was the sample rate, read back at you.
  • Channel power integrated over the channel, not the capture, so widening the span no longer makes a station louder.
  • ACPR on the adjacent bands, each sized from the measured occupancy. An undefined ratio reads undefined, never a guess.
  • A modulation classifier honest about being a bandwidth heuristic, and a verdict card that says what it thinks and why.

All of it hand written: the FIRs, the FM discriminator, the AM envelope detector, the Goertzel tone search, the whole RDS chain down to the CRC. The only maths dependencies in the program are an FFT for drawing the MPX spectrum and a complex number type. Not a purity contest, just the only way to know what every number actually means.

🔧 Under the hood

  • RadioText used to never arrive. Every gap in reception threw away half confirmed characters, and RadioText needs eleven unbroken seconds where a station name needs two.
  • + and - were dead keys on the spectrum only view (2), which also threw away any zoom you had set on the rail.
  • The waterfall left a blank strip on tall terminals. Deeper buffer now, so J and K have more to scroll back through.
  • One saturation scale. SAT read green on the rail and red in the micro views at the same instant. The number means one thing everywhere now, and the reassuring part moved to clip headroom, where it belongs.
  • On RTL-SDR the field gain rows started in three different columns, because the labels were sized for three letter names and Tuner is five. HackRF was never affected, which is why nobody noticed.
  • Themes and layouts are files. Drop a TOML in ~/.config/sdrtop/themes/ or presets/ and it exists. Nothing to register, nothing to rebuild.
  • No function is over 200 lines any more, down from fourteen, and the tests went from about 550 to 830. Riveting stuff. It does mean the next feature is less likely to break the last one.

📦 Get it

First release published on crates.io! 🦀 If you already have a Rust toolchain ready:

cargo install sdrtop

Or install with one line on any Linux distribution using the universal installer script:

curl -fsSL https://raw.githubusercontent.com/mustang6139/sdrtop/main/packaging/install.sh | sh

It works out which distribution you are on, installs libhackrf and librtlsdr under whatever names that distribution gives them (apt, dnf, pacman, zypper, apk, xbps, emerge and nix are all handled), drops sdrtop in /usr/local/bin, sorts out the udev rules and your plugdev membership, and runs the result to prove it works. --prefix ~/.local if you would rather it never touched root, --uninstall to undo it.

The interesting part is what it does when the prebuilt binary would not run. It does not guess from your distribution's name; it runs ldd over the downloaded binary and reads the answer. Ubuntu and Mint package librtlsdr with a different soname to Debian's, and a Raspberry Pi is not x86_64 at all, so in both cases the installer fetches Rust and builds from source instead. Takes a few minutes, asks you nothing, and links what your machine actually has.

Also on the release page: the x86_64 tarball on its own, and SHA256SUMS, which the installer checks before it unpacks anything.


Still early development, and the known issues list has not got any shorter. If something looks broken it is either a bug or an undocumented feature, and I would genuinely like to hear which one you think it is.

73 de sdrtop. 📻

Full Changelog: v0.3.5...v0.4.1

Don't miss a new sdrtop release

NewReleases is sending notifications on new releases.