sjg 09634eb851
CI / lint (pull_request) Successful in 2m21s
CI / test (pull_request) Successful in 8m7s
CI / frontend (push) Successful in 2m57s
CI / reuse (push) Successful in 3s
CI / frontend (pull_request) Successful in 3m47s
CI / reuse (pull_request) Successful in 3s
CI / lint (push) Successful in 2m16s
CI / test (push) Successful in 7m19s
[fix](trx-frontend-http): tidy up the map's filter bar
The bar explained itself in prose: "All bands visible by default" sat
between the chips and the next group, taking width the bar could not
spare and reading as a stray line of text. An "All" chip says the same
thing in a chip's width and gives the selection somewhere to be undone.

Band chips also came up dimmed at the very moment every band was on the
map -- an empty selection is no filter at all, so nothing is dimmed
until something is picked. The path toggles drop their "On"/"Off"
suffix, which cost most of a row and only repeated what their own
highlight already said; state moves to aria-pressed and the tooltip.

The rest is alignment. The rule dividing the buttons from the filters
is drawn on the button block's edge, and a centred block left it
floating as a stub beside a two-row bar; stacked, it lay down the left
of a block that sits underneath. The labels sat at their natural
widths, so each row's first control started somewhere different, and
the two pairs of phase buttons differed in width, so the groups after
them missed each other by four pixels. One gutter for every label, one
width for both pairs, and the search field moved last where it can take
the room the fixed-width groups leave.

The map layout test now covers the chips, the divider's height and the
rows' shared start.

Signed-off-by: Stan Grams <sjg@haxx.space>
2026-08-05 21:43:57 +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-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

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, generate example configs and edit them by hand:

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

4. Run

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

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%