33
33
import numpy as np
34
34
35
35
36
- def measure_rt60 (h , fs = 1 , decay_db = 60 , plot = False , rt60_tgt = None ):
36
+ def measure_rt60 (h , fs = 1 , decay_db = 60 , energy_thres = 0.95 , plot = False , rt60_tgt = None ):
37
37
"""
38
38
Analyze the RT60 of an impulse response. Optionaly plots some useful information.
39
39
@@ -47,6 +47,10 @@ def measure_rt60(h, fs=1, decay_db=60, plot=False, rt60_tgt=None):
47
47
The decay in decibels for which we actually estimate the time. Although
48
48
we would like to estimate the RT60, it might not be practical. Instead,
49
49
we measure the RT20 or RT30 and extrapolate to RT60.
50
+ energy_thres: float
51
+ This should be a value between 0.0 and 1.0.
52
+ If provided, the fit will be done using a fraction energy_thres of the
53
+ whole energy. This is useful when there is a long noisy tail for example.
50
54
plot: bool, optional
51
55
If set to ``True``, the power decay and different estimated values will
52
56
be plotted (default False).
@@ -60,21 +64,36 @@ def measure_rt60(h, fs=1, decay_db=60, plot=False, rt60_tgt=None):
60
64
61
65
# The power of the impulse response in dB
62
66
power = h ** 2
67
+ # Backward energy integration according to Schroeder
63
68
energy = np .cumsum (power [::- 1 ])[::- 1 ] # Integration according to Schroeder
64
69
70
+ if energy_thres < 1.0 :
71
+ assert 0.0 < energy_thres < 1.0
72
+ energy -= energy [0 ] * (1.0 - energy_thres )
73
+ energy = np .maximum (energy , 0.0 )
74
+
65
75
# remove the possibly all zero tail
66
76
i_nz = np .max (np .where (energy > 0 )[0 ])
67
77
energy = energy [:i_nz ]
68
78
energy_db = 10 * np .log10 (energy )
69
79
energy_db -= energy_db [0 ]
70
80
81
+ min_energy_db = - np .min (energy_db )
82
+ if min_energy_db - 5 < decay_db :
83
+ decay_db = min_energy_db
84
+
71
85
# -5 dB headroom
72
- i_5db = np .min (np .where (- 5 - energy_db > 0 )[0 ])
86
+ try :
87
+ i_5db = np .min (np .where (energy_db < - 5 )[0 ])
88
+ except ValueError :
89
+ return 0.0
73
90
e_5db = energy_db [i_5db ]
74
91
t_5db = i_5db / fs
75
-
76
92
# after decay
77
- i_decay = np .min (np .where (- 5 - decay_db - energy_db > 0 )[0 ])
93
+ try :
94
+ i_decay = np .min (np .where (energy_db < - 5 - decay_db )[0 ])
95
+ except ValueError :
96
+ i_decay = len (energy_db )
78
97
t_decay = i_decay / fs
79
98
80
99
# compute the decay time
0 commit comments