Source code for spafe.fbanks.bark_fbanks

##############################################################################################
#                             Bark-filter-banks implementation
##############################################################################################
import numpy as np
from ..utils.exceptions import ParameterError, ErrorMsgs
from ..utils.converters import hz2bark, fft2bark, bark2fft


[docs]def Fm(fb, fc): """ Compute a Bark filter around a certain center frequency in bark. Args: fb (int): frequency in Bark. fc (int): center frequency in Bark. Returns: (float) : associated Bark filter value/amplitude. """ if fc - 2.5 <= fb <= fc - 0.5: return 10**(2.5 * (fb - fc + 0.5)) elif fc - 0.5 < fb < fc + 0.5: return 1 elif fc + 0.5 <= fb <= fc + 1.3: return 10**(-2.5 * (fb - fc - 0.5)) else: return 0
[docs]def bark_filter_banks(nfilts=20, nfft=512, fs=16000, low_freq=0, high_freq=None, scale="constant"): """ Compute Bark-filterbanks. The filters are stored in the rows, the columns correspond to fft bins. Args: nfilts (int) : the number of filters in the filterbank. (Default 20) nfft (int) : the FFT size. (Default is 512) fs (int) : sample rate/ sampling frequency of the signal. (Default 16000 Hz) low_freq (int) : lowest band edge of mel filters. (Default 0 Hz) high_freq (int) : highest band edge of mel filters. (Default samplerate/2) scale (str) : choose if max bins amplitudes ascend, descend or are constant (=1). Default is "constant" Returns: a numpy array of size nfilts * (nfft/2 + 1) containing filterbank. Each row holds 1 filter. """ # init freqs high_freq = high_freq or fs / 2 low_freq = low_freq or 0 # run checks if low_freq < 0: raise ParameterError(ErrorMsgs["low_freq"]) if high_freq > (fs / 2): raise ParameterError(ErrorMsgs["high_freq"]) # compute points evenly spaced in Bark scale (points are in Bark) low_bark = hz2bark(low_freq) high_bark = hz2bark(high_freq) bark_points = np.linspace(low_bark, high_bark, nfilts + 4) # we use fft bins, so we have to convert from Bark to fft bin number bins = np.floor(bark2fft(bark_points, fs, nfft)) fbank = np.zeros([nfilts, nfft // 2 + 1]) # init scaler if scale == "descendant" or scale == "constant": c = 1 else: c = 0 for j in range(2, nfilts + 2): # compute scaler if scale == "descendant": c -= 1 / nfilts c = c * (c > 0) + 0 * (c < 0) elif scale == "ascendant": c += 1 / nfilts c = c * (c < 1) + 1 * (c > 1) for i in range(int(bins[j - 2]), int(bins[j + 2])): fc = bark_points[j] fb = fft2bark(i, fs, nfft) fbank[j - 2, i] = c * Fm(fb, fc) return np.abs(fbank)