pyFDN.td.TimeVaryingKroneckerMatrix#
- class pyFDN.td.TimeVaryingKroneckerMatrix(angles, fs, *, rate=0.0, depth=0.0, phase=0.0, kernel_type='rotation', waveform='sine')[source]#
Kronecker feedback matrix with per-kernel angle modulation (time-varying feedback).
Each kernel angle follows
theta_i(t) = angles[i] + depth[i] * w(2 * pi * rate[i] * t + phase[i])withwa unit-amplitude sine or triangle, so the matrix is orthogonal at every sample yet never constant. This is the matrix modulation of Coppola (2026, Section 5.4): unlike delay-line modulation it changes only the routing coefficients between delay lines, which breaks up fixed modal resonances without the chorusing that modulated delays introduce.Because the angles are consumed by the fast butterfly, per-sample modulation costs no more than the static matrix – there is no
N x Nmatrix to rebuild when an angle moves.Sits on the feedback path of a
Recursion, or goes straight into thepost_matrixargument ofpyFDN.process_dss()withAleft as the identity, in which case this operator is the feedback matrix.- Parameters:
angles (
ArrayLike) –Munmodulated kernel angles in radians, innermost first. The modulation is centred on these.fs (
float) – Sampling rate in Hz; the modulation clock.rate (
ArrayLike) – Modulation frequency in Hz, one value or one per kernel.depth (
ArrayLike) – Modulation amplitude in radians, one value or one per kernel. Zero leaves a kernel static, which is how a single level is singled out for modulation (the paper modulatestheta_{M-1}).phase (
ArrayLike) – Initial modulation phase in radians, one value or one per kernel.kernel_type (
str|Sequence[str]) –"rotation"or"reflection", either once for all kernels or one per kernel.waveform (
str) – Modulation shape.
- Variables:
sample_index (int) – Current sample index; the modulation clock.
reset()rewinds it.Example:: –
# 16 channels, stereo halves decoupled, theta_3 modulated at 0.2 Hz depth = [0.0, 0.0, 0.2 * np.pi, 0.0] td.TimeVaryingKroneckerMatrix(
pyFDN.kronecker_angles(16, theta4=0.0), fs, rate=0.2, depth=depth
)
- __init__(angles, fs, *, rate=0.0, depth=0.0, phase=0.0, kernel_type='rotation', waveform='sine')[source]#
Methods
__init__(angles, fs, *[, rate, depth, ...])angles_at(sample_indices)Kernel angles at the given sample indices, shape
(len(indices), M).process_block(block)Process one block and advance internal state.
process_signal(signal, *[, squeeze])Process a whole signal in one call, from the current state.
reset()Rewind the modulation clock to sample zero.
Attributes
in_channelsout_channels- angles_at(sample_indices)[source]#
Kernel angles at the given sample indices, shape
(len(indices), M).Exposed so the modulation trajectory can be plotted or fed to
pyFDN.kronecker_matrix()for analysis without rendering audio.- Return type: