| """Tests for the active-section / intro-skip detector.""" |
|
|
| from __future__ import annotations |
|
|
| import numpy as np |
| import pytest |
|
|
| from backend.features import ANALYSIS_WINDOW_S, detect_active_section |
|
|
|
|
| SR = 22050 |
|
|
|
|
| def test_short_track_returns_full_range(): |
| y = np.random.randn(int(60 * SR)).astype(np.float32) * 0.5 |
| start, end = detect_active_section(y, SR, target_s=ANALYSIS_WINDOW_S) |
| assert start == 0.0 |
| assert abs(end - 60.0) < 1.0 |
|
|
|
|
| def test_quiet_intro_is_skipped(): |
| """Intro at 5% amplitude, loud section at 80% — detector must land on the loud part.""" |
| intro = np.random.randn(int(120 * SR)).astype(np.float32) * 0.05 |
| loud = np.random.randn(int(90 * SR)).astype(np.float32) * 0.8 |
| outro = np.random.randn(int(60 * SR)).astype(np.float32) * 0.1 |
| y = np.concatenate([intro, loud, outro]) |
|
|
| start, end = detect_active_section(y, SR, target_s=90.0) |
| |
| assert 100 <= start <= 140, f"start {start} should be near 120s" |
| assert end - start == pytest.approx(90.0, abs=1.0) |
|
|
|
|
| def test_uniform_energy_returns_a_valid_window(): |
| """No clear energy gradient — any window of the target size is acceptable |
| as long as it sits inside the track and has the right length.""" |
| y = (np.random.randn(int(200 * SR)) * 0.3).astype(np.float32) |
| start, end = detect_active_section(y, SR, target_s=90.0) |
| assert 0.0 <= start <= 200.0 - 90.0 |
| assert end - start == pytest.approx(90.0, abs=1.0) |
|
|
|
|
| def test_loud_section_at_end(): |
| quiet = np.random.randn(int(180 * SR)).astype(np.float32) * 0.05 |
| loud = np.random.randn(int(90 * SR)).astype(np.float32) * 0.9 |
| y = np.concatenate([quiet, loud]) |
| start, end = detect_active_section(y, SR, target_s=90.0) |
| assert start >= 170, f"expected window near end (~180s), got {start}" |
|
|
|
|
| def test_zero_signal_returns_first_window(): |
| """Pathological all-zero input should not crash.""" |
| y = np.zeros(int(200 * SR), dtype=np.float32) |
| start, end = detect_active_section(y, SR, target_s=90.0) |
| assert start == 0.0 |
| assert end == pytest.approx(90.0, abs=1.0) |
|
|
|
|
| def test_target_longer_than_track_returns_full(): |
| y = np.random.randn(int(45 * SR)).astype(np.float32) * 0.4 |
| start, end = detect_active_section(y, SR, target_s=90.0) |
| assert start == 0.0 |
| assert end == pytest.approx(45.0, abs=1.0) |
|
|