Spaces:
Running
Running
import librosa | |
import numpy as np | |
from basis import ScoreBasis | |
class FWSEGSNR(ScoreBasis): | |
def __init__(self): | |
super(FWSEGSNR, self).__init__(name='FWSEGSNR') | |
self.intrusive = False | |
def windowed_scoring(self, audios, score_rate): | |
if len(audios) != 2: | |
return None | |
return fwsegsnr(audios[1], audios[0], score_rate) | |
def fwsegsnr(x, y, fs, frame_sz = 0.025, shift_sz= 0.01, win='hann', numband=23): | |
epsilon = np.finfo(np.float32).eps | |
frame = int(np.fix(frame_sz * fs)) | |
shift = int(np.fix(shift_sz * fs)) | |
window = win | |
nband = numband | |
noverlap = frame - shift | |
fftpt = int(2**np.ceil(np.log2(np.abs(frame)))) | |
x = x / np.sqrt(sum(np.power(x, 2))) | |
y = y / np.sqrt(sum(np.power(y, 2))) | |
assert len(x) == len(y), print('Wav length are not matched!') | |
X_stft = np.abs(librosa.stft(x, n_fft=fftpt, hop_length=shift, win_length=frame, window=window, center=False)) | |
Y_stft = np.abs(librosa.stft(y, n_fft=fftpt, hop_length=shift, win_length=frame, window=window, center=False)) | |
num_freq = X_stft.shape[0] | |
num_frame = X_stft.shape[1] | |
X_mel = librosa.feature.melspectrogram(S=X_stft, sr=fs, n_mels=nband, fmin=0, fmax=fs/2) | |
Y_mel = librosa.feature.melspectrogram(S=Y_stft, sr=fs, n_mels=nband, fmin=0, fmax=fs/2) | |
# Calculate SNR. | |
W = np.power(Y_mel, 0.2) | |
E = X_mel - Y_mel | |
E[E == 0.0] = epsilon | |
E_power = np.power(E, 2) | |
Y_div_E = np.divide((np.power(Y_mel,2)), (np.power(E,2))) | |
Y_div_E[Y_div_E==0] = epsilon | |
ds = 10 * np.divide(np.sum(np.multiply(W, np.log10(Y_div_E)), 1), np.sum(W, 1)) | |
ds[ds > 35] = 35 | |
ds[ds < -10] = -10 | |
d = np.mean(ds) | |
return d | |