def mel_filter_bank(fs: int,
window_width: int,
n_filt: int = 40) -> (np.ndarray, np.ndarray):
"""
Computes Mel filter banks for the specified parameters.
A power spectrogram can be converted to a Mel spectrogram by multiplying it with the filter bank. This method exists
so that the computation of Mel filter banks does not have to be repeated for each computation of a Mel spectrogram.
The coefficients of Mel filter banks depend on the sampling frequency and the window width that were used to
generate power spectrograms.
Parameters
----------
fs: int
The sampling frequency of signals
window_width: int
The window width in samples used to generate spectrograms
n_filt: int
The number of filters to compute
Returns
-------
f: numpy.ndarray
Array of Hertz frequency values for the filter banks
filters: numpy.ndarray
Array of Mel filter bank coefficients. The first axis corresponds to different filters, and the second axis
corresponds to the original frequency bands
"""
n_fft = window_width
low_freq_mel = 0
high_freq_mel = (2595 * np.log10(1 + (fs / 2) / 700)) # Convert Hz to Mel
mel_points = np.linspace(low_freq_mel, high_freq_mel, n_filt + 2) # Equally spaced in Mel scale
hz_points = (700 * (10 ** (mel_points / 2595) - 1)) # Convert Mel to Hz
bin = np.floor((n_fft + 1) * hz_points / fs)
fbank = np.zeros((n_filt, int(np.floor(n_fft / 2 + 1))))
for m in range(1, n_filt + 1):
f_m_minus = int(bin[m - 1]) # left
f_m = int(bin[m]) # center
f_m_plus = int(bin[m + 1]) # right
for k in range(f_m_minus, f_m):
fbank[m - 1, k] = (k - bin[m - 1]) / (bin[m] - bin[m - 1])
for k in range(f_m, f_m_plus):
fbank[m - 1, k] = (bin[m + 1] - k) / (bin[m + 1] - bin[m])
return hz_points[1:n_filt + 1], fbank
评论列表
文章目录