Go-based FM stereo transmitter with RDS, Windows-first and cross-platform
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

9.3KB

Project Plan - fm-rds-tx

1. Mission

Create a Go-based UKW/FM stereo transmitter with RDS that can run on standard Linux systems and, where feasible, on Raspberry Pi / SBC-class hardware.

Primary design goals:

  • reliable CPU implementation first
  • clean architecture for real-time DSP
  • optional CUDA path for selected heavy DSP blocks
  • practical control interfaces for audio, RDS, frequency, and TX settings
  • portability across x86_64 Linux and ARM Linux

2. Non-negotiable constraints

  • Use only inside the licensed event window and within the license conditions.
  • No assumption that software-only limiting of TX power is sufficient; real RF power control depends on hardware.
  • Emissions, pilot level, deviation, RDS injection, harmonics/spurs, and filtering must be measured on real equipment.
  • The software must support safe defaults and explicit operator confirmation for potentially risky RF settings.

Technical

  • Go as the primary implementation language.
  • Linux is the primary target.
  • Raspberry Pi / ARM compatibility must be preserved for the CPU path.
  • CUDA is optional and must be runtime-detectable, never mandatory.

3. High-level architecture

Audio In  ─┐
           ├─> audio preprocessing ─> stereo encoder ─┐
RDS In   ──┘                                          ├─> MPX generator ─> output backend ─> exciter / SDR / DAC
                                                      │
Config/API/CLI ───────────────────────────────────────┘

Core components:

  1. Audio ingest
    • file / playlist input
    • live PCM input
    • optional network audio input later
  2. Audio preprocessing
    • sample-rate conversion
    • gain staging
    • limiter / clipper (careful, broadcast chain quality matters)
    • optional pre-emphasis
  3. Stereo encoder
    • L+R baseband
    • 19 kHz pilot
    • L-R double-sideband suppressed-carrier at 38 kHz
  4. RDS encoder
    • PS, RT, PI, PTY, TA/TP basics
    • group scheduler
    • 57 kHz subcarrier insertion
  5. MPX generator
    • combine mono/stereo + pilot + RDS
    • deviation / injection calibration hooks
  6. Output backend
    • IQ output for SDR-based transmit chain
    • composite/MPX output if supported by hardware
    • test file output for offline analysis
  7. Control plane
    • config file
    • CLI
    • HTTP API
    • optional small web UI later

4. Proposed phased roadmap

Phase 0 - Research & requirements freeze

Deliverables:

  • supported hardware/backend shortlist
  • target sample rates and timing model
  • legal/operational assumption document
  • MVP feature freeze

Tasks:

  • decide primary output mode:
    • SDR IQ output
    • direct MPX/composite output
    • both
  • shortlist hardware targets:
    • Linux PC + SDR
    • Raspberry Pi 4/5 + SDR
    • other ARM SBC
  • define minimum RDS feature set for MVP
  • define exact operator parameters and safe ranges

Open question:

  • which TX hardware/exciter are we driving?
    • HackRF / Pluto / Lime / bladeRF / RTL-SDR not suitable for TX / custom DAC / external exciter input

Phase 1 - Repository bootstrap

Deliverables:

  • initial Go module
  • package layout
  • build/test/lint scripts
  • baseline docs

Suggested structure:

cmd/fmrtx/
internal/audio/
internal/dsp/
internal/stereo/
internal/rds/
internal/mpx/
internal/output/
internal/control/
internal/config/
internal/platform/
internal/telemetry/
docs/
examples/
scripts/

Tasks:

  • initialize module
  • define config schema
  • add structured logging
  • add benchmark harness for DSP blocks
  • add deterministic test vectors where possible

Phase 2 - CPU MVP pipeline

Goal: produce valid offline MPX / IQ output from known inputs.

Deliverables:

  • stereo encoder MVP
  • RDS encoder MVP
  • MPX combiner
  • WAV/file output for verification
  • offline spectrum / pilot / RDS validation tooling

Tasks:

  • implement audio resampler path
  • generate 19 kHz pilot with stable phase
  • implement L+R and L-R paths
  • implement 57 kHz RDS subcarrier generation
  • implement basic group 0A / 2A support
  • build verification scripts for:
    • pilot amplitude
    • stereo separation sanity
    • RDS subcarrier presence
    • modulation headroom checks

Acceptance criteria:

  • generated composite can be decoded by reference analysis tools
  • RDS PS and RadioText can be recovered reliably from recorded output
  • CPU use acceptable on x86 Linux for real-time operation

Phase 3 - Real-time output backend

Goal: real-time transmit-capable software chain.

Deliverables:

  • live audio input path
  • real-time scheduler/buffering
  • first real output backend
  • underrun/overrun telemetry

Backend options to evaluate:

  1. SoapySDR backend for broad SDR support
  2. Vendor-native backend for selected hardware where latency/control is better
  3. Composite audio backend for hardware exciters that accept MPX input

Tasks:

  • define backend abstraction
  • implement timing-safe ring buffers
  • implement frequency/config control surfaces
  • expose operator-safe start/stop + status endpoints

Acceptance criteria:

  • stable continuous real-time output for multi-hour tests
  • no audible glitches under expected load
  • backend reports lock/state/errors cleanly

Phase 4 - Broadcast chain quality work

Deliverables:

  • gain staging and limiter improvements
  • pre-emphasis options
  • calibration tools
  • monitoring/telemetry dashboards or endpoints

Tasks:

  • tune audio processing to avoid ugly overmodulation
  • add regional pre-emphasis selection if needed
  • add composite level calibration workflow
  • add spectrum snapshots / diagnostics hooks

Acceptance criteria:

  • operator can set conservative legal operating point
  • composite behavior measurable and repeatable

Phase 5 - CUDA acceleration (optional)

Goal: accelerate only the blocks that are actually worth offloading.

Candidates:

  • FIR/filter banks
  • resampling kernels
  • vector mixing / waveform generation at higher rates
  • possibly stereo/RDS composite generation if profiling justifies it

Rules:

  • CPU path remains canonical and fully functional
  • CUDA path selected at runtime
  • identical output targets within defined tolerance
  • no CUDA dependency on ARM/SBC builds

Tasks:

  • benchmark CPU hotspots first
  • define clean Go <-> native/CUDA boundary
  • prototype one block at a time
  • compare latency overhead vs throughput gain

Acceptance criteria:

  • measurable real benefit on supported GPU hosts
  • no regression for non-CUDA systems

Phase 6 - SBC / Raspberry Pi optimization

Deliverables:

  • tuned CPU profile for ARM
  • deployment docs
  • systemd service example

Tasks:

  • test on Pi 4/5 or equivalent ARM SBC
  • reduce allocation churn and GC pressure
  • use fixed-size buffers where practical
  • document thermal/load expectations

Acceptance criteria:

  • stable real-time operation on target SBC profile for chosen backend and sample rate

5. Interfaces to expose

Audio input

MVP:

  • local WAV/PCM file
  • local audio device or pipe input

Later:

  • RTP/UDP
  • Icecast/HTTP pull
  • JACK/PipeWire integration

RDS input/control

MVP:

  • static config for PI, PS, PTY
  • dynamic RadioText update API
  • TA/TP flags

Later:

  • event/queue-based RDS scheduler
  • external automation bridge

TX / RF controls

Important: actual supported parameters depend on hardware backend.

Expose where meaningful:

  • center frequency
  • sample rate
  • output gain / drive level
  • stereo enable/disable
  • pilot level
  • RDS injection level
  • pre-emphasis mode
  • backend device selection

Be careful with naming:

  • use drive level / output gain in software
  • do not promise true absolute RF power control unless hardware can measure/control it

6. Risks and unknowns

  1. Hardware backend choice dominates complexity
    • the whole design changes depending on SDR vs composite exciter
  2. Raspberry Pi real-time headroom may be tight
    • especially at higher sample rates and with extra DSP
  3. CUDA may be unnecessary for MVP
    • profiling may show good CPU performance already
  4. Broadcast-quality audio processing is deeper than “just encode stereo”
    • limiter/clipper/processing can become a whole subproject
  5. Regulatory and RF compliance live outside the codebase too
    • filters, clocks, linearity, and measurement gear matter

Ship this first:

  • Linux CLI daemon in Go
  • CPU-only path
  • stereo MPX generation
  • basic RDS (PS + RT + PI + PTY)
  • file output + one real hardware backend
  • config file + HTTP status/control API
  • test/analysis tooling for composite validation

Defer until proven necessary:

  • CUDA
  • fancy web UI
  • advanced audio processing
  • many hardware backends at once

8. Immediate next steps

  1. Decide the first output backend/hardware target.
  2. Freeze MVP feature list.
  3. Bootstrap the Go module and package skeleton.
  4. Implement offline composite generation first.
  5. Add verification tooling before real TX tests.
  6. Only then bring up live hardware output.

9. Suggested first milestone

Milestone A: Offline stereo + RDS composite generator

Definition of done:

  • takes WAV input + simple RDS config
  • emits composite/baseband output file
  • reference tools can decode pilot + stereo + RDS correctly
  • architecture is ready for later real-time backend insertion

This is the safest and smartest place to start.