What's New
Music Identification (Shazam-style)
- Identify Song button in the Control Panel — captures 10s of audio and recognises what's playing
- AudD (primary) + ACRCloud (fallback) — configure API keys in
config.yaml - Opus codec path: server captures from its internal PCM ring buffer (no client round-trip)
- ADPCM/none path: client captures from the audio worklet and uploads WAV
- Rate-limited token flow: clicking the button sends
identify_startover WebSocket; server issues a one-time UUID token (20s TTL, single-use) before processing the request- Max 3 recognitions per minute per persistent client ID
- Pending token blocks duplicate requests
- Rate limit / error messages delivered as toast notifications via WebSocket
- Result panel shows title, artist, album, Spotify / YouTube / Apple Music links
Toast Notifications
- Server-pushed toast messages displayed as a fixed overlay (bottom-right)
- Auto-dismiss after 5s, manual dismiss button
- Used for rate-limit errors and other server-initiated notifications
RDS Extended Group Types
- Group 1A: Extended Country Code (ECC)
- Group 10A: Programme Type Name (PTYN, 8 chars)
- Group 14A: Enhanced Other Networks (EON — PI, PS, AF list per network)
- Decoded on both client (TypeScript) and server (Go) sides
IQ Recording (SigMF)
POST /api/admin/dongles/{id}/record→ start recording raw IQ to diskDELETE /api/admin/dongles/{id}/record→ stop and write.sigmf-metasidecarGET /api/admin/recordings→ list active recordings- Format:
cu8(complex uint8, RTL-SDR native) with SigMF metadata
Graceful Shutdown Hardening
Manager.Stop()now closes all Opus encoder instances (was leaking libopus memory)- Active IQ recordings stopped cleanly with SigMF metadata written on SIGINT/SIGTERM
- Drain timeout logged as warning; total elapsed time logged on clean exit
Benchmark Improvements
- Rewrote dongle pipeline benchmarks to accurately model the fan-out architecture
SetBytes = chunkSize(not × N clients) — correct throughput accounting- New benchmarks:
SharedFftCost,PerClientIqExtract{WFM,NFM},SingleClientFull{WFM,NFM},NClientFanOutWFM/{1,2,5,10}_clients - Key result: 5 clients cost only +27% wall-clock vs 1 client thanks to goroutine parallelism
Docs
serverng/TASKS.mdandserverng/PLAN.mdremoved; content merged into rootplan.mdplan.mdnow contains Go backend architecture reference with measured performance numbers