zhzluke96
update
d2b7e94
raw
history blame
2.51 kB
import itertools
import os
import random
import time
import warnings
from typing import Union
import numpy as np
_DEBUG = bool(os.environ.get("DEBUG", False))
class Effect:
def apply(self, wav: np.ndarray, sr: int):
"""
Args:
wav: (T)
sr: sample rate
Returns:
wav: (T) with the same sample rate of `sr`
"""
raise NotImplementedError
def __call__(self, wav: np.ndarray, sr: int):
"""
Args:
wav: (T)
sr: sample rate
Returns:
wav: (T) with the same sample rate of `sr`
"""
assert len(wav.shape) == 1, wav.shape
if _DEBUG:
start = time.time()
else:
start = None
shape = wav.shape
assert wav.ndim == 1, f"{self}: Expected wav.ndim == 1, got {wav.ndim}."
wav = self.apply(wav, sr)
assert shape == wav.shape, f"{self}: {shape} != {wav.shape}."
if start is not None:
end = time.time()
print(f"{self.__class__.__name__}: {end - start:.3f} sec")
return wav
class Chain(Effect):
def __init__(self, *effects):
super().__init__()
self.effects = effects
def apply(self, wav, sr):
for effect in self.effects:
wav = effect(wav, sr)
return wav
class Maybe(Effect):
def __init__(self, prob, effect):
super().__init__()
self.prob = prob
self.effect = effect
if _DEBUG:
warnings.warn("DEBUG mode is on. Maybe -> Must.")
self.prob = 1
def apply(self, wav, sr):
if random.random() > self.prob:
return wav
return self.effect(wav, sr)
class Choice(Effect):
def __init__(self, *effects, **kwargs):
super().__init__()
self.effects = effects
self.kwargs = kwargs
def apply(self, wav, sr):
return np.random.choice(self.effects, **self.kwargs)(wav, sr)
class Permutation(Effect):
def __init__(self, *effects, n: Union[int, None] = None):
super().__init__()
self.effects = effects
self.n = n
def apply(self, wav, sr):
if self.n is None:
n = np.random.binomial(len(self.effects), 0.5)
else:
n = self.n
if n == 0:
return wav
perms = itertools.permutations(self.effects, n)
effects = random.choice(list(perms))
return Chain(*effects)(wav, sr)