ITO-Master / modules /fx_utils.py
jhtonyKoo's picture
modify app
6bbce1b
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
import numpy as np
import scipy
import math
import librosa
import librosa.display
import fnmatch
import os
from functools import partial
import pyloudnorm
from scipy.signal import lfilter
from sklearn.metrics import mean_absolute_error, mean_squared_error
from sklearn.metrics.pairwise import paired_distances
import matplotlib.pyplot as plt
def db(x):
"""Computes the decible energy of a signal"""
return 20*np.log10(np.sqrt(np.mean(np.square(x))))
def melspectrogram(y, mirror_pad=False):
"""Compute melspectrogram feature extraction
Keyword arguments:
signal -- input audio as a signal in a numpy object
inputnorm -- normalization of output
mirror_pad -- pre and post-pend mirror signals
Returns freq x time
Assumes the input sampling rate is 22050Hz
"""
# Extract mel.
fftsize = 1024
window = 1024
hop = 512
melBin = 128
sr = 22050
# mirror pad signal
# first embedding centered on time 0
# last embedding centered on end of signal
if mirror_pad:
y = np.insert(y, 0, y[0:int(half_frame_length_sec * sr)][::-1])
y = np.insert(y, len(y), y[-int(half_frame_length_sec * sr):][::-1])
S = librosa.core.stft(y,n_fft=fftsize,hop_length=hop,win_length=window)
X = np.abs(S)
mel_basis = librosa.filters.mel(sr,n_fft=fftsize,n_mels=melBin)
mel_S = np.dot(mel_basis,X)
# value log compression
mel_S = np.log10(1+10*mel_S)
mel_S = mel_S.astype(np.float32)
return mel_S
def getFilesPath(directory, extension):
n_path=[]
for path, subdirs, files in os.walk(directory):
for name in files:
if fnmatch.fnmatch(name, extension):
n_path.append(os.path.join(path,name))
n_path.sort()
return n_path
def getRandomTrim(x, length, pad=0, start=None):
length = length+pad
if x.shape[0] <= length:
x_ = x
while(x.shape[0] <= length):
x_ = np.concatenate((x_,x_))
else:
if start is None:
start = np.random.randint(0, x.shape[0]-length, size=None)
end = length+start
if end > x.shape[0]:
x_ = x[start:]
x_ = np.concatenate((x_, x[:length-x.shape[0]]))
else:
x_ = x[start:length+start]
return x_[:length]
def fadeIn(x, length=128):
w = scipy.signal.hann(length*2, sym=True)
w1 = w[0:length]
ones = np.ones(int(x.shape[0]-length))
w = np.append(w1, ones)
return x*w
def fadeOut(x, length=128):
w = scipy.signal.hann(length*2, sym=True)
w2 = w[length:length*2]
ones = np.ones(int(x.shape[0]-length))
w = np.append(ones, w2)
return x*w
def plotTimeFreq(audio, sr, n_fft=512, hop_length=128, ylabels=None):
n = len(audio)
# plt.figure(figsize=(14, 4*n))
colors = list(plt.cm.viridis(np.linspace(0,1,n)))
X = []
X_db = []
maxs = np.zeros((n,))
mins = np.zeros((n,))
maxs_t = np.zeros((n,))
for i, x in enumerate(audio):
if x.ndim == 2 and x.shape[-1] == 2:
x = librosa.core.to_mono(x.T)
X_ = librosa.stft(x, n_fft=n_fft, hop_length=hop_length)
X_db_ = librosa.amplitude_to_db(abs(X_))
X.append(X_)
X_db.append(X_db_)
maxs[i] = np.max(X_db_)
mins[i] = np.min(X_db_)
maxs_t[i] = np.max(np.abs(x))
vmax = np.max(maxs)
vmin = np.min(mins)
tmax = np.max(maxs_t)
for i, x in enumerate(audio):
if x.ndim == 2 and x.shape[-1] == 2:
x = librosa.core.to_mono(x.T)
plt.subplot(n, 2, 2*i+1)
librosa.display.waveplot(x, sr=sr, color=colors[i])
if ylabels:
plt.ylabel(ylabels[i])
plt.ylim(-tmax,tmax)
plt.subplot(n, 2, 2*i+2)
librosa.display.specshow(X_db[i], sr=sr, x_axis='time', y_axis='log',
hop_length=hop_length, cmap='GnBu', vmax=vmax, vmin=vmin)
# plt.colorbar(format='%+2.0f dB')
def slicing(x, win_length, hop_length, center = True, windowing = False, pad = 0):
# Pad the time series so that frames are centered
if center:
# x = np.pad(x, int((win_length-hop_length+pad) // 2), mode='constant')
x = np.pad(x, ((int((win_length-hop_length+pad)//2), int((win_length+hop_length+pad)//2)),), mode='constant')
# Window the time series.
y_frames = librosa.util.frame(x, frame_length=win_length, hop_length=hop_length)
if windowing:
window = scipy.signal.hann(win_length, sym=False)
else:
window = 1.0
f = []
for i in range(len(y_frames.T)):
f.append(y_frames.T[i]*window)
return np.float32(np.asarray(f))
def overlap(x, x_len, win_length, hop_length, windowing = True, rate = 1):
x = x.reshape(x.shape[0],x.shape[1]).T
if windowing:
window = scipy.signal.hann(win_length, sym=False)
rate = rate*hop_length/win_length
else:
window = 1
rate = 1
n_frames = x_len / hop_length
expected_signal_len = int(win_length + hop_length * (n_frames))
y = np.zeros(expected_signal_len)
for i in range(int(n_frames)):
sample = i * hop_length
w = x[:, i]
y[sample:(sample + win_length)] = y[sample:(sample + win_length)] + w*window
y = y[int(win_length // 2):-int(win_length // 2)]
return np.float32(y*rate)
def highpassFiltering(x_list, f0, sr):
b1, a1 = scipy.signal.butter(4, f0/(sr/2),'highpass')
x_f = []
for x in x_list:
x_f_ = scipy.signal.filtfilt(b1, a1, x).copy(order='F')
x_f.append(x_f_)
return x_f
def lineartodB(x):
return 20*np.log10(x)
def dBtoLinear(x):
return np.power(10,x/20)
def lufs_normalize(x, sr, lufs, log=True):
# measure the loudness first
meter = pyloudnorm.Meter(sr) # create BS.1770 meter
loudness = meter.integrated_loudness(x+1e-10)
if log:
print("original loudness: ", loudness," max value: ", np.max(np.abs(x)))
loudness_normalized_audio = pyloudnorm.normalize.loudness(x, loudness, lufs)
maxabs_amp = np.maximum(1.0, 1e-6 + np.max(np.abs(loudness_normalized_audio)))
loudness_normalized_audio /= maxabs_amp
loudness = meter.integrated_loudness(loudness_normalized_audio)
if log:
print("new loudness: ", loudness," max value: ", np.max(np.abs(loudness_normalized_audio)))
return loudness_normalized_audio
import soxbindings as sox
def lufs_normalize_compand(x, sr, lufs):
tfm = sox.Transformer()
tfm.compand(attack_time = 0.001,
decay_time = 0.01,
soft_knee_db = 1.0,
tf_points = [(-70, -70), (-0.1, -20), (0, 0)])
x = tfm.build_array(input_array=x, sample_rate_in=sr).astype(np.float32)
# measure the loudness first
meter = pyloudnorm.Meter(sr) # create BS.1770 meter
loudness = meter.integrated_loudness(x)
print("original loudness: ", loudness," max value: ", np.max(np.abs(x)))
loudness_normalized_audio = pyloudnorm.normalize.loudness(x, loudness, lufs)
maxabs_amp = np.maximum(1.0, 1e-6 + np.max(np.abs(loudness_normalized_audio)))
loudness_normalized_audio /= maxabs_amp
loudness = meter.integrated_loudness(loudness_normalized_audio)
print("new loudness: ", loudness," max value: ", np.max(np.abs(loudness_normalized_audio)))
return loudness_normalized_audio
def getDistances(x,y):
distances = {}
distances['mae'] = mean_absolute_error(x, y)
distances['mse'] = mean_squared_error(x, y)
distances['euclidean'] = np.mean(paired_distances(x, y, metric='euclidean'))
distances['manhattan'] = np.mean(paired_distances(x, y, metric='manhattan'))
distances['cosine'] = np.mean(paired_distances(x, y, metric='cosine'))
distances['mae'] = round(distances['mae'], 5)
distances['mse'] = round(distances['mse'], 5)
distances['euclidean'] = round(distances['euclidean'], 5)
distances['manhattan'] = round(distances['manhattan'], 5)
distances['cosine'] = round(distances['cosine'], 5)
return distances
def getMFCC(x, sr, mels=128, mfcc=13, mean_norm=False):
melspec = librosa.feature.melspectrogram(y=x, sr=sr, S=None,
n_fft=1024, hop_length=256,
n_mels=mels, power=2.0)
melspec_dB = librosa.power_to_db(melspec, ref=np.max)
mfcc = librosa.feature.mfcc(S=melspec_dB, sr=sr, n_mfcc=mfcc)
if mean_norm:
mfcc -= (np.mean(mfcc, axis=0))
return mfcc
def getMSE_MFCC(y_true, y_pred, sr, mels=128, mfcc=13, mean_norm=False):
ratio = np.mean(np.abs(y_true))/np.mean(np.abs(y_pred))
y_pred = ratio*y_pred
y_mfcc = getMFCC(y_true, sr, mels=mels, mfcc=mfcc, mean_norm=mean_norm)
z_mfcc = getMFCC(y_pred, sr, mels=mels, mfcc=mfcc, mean_norm=mean_norm)
return getDistances(y_mfcc[:,:], z_mfcc[:,:])