Systems and subsystems
ENF: mains hum
Tracks the 50 or 60 Hz hum a mains-powered recording chain leaves behind, and whether it is stable across the clip. Rule-based and mild on purpose: on our training data hum means a home studio, which means one real corpus, so a learned version would learn the corpus.
In plain words
The electrical network frequency (ENFElectrical network frequency: the faint 50 or 60 Hz hum a mains-powered recording chain leaves in a recording, and how stable it is. Evidence about the recording environment.) is the rubric's acoustic-environment technique: a genuine recording made near mains power carries a faint hum at the grid frequency, and a spliced or fabricated background may carry a hum that jumps. Stable hum is in about a third of LJ Speech clips and almost no generated audio, so it is corpus evidence, not class evidence, and it stays out of the score.
What goes in and comes out
In: the clip, silence-trimmed, capped and RMS-normalized. Out: the better of the 50 and 60 Hz candidates with its signal-to-noise ratio, the fraction of frames where it is present, its frequency, its spread and range; and one of three sentences: no hum, stable hum "consistent with a genuine electrical recording environment", or discontinuous hum "consistent with a fabricated or spliced background".
Where it lives
Parameters and where each is set
- Windows of 2.0source: src/hearsay/detectors/enf.py line 29 (GitHub; assumes main is public) s every 0.5source: src/hearsay/detectors/enf.py line 29 (GitHub; assumes main is public) s over at most 8.0source: src/hearsay/detectors/enf.py line 29 (GitHub; assumes main is public) s, with a large FFT so the bins are about half a hertz; for each candidate, the peak within ±1 Hz per frame with quadratic interpolation, and its SNR against the neighbouring band (enf.py, lines 29–70).
- Present when the median SNR is at least 12.0source: src/hearsay/detectors/enf.py line 31 (GitHub; assumes main is public) dB and the hum is found in at least 0.6source: src/hearsay/detectors/enf.py line 31 (GitHub; assumes main is public) of frames; stable when, in addition, the frequency's standard deviation is at most 0.25source: src/hearsay/detectors/enf.py line 31 (GitHub; assumes main is public) Hz and its range at most 0.5source: src/hearsay/detectors/enf.py line 31 (GitHub; assumes main is public) Hz (enf.py, lines 85–92).
- Scores: stable hum 0.4source: src/hearsay/detectors/enf.py line 32 (GitHub; assumes main is public), jumpy hum 0.6source: src/hearsay/detectors/enf.py line 32 (GitHub; assumes main is public), none 0.5source: src/hearsay/detectors/enf.py line 32 (GitHub; assumes main is public); mild by design, and never fused.
Status
Built; evidence only.
Numbers
Stable hum in 36%source: README.md, section what-did-not-work of LJ Speech clips and 21%source: README.md, section what-did-not-work of LibriSpeech; under 0.5%source: docs/architecture.md, section 11-shortcut-ledger of nine generators. Only 24source: README.md, section what-did-not-work test files carry hum. In the ablation it flagged 591source: README.md, section orchestration-what-routing-changes holdout rows without moving a score.
Known limits
It cannot be validated as a class detector on this data. A test clip with a stable hum can be a fake: worked example 5 is one.
Tests that pin it
tests/test_enf_detector.py: a stable 60 Hz hum, 50 Hz, none, a hum that jumps by 1 Hz mid-clip is discontinuous, digital silence, a short clip, contract and determinism, the analysis keys, registration.
Sources
The CPU detectors report, "ENF (mains hum) detector"; worked example 5.