Starting a new session? Read NEXT_STEPS.md first. It tells you (or an AI assistant) exactly where the project is and what to do next without needing to re-derive context.
Detect, count, and analyze popping noises in overnight audio recordings of an attic/ceiling/walls. Built for the Sony ICD-UX570 voice recorder workflow.
- Detect sharp transient "pop" sounds in long (~6h) WAV files while ignoring sleep noises like breathing, mumbling, talking, footsteps, and movement.
- Store every detected pop in a SQLite database, with rich features (loudness, attack time, spectral character) so later analysis tools can query without re-processing audio.
- Emit Audacity label files alongside each run so you can drag the labels onto the WAV in Audacity and audit every detection by ear.
- Calibrate against a small set of human-labeled nights: confirm that real pops are caught and that sleep sounds, talking, and other non-pops are not.
Later (after detector is locked in): count tools, cluster tools, highlight reel generation, before/after comparison, plots.
popAnalyzer/
├── README.md # this file
├── ARCHITECTURE.md # how the detector works, file-by-file
├── TUNING.md # ← READ THIS if you (AI or human) need to improve the detector
├── CHANGELOG.md # record every tuning iteration here
├── config.yaml # all detection parameters live here
├── requirements.txt
├── .gitignore
├── detect_pops.py # CLI: run detector on one or more night_*.wav files
├── calibrate.py # CLI: run detector against labeled nights, report metrics
├── reset_db.py # CLI: wipe the pop database (used after calibration is locked)
├── popanalyzer/ # the library (signal processing, detection, db)
│ ├── __init__.py
│ ├── io.py
│ ├── features.py
│ ├── detect.py
│ ├── db.py
│ └── utils.py
└── labels/ # human-labeled ground truth, one YAML per night
├── night_2026-01-14.yaml
└── night_2026-01-21.yaml
cd C:\Users\jbert\source\popAnalyzer
python -m pip install -r requirements.txt
# Run detector on one night (write pops to db, write Audacity labels next to db)
python detect_pops.py "\\NAS_OF_DEATH\Tino_Share\AtticAudio\Nights\night_2026-01-14.wav"
# Run the calibration check against all labeled nights
python calibrate.py
# After agreeing the detector is good, clear the db and run on everything
python reset_db.py
python detect_pops.py "\\NAS_OF_DEATH\Tino_Share\AtticAudio\Nights\*.wav"- Database:
test_outputs/pops.dbwhile we're calibrating. Once locked in, this will move (see TUNING.md → "Finalizing"). - Audacity label files: alongside the database, e.g.
test_outputs/night_2026-01-14_labels.txt. - Diagnostic dumps (with
--diagnostic):test_outputs/diagnostic_<night>.csv.
The WAV files themselves are read from wherever you point the CLI; the detector never writes back to the audio folder.
🟡 Calibrating. The detector exists with default parameters. Run
calibrate.py to see how it performs against the two labeled nights. See
TUNING.md for what to adjust based on the results.