Files
sdr-recorder/openspec/changes/archive/2026-03-19-improved-false-positive-detection/design.md
Michael Smith 733fe76ed5 Tune FFT size and squelch to reduce false-positive recordings
Increase fft_size from 512 (default) to 2048 for better NFM channel
isolation, and add squelch_snr_threshold = 15.0 dB per channel to
reject noise-triggered recordings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 13:25:37 +00:00

2.9 KiB

Context

RTLSDR-Airband monitors 3 CB channels (26.985, 27.035, 27.075 MHz) via a single RTL-SDR dongle on a Pi 400. Recordings split per transmission produce many false positives — short noise-triggered files, often on multiple channels simultaneously.

Current config: fft_size commented out (defaults to 512), no squelch_snr_threshold set (defaults to 9.54 dB). Both contribute to over-sensitivity.

Goals / Non-Goals

Goals:

  • Reduce false-positive recordings caused by noise, static, and weak signals
  • Achieve this through RTLSDR-Airband config tuning only — no post-processing

Non-Goals:

  • Eliminating 100% of false positives (some noise will always slip through)
  • Automated cleanup scripts or post-processing pipelines
  • Changes to gain, bandwidth, or sample rate (these are working adequately)

Decisions

1. Set fft_size = 2048

Decision: Uncomment and increase fft_size from the current default of 512 to 2048.

Rationale: With 3 NFM channels spaced 10 kHz apart using 8 kHz bandwidth, a 512-point FFT produces bins too wide for clean separation. This causes energy from one channel (or wideband noise) to bleed into adjacent channels, triggering simultaneous false recordings. The simultaneous cross-channel triggers observed in the recordings confirm this.

2048 provides 4x the spectral resolution. Going to 4096 would be even better but may stress the Pi 400's CPU; 2048 is a safe starting point.

Alternatives considered:

  • 4096: Best selectivity but higher CPU cost. Can try later if 2048 isn't sufficient.
  • 1024 (the previously commented-out value): Moderate improvement but may not fully resolve cross-channel bleed.

2. Add squelch_snr_threshold = 15.0 per channel

Decision: Set an explicit SNR threshold of 15 dB on each channel.

Rationale: The default 9.54 dB is calibrated for aviation AM monitoring where signals are cleaner. CB at 27 MHz has a higher noise floor and more atmospheric interference. 15 dB is a reasonable starting point that should reject most noise while still capturing normal-strength CB transmissions.

Alternatives considered:

  • 20-25 dB: More aggressive, but risks missing weaker legitimate transmissions. Can increase later if 15 isn't enough.
  • squelch_threshold (absolute dBFS): Harder to tune and doesn't adapt to changing noise floor conditions. The SNR-relative approach is more robust.

Risks / Trade-offs

  • [Weak signals missed] → Higher squelch threshold will drop marginal transmissions. Acceptable trade-off — false positives are currently more disruptive than missed weak signals.
  • [CPU increase from larger FFT] → 2048 uses more CPU than 512. Pi 400 quad-core should handle this comfortably, but worth monitoring after deployment.
  • [Iterative tuning needed] → These values are starting points. May need adjustment after observing results over a day or two.