Backend Performance
Codec
- opus-lo quality tier (16k mono / 32k stereo) — for AM/NFM voice clients
- 60ms Opus frames (was 20ms) — 3× fewer encoder calls per second
- Opus complexity defaults to 5 (was 10) — ~30% encode CPU reduction with no audible difference at ≤64kbps
- Opus complexity now configurable via Admin → General → DSP & History
- Fix Close() race panic: buffers no longer zeroed on pipeline close; concurrent Process() calls finish safely
Hot path allocations
- Zero-alloc IQ client snapshot — reuse per-dongle scratch slice instead of allocating
[]cpEntryon every IQ chunk (~50Hz × N dongles) - Single-alloc FFT broadcast —
EncodeMessage/EncodeMessageFloorwrite type byte + header + deflated payload in onemake, eliminating the intermediate copy EncodePayloadFloortwo-alloc pattern also fixed (was allocatingdeflatedthenpayloadseparately)
DSP
- fastLog10Power — replaces
math.Log10per FFT bin with a bitcast + 5-op IEEE 754 polynomial. ~5–12× faster depending on CPU, <0.01 dB error, imperceptible on waterfall - Incremental PLL phasor —
FmStereoDemodno longer callsmath.Sin/math.Cos240,000×/sec per WFM client. Running (sin φ, cos φ) phasor rotated by 5th-order Taylor step; renorms every 1000 samples. Eliminates the dominant CPU cost for WFM on x86 - Batch FIR processing —
simpleFirgainsprocessBatch();FmStereoDemod.Processrestructured into two passes with batch FIR between them, enabling compiler auto-vectorization of the 51-tap × 240kHz inner loop
Stats / GC
- Removed
runtime.ReadMemStatsstop-the-world pause from the 2-second stats loop; replaced withsyscall.GetrusageRSS (zero allocation, no GC pause). Platform-aware: bytes on Darwin, kilobytes on Linux
Build
GOAMD64=v3added to both Dockerfiles — targets AVX2 (Intel Haswell 2013+, AMD Ryzen 1000+), enabling 8-wide float32 SIMD for FIR/FFT loops without native-only portability issues- New
build:go:native/build:go:opus:native/build:go:full:nativenpm scripts useGOAMD64=v3for local builds - GitHub Actions workflow unchanged —
GOAMD64=v3flows from Dockerfile automatically
Admin UI
- Music ID API keys (AudD / ACRCloud) now use
type=text+autocomplete=off— prevents browser password autofill on the General config page - Admin password field uses
autocomplete=new-password - opusComplexity correctly populated when reopening admin page (was missing from
loadServerConfigmapping)