2022-09-03 18:59:14 +00:00
|
|
|
#!/usr/bin/python3
|
|
|
|
import numpy as np
|
2022-10-01 17:59:35 +00:00
|
|
|
from lasp import cppSLM
|
2022-09-03 18:59:14 +00:00
|
|
|
from lasp.filter import SPLFilterDesigner
|
2023-01-12 19:31:55 +00:00
|
|
|
|
2022-09-03 18:59:14 +00:00
|
|
|
|
|
|
|
def test_cppslm1():
|
|
|
|
"""
|
|
|
|
Generate a sine wave
|
|
|
|
"""
|
|
|
|
fs = 48000
|
2023-01-12 19:31:55 +00:00
|
|
|
omg = 2 * np.pi * 1000
|
|
|
|
|
|
|
|
slm = cppSLM.fromBiquads(fs, 2e-5, 1, 0.125,
|
|
|
|
np.array([[1., 0, 0, 1, 0, 0]]).T)
|
|
|
|
|
|
|
|
t = np.linspace(0, 10, 10 * fs, endpoint=False)
|
|
|
|
|
|
|
|
# Input signal with an rms of 1 Pa
|
|
|
|
in_ = np.sin(omg * t) * np.sqrt(2)
|
|
|
|
|
2022-09-03 18:59:14 +00:00
|
|
|
# Compute overall RMS
|
2023-01-12 19:31:55 +00:00
|
|
|
rms = np.sqrt(np.sum(in_**2) / in_.size)
|
2022-09-03 18:59:14 +00:00
|
|
|
# Compute overall level
|
2023-01-12 19:31:55 +00:00
|
|
|
level = 20 * np.log10(rms / 2e-5)
|
|
|
|
|
2022-09-03 18:59:14 +00:00
|
|
|
# Output of SLM
|
|
|
|
out = slm.run(in_)
|
2023-01-12 19:31:55 +00:00
|
|
|
|
2022-09-03 18:59:14 +00:00
|
|
|
# Output of SLM should be close to theoretical
|
|
|
|
# level, at least for reasonable time constants
|
|
|
|
# (Fast, Slow etc)
|
2023-01-12 19:31:55 +00:00
|
|
|
assert (np.isclose(out[-1, 0], level))
|
2022-09-03 18:59:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_cppslm2():
|
|
|
|
"""
|
|
|
|
Generate a sine wave, now A-weighted
|
|
|
|
"""
|
|
|
|
fs = 48000
|
2023-01-12 19:31:55 +00:00
|
|
|
omg = 2 * np.pi * 1000
|
|
|
|
|
2022-09-03 18:59:14 +00:00
|
|
|
filt = SPLFilterDesigner(fs).A_Sos_design()
|
2023-01-12 19:31:55 +00:00
|
|
|
slm = cppSLM.fromBiquads(fs, 2e-5, 0, 0.125,
|
|
|
|
filt.flatten(), # Pre-filter coefs
|
|
|
|
np.array([[1., 0, 0, 1, 0, 0]]).T # Bandpass coefs
|
|
|
|
)
|
|
|
|
|
|
|
|
t = np.linspace(0, 10, 10 * fs, endpoint=False)
|
|
|
|
|
|
|
|
# Input signal with an rms of 1 Pa
|
|
|
|
in_ = np.sin(omg * t) * np.sqrt(2)
|
|
|
|
|
2022-09-03 18:59:14 +00:00
|
|
|
# Compute overall RMS
|
2023-01-12 19:31:55 +00:00
|
|
|
rms = np.sqrt(np.sum(in_**2) / in_.size)
|
2022-09-03 18:59:14 +00:00
|
|
|
# Compute overall level
|
2023-01-12 19:31:55 +00:00
|
|
|
level = 20 * np.log10(rms / 2e-5)
|
|
|
|
|
2022-09-03 18:59:14 +00:00
|
|
|
# Output of SLM
|
|
|
|
out = slm.run(in_)
|
|
|
|
|
|
|
|
# Output of SLM should be close to theoretical
|
|
|
|
# level, at least for reasonable time constants
|
|
|
|
# (Fast, Slow etc)
|
2023-01-12 19:31:55 +00:00
|
|
|
assert np.isclose(out[-1, 0], level, atol=1e-2)
|
|
|
|
|
2022-09-03 18:59:14 +00:00
|
|
|
|
2022-10-01 17:59:35 +00:00
|
|
|
def test_cppslm3():
|
|
|
|
fs = 48000
|
2023-01-12 19:31:55 +00:00
|
|
|
omg = 2 * np.pi * 1000
|
|
|
|
|
2022-10-01 17:59:35 +00:00
|
|
|
filt = SPLFilterDesigner(fs).A_Sos_design()
|
2023-01-12 19:31:55 +00:00
|
|
|
slm = cppSLM.fromBiquads(fs, 2e-5, 0, 0.125,
|
|
|
|
filt.flatten(),
|
|
|
|
np.array([[1., 0, 0, 1, 0, 0]]).T)
|
|
|
|
t = np.linspace(0, 10, 10 * fs, endpoint=False)
|
|
|
|
|
|
|
|
in_ = 10 * np.sin(omg * t) * np.sqrt(2) + np.random.randn()
|
2022-10-01 17:59:35 +00:00
|
|
|
# Compute overall RMS
|
2023-01-12 19:31:55 +00:00
|
|
|
rms = np.sqrt(np.sum(in_**2) / in_.size)
|
2022-10-01 17:59:35 +00:00
|
|
|
# Compute overall level
|
2023-01-12 19:31:55 +00:00
|
|
|
level = 20 * np.log10(rms / 2e-5)
|
|
|
|
|
2022-10-01 17:59:35 +00:00
|
|
|
# Output of SLM
|
|
|
|
out = slm.run(in_)
|
2023-01-12 19:31:55 +00:00
|
|
|
|
|
|
|
Lpeak = 20 * np.log10(np.max(np.abs(in_) / 2e-5))
|
2022-10-01 17:59:35 +00:00
|
|
|
Lpeak
|
|
|
|
slm.Lpeak()
|
2023-01-12 19:31:55 +00:00
|
|
|
assert np.isclose(out[-1, 0], slm.Leq()[0], atol=1e-2)
|
|
|
|
assert np.isclose(Lpeak, slm.Lpeak()[0], atol=2e0)
|
2022-09-03 18:59:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
test_cppslm1()
|
|
|
|
test_cppslm2()
|
2022-10-01 17:59:35 +00:00
|
|
|
test_cppslm3()
|