From c2b0f7e4fb4738afcae1705db8f983dd90a669a4 Mon Sep 17 00:00:00 2001 From: historia Date: Sun, 6 Sep 2026 15:17:57 -0400 Subject: inital commit --- lib/tests/conftest.py | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 lib/tests/conftest.py (limited to 'lib/tests/conftest.py') diff --git a/lib/tests/conftest.py b/lib/tests/conftest.py new file mode 100644 index 0000000..885d22b --- /dev/null +++ b/lib/tests/conftest.py @@ -0,0 +1,70 @@ +from __future__ import annotations + +import sys +from pathlib import Path + +import numpy as np +import pytest + +SRC = Path(__file__).resolve().parents[1] / "src" +sys.path.insert(0, str(SRC)) +sys.path.insert(0, str(Path(__file__).resolve().parent)) + +SR = 44100 + + +def speechish( + dur: float, + sr: int = SR, + level_dbfs: float = -20.0, + seed: int = 0, +) -> np.ndarray: + rng = np.random.default_rng(seed) + n = int(sr * dur) + t = np.arange(n) / sr + f0 = 110.0 * (1.0 + 0.02 * np.sin(2 * np.pi * 0.9 * t)) + phase = 2 * np.pi * np.cumsum(f0) / sr + x = np.zeros(n) + for k in range(1, 9): + x += (1.0 / k**1.3) * np.sin(k * phase + 0.3 * k) + syll = 0.5 + 0.5 * np.sin(2 * np.pi * 3.0 * t + float(rng.uniform(0, 6))) + pauses = (np.sin(2 * np.pi * 0.5 * t) > -0.6).astype(float) + env = np.clip(syll, 0.02, 1.0) ** 0.6 * np.maximum(pauses, 0.05) + x = x * env + x /= np.max(np.abs(x)) + 1e-12 + return (x * (10 ** (level_dbfs / 20.0))).astype(np.float32) + + +def sine(freq: float, dur: float, sr: int = SR, peak_dbfs: float = -20.0) -> np.ndarray: + t = np.arange(int(sr * dur)) / sr + return (10 ** (peak_dbfs / 20.0) * np.sin(2 * np.pi * freq * t)).astype(np.float32) + + +def band_db(x: np.ndarray, sr: int, lo: float, hi: float) -> float: + from scipy import signal + + sos = signal.butter(4, [lo, hi], btype="bandpass", fs=sr, output="sos") + y = signal.sosfilt(sos, x.astype(np.float64)) + r = np.sqrt(np.mean(np.square(y))) + if r <= 0: + return -120.0 + return float(20 * np.log10(r)) + + +@pytest.fixture +def sr() -> int: + return SR + + +@pytest.fixture +def speech() -> np.ndarray: + return speechish(6.0, level_dbfs=-20.0) + + +@pytest.fixture +def noisy_speech(sr, speech) -> np.ndarray: + rng = np.random.default_rng(7) + noise = rng.standard_normal(speech.size) + noise *= (10 ** (-48.0 / 20.0)) / np.sqrt(np.mean(np.square(noise))) + hum = 0.003 * np.sin(2 * np.pi * 50.0 * np.arange(speech.size) / sr) + return (speech + noise + hum).astype(np.float32) -- cgit v1.2.3