@@ -46,40 +46,49 @@ def test_schroeder_integration_multi_cdim(is_energy):
4646 npt .assert_almost_equal (energy_decay_curve .time [1 , 0 ], truth )
4747
4848
49- def test_edc_eyring ():
50- alphas = [0.9 , 0.1 ]
51- surfaces = [2 , 5 * 2 ]
52- volume = 2 * 2 * 2
49+ @pytest .mark .parametrize (
50+ "edc_function" ,
51+ [ra .edc .energy_decay_curve_chu ,
52+ ra .edc .energy_decay_curve_lundeby ,
53+ ra .edc .energy_decay_curve_chu_lundeby ],
54+ )
55+ def test_multidim_edc (edc_function ):
56+ """
57+ Test if edcs from multichannel signal are equal to corresponding single
58+ channel edcs.
59+ """
60+ rir = pf .signals .files .room_impulse_response ()
61+ rir_oct = pf .dsp .filter .fractional_octave_bands (rir , 1 )
62+ shape = rir_oct .time .shape
63+ edc = edc_function (rir_oct , channel_independent = True )
64+
65+ assert shape == edc .time .shape
66+
67+ edc = edc .flatten ()
68+ rir_oct = rir_oct .flatten ()
69+
70+ for i in range (edc .cshape [0 ]):
71+ baseline = edc_function (rir_oct [i ])
72+ npt .assert_array_equal (edc [i ].time , baseline .time )
73+
74+
75+ def test_edc_function ():
76+ """Test for the parametric energy decay curve based on previous
77+ implementation which also included RT prediction using Sabine's equation.
78+ """
5379 times = np .linspace (0 , 0.25 , 50 )
54- edc = ra .parametric .energy_decay_curve_analytic (
55- surfaces , alphas , volume , times , method = 'eyring' , air_absorption = False )
5680
57- truth = array ([
58- 1.00000000e+00 , 8.39817186e-01 , 7.05292906e-01 , 5.92317103e-01 ,
59- 4.97438083e-01 , 4.17757051e-01 , 3.50839551e-01 , 2.94641084e-01 ,
60- 2.47444646e-01 , 2.07808266e-01 , 1.74520953e-01 , 1.46565696e-01 ,
61- 1.23088390e-01 , 1.03371746e-01 , 8.68133684e-02 , 7.29073588e-02 ,
62- 6.12288529e-02 , 5.14210429e-02 , 4.31842755e-02 , 3.62668968e-02 ,
63- 3.04575632e-02 , 2.55787850e-02 , 2.14815032e-02 , 1.80405356e-02 ,
64- 1.51507518e-02 , 1.27238618e-02 , 1.06857178e-02 , 8.97404943e-03 ,
65- 7.53656094e-03 , 6.32933340e-03 , 5.31548296e-03 , 4.46403394e-03 ,
66- 3.74897242e-03 , 3.14845147e-03 , 2.64412365e-03 , 2.22058049e-03 ,
67- 1.86488165e-03 , 1.56615966e-03 , 1.31528780e-03 , 1.10460130e-03 ,
68- 9.27663155e-04 , 7.79067460e-04 , 6.54274242e-04 , 5.49470753e-04 ,
69- 4.61454981e-04 , 3.87537824e-04 , 3.25460924e-04 , 2.73327678e-04 ,
70- 2.29545281e-04 , 1.92776072e-04 ,
71- ])
72-
73- npt .assert_almost_equal (edc , truth )
74-
75-
76- def test_edc_sabine ():
77- alphas = [0.9 , 0.1 ]
78- surfaces = [2 , 5 * 2 ]
81+ c = 343.4
82+
7983 volume = 2 * 2 * 2
80- times = np .linspace (0 , 0.25 , 50 )
81- edc = ra .parametric .energy_decay_curve_analytic (
82- surfaces , alphas , volume , times , method = 'sabine' , air_absorption = False )
84+ alphas = np .asarray ([0.9 , 0.1 ])
85+ surfaces = np .asarray ([2 , 5 * 2 ])
86+ surface_room = np .sum (surfaces )
87+ alpha_mean = np .sum (surfaces * alphas ) / surface_room
88+
89+ rt = 24 * np .log (10 )/ c * volume / (surface_room * alpha_mean )
90+ energy = 1
91+ edc = ra .parametric .energy_decay_curve (times , rt , energy )
8392
8493 truth = array ([
8594 1.00000000e+00 , 8.57869258e-01 , 7.35939663e-01 , 6.31340013e-01 ,
@@ -96,30 +105,38 @@ def test_edc_sabine():
96105 1.17632849e-03 , 1.00913605e-03 , 8.65706791e-04 , 7.42663242e-04 ,
97106 6.37107964e-04 , 5.46555336e-04 ,
98107 ])
99- npt .assert_almost_equal (edc , truth )
108+ npt .assert_almost_equal (edc . time , np . atleast_2d ( truth ) )
100109
101110
102- @pytest .mark .parametrize (
103- "edc_function" ,
104- [ra .edc .energy_decay_curve_chu ,
105- ra .edc .energy_decay_curve_lundeby ,
106- ra .edc .energy_decay_curve_chu_lundeby ],
107- )
108- def test_multidim_edc (edc_function ):
109- """
110- Test if edcs from multichannel signal are equal to corresponding single
111- channel edcs.
111+ def test_parametric_edc ():
112+ """Test returned edc by the parametric edc function and shape broadcasting.
112113 """
113- rir = pf .signals .files .room_impulse_response ()
114- rir_oct = pf .dsp .filter .fractional_octave_bands (rir , 1 )
115- shape = rir_oct .time .shape
116- edc = edc_function (rir_oct , channel_independent = True )
114+ times = np .linspace (0 , 0.25 , 50 )
115+ T_60 = np .array ([2 , 1 ])
117116
118- assert shape == edc .time .shape
117+ edc = ra .parametric .energy_decay_curve (times , T_60 )
118+ assert edc .cshape == (2 ,)
119119
120- edc = edc . flatten ( )
121- rir_oct = rir_oct . flatten ( )
120+ e_0 = np . ones_like ( T_60 )
121+ edc = ra . parametric . energy_decay_curve ( times , T_60 , energy = e_0 )
122122
123- for i in range (edc .cshape [0 ]):
124- baseline = edc_function (rir_oct [i ])
125- npt .assert_array_equal (edc [i ].time , baseline .time )
123+ damping_term = 6 * np .log (10 ) / T_60
124+ truth = np .atleast_2d (e_0 ).T * np .exp (- np .atleast_2d (damping_term ).T * times )
125+
126+ npt .assert_almost_equal (edc .time , truth )
127+ assert edc .cshape == (2 ,)
128+
129+ edc = ra .parametric .energy_decay_curve (
130+ times , np .ones ((3 , 2 )), energy = np .ones ((3 , 2 )))
131+
132+ assert edc .cshape == (3 , 2 )
133+
134+
135+ def test_parametric_edc_wrong_shapes ():
136+ """Test error handling for wrong shapes."""
137+ times = np .linspace (0 , 0.25 , 50 )
138+ T_60 = np .array ([2 , 1 ])
139+ energy = np .array ([1 , 1 , 1 ])
140+
141+ with pytest .raises (ValueError , match = "same shape." ):
142+ ra .parametric .energy_decay_curve (times , T_60 , energy = energy )
0 commit comments