Added methods to filter bank designer to create narrow-band spectra from octave band results, assuming a uniform power spectrum in a certain band
This commit is contained in:
parent
2270a297cc
commit
8c6e6a5828
@ -52,7 +52,6 @@ class FilterBankDesigner:
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True if filter is norm-compliant, False if not
|
True if filter is norm-compliant, False if not
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# Skip zero-frequency
|
# Skip zero-frequency
|
||||||
if np.isclose(freq[0], 0):
|
if np.isclose(freq[0], 0):
|
||||||
@ -62,7 +61,8 @@ class FilterBankDesigner:
|
|||||||
|
|
||||||
# Interpolate limites to frequency array as given
|
# Interpolate limites to frequency array as given
|
||||||
llim_full = np.interp(freq, freqlim, llim, left=-np.inf, right=-np.inf)
|
llim_full = np.interp(freq, freqlim, llim, left=-np.inf, right=-np.inf)
|
||||||
ulim_full = np.interp(freq, freqlim, ulim, left=ulim[0], right=ulim[-1])
|
ulim_full = np.interp(freq, freqlim, ulim,
|
||||||
|
left=ulim[0], right=ulim[-1])
|
||||||
|
|
||||||
return bool(np.all(llim_full <= h_dB) and
|
return bool(np.all(llim_full <= h_dB) and
|
||||||
np.all(ulim_full >= h_dB))
|
np.all(ulim_full >= h_dB))
|
||||||
@ -161,6 +161,66 @@ class FilterBankDesigner:
|
|||||||
raise ValueError(
|
raise ValueError(
|
||||||
f'Could not find an x-value corresponding to {nom_txt}.')
|
f'Could not find an x-value corresponding to {nom_txt}.')
|
||||||
|
|
||||||
|
def getxs(self, nom_txt_start, nom_txt_end):
|
||||||
|
"""Returns a list of all filter designators, for given start end end
|
||||||
|
nominal frequencies.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
nom_txt_start: Start frequency band, i.e. '31.5'
|
||||||
|
nom_txt_end: End frequency band, i.e. '10k'
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
[x0, x1, ..]
|
||||||
|
"""
|
||||||
|
xstart = self.nominal_txt_tox(nom_txt_start)
|
||||||
|
xend = self.nominal_txt_tox(nom_txt_end)
|
||||||
|
return list(range(xstart, xend+1))
|
||||||
|
|
||||||
|
def getNarrowBandFromOctaveBand(self, xl, xu,
|
||||||
|
levels_in_bands, npoints=500):
|
||||||
|
"""Create a narrow band spectrum based on a spectrum in (fractional)
|
||||||
|
octave bands. The result is create such that the total energy in each
|
||||||
|
frequency band is constant. The latter can be checked by working it
|
||||||
|
back to (fractional) octave bands, which is doen using the function
|
||||||
|
`getOctaveBandsFromNarrowBand`. Note that the resulting narrow band has
|
||||||
|
units of *power*, not power spectral density. Input should be levels in
|
||||||
|
**deciBells**.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
xl: Band designator of lowest band
|
||||||
|
xu: Band designator of highest band
|
||||||
|
levels_in_bands: levels in dB for each band, should have length
|
||||||
|
(xu+1 - xl)
|
||||||
|
npoints: Number of discrete frequency points in linear frequency
|
||||||
|
array.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
freq, levels_dB. Where levels_dB is an array of narrow band levels
|
||||||
|
"""
|
||||||
|
# Lowest frequency of all frequencies
|
||||||
|
fll = self.fl(xl)
|
||||||
|
# Highest frequency of all frequencies
|
||||||
|
fuu = self.fu(xu)
|
||||||
|
|
||||||
|
freq = np.linspace(fll, fuu, npoints)
|
||||||
|
levels_narrow = np.empty_like(freq)
|
||||||
|
for i, x in enumerate(range(xl, xu + 1)):
|
||||||
|
fl = self.fl(x)
|
||||||
|
fu = self.fu(x)
|
||||||
|
# Find the indices in the frequency array which correspond to the
|
||||||
|
# frequency band x
|
||||||
|
if x != xu:
|
||||||
|
indices_cur = np.where((freq >= fl) & (freq < fu))
|
||||||
|
else:
|
||||||
|
indices_cur = np.where((freq >= fl) & (freq <= fu))
|
||||||
|
|
||||||
|
power_cur = 10**(levels_in_bands[i] / 10)
|
||||||
|
power_narrow = power_cur / indices_cur[0].size
|
||||||
|
level_narrow = 10*np.log10(power_narrow)
|
||||||
|
levels_narrow[indices_cur] = level_narrow
|
||||||
|
|
||||||
|
return freq, levels_narrow
|
||||||
|
|
||||||
|
|
||||||
class OctaveBankDesigner(FilterBankDesigner):
|
class OctaveBankDesigner(FilterBankDesigner):
|
||||||
"""Octave band filter designer."""
|
"""Octave band filter designer."""
|
||||||
@ -204,9 +264,11 @@ class OctaveBankDesigner(FilterBankDesigner):
|
|||||||
mininf = -1e300
|
mininf = -1e300
|
||||||
|
|
||||||
if filter_class == 1:
|
if filter_class == 1:
|
||||||
lower_limits_pos = [-0.3, -0.4, -0.6, -1.3, -5.0, -5.0] + 4*[mininf]
|
lower_limits_pos = [-0.3, -0.4, -
|
||||||
|
0.6, -1.3, -5.0, -5.0] + 4*[mininf]
|
||||||
elif filter_class == 0:
|
elif filter_class == 0:
|
||||||
lower_limits_pos = [-0.15, -0.2, -0.4, -1.1, -4.5, -4.5] + 4*[mininf]
|
lower_limits_pos = [-0.15, -0.2, -
|
||||||
|
0.4, -1.1, -4.5, -4.5] + 4*[mininf]
|
||||||
lower_limits_neg = lower_limits_pos[:]
|
lower_limits_neg = lower_limits_pos[:]
|
||||||
lower_limits_neg.reverse()
|
lower_limits_neg.reverse()
|
||||||
lower_limits = np.asarray(lower_limits_neg[:-1] + lower_limits_pos)
|
lower_limits = np.asarray(lower_limits_neg[:-1] + lower_limits_pos)
|
||||||
@ -223,7 +285,6 @@ class OctaveBankDesigner(FilterBankDesigner):
|
|||||||
|
|
||||||
return freqs, lower_limits, upper_limits
|
return freqs, lower_limits, upper_limits
|
||||||
|
|
||||||
|
|
||||||
def nominal_txt(self, x):
|
def nominal_txt(self, x):
|
||||||
"""Returns textual repressentation of corresponding to the nominal
|
"""Returns textual repressentation of corresponding to the nominal
|
||||||
frequency."""
|
frequency."""
|
||||||
|
Loading…
Reference in New Issue
Block a user