A Linux toolset for high-throughput SDR streaming with the RX888 / RX888mk2.
The streaming engine is a shared library (librx888); on top of it, three
command-line programs form a Unix pipeline that captures raw USB3 samples,
decimates them to complex IQ, and records to disk in SigMF format:
rx888_stream → rx888_dsp → iqrecord
(USB3→stdout) (stdin→stdout) (stdin→files)
int16 real int16→cf32 cf32_le
135 MS/s 4:1 decimation SigMF + run.json
33.75 MS/s out
rx888_stream is a thin CLI wrapper around librx888.so. The library is
also what gr-rx888 (a GNU Radio out-of-tree source block, planning docs
under doc/gr-rx888/) will consume — same code path for both.
- Linux (x86_64) — kernel USB3 support, sufficient USBFS buffer memory
- libusb-1.0 development headers (
libusb-1.0-0-devon Debian/Ubuntu) - AVX2 + FMA capable CPU (required by
rx888_dsponly) - RX888 / RX888mk2 with USB3 cable and host port
Build deps on Ubuntu 24.04:
sudo apt install build-essential pkg-config libusb-1.0-0-devmake # librx888.so + librx888.a + pkg-config + 3 binaries
make check # non-hardware ABI / CLI tests (also runs in CI)To build a single program:
make rx888_stream # links librx888.so
make rx888_dsp
make iqrecordThe FX3 firmware blob is not vendored. It is fetched from the
ringof/rx888-firmware release
matching firmware/VERSION and checksum-verified against firmware/SHA256SUMS:
make firmware # fetch the pinned version
make firmware-latest # bump to the most recent rx888-firmware release
# (used by the auto-bump CI workflow)firmware/SDDC_FX3.img is gitignored. make install refuses to run until
the blob has been fetched.
sudo make install # installs to /usr/local
sudo make install PREFIX=/opt/rx888 # custom prefix
sudo make uninstallThis installs librx888.so, librx888.a, librx888.pc, librx888.h,
the three binaries, the firmware blob, and the udev rule. After installing:
sudo udevadm control --reload-rules && sudo udevadm trigger1. Set up USB buffer memory (once per boot for 135 MS/s):
sudo sh -c 'echo 1000 > /sys/module/usbcore/parameters/usbfs_memory_mb'For 32 MS/s, 256 MiB is plenty. To make this persistent, drop a
tmpfiles.d snippet:
echo 'w /sys/module/usbcore/parameters/usbfs_memory_mb - - - - 256' \
| sudo tee /usr/lib/tmpfiles.d/rx888.conf
sudo systemd-tmpfiles --create /usr/lib/tmpfiles.d/rx888.conf(/etc/modprobe.d/usbcore.conf does not work on Ubuntu — usbcore is
built into the kernel, not a module.)
2. Fetch firmware:
make firmware3. Stream, decimate, record:
rx888_stream -f firmware/SDDC_FX3.img -s 135000000 \
| rx888_dsp --block-on-full \
| iqrecord /data/capture --freq 7100000 --desc "7.1 MHz capture"4. Stream to GQRX via FIFO:
mkfifo /tmp/iq.fifo
rx888_stream -f firmware/SDDC_FX3.img -s 135000000 \
| rx888_dsp -o /tmp/iq.fifoConfigure GQRX to read from /tmp/iq.fifo (complex float32, 33.75 MHz).
make check # non-hardware: librx888 ABI + CLI smoke. Run on every PR.
make hw-check # hardware: throughput, stop/start cycles, sample sanity.
# Requires RX888 + RX888_HW_TEST=1.Test scripts live under tests/. See doc/rx888_stream_testplan.md.
| Program | Purpose | Input | Output |
|---|---|---|---|
rx888_stream |
USB3 bulk capture (CLI over librx888) | RX888 device | int16 real samples on stdout |
rx888_dsp |
DSP decimation (4:1) | int16 real on stdin | cf32 IQ on stdout or FIFO |
iqrecord |
SigMF file recorder | cf32 IQ on stdin | .sigmf-data + .sigmf-meta files |
Per-program docs in doc/:
doc/librx888.md— library API and threading modeldoc/rx888_stream.md— CLI options and pipeline examplesdoc/rx888_dsp.md/doc/rx888_dsp_arch.mddoc/iqrecord.mddoc/gr-rx888/— design plan for the GNU Radio source block
rx888_tools/
├── Makefile Build, install, firmware, tests
├── src/
│ ├── librx888.c Streaming engine (libusb + threading)
│ ├── ezusb.c FX3 firmware upload (vendored, GPL-2.0+)
│ ├── rx888_stream.c Thin CLI over librx888 (~200 lines)
│ ├── rx888_dsp.c AVX2/FMA DSP pipeline
│ └── iqrecord.c SigMF recorder
├── include/
│ ├── librx888.h Public library API
│ ├── rx888.h FX3 protocol constants
│ └── ezusb.h EZ-USB API
├── firmware/
│ ├── VERSION Pinned rx888-firmware tag
│ ├── SHA256SUMS Expected checksum
│ └── (SDDC_FX3.img) Fetched, never committed
├── tests/ DSP/iqrecord scripts + librx888 + hw tests
├── doc/ Documentation
├── udev/ udev rule for non-root device access
└── .github/workflows/ CI + auto-firmware-bump
MIT for the original tools — see LICENSE.
src/ezusb.c and include/ezusb.h are GPL-2.0-or-later (derived from the
Linux kernel fxload utility). Because librx888.so links them, the
library and rx888_stream binary are distributed under GPL-3.0-or-later
(compatible with GPL-2.0-or-later upstream and with GNU Radio downstream).
rx888_dsp and iqrecord are MIT only.