import numpy as np from conftest import sine, speechish from producer import meters def test_rms_and_peak_of_sine(sr): x = sine(1000, 3.0, sr, peak_dbfs=-17.0) assert abs(meters.rms_db(x) + 20.0) < 0.1 assert abs(meters.sample_peak_db(x) + 17.0) < 0.05 def test_true_peak_bounds(sr): x = sine(1000, 3.0, sr, peak_dbfs=-17.0) tp = meters.true_peak_db(x, sr) sp = meters.sample_peak_db(x) assert sp - 0.01 <= tp <= sp + 0.6 def test_true_peak_blockwise_matches_whole_file(sr): from scipy import signal rng = np.random.default_rng(3) n = sr * 75 x = ( 0.5 * np.sin(2 * np.pi * 997.0 * np.arange(n) / sr) + 0.02 * rng.standard_normal(n) ).astype(np.float32) half = 10 * 4 h = signal.firwin(2 * half + 1, 0.25, window=("kaiser", 8.0)).astype(np.float32) ref = meters.sample_peak_db(signal.resample_poly(x, 4, 1, window=h)) assert abs(meters.true_peak_db(x, sr) - ref) < 0.01 def test_lufs_of_sine(sr): x = sine(1000, 3.0, sr, peak_dbfs=-17.0) assert abs(meters.lufs(x, sr) + 20.05) < 0.2 def test_lufs_silence(): assert meters.lufs(np.zeros(48000, dtype=np.float32), 48000) == meters.SILENCE_DB def test_noise_floor_below_speech(sr): x = speechish(8.0, sr, level_dbfs=-20.0) floor = meters.noise_floor_db(x, sr) assert floor < meters.rms_db(x) - 4.0 def test_speech_level_db_ignores_leading_silence(sr): x = speechish(6.0, sr, level_dbfs=-20.0) y = np.concatenate([np.zeros(sr * 4, dtype=np.float32), x]) assert abs(meters.speech_level_db(x, sr) - meters.speech_level_db(y, sr)) < 1.0 assert meters.speech_level_db(x, sr) > meters.rms_db(x) def test_all_meters_keys(sr): d = meters.all_meters(speechish(3.0, sr), sr) assert set(d) == { "rms_db", "sample_peak_db", "true_peak_db", "lufs", "noise_floor_db", "duration_s", }