Typo fix. Added 44.1 kHz as possible sampling frequency for computing filters.
This commit is contained in:
parent
f7a49dc4ff
commit
90a5d87419
@ -67,7 +67,7 @@ std::vector<unique_ptr<Filter>> createBandPass(const dmat &coefs) {
|
||||
return bf;
|
||||
}
|
||||
us SLM::suggestedDownSamplingFac(const d fs,const d tau) {
|
||||
if(tau<0) throw rte("Invalid time weightin time constant");
|
||||
if(tau<0) throw rte("Invalid time weighting time constant");
|
||||
if(fs<=0) throw rte("Invalid sampling frequency");
|
||||
// A reasonable 'framerate' for the sound level meter, based on the
|
||||
// filtering time constant.
|
||||
|
@ -10,12 +10,14 @@ Resulting filters are supposed to be standard compliant.
|
||||
See test/octave_fir_test.py for a testing
|
||||
|
||||
"""
|
||||
from .fir_design import bandpass_fir_design, freqResponse as firFreqResponse
|
||||
import numpy as np
|
||||
import warnings
|
||||
|
||||
import numpy as np
|
||||
# For designing second-order sections
|
||||
from scipy.signal import butter
|
||||
|
||||
from .fir_design import bandpass_fir_design
|
||||
from .fir_design import freqResponse as firFreqResponse
|
||||
|
||||
__all__ = ['OctaveBankDesigner', 'ThirdOctaveBankDesigner']
|
||||
|
||||
@ -61,11 +63,13 @@ class FilterBankDesigner:
|
||||
|
||||
# Interpolate limites to frequency array as given
|
||||
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
|
||||
np.all(ulim_full >= h_dB))
|
||||
return bool(np.all(llim_full <= h_dB) and np.all(ulim_full >= h_dB))
|
||||
|
||||
def band_limits(self, x, filter_class):
|
||||
raise NotImplementedError()
|
||||
@ -81,7 +85,8 @@ class FilterBankDesigner:
|
||||
if self.nominal_txt(x) == nom_txt:
|
||||
return x
|
||||
raise ValueError(
|
||||
f'Could not find a nominal frequency corresponding to {nom_txt}. Hint: use \'5k\' instead of \'5000\'.')
|
||||
f'Could not find a nominal frequency corresponding to {nom_txt}. Hint: use \'5k\' instead of \'5000\'.'
|
||||
)
|
||||
|
||||
def sanitize_input(self, input_):
|
||||
if isinstance(input_, int):
|
||||
@ -99,7 +104,6 @@ class FilterBankDesigner:
|
||||
x = [self.sanitize_input(xi) for xi in input_]
|
||||
return np.asarray(x)
|
||||
|
||||
|
||||
def getxs(self, nom_txt_start, nom_txt_end):
|
||||
"""Returns a list of all filter designators, for given start end end
|
||||
nominal frequencies.
|
||||
@ -114,6 +118,7 @@ class FilterBankDesigner:
|
||||
xstart = self.nominal_txt_tox(nom_txt_start)
|
||||
xend = self.nominal_txt_tox(nom_txt_end)
|
||||
return list(range(xstart, xend + 1))
|
||||
|
||||
def fm(self, x):
|
||||
"""Returns the exact midband frequency of the bandpass filter.
|
||||
|
||||
@ -200,9 +205,11 @@ class FilterBankDesigner:
|
||||
|
||||
return firFreqResponse(fd, freq, fir)
|
||||
|
||||
|
||||
def getNarrowBandFromOctaveBand(self, xl, xu,
|
||||
levels_in_bands, npoints=500,
|
||||
def getNarrowBandFromOctaveBand(self,
|
||||
xl,
|
||||
xu,
|
||||
levels_in_bands,
|
||||
npoints=500,
|
||||
method='flat',
|
||||
scale='lin'):
|
||||
"""Create a narrow band spectrum based on a spectrum in (fractional)
|
||||
@ -351,11 +358,11 @@ class OctaveBankDesigner(FilterBankDesigner):
|
||||
mininf = -1e300
|
||||
|
||||
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:
|
||||
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.reverse()
|
||||
lower_limits = np.asarray(lower_limits_neg[:-1] + lower_limits_pos)
|
||||
@ -375,7 +382,8 @@ class OctaveBankDesigner(FilterBankDesigner):
|
||||
def nominal_txt(self, x):
|
||||
"""Returns textual repressentation of corresponding to the nominal
|
||||
frequency."""
|
||||
nominals = {4: '16k',
|
||||
nominals = {
|
||||
4: '16k',
|
||||
3: '8k',
|
||||
2: '4k',
|
||||
1: '2k',
|
||||
@ -385,7 +393,8 @@ class OctaveBankDesigner(FilterBankDesigner):
|
||||
-3: '125',
|
||||
-4: '63',
|
||||
-5: '31.5',
|
||||
-6: '16'}
|
||||
-6: '16'
|
||||
}
|
||||
assert len(nominals) == len(self.xs)
|
||||
return nominals[x]
|
||||
|
||||
@ -472,16 +481,12 @@ class ThirdOctaveBankDesigner(FilterBankDesigner):
|
||||
super().__init__(fs)
|
||||
self.xs = list(range(-16, 14))
|
||||
# Text corresponding to the nominal frequency
|
||||
self._nominal_txt = ['25', '31.5', '40',
|
||||
'50', '63', '80',
|
||||
'100', '125', '160',
|
||||
'200', '250', '315',
|
||||
'400', '500', '630',
|
||||
'800', '1k', '1.25k',
|
||||
'1.6k', '2k', '2.5k',
|
||||
'3.15k', '4k', '5k',
|
||||
'6.3k', '8k', '10k',
|
||||
'12.5k', '16k', '20k']
|
||||
self._nominal_txt = [
|
||||
'25', '31.5', '40', '50', '63', '80', '100', '125', '160', '200',
|
||||
'250', '315', '400', '500', '630', '800', '1k', '1.25k', '1.6k',
|
||||
'2k', '2.5k', '3.15k', '4k', '5k', '6.3k', '8k', '10k', '12.5k',
|
||||
'16k', '20k'
|
||||
]
|
||||
|
||||
assert len(self.xs) == len(self._nominal_txt)
|
||||
|
||||
@ -501,7 +506,6 @@ class ThirdOctaveBankDesigner(FilterBankDesigner):
|
||||
index_stop = x[-1] - self.xs[0]
|
||||
return self._nominal_txt[index_start:index_stop + 1]
|
||||
|
||||
|
||||
def band_limits(self, x, filter_class=0):
|
||||
"""Returns the third octave band filter limits for filter designator x.
|
||||
|
||||
@ -518,11 +522,15 @@ class ThirdOctaveBankDesigner(FilterBankDesigner):
|
||||
|
||||
fm = self.G**(x / self.b) * self.fr
|
||||
plusinf = 20
|
||||
f_ratio_pos = [1., 1.02667, 1.05575, 1.08746, 1.12202, 1.12202,
|
||||
1.29437, 1.88173, 3.05365, 5.39195, plusinf]
|
||||
f_ratio_pos = [
|
||||
1., 1.02667, 1.05575, 1.08746, 1.12202, 1.12202, 1.29437, 1.88173,
|
||||
3.05365, 5.39195, plusinf
|
||||
]
|
||||
|
||||
f_ratio_neg = [0.97402, 0.94719, 0.91958, 0.89125, 0.89125,
|
||||
0.77257, 0.53143, 0.32748, 0.18546, 1/plusinf]
|
||||
f_ratio_neg = [
|
||||
0.97402, 0.94719, 0.91958, 0.89125, 0.89125, 0.77257, 0.53143,
|
||||
0.32748, 0.18546, 1 / plusinf
|
||||
]
|
||||
f_ratio_neg.reverse()
|
||||
|
||||
f_ratio = f_ratio_neg + f_ratio_pos
|
||||
@ -541,11 +549,15 @@ class ThirdOctaveBankDesigner(FilterBankDesigner):
|
||||
upper_limits = np.array(upper_limits_neg[:-1] + upper_limits_pos)
|
||||
|
||||
if filter_class == 1:
|
||||
lower_limits_pos = [-.3, -.4, -.6, -1.3, -5, -5, mininf, mininf,
|
||||
mininf, mininf, mininf]
|
||||
lower_limits_pos = [
|
||||
-.3, -.4, -.6, -1.3, -5, -5, mininf, mininf, mininf, mininf,
|
||||
mininf
|
||||
]
|
||||
elif filter_class == 0:
|
||||
lower_limits_pos = [-.15, -.2, -.4, -1.1, -4.5, -4.5, mininf, mininf,
|
||||
mininf, mininf, mininf]
|
||||
lower_limits_pos = [
|
||||
-.15, -.2, -.4, -1.1, -4.5, -4.5, mininf, mininf, mininf,
|
||||
mininf, mininf
|
||||
]
|
||||
|
||||
lower_limits_neg = lower_limits_pos[:]
|
||||
lower_limits_neg.reverse()
|
||||
@ -592,13 +604,17 @@ class ThirdOctaveBankDesigner(FilterBankDesigner):
|
||||
filter."""
|
||||
# Idea: correct for frequency warping:
|
||||
if np.isclose(self.fs, 48000):
|
||||
return 1.00
|
||||
elif np.isclose(self.fs, 41000):
|
||||
warnings.warn(
|
||||
f'Frequency {self.fs} might not result in correct filters')
|
||||
|
||||
return 1.00
|
||||
elif np.isclose(self.fs, 32768):
|
||||
return 1.00
|
||||
else:
|
||||
raise ValueError('Unimplemented sampling frequency for SOS'
|
||||
'filter design')
|
||||
|
||||
def sosFac_u(self, x):
|
||||
"""Right side percentage of change in cut-on frequency for designing
|
||||
the filter."""
|
||||
|
Loading…
Reference in New Issue
Block a user