diff options
| author | godosa <godosa@godosa.eu> | 2026-10-06 23:39:36 +0200 |
|---|---|---|
| committer | godosa <godosa@godosa.eu> | 2026-10-06 23:39:36 +0200 |
| commit | 39066900773e7857faf2d02e7ed51b71d219d97d (patch) | |
| tree | ffab8e4ddd971626776c3b1f4ce1da2c186c2187 /scripts/test_audio_report.py | |
| download | godosa-engine-39066900773e7857faf2d02e7ed51b71d219d97d.tar.gz godosa-engine-39066900773e7857faf2d02e7ed51b71d219d97d.zip | |
godosa-engine: initial public history
Diffstat (limited to 'scripts/test_audio_report.py')
| -rw-r--r-- | scripts/test_audio_report.py | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/scripts/test_audio_report.py b/scripts/test_audio_report.py new file mode 100644 index 0000000..87862ca --- /dev/null +++ b/scripts/test_audio_report.py @@ -0,0 +1,44 @@ +import array +import math +import struct +import sys +import tempfile +import unittest +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parent)) +import audio_report as ar + + +def wav_bytes(frames, rate=8000, channels=2, data_size=None): + raw = frames.tobytes() + size = len(raw) if data_size is None else data_size + return struct.pack("<4sI4s4sIHHIIHH4sI", b"RIFF", 36 + size, b"WAVE", b"fmt ", 16, 1, channels, + rate, rate * channels * 2, channels * 2, 16, b"data", size) + raw + + +class AudioReportTests(unittest.TestCase): + def test_reads_to_eof_even_with_placeholder_data_size(self): + frames = array.array("h", [1000, -1000] * 8000) # 1 s stereo at 8 kHz + with tempfile.TemporaryDirectory() as tmp: + path = Path(tmp) / "a.wav" + path.write_bytes(wav_bytes(frames, data_size=0)) # killed writer: size never fixed + rate, channels, samples = ar.read_wav(path) + self.assertEqual((rate, channels, len(samples)), (8000, 2, 16000)) + + def test_levels_per_second_of_mono_mix(self): + # second 0: full-scale square on both channels (0 dBFS); second 1: silence + loud = [16384 if (i // 20) % 2 else -16384 for i in range(8000)] + frames = array.array("h", [v for s in loud for v in (s, s)] + [0, 0] * 8000) + lv = ar.levels(8000, 2, frames) + self.assertEqual(len(lv), 2) + self.assertAlmostEqual(lv[0][1], 20 * math.log10(0.5), places=3) # rms of ±0.5 square + self.assertEqual(lv[1][1], -120.0) + + def test_opposite_channels_cancel_in_the_mix(self): + frames = array.array("h", [8000, -8000] * 8000) + self.assertEqual(ar.levels(8000, 2, frames)[0][1], -120.0) + + +if __name__ == "__main__": + unittest.main() |
