pyFDN.trainable_from_build#
- pyFDN.trainable_from_build(build, *, trainable=None, matrix='orthogonal', post_delay=None, post_matrix=None, post_output=None, nfft=16384, alias_decay_db=0.0, device=None, dtype=None)[source]#
Build a trainable flamo
Shellinitialized from anFDNBuild.The gains and the feedback matrix come from the build. The three filter hooks are the build’s own baked SOS banks, frozen, unless you hand in a module for that position – which is how a designed, trainable filter gets in, since a baked build no longer remembers the reverberation time or the EQ curve it was designed from:
model = pyFDN.trainable_from_build( build, post_delay=pyFDN.AttenuationFilter( 1.0, build.delays, build.fs, rt_nyquist=1.0, design="first_order_shelf", nfft=nfft), post_output=pyFDN.OutputEQ( 0.0, build.C.shape[0], build.fs, design="first_order_shelf", nfft=nfft), )
Each of those modules is trained because it says so itself (both default to
requires_grad=True); passrequires_grad=Falsefor a designed filter that must not move.- Parameters:
build (
FDNBuild) – Initial FDN (A/B/C/D/delays/fs+ optionalpost_delay/post_outputSOS banks).trainable (
Trainable|None) – Which gain groups are trained (defaultTrainable). It says nothing about the filter hooks: each module below carries its ownrequires_grad, and is wired in exactly as it was built.matrix (
Literal['orthogonal','random']) – Feedback-matrix parametrization.post_delay (
Any) – In-loop filter, replacingbuild.post_delay. AAttenuationFilterhere makes the trained parameter the reverberation time itself, which keeps the loop contractive for every value it can take.post_matrix (
Any) – Filter on the feedback path, replacingbuild.post_matrix.post_output (
Any) – Output EQ, replacingbuild.post_output; typically anOutputEQ. It sits outside the recursion, which makes it the only part of an FDN that can shape the response’s spectral envelope without touching the decay –bandcare single numbers per delay line, with no frequency dependence at all.nfft (
int) – FFT size.alias_decay_db (
float) –The accuracy of the rendered impulse response, in dB. Applies a \(\gamma^n\) envelope to every module (evaluating the system on a circle of radius \(\gamma < 1\)); the shell’s output layer removes it again, so the response is the true one and only the time-aliased wrap-around remains, suppressed by exactly
alias_decay_db. In float32 the reconstruction amplifies round-off by the same factor, so ~60 dB is the practical ceiling; usedtype=torch.float64beyond that.Leave at 0 for a decaying FDN, which damps itself within
nfftsamples. A lossless FDN needs it: with its poles exactly on the unit circle the FFT-domain evaluation is near-singular and the response comes out wrong, not merely aliased. It does not affect the extracted build (it enters the frequency-domain evaluation, not the parametermap, sopyFDN.extract_build()still returns the undampedA/B/C). A module you pass into a hook must have been built with the same value: it is a change of evaluation radius for the whole system, not a per-module gain.device (
Any) – Torch device / dtype (default cpu-or-cuda / float32).dtype (
Any) – Torch device / dtype (default cpu-or-cuda / float32).
- Return type: