Go-based FM stereo transmitter with RDS, Windows-first and cross-platform
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

3.9KB

fm-rds-tx

Go-based FM stereo transmitter with RDS. Supports ADALM-Pluto (PlutoSDR) and any SoapySDR-compatible TX device.

Status: v0.7.0-pre — hardware bring-up milestone

What works

  • Complete DSP chain: pre-emphasis → stereo encoding → RDS (IEC 62106) → MPX → limiter → FM modulation
  • Real hardware TX via SoapySDR CGO binding (PlutoSDR tested)
  • Continuous TX engine with Start/Stop/Stats
  • IQ resampling (composite rate → device rate)
  • HTTP control plane with /tx/start, /tx/stop, /runtime
  • 82 passing tests including spectral verification

Signal path

Audio Source → PreEmphasis(50µs) → StereoEncoder(19k+38k) → RDS(57k)
→ MPX Combiner → Limiter → FM Modulator(±75kHz)
→ IQ Resample(228k→528k) → SoapySDR → PlutoSDR RF

Build

# Without hardware (simulation/offline only):
go build ./cmd/fmrtx
go build ./cmd/offline

# With SoapySDR hardware support (requires PothosSDR installed):
go build -tags soapy ./cmd/fmrtx

Usage

List available SDR devices

.\fmrtx.exe --list-devices

Offline IQ file generation

.\fmrtx.exe --dry-run --dry-output build/dryrun/frame.json
go run ./cmd/offline -duration 2s -output build/offline/composite.iqf32

Real TX (PlutoSDR)

# Start with manual TX control via HTTP:
.\fmrtx.exe --tx --config docs/config.plutosdr.json

# Start with auto-TX on launch:
.\fmrtx.exe --tx --tx-auto-start --config docs/config.plutosdr.json

HTTP control

POST http://localhost:8088/tx/start    → start transmission
POST http://localhost:8088/tx/stop     → stop transmission
GET  http://localhost:8088/runtime     → engine + driver telemetry
GET  http://localhost:8088/status      → config status
GET  http://localhost:8088/config      → full config
POST http://localhost:8088/config      → patch config (freq, RDS, etc.)
GET  http://localhost:8088/dry-run     → dry-run summary
GET  http://localhost:8088/healthz     → health check

PlutoSDR notes

  • Device rate: 528 kHz (PlutoSDR minimum ~521 kHz)
  • IQ format: CF32 (float32 interleaved I/Q)
  • Gain range: 0–89 dB (outputDrive 0..1 maps to 0..89 dB)
  • SoapySDR driver name: plutosdr
  • Requires: PothosSDR or SoapySDR + SoapyPlutoSDR plugin installed

Repository layout

cmd/
  fmrtx/          main CLI (--tx, --dry-run, --simulate-tx, --list-devices)
  offline/        offline IQ file generator
internal/
  app/            TX engine (continuous chunk loop) + simulated transmit
  audio/          sample types, WAV loader, resampler, tone generator
  config/         config schema, validation, PI parsing
  control/        HTTP control plane (/tx/start, /tx/stop, /runtime)
  dryrun/         JSON dry-run summaries
  dsp/            oscillator, pre-emphasis, FM modulator, limiter, Goertzel, IQ resampler
  mpx/            MPX combiner
  offline/        offline composite generation (full DSP chain)
  output/         backend abstractions (file, dummy)
  platform/       SoapyDriver interface, SoapyBackend, SimulatedDriver
  platform/soapysdr/  CGO SoapySDR native binding (build tag: soapy)
  rds/            RDS encoder (IEC 62106, CRC, differential, group scheduler)
  stereo/         stereo encoder (19 kHz pilot, 38 kHz DSB-SC)
docs/
  config.sample.json                default config
  config.plutosdr.json              PlutoSDR-specific config
  pro-runtime-hardening-workboard.md  living workboard for pro runtime hardening
scripts/
examples/

Planning / workboard

For the current pro-runtime-hardening track, see:

  • docs/pro-runtime-hardening-workboard.md

This document is the detailed working board for status tracking, confirmed findings, open decisions, verification notes, and implementation progress.

This project is intended only for lawful use within relevant license and regulatory constraints. RF output, deviation, filtering, and transmitted power must be validated with proper measurement equipment.