Spaces:
Running
Running
import numpy as np | |
import math | |
class MelSpectrogram: | |
def __init__(self, n_filt, freq_low, freq_high, frame_size, fs, n_fft): | |
self.n_filt = n_filt | |
self.n_fft = n_fft | |
self.freq_low = freq_low | |
self.freq_high = freq_high | |
self.frame_size = frame_size | |
self.fs = fs | |
self.filt_bank = self.build_filterbank(freq_low, freq_high, n_filt, n_fft, fs) | |
self.mel_power = np.zeros(n_filt, dtype=np.float32) | |
self.mel_spectrogram_image = np.zeros((n_filt, n_filt), dtype=np.float32) | |
def build_filterbank(self, l, h, n_filt, n_fft, fs): | |
lower_mel = 1125 * math.log(1 + l / 700) | |
higher_mel = 1125 * math.log(1 + h / 700) | |
rows = math.floor(n_fft / 2) | |
columns = n_filt | |
filterbank = np.zeros((rows, columns), dtype=np.float32) | |
diff = (higher_mel - lower_mel) / (n_filt + 1) | |
mel_band = lower_mel | |
freq_band = 700 * (math.exp(mel_band / 1125) - 1) | |
f = np.zeros(n_filt + 2, dtype=np.int32) | |
f[0] = math.floor((n_fft + 1) * freq_band / fs) | |
for i in range(1, n_filt + 2): | |
mel_band = mel_band + diff | |
freq_band = 700 * (math.exp(mel_band / 1125) - 1) | |
f[i] = math.floor((n_fft + 1) * freq_band / fs) | |
for k in range(1, rows + 1): | |
for m in range(1, columns + 1): | |
if (k > f[m - 1]) and (k <= f[m]): | |
filterbank[k - 1][m - 1] = float(k - f[m - 1]) / float( | |
f[m] - f[m - 1] | |
) | |
elif (k > f[m]) and (k <= f[m + 1]): | |
filterbank[k - 1][m - 1] = float(f[m + 1] - k) / float( | |
f[m + 1] - f[m] | |
) | |
return filterbank | |
def mel_calculate(self, fft_data): | |
for i in range(self.n_filt): | |
sum_val = 0 | |
for j in range(math.floor(self.n_fft / 2)): | |
sum_val += self.filt_bank[j][i] * fft_data[j] | |
self.mel_power[i] = math.log(sum_val + 1e-8) | |
def mel_image_create(self): | |
# Shift the 2-d image up | |
for i in range(self.n_filt - 1): | |
self.mel_spectrogram_image[i] = np.copy(self.mel_spectrogram_image[i + 1]) | |
# Add the current mel-spectrogram power to the bottom row | |
self.mel_spectrogram_image[self.n_filt - 1] = np.copy(self.mel_power) | |
def update_image(self, fft_data): | |
self.mel_calculate(fft_data) | |
self.mel_image_create() | |