github gbozo/no-sdr v2.4.0

latest releases: v2.10.5, v2.10.4, v2.10.3...
5 months ago

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_start over 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 disk
  • DELETE /api/admin/dongles/{id}/record → stop and write .sigmf-meta sidecar
  • GET /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.md and serverng/PLAN.md removed; content merged into root plan.md
  • plan.md now contains Go backend architecture reference with measured performance numbers

Don't miss a new no-sdr release

NewReleases is sending notifications on new releases.