BandwiseBinaryClassifier is work in progress; TODO: Shape Piping.
This commit is contained in:
@ -1,10 +1,18 @@
|
||||
import librosa
|
||||
from librosa import display
|
||||
import torch
|
||||
from scipy.signal import butter, lfilter
|
||||
|
||||
from ml_lib.modules.utils import AutoPad
|
||||
import numpy as np
|
||||
|
||||
|
||||
def scale_minmax(x, min=0.0, max=1.0):
|
||||
x_std = (x - x.min()) / (x.max() - x.min())
|
||||
x_scaled = x_std * (max - min) + min
|
||||
return x_scaled
|
||||
|
||||
|
||||
def butter_lowpass(cutoff, sr, order=5):
|
||||
nyq = 0.5 * sr
|
||||
normal_cutoff = cutoff / nyq
|
||||
@ -58,37 +66,54 @@ class NormalizeMelband(object):
|
||||
return x
|
||||
|
||||
|
||||
class AutoPadToShape(object):
|
||||
def __init__(self, shape):
|
||||
self.shape = shape
|
||||
|
||||
def __call__(self, x):
|
||||
if not torch.is_tensor(x):
|
||||
x = torch.as_tensor(x)
|
||||
embedding = torch.zeros(self.shape)
|
||||
embedding[: x.shape] = x
|
||||
return embedding
|
||||
|
||||
def __repr__(self):
|
||||
return f'AutoPadTransform({self.shape})'
|
||||
|
||||
|
||||
class Melspectogram(object):
|
||||
def __init__(self, **kwargs):
|
||||
self.__dict__.update(kwargs)
|
||||
class AudioToMel(object):
|
||||
def __init__(self, amplitude_to_db=False, power_to_db=False, **kwargs):
|
||||
assert not all([amplitude_to_db, power_to_db]), "Choose amplitude_to_db or power_to_db, not both!"
|
||||
self.mel_kwargs = kwargs
|
||||
self.amplitude_to_db = amplitude_to_db
|
||||
self.power_to_db = power_to_db
|
||||
|
||||
def __call__(self, y):
|
||||
mel = librosa.feature.melspectrogram(y, **self.__dict__)
|
||||
mel = librosa.amplitude_to_db(mel, ref=np.max)
|
||||
mel = librosa.feature.melspectrogram(y, **self.mel_kwargs)
|
||||
if self.amplitude_to_db:
|
||||
mel = librosa.amplitude_to_db(mel, ref=np.max)
|
||||
if self.power_to_db:
|
||||
mel = librosa.power_to_db(mel, ref=np.max)
|
||||
return mel
|
||||
|
||||
def __repr__(self):
|
||||
return f'MelSpectogram({self.__dict__})'
|
||||
|
||||
|
||||
class PowerToDB(object):
|
||||
def __init__(self, running_max=False):
|
||||
self.running_max = 0 if running_max else None
|
||||
|
||||
def __call__(self, x):
|
||||
if self.running_max is not None:
|
||||
self.running_max = max(np.max(x), self.running_max)
|
||||
return librosa.power_to_db(x, ref=self.running_max)
|
||||
return librosa.power_to_db(x, ref=np.max)
|
||||
|
||||
|
||||
class LowPass(object):
|
||||
def __init__(self, sr=16000):
|
||||
self.sr = sr
|
||||
|
||||
def __call__(self, x):
|
||||
return butter_lowpass_filter(x, 1000, 1)
|
||||
return butter_lowpass_filter(x, 1000, 1)
|
||||
|
||||
|
||||
class MelToImage(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def __call__(self, x):
|
||||
# Source to Solution: https://stackoverflow.com/a/57204349
|
||||
mels = np.log(x + 1e-9) # add small number to avoid log(0)
|
||||
|
||||
# min-max scale to fit inside 8-bit range
|
||||
img = scale_minmax(mels, 0, 255).astype(np.uint8)
|
||||
img = np.flip(img, axis=0) # put low frequencies at the bottom in image
|
||||
img = 255 - img # invert. make black==more energy
|
||||
return img
|
||||
|
Reference in New Issue
Block a user