acids-transforms 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- acids_transforms/__init__.py +3 -0
- acids_transforms/transforms/__init__.py +9 -0
- acids_transforms/transforms/base.py +232 -0
- acids_transforms/transforms/dgt.py +667 -0
- acids_transforms/transforms/mel.py +77 -0
- acids_transforms/transforms/misc.py +212 -0
- acids_transforms/transforms/norm.py +99 -0
- acids_transforms/transforms/oadd.py +106 -0
- acids_transforms/transforms/raw.py +316 -0
- acids_transforms/transforms/sinebank.py +279 -0
- acids_transforms/transforms/spectral_repr.py +551 -0
- acids_transforms/transforms/stft.py +788 -0
- acids_transforms/utils/__init__.py +2 -0
- acids_transforms/utils/heapq.py +59 -0
- acids_transforms/utils/misc.py +237 -0
- acids_transforms/utils/tracing.py +82 -0
- acids_transforms-1.0.0.dist-info/METADATA +180 -0
- acids_transforms-1.0.0.dist-info/RECORD +21 -0
- acids_transforms-1.0.0.dist-info/WHEEL +5 -0
- acids_transforms-1.0.0.dist-info/licenses/LICENSE +674 -0
- acids_transforms-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import torch.nn as nn
|
|
2
|
+
import functools
|
|
3
|
+
import torch
|
|
4
|
+
from typing import Union
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class NotInvertibleError(Exception):
|
|
8
|
+
pass
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
InversionEnumType = Union[str, None]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AudioTransform(nn.Module):
|
|
15
|
+
# python-side descriptors, not compiled by torch.jit.script (e.g. tracable returns a global flag)
|
|
16
|
+
__jit_unused_properties__ = ["invertible", "scriptable", "tracable", "needs_scaling", "ratio"]
|
|
17
|
+
invertible = True
|
|
18
|
+
scriptable = False
|
|
19
|
+
tracable = False
|
|
20
|
+
needs_scaling = False
|
|
21
|
+
|
|
22
|
+
def __init__(self, sr=44100):
|
|
23
|
+
super(AudioTransform, self).__init__()
|
|
24
|
+
self.sr = sr
|
|
25
|
+
|
|
26
|
+
def __repr__(self):
|
|
27
|
+
return "AudioTransform()"
|
|
28
|
+
|
|
29
|
+
def __add__(self, transform):
|
|
30
|
+
if isinstance(transform, ComposeAudioTransform):
|
|
31
|
+
return ComposeAudioTransform(transforms=[self] + transform.transforms)
|
|
32
|
+
elif isinstance(transform, AudioTransform):
|
|
33
|
+
return ComposeAudioTransform(transforms=[self, transform])
|
|
34
|
+
else:
|
|
35
|
+
raise TypeError(
|
|
36
|
+
'AudioTransform cannot be added to type: %s' % type(transform))
|
|
37
|
+
|
|
38
|
+
@torch.jit.export
|
|
39
|
+
def scale_data(self, x: torch.Tensor) -> None:
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
@torch.jit.export
|
|
43
|
+
def forward(self, x):
|
|
44
|
+
return x
|
|
45
|
+
|
|
46
|
+
def get_inversion_modes(self):
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
@torch.jit.export
|
|
50
|
+
def invert(self, x: torch.Tensor) -> torch.Tensor:
|
|
51
|
+
return x
|
|
52
|
+
|
|
53
|
+
@torch.jit.export
|
|
54
|
+
def forward_with_time(self, x: torch.Tensor, time: torch.Tensor):
|
|
55
|
+
return self.forward(x), time
|
|
56
|
+
|
|
57
|
+
def realtime(self):
|
|
58
|
+
return self
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def ratio(self):
|
|
62
|
+
return 1
|
|
63
|
+
|
|
64
|
+
def test_forward(self, x: torch.Tensor, time: torch.Tensor = None):
|
|
65
|
+
if time is None:
|
|
66
|
+
return self.forward(x)
|
|
67
|
+
else:
|
|
68
|
+
return self.forward_with_time(x, time)
|
|
69
|
+
|
|
70
|
+
def test_inversion(self, x: torch.Tensor):
|
|
71
|
+
if not self.invertible:
|
|
72
|
+
raise NotImplementedError
|
|
73
|
+
x_transformed = self.forward(x)
|
|
74
|
+
x_inv = self.invert(x_transformed)
|
|
75
|
+
return {'inverted': x_inv}
|
|
76
|
+
|
|
77
|
+
@classmethod
|
|
78
|
+
def test_scripted_transform(cls, transform, batch_size=(2,2), invert=True):
|
|
79
|
+
x = torch.zeros(*batch_size, 44100)
|
|
80
|
+
time = torch.zeros(*batch_size)
|
|
81
|
+
x_t = transform.forward(x)
|
|
82
|
+
x_t, time_t = transform.forward_with_time(x, time)
|
|
83
|
+
if invert:
|
|
84
|
+
x_inv = transform.invert(x_t)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class ComposeAudioTransform(AudioTransform):
|
|
88
|
+
|
|
89
|
+
@property
|
|
90
|
+
def invertible(self):
|
|
91
|
+
for t in self.transforms:
|
|
92
|
+
if not t.invertible:
|
|
93
|
+
return False
|
|
94
|
+
return True
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def needs_scaling(self):
|
|
98
|
+
for t in self.transforms:
|
|
99
|
+
if t.needs_scaling:
|
|
100
|
+
return True
|
|
101
|
+
return False
|
|
102
|
+
|
|
103
|
+
@property
|
|
104
|
+
def scriptable(self):
|
|
105
|
+
for t in self.transforms:
|
|
106
|
+
if not t.scriptable:
|
|
107
|
+
return False
|
|
108
|
+
return True
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def tracable(self):
|
|
112
|
+
for t in self.transforms:
|
|
113
|
+
if not t.tracable:
|
|
114
|
+
return False
|
|
115
|
+
return True
|
|
116
|
+
|
|
117
|
+
def __getitem__(self, item):
|
|
118
|
+
return self.transforms[item]
|
|
119
|
+
|
|
120
|
+
def __init__(self, transforms=[], sr=44100):
|
|
121
|
+
super().__init__()
|
|
122
|
+
self.transforms = nn.ModuleList(transforms)
|
|
123
|
+
|
|
124
|
+
def __repr__(self) -> str:
|
|
125
|
+
return "ComposeAudioTransform(%s)" % [t.__repr__()+"\n" for t in self.transforms]
|
|
126
|
+
|
|
127
|
+
def __add__(self, itm):
|
|
128
|
+
if not isinstance(itm, AudioTransform):
|
|
129
|
+
raise TypeError(
|
|
130
|
+
"ComposeAudioTransform can only be added to other AudioTransforms")
|
|
131
|
+
if isinstance(itm, ComposeAudioTransform):
|
|
132
|
+
return ComposeAudioTransform(list(self.transforms) + list(itm.transforms))
|
|
133
|
+
else:
|
|
134
|
+
return ComposeAudioTransform(list(self.transforms) + [itm])
|
|
135
|
+
|
|
136
|
+
def __radd__(self, other):
|
|
137
|
+
if not isinstance(other, AudioTransform):
|
|
138
|
+
raise TypeError(
|
|
139
|
+
"ComposeAudioTransform can only be added to other AudioTransforms")
|
|
140
|
+
if isinstance(other, ComposeAudioTransform):
|
|
141
|
+
return ComposeAudioTransform(list(other.transforms) + list(self.transforms))
|
|
142
|
+
else:
|
|
143
|
+
return ComposeAudioTransform([other] + list(self.transforms))
|
|
144
|
+
|
|
145
|
+
def realtime(self):
|
|
146
|
+
return ComposeAudioTransform(transforms=[t.realtime() for t in self.transforms], sr=self.sr)
|
|
147
|
+
|
|
148
|
+
@property
|
|
149
|
+
def ratio(self):
|
|
150
|
+
ratio = 1
|
|
151
|
+
for t in self.transforms:
|
|
152
|
+
ratio = ratio * t.ratio
|
|
153
|
+
return ratio
|
|
154
|
+
|
|
155
|
+
@torch.jit.export
|
|
156
|
+
def scale_data(self, x):
|
|
157
|
+
for t in self.transforms:
|
|
158
|
+
t.scale_data(x)
|
|
159
|
+
x = t(x)
|
|
160
|
+
|
|
161
|
+
@torch.jit.export
|
|
162
|
+
def forward(self, x: torch.Tensor):
|
|
163
|
+
for t in self.transforms:
|
|
164
|
+
x = t(x)
|
|
165
|
+
return x
|
|
166
|
+
|
|
167
|
+
@torch.jit.export
|
|
168
|
+
def forward_with_time(self, x: torch.Tensor, time: torch.Tensor):
|
|
169
|
+
for t in self.transforms:
|
|
170
|
+
x, time = t.forward_with_time(x, time)
|
|
171
|
+
return x, time
|
|
172
|
+
|
|
173
|
+
@torch.jit.export
|
|
174
|
+
def invert(self, x, inversion_mode: InversionEnumType = None):
|
|
175
|
+
for t in self.transforms[::-1]:
|
|
176
|
+
x = t.invert(x, inversion_mode=inversion_mode)
|
|
177
|
+
return x
|
|
178
|
+
|
|
179
|
+
def get_inversion_modes(self, idx):
|
|
180
|
+
return type(self.transforms[idx]).get_inversion_modes()
|
|
181
|
+
|
|
182
|
+
def test_inversion(self, x: torch.Tensor):
|
|
183
|
+
if not self.invertible:
|
|
184
|
+
raise NotImplementedError
|
|
185
|
+
x_transformed = x
|
|
186
|
+
for t in self.transforms:
|
|
187
|
+
x_transformed = t.invert(x_transformed)
|
|
188
|
+
x_inv = x_transformed
|
|
189
|
+
for t in reversed(self.transforms):
|
|
190
|
+
x_inv = t.invert(x_inv)
|
|
191
|
+
return x_inv
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def apply_transform_to_list(transform, data, time=None, **kwargs):
|
|
195
|
+
if time is None:
|
|
196
|
+
outs = [transform(data[i], **kwargs) for i in range(len(data))]
|
|
197
|
+
return outs
|
|
198
|
+
else:
|
|
199
|
+
outs = [transform(data[i], time=time[i], **kwargs)
|
|
200
|
+
for i in range(len(data))]
|
|
201
|
+
return [o[0] for o in outs], [o[1] for o in outs]
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def apply_invert_transform_to_list(transform, data, time=None, **kwargs):
|
|
205
|
+
if time is None:
|
|
206
|
+
outs = [transform.invert(data[i], **kwargs) for i in range(len(data))]
|
|
207
|
+
return outs
|
|
208
|
+
else:
|
|
209
|
+
outs = [transform.invert(data[i], time=time[i], **kwargs)
|
|
210
|
+
for i in range(len(data))]
|
|
211
|
+
return [o[0] for o in outs], [o[1] for o in outs]
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
_CanTrace = False
|
|
215
|
+
make_fx = None
|
|
216
|
+
try:
|
|
217
|
+
from torch.fx.experimental.proxy_tensor import make_fx as tft_make_fx
|
|
218
|
+
|
|
219
|
+
def make_fx(obj, *args, _fn="forward", **kwargs):
|
|
220
|
+
if _fn == "forward":
|
|
221
|
+
return tft_make_fx(obj, *args, **kwargs)
|
|
222
|
+
else:
|
|
223
|
+
# @functools.wraps(getattr(obj, _fn))
|
|
224
|
+
def _closure(*args, **kwargs):
|
|
225
|
+
return getattr(obj, _fn)(*args, **kwargs)
|
|
226
|
+
return tft_make_fx(_closure, *args, **kwargs)
|
|
227
|
+
|
|
228
|
+
# tracing relies on symbolic make_fx, custom operators (torch >= 2.4, see utils.tracing) and fake fft kernels
|
|
229
|
+
# (aten._fft_r2c, torch >= 2.7) : transforms are not tracable before torch 2.7.
|
|
230
|
+
_CanTrace = tuple(int(v) for v in torch.__version__.split("+")[0].split(".")[:2]) >= (2, 7)
|
|
231
|
+
except ModuleNotFoundError:
|
|
232
|
+
pass
|