"""Tests for the adaptive loud-section detector in web.py.""" import math from web import _loud_sections, _noise_floor_db WINDOW_DUR = 0.1 # 100 ms windows, as produced by WINDOW_SAMPLES at 48 kHz def _run(rms, margin_db=12.0, min_gap=2.0): duration = len(rms) * WINDOW_DUR return _loud_sections(rms, WINDOW_DUR, duration, margin_db, min_gap) def test_burst_above_quiet_floor_is_detected(): rms = [0.002] * 1200 # 2 min of quiet ambience (−54 dBFS) rms[600:610] = [0.05] * 10 # 1 s burst at −26 dBFS (+28 dB) sections = _run(rms) assert len(sections) == 1 s = sections[0] assert s['start'] == 60.0 assert 60.5 <= s['end'] <= 62.0 assert 26.0 <= s['score'] <= 30.0 def test_slow_ambience_swell_is_not_detected(): # Level rises 20 dB over 10 minutes and back down — e.g. rain setting in. # The old fixed threshold would have flagged the entire loud half. up = [0.002 * 10 ** (i / 6000 * 1.0) for i in range(6000)] # −54 → −34 dB down = list(reversed(up)) assert _run(up + down) == [] def test_burst_still_detected_on_loud_ambience(): # Same +28 dB prominence as the quiet test, but on a 20 dB louder floor. rms = [0.02] * 1200 rms[600:610] = [0.5] * 10 sections = _run(rms) assert len(sections) == 1 assert sections[0]['start'] == 60.0 def test_min_rms_floor_suppresses_blips_in_digital_silence(): rms = [0.000001] * 1200 rms[600:605] = [0.004] * 5 # −48 dBFS: audible blip, but below MIN_RMS+12dB assert _run(rms) == [] rms[600:605] = [0.05] * 5 # −26 dBFS clearly clears the clamped floor assert len(_run(rms)) == 1 def test_min_gap_merges_nearby_bursts(): rms = [0.002] * 1200 rms[600:605] = [0.05] * 5 rms[615:620] = [0.05] * 5 # 1 s gap < 2 s min_gap → one section rms[900:905] = [0.05] * 5 # 28 s away → separate section sections = _run(rms) assert len(sections) == 2 assert sections[0]['start'] == 60.0 assert sections[0]['end'] >= 61.5 assert sections[1]['start'] == 90.0 def test_noise_floor_tracks_blocks_and_ignores_short_events(): quiet_db = 20 * math.log10(0.002) db = [quiet_db] * 1200 db[600:650] = [-20.0] * 50 # 5 s event must not raise its own floor floor = _noise_floor_db(db, WINDOW_DUR) assert len(floor) == len(db) assert all(abs(f - quiet_db) < 1.0 for f in floor)