flamo 0.1.6__py3-none-any.whl → 0.1.8__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.
- flamo/auxiliary/reverb.py +77 -3
- flamo/functional.py +42 -1
- {flamo-0.1.6.dist-info → flamo-0.1.8.dist-info}/METADATA +1 -1
- {flamo-0.1.6.dist-info → flamo-0.1.8.dist-info}/RECORD +6 -6
- {flamo-0.1.6.dist-info → flamo-0.1.8.dist-info}/WHEEL +0 -0
- {flamo-0.1.6.dist-info → flamo-0.1.8.dist-info}/licenses/LICENSE +0 -0
flamo/auxiliary/reverb.py
CHANGED
|
@@ -67,7 +67,18 @@ class inverse_map_gamma(torch.nn.Module):
|
|
|
67
67
|
return y
|
|
68
68
|
else:
|
|
69
69
|
return y**(1/self.delays)
|
|
70
|
-
|
|
70
|
+
|
|
71
|
+
class map_gfdn_gamma(torch.nn.Module):
|
|
72
|
+
def __init__(self, delays: torch.Tensor, n_groups: int, fs: int):
|
|
73
|
+
super().__init__()
|
|
74
|
+
self.delays = delays
|
|
75
|
+
self.n_groups = n_groups
|
|
76
|
+
self.fs = fs
|
|
77
|
+
|
|
78
|
+
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
|
79
|
+
"""Map input to grouped RT values."""
|
|
80
|
+
gamma = torch.mul(rt2slope(x, self.fs).unsqueeze(-1), self.delays.unsqueeze(0))
|
|
81
|
+
return gamma
|
|
71
82
|
|
|
72
83
|
class HomogeneousFDN:
|
|
73
84
|
r"""
|
|
@@ -281,7 +292,7 @@ class HomogeneousFDN:
|
|
|
281
292
|
rt60, self.config_dict.sample_rate, torch.tensor(self.delays)
|
|
282
293
|
).squeeze()
|
|
283
294
|
return 10 ** (gdB / 20)
|
|
284
|
-
|
|
295
|
+
|
|
285
296
|
|
|
286
297
|
class parallelFDNAccurateGEQ(dsp.parallelAccurateGEQ):
|
|
287
298
|
r"""
|
|
@@ -371,6 +382,70 @@ class parallelFDNAccurateGEQ(dsp.parallelAccurateGEQ):
|
|
|
371
382
|
self.input_channels = len(self.delays)
|
|
372
383
|
self.output_channels = len(self.delays)
|
|
373
384
|
|
|
385
|
+
class parallelGFDNAccurateGEQ(parallelFDNAccurateGEQ):
|
|
386
|
+
# TODO
|
|
387
|
+
def __init__(
|
|
388
|
+
self,
|
|
389
|
+
octave_interval: int = 1,
|
|
390
|
+
n_groups: int = 2,
|
|
391
|
+
nfft: int = 2**11,
|
|
392
|
+
fs: int = 48000,
|
|
393
|
+
delays: torch.Tensor = None,
|
|
394
|
+
alias_decay_db: float = 0.0,
|
|
395
|
+
start_freq: float = 31.25,
|
|
396
|
+
end_freq: float = 16000.0,
|
|
397
|
+
device=None
|
|
398
|
+
):
|
|
399
|
+
assert (delays is not None), "Delays must be provided"
|
|
400
|
+
self.delays = delays
|
|
401
|
+
map = map_gfdn_gamma(delays, n_groups, fs)
|
|
402
|
+
super().__init__(
|
|
403
|
+
size=( ),
|
|
404
|
+
octave_interval=octave_interval,
|
|
405
|
+
nfft=nfft,
|
|
406
|
+
delays=delays,
|
|
407
|
+
fs=fs,
|
|
408
|
+
map=map,
|
|
409
|
+
alias_decay_db=alias_decay_db,
|
|
410
|
+
start_freq=start_freq,
|
|
411
|
+
end_freq=end_freq,
|
|
412
|
+
device=device
|
|
413
|
+
)
|
|
414
|
+
self.n_gains = self.size[0]
|
|
415
|
+
self.size = (n_groups * self.size[0], len(delays))
|
|
416
|
+
self.param = param = torch.nn.Parameter(
|
|
417
|
+
torch.empty(self.size, device=self.device), requires_grad=self.requires_grad
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
def get_poly_coeff(self, param):
|
|
421
|
+
r"""
|
|
422
|
+
Computes the polynomial coefficients for the SOS section.
|
|
423
|
+
"""
|
|
424
|
+
a = torch.zeros((3, self.size[0]+1, len(self.delays)), device=self.device)
|
|
425
|
+
b = torch.zeros((3, self.size[0]+1, len(self.delays)), device=self.device)
|
|
426
|
+
for n_i in range(len(self.delays)):
|
|
427
|
+
for i_group in range(self.n_gains):
|
|
428
|
+
(
|
|
429
|
+
b[:, i_group * (self.n_gains) : (i_group + 1) * self.n_gains, n_i],
|
|
430
|
+
a[:, i_group * (self.n_gains) : (i_group + 1) * self.n_gains, n_i],
|
|
431
|
+
) = accurate_geq(
|
|
432
|
+
target_gain=param[
|
|
433
|
+
i_group * self.n_gains : (i_group + 1) * self.n_gains, n_i
|
|
434
|
+
],
|
|
435
|
+
center_freq=self.center_freq,
|
|
436
|
+
shelving_crossover=self.shelving_crossover,
|
|
437
|
+
fs=self.fs,
|
|
438
|
+
device=self.device,
|
|
439
|
+
)
|
|
440
|
+
|
|
441
|
+
b_aa = torch.einsum('p, pon -> pon', self.alias_envelope_dcy.to(torch.double), b.to(torch.double))
|
|
442
|
+
a_aa = torch.einsum('p, pon -> pon', self.alias_envelope_dcy.to(torch.double), a.to(torch.double))
|
|
443
|
+
B = torch.fft.rfft(b_aa, self.nfft, dim=0)
|
|
444
|
+
A = torch.fft.rfft(a_aa, self.nfft, dim=0)
|
|
445
|
+
H_temp = torch.prod(B, dim=1) / (torch.prod(A, dim=1))
|
|
446
|
+
H = torch.where(torch.abs(torch.prod(A, dim=1)) != 0, H_temp, torch.finfo(H_temp.dtype).eps*torch.ones_like(H_temp))
|
|
447
|
+
H_type = torch.complex128 if param.dtype == torch.float64 else torch.complex64
|
|
448
|
+
return H.to(H_type), B, A
|
|
374
449
|
|
|
375
450
|
class parallelFDNGEQ(dsp.parallelGEQ):
|
|
376
451
|
r"""
|
|
@@ -721,7 +796,6 @@ class parallelFDNPEQ(Filter):
|
|
|
721
796
|
self.output_channels = len(self.delays)
|
|
722
797
|
|
|
723
798
|
|
|
724
|
-
|
|
725
799
|
class parallelFirstOrderShelving(dsp.parallelFilter):
|
|
726
800
|
|
|
727
801
|
def __init__(
|
flamo/functional.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import math
|
|
1
2
|
import torch
|
|
2
3
|
import torch.nn as nn
|
|
3
4
|
import numpy as np
|
|
@@ -175,11 +176,12 @@ def signal_gallery(
|
|
|
175
176
|
- ``sweep``: A linear sweep from 20 Hz to 20 kHz.
|
|
176
177
|
- ``wgn``: White Gaussian noise.
|
|
177
178
|
- ``exp``: An exponential decay signal.
|
|
179
|
+
- ``velvet``: A velvet noise signal with density :attr:`rate` impulses per second.
|
|
178
180
|
- ``reference``: A reference signal provided as argument :attr:`reference`.
|
|
179
181
|
|
|
180
182
|
**Arguments**:
|
|
181
183
|
- **batch_size** (int): The number of batches to generate.
|
|
182
|
-
- **n_samples** (int):
|
|
184
|
+
- **n_samples** (int): The signal length in samples.
|
|
183
185
|
- **n_channel** (int): The number of channels in each signal.
|
|
184
186
|
- **signal_type** (str, optional): The type of signal to generate. Defaults to 'impulse'.
|
|
185
187
|
- **fs** (int, optional): The sampling frequency of the signals. Defaults to 48000.
|
|
@@ -198,6 +200,7 @@ def signal_gallery(
|
|
|
198
200
|
"exp",
|
|
199
201
|
"reference",
|
|
200
202
|
"noise",
|
|
203
|
+
"velvet",
|
|
201
204
|
}
|
|
202
205
|
|
|
203
206
|
if signal_type not in signal_types:
|
|
@@ -243,6 +246,12 @@ def signal_gallery(
|
|
|
243
246
|
.expand(batch_size, n_samples, n)
|
|
244
247
|
.to(device)
|
|
245
248
|
)
|
|
249
|
+
case "velvet":
|
|
250
|
+
x = torch.empty((batch_size, n_samples, n), device=device)
|
|
251
|
+
for i_batch in range(batch_size):
|
|
252
|
+
for i_ch in range(n):
|
|
253
|
+
x[i_batch, :, i_ch] = gen_velvet_noise(n_samples, fs, rate, device)
|
|
254
|
+
return x
|
|
246
255
|
case "reference":
|
|
247
256
|
if isinstance(reference, torch.Tensor):
|
|
248
257
|
return reference.expand(batch_size, n_samples, n).to(device)
|
|
@@ -254,6 +263,38 @@ def signal_gallery(
|
|
|
254
263
|
return torch.randn((batch_size, n_samples, n), device=device)
|
|
255
264
|
|
|
256
265
|
|
|
266
|
+
def gen_velvet_noise(n_samples: int, fs: int, density: float, device: str | torch.device = None) -> torch.Tensor:
|
|
267
|
+
r"""
|
|
268
|
+
Generate a velvet noise sequence.
|
|
269
|
+
**Arguments**:
|
|
270
|
+
- **n_samples** (int): The length of the signal in samples.
|
|
271
|
+
- **fs** (int): The sampling frequency of the signal in Hz.
|
|
272
|
+
- **density** (float): The density of impulses in impulses per second.
|
|
273
|
+
- **device** (str | torch.device): The device of constructed tensors.
|
|
274
|
+
**Returns**:
|
|
275
|
+
- torch.Tensor: A tensor of shape (n_samples,) containing the velvet noise sequence.
|
|
276
|
+
"""
|
|
277
|
+
Td = fs / density # average distance between impulses
|
|
278
|
+
num_impulses = n_samples / Td # expected number of impulses
|
|
279
|
+
floor_impulses = math.floor(num_impulses)
|
|
280
|
+
grid = torch.arange(floor_impulses) * Td
|
|
281
|
+
|
|
282
|
+
jitter_factors = torch.rand(floor_impulses)
|
|
283
|
+
impulse_indices = torch.ceil(grid + jitter_factors * (Td - 1)).long()
|
|
284
|
+
|
|
285
|
+
# first impulse is at position 0 and all indices are within bounds
|
|
286
|
+
impulse_indices[0] = 0
|
|
287
|
+
impulse_indices = torch.clamp(impulse_indices, max=n_samples - 1)
|
|
288
|
+
|
|
289
|
+
# Generate random signs (+1 or -1)
|
|
290
|
+
signs = 2 * torch.randint(0, 2, (floor_impulses,)) - 1
|
|
291
|
+
|
|
292
|
+
# Construct sparse signal
|
|
293
|
+
sequence = torch.zeros(n_samples, device=device)
|
|
294
|
+
sequence[impulse_indices] = signs.float()
|
|
295
|
+
|
|
296
|
+
return sequence
|
|
297
|
+
|
|
257
298
|
def hertz2rad(hertz: torch.Tensor, fs: int):
|
|
258
299
|
r"""
|
|
259
300
|
Convert frequency from Hz to rad.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flamo
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.8
|
|
4
4
|
Summary: An Open-Source Library for Frequency-Domain Differentiable Audio Processing
|
|
5
5
|
Project-URL: Homepage, https://github.com/gdalsanto/flamo
|
|
6
6
|
Project-URL: Issues, https://github.com/gdalsanto/flamo/issues
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
flamo/__init__.py,sha256=ujezWOJfD7DUoj4q1meeMUnB97rOEtNR7mYw_PE9LMg,49
|
|
2
|
-
flamo/functional.py,sha256=
|
|
2
|
+
flamo/functional.py,sha256=8cKYzR5GDzH4ph4ja7x1znNFL-8ufWoxa666QHaZR1A,36917
|
|
3
3
|
flamo/utils.py,sha256=ypGKSABZMphgIrjCKgCH-zgR7BaupRbyzuUhsZFqAAM,3350
|
|
4
4
|
flamo/auxiliary/__init__.py,sha256=7lVNh8OxHloZ4KPmp-iTUJnUbi8XbuRzGaQ3Z-NKXio,42
|
|
5
5
|
flamo/auxiliary/eq.py,sha256=eIWMIq0ggizXLhTdeWWbgBXWUFXCJyoEbkBH7Gzasao,6779
|
|
6
6
|
flamo/auxiliary/filterbank.py,sha256=02w8dI8HoNDtKpdVhSJkIkd-h-KNXvZtivf3l4_ozzU,9866
|
|
7
7
|
flamo/auxiliary/minimize.py,sha256=fMTAAAk9yD7Y4luKS4XA1-HTq44xo2opq_dRPRrhlIY,2474
|
|
8
|
-
flamo/auxiliary/reverb.py,sha256=
|
|
8
|
+
flamo/auxiliary/reverb.py,sha256=9c9aLRJCBnudNF3kefcf76HobFicrsxI3GcXyiOcYxo,34737
|
|
9
9
|
flamo/auxiliary/scattering.py,sha256=qlK8cynrpde56yLlbPuScC0Y1VmsPb0SFXl6Xisv6hA,9420
|
|
10
10
|
flamo/auxiliary/velvet.py,sha256=B4pYEnhaQPkh02pxqiGdAhLRX2g-eWtHezphi0_h4Qs,4201
|
|
11
11
|
flamo/auxiliary/config/config.py,sha256=CxXj-8sLq0_m9KyLg1a6NwLoK1UvTz3i0jZOLraq14I,2893
|
|
@@ -18,7 +18,7 @@ flamo/optimize/utils.py,sha256=R5-KoZagRho3eykY88pC3UB2mc5SsE4Yv9X-ogskXdA,1610
|
|
|
18
18
|
flamo/processor/__init__.py,sha256=paGdxGVZgA2VAs0tBwRd0bobzGxeyK79DS7ZGO8drkI,41
|
|
19
19
|
flamo/processor/dsp.py,sha256=n92YJPrES-ydwHgXmZ9RkFevIC3n-Wh4X8I1QNZqcV0,126378
|
|
20
20
|
flamo/processor/system.py,sha256=9XwLtaGEVs9glVOFvyiPnQpsnR_Wjrv6k1i1qCs8D1Q,42516
|
|
21
|
-
flamo-0.1.
|
|
22
|
-
flamo-0.1.
|
|
23
|
-
flamo-0.1.
|
|
24
|
-
flamo-0.1.
|
|
21
|
+
flamo-0.1.8.dist-info/METADATA,sha256=a0hX9Mfk2wSUX7nPKwesQ6WYnmpgSUNpf_iBitMz2iA,7825
|
|
22
|
+
flamo-0.1.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
23
|
+
flamo-0.1.8.dist-info/licenses/LICENSE,sha256=smMocRH7xdPT5RvFNqSLtbSNzohXJM5G_rX1Qaej6vg,1120
|
|
24
|
+
flamo-0.1.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|