1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
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",
}
|