- RRC_ALPHA 0.75→0.50: narrower noise BW, ~0.6 dB SNR gain - COSTAS_KI 3.5e-7: maintain ζ≈0.68 (1e-6 caused loop instability) - Soft confidence: use biphase_i.abs() instead of full vector magnitude so OSD confidence is aligned with bit-decision sign; suppresses false groups under noise with residual Costas phase error - OSD(2) in locked mode: corrects ≤2-bit errors after block sync - Search mode: hard decode only for Block A; OSD(1) in search yielded ~13% false Block A rate per bit, letting wrong clock candidates accumulate false groups as fast as the correct candidate - Incumbent candidate tracking (best_candidate_idx): the winning candidate updates best_state at equal score; challengers need strictly higher score; best_score tracks incumbent even on no-state-change groups so challengers can't leapfrog on a single false group - blocks_to_chips: add NRZI (NRZ-Mark) pre-encoding so the differential biphase decoder recovers actual data bits rather than XOR-of-pairs - Add blocks_to_chips_round_trips_all_groups test: verifies all 16 blocks across 4 PS segments round-trip correctly without BPSK modulation [fix](trx-backend-soapysdr): lower pilot lock threshold for weak-signal RDS - PILOT_LOCK_THRESHOLD 0.25→0.20, add PILOT_LOCK_ONSET=0.30 constant - Pilot reference engages at coherence ≥0.36 (was ≥0.45) WIP: end_to_end_clean_signal_decodes_ps still failing (13/15 pass). Decoder skips segment 2 due to ISI from rectangular test chips through RRC receive filter. chips_to_rds_signal needs RRC pulse shaping. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Stan Grams <sjg@haxx.space>
trx-rs
trx-rs is a modular amateur radio control stack written in Rust.
It splits radio hardware access from user-facing interfaces so you can run
rig control, SDR DSP, decoding, audio streaming, and web access as separate,
composable pieces.
The project is built around two primary binaries:
trx-server: talks to radios and SDR backendstrx-client: connects to the server and exposes frontends such as the web UI
Web UI Demo
GIF placeholder: add an animated walkthrough of the website here.
What It Does
- Controls supported radios over networked client/server boundaries
- Exposes a browser UI, a rigctl-compatible frontend, and JSON-based control
- Supports SDR workflows with live spectrum, waterfall, demodulation, and decode
- Streams Opus audio between server, client, and browser
- Runs multiple decoders including AIS, APRS, CW, FT8, RDS, VDES, and WSPR
- Supports multi-rig deployments and SDR virtual channels
- Loads backends and frontends via plugins
Architecture
At a high level:
trx-serverowns the radio hardware and DSP pipeline.trx-clientconnects to the server over TCP for control and audio.- Frontends hang off
trx-client, including the HTTP web UI.
This separation is intentional: it keeps hardware access local to one host while making control and monitoring available elsewhere on the network.
Workspace Layout
src/trx-core: shared types, rig state, controller logicsrc/trx-protocol: client/server protocol types and codecssrc/trx-app: shared app bootstrapping, config, logging, pluginssrc/trx-server: server binary and backend integrationsrc/trx-client: client binary and remote connection handlingsrc/trx-client/trx-frontend: frontend abstractionsrc/decoders: protocol-specific decoder cratesexamples/trx-plugin-example: minimal plugin example
Supported Pieces
Backends
- Yaesu FT-817
- Yaesu FT-450D
- SoapySDR-based SDR backend
Frontends
- HTTP web frontend
- rigctl-compatible TCP frontend
- JSON-over-TCP frontend
Decoders
- AIS
- APRS
- CW
- FT8
- RDS
- VDES
- WSPR
Build Requirements
You will need Rust plus a few system libraries.
Common dependencies
libopuspkg-configorpkgconfcmake
SDR builds
libsoapysdr
Audio builds
- Core Audio on macOS, or ALSA development packages on Linux
Configuration
Both trx-server and trx-client read from a shared trx-rs.toml.
- Default lookup order: current directory,
~/.config/trx-rs,/etc/trx-rs - Use
--config <FILE>to point at an explicit config file - Use
--print-configto print an example combined config
Start from trx-rs.toml.example.
Quick Start
1. Build
cargo build
2. Create a config file
cp trx-rs.toml.example trx-rs.toml
Adjust backend, frontend, audio, and auth settings for your environment.
3. Run the server
cargo run -p trx-server
4. Run the client
cargo run -p trx-client
5. Open the web UI
Open the configured HTTP frontend address in a browser.
Web Frontend Highlights
- Real-time spectrum and waterfall
- Frequency, mode, and bandwidth control
- Decoder dashboards and history
- SDR virtual channels
- Browser RX/TX audio
- Optional authentication with read-only and control roles
Authentication
The HTTP frontend supports optional passphrase-based authentication.
rx: read-only accesscontrol: full control access
When exposing the web UI beyond a trusted LAN, run it behind HTTPS and enable secure cookie settings in the config.
Audio
Audio is transported as Opus between server, client, and browser.
trx-servercaptures and encodes audiotrx-clientrelays audio to the HTTP frontend- Browsers connect over
/audio
Documentation
- User Manual: configuration, features, and usage
- Architecture: system design, crate layout, data flow, and internals
CONTRIBUTING.md: contribution and commit rules
Project Status
This is an active project with evolving APIs and frontend behavior. Expect some rough edges and ongoing refactors.
License
Licensed under BSD-2-Clause.
See LICENSES for bundled third-party license files.
