Terminal waterfall visualizer for RTL-SDR, written in Java with plain ANSI colors — no dependencies.
Reads rtl_power-format CSV lines over TCP and renders a scrolling red-scale waterfall display that adapts to your terminal width.
- Java 17+
tput(standard on macOS and Linux)- RTL-SDR dongle with
rtl_powerandncinstalled on the host
1. On the machine with the dongle, stream rtl_power over TCP:
rtl_power -f 88M:108M:200k -g 40 -i 1 - | nc -lk 1234-f 88M:108M:200k— frequency range and bin size (adjust to taste)-g 40— gain in dB-i 1— one sweep per secondnc -lk 1234— serve the CSV stream on TCP port 1234
If running on a Raspberry Pi and connecting from another machine, replace 127.0.0.1 in TcpClient.java with the Pi's IP address.
2. Run the visualizer:
./gradlew runOr build a standalone distribution:
./gradlew installDist
./app/build/install/app/bin/app88.0 92.0 96.0 100.0 104.0 108.0 MHz
█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█████▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄████▄ -54 dBm
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
...
- Frequency axis at the top, labeled in MHz
- Each row = one sweep of spectrum data
- Red heat scale: black = noise floor, dark red = weak signal, bright red = strong, white = peak (−55 dBm → −5 dBm)
- dBm annotation on every 10th row
- Automatically adapts to terminal width on resize
| Class | Role |
|---|---|
Main |
Wires components, starts threads, resets terminal on exit |
TcpClient |
Connects to 127.0.0.1:1234, parses CSV, enqueues frames |
WaterfallRenderer |
Dequeues frames, renders ANSI rows, handles resize |
FrequencyHeader |
Builds the MHz axis label string |
PowerFrame |
Data record: one parsed CSV line |
Expects standard rtl_power CSV output over TCP:
date,time,start_hz,end_hz,bin_hz,samples,power0,power1,...,powerN
Example:
2026-06-28,12:00:01,88000000,108000000,200000,64,-55.1,-54.8,-53.2,...
./gradlew test