File size: 2,475 Bytes
88b5dc0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
import itertools
import os
import random
import time
import warnings
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: 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)
|