Add multiband waveform view

- waveform.py: render_multiband_waveform() — N rows of ASCII bars, each row
  labeled with its band-start time. Makes it easy to find timestamps in
  long audio by counting row + column.
- cli.py: new 'multiband' / 'mb' subcommand
- Fixed: multiband band alignment was drifting (off-by-one in samples)
- tests: 1 new multiband smoke test; 62 total all passing
This commit is contained in:
2026-07-27 04:25:18 -07:00
parent fa0628f0e2
commit 6b12130bbd
3 changed files with 103 additions and 1 deletions
+25
View File
@@ -122,5 +122,30 @@ def test_find_pauses_returns_list():
# The first silence should start near 0 and end near 5
assert pauses[0][0] < 1.0
assert pauses[0][1] > 4.0
finally:
path.unlink(missing_ok=True)
def test_render_multiband_smoke():
"""render_multiband_waveform: 6-sec audio, 3 bands of 2 sec each → 3 rows."""
from sermon_clean.waveform import render_multiband_waveform
import tempfile, subprocess
with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as f:
path = Path(f.name)
try:
# 6-sec 440Hz tone
subprocess.run([
"ffmpeg", "-y", "-v", "error",
"-f", "lavfi", "-i", "sine=frequency=440:duration=6",
str(path),
], check=True)
result = render_multiband_waveform(path, width=30, band_seconds=2.0)
band_lines = [line for line in result.splitlines() if "|" in line]
# 6-sec audio at 2-sec bands → 3 full bands + 1 partial = 4 rows
assert len(band_lines) in (3, 4), f"expected 3-4 bands, got {len(band_lines)}"
# First band should be labeled 0:00
assert band_lines[0].startswith("0:00")
# Second should be 0:02
assert band_lines[1].startswith("0:02")
finally:
path.unlink(missing_ok=True)