sjgandClaude Opus 4.8 df7483fe30
CI / lint (push) Failing after 4s
CI / test (push) Successful in 10m37s
CI / frontend (push) Successful in 5m41s
CI / reuse (push) Successful in 5s
[feat](trx-rs): configurable DIG sideband for SDR (auto/USB/LSB)
DIG has no inherent sideband; on the SDR backend it was always demodulated
as USB. Make it resolve to USB or LSB via a policy that defaults to the
amateur SSB/data convention (USB at/above 10 MHz, LSB below) and can be
overridden globally from the advanced radio controls or per-bookmark.

Design: the logical DIG mode is kept in RigState (display, decoder gating)
while the SDR pipeline is handed a concrete USB/LSB demodulator resolved from
(policy, dial frequency). Resolution happens at the boundary — the rig for
the primary channel and the virtual-channel manager for vchans — so the hot
DSP/demod path is untouched. The resolved sideband is only re-pushed when it
actually changes (e.g. tuning DIG/Auto across 10 MHz), keeping ordinary
tuning glitch-free.

Core/protocol:
- New `DigSidebandPolicy { Auto, Usb, Lsb }` with `resolve(freq)` and an
  `effective_demod_mode()` helper (trx-core), re-exported at the crate root.
- `RigCommand::SetSdrDigSideband`, `RigSdr::set_sdr_dig_sideband`, and a
  `RigFilterState.sdr_dig_sideband` field for state sync; wired through the
  ClientCommand mapping.

Config: `[rig.sdr] dig_sideband = "auto"` (regenerated trx-rs.toml.example).

SDR backend: the vchan manager owns the shared policy (atomic); the rig
applies it to the primary channel and, on `set_sdr_dig_sideband`, re-resolves
all DIG virtual channels.

Frontend: a mode-gated "DIG sideband" selector in the SDR advanced controls
(POST /set_sdr_dig_sideband), reflecting server state; bookmarks gain an
optional `dig_sideband` field (form selector shown only for DIG) that, on
apply, sets the global policy before switching to DIG. The scheduler honours
it for automated bookmark activation too.

Tests: policy resolution / effective-mode / u8+parse round-trips (trx-core);
a vchan integration test asserting a DIG channel resolves to LSB below
10 MHz, flips with the policy, and still lists as DIG.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UiK871ht2uPFBHtMbxy3wD
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-08-16 00:26:45 +02:00
2026-05-17 23:25:14 +02:00
2026-05-17 23:25:14 +02:00
2026-05-17 23:25:14 +02:00
2026-05-17 23:25:14 +02:00
2026-08-10 23:47:51 +02:00
2026-05-17 23:25:14 +02:00

trx-rs logo

trx-rs

A modular amateur radio control stack written in Rust.

License

trx-rs 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.

Backends Yaesu FT-817, Yaesu FT-450D, SoapySDR
Frontends Web UI, rigctl-compatible TCP, JSON-over-TCP
Decoders AIS, APRS, CW, FT8, RDS, VDES, WSPR
Audio Opus streaming between server, client, and browser

Quick Start

1. Install dependencies

Debian / Ubuntu
sudo apt install build-essential pkg-config cmake libopus-dev libasound2-dev
# Optional — SDR support
sudo apt install libsoapysdr-dev
Fedora
sudo dnf install gcc pkg-config cmake opus-devel alsa-lib-devel
# Optional — SDR support
sudo dnf install SoapySDR-devel
Arch Linux
sudo pacman -S base-devel pkgconf cmake opus alsa-lib
# Optional — SDR support
sudo pacman -S soapysdr
macOS (Homebrew)
brew install cmake opus
# Optional — SDR support
brew install soapysdr

See Build Requirements in the wiki for details on each library.

Note: cmake is required even when a system Opus library is installed. The audiopus_sys crate probes for Opus via pkg-config; if it is not found (or pkg-config is unavailable), it falls back to compiling a vendored copy of Opus with CMake. A missing cmake therefore fails the build with is cmake not installed? rather than a missing-Opus error.

2. Build

cargo build --release

Build without SDR support: cargo build --release --no-default-features

3. Configure

Run the interactive setup wizard to generate config files for your station:

./target/release/trx-configurator

The wizard walks you through rig selection, serial port detection, audio settings, and frontend options, then writes trx-server.toml and trx-client.toml.

Alternatively, copy trx-rs.toml.example — a commented example covering every setting — and edit it by hand:

cp trx-rs.toml.example trx-rs.toml
./target/release/trx-server --check-config --config trx-rs.toml

--check-config reports everything wrong with a config without starting anything. --print-config prints the same settings without comments.

4. Run

./target/release/trx-server --config trx-server.toml
./target/release/trx-client --config trx-client.toml

A single trx-rs.toml can configure both: the server reads its [trx-server] section and the client reads [trx-client].

Open the configured HTTP frontend address in a browser (default http://localhost:8080).

How It Works

graph TD
    SDR1["SDR #1"] & SDR2["SDR #2"] <-->|USB| S1["trx-server A"]
    SDR3["SDR #3"] & FT817["FT-817"] <-->|USB / serial| S2["trx-server B"]

    S1 <-->|"JSON-TCP :4530"| C1["trx-client"]
    S1 -->|"Opus-TCP per rig"| C1
    S2 <-->|"JSON-TCP :4530"| C1
    S2 -->|"Opus-TCP per rig"| C1

    C1 <-->|internal channels| F1["Web UI :8080"]
    C1 <-->|internal channels| F2["rigctl :4532"]

Each trx-server owns one or more rigs and runs DSP, decoding, and audio capture locally. A trx-client connects to any number of servers over TCP and exposes them through a unified set of frontends.

Documentation

Resource Description
User Manual Configuration, features, and usage
Architecture System design, crate layout, data flow, and internals
Optimization Guidelines Performance guidelines for the real-time DSP pipeline
Planned Features Roadmap and design notes
Contributing Commit conventions, workflow, and code style

License

GPL-2.0-or-later. See LICENSES for the full license text and bundled third-party license files. Bundled third-party components retain their original licenses: Leaflet is BSD-2-Clause, DSEG is OFL-1.1, and opus-decoder is MIT. The APRS symbol sprites come from hessu/aprs-symbols; their per-symbol copyright status is catalogued in LICENSES/LicenseRef-APRS-Symbols.txt.

S
Description
Experimental ham rig and SDR controller written in Rust
Readme
34 MiB
Languages
Rust 52.7%
JavaScript 20.7%
TypeScript 19.9%
CSS 4.1%
HTML 2.3%
Other 0.2%