|
sfFDN
|
An orthogonal time-varying feedback matrix for an FDN. More...
#include <time_varying_feedback_matrix.h>
Public Member Functions | |
| TimeVaryingFeedbackMatrix (const TimeVaryingFeedbackMatrixOptions &options) | |
| Constructs a time-varying feedback matrix. | |
| void | SetModulation (std::span< const ModulationOptions > modulation_configs) |
| Sets the modulation options for each rotation block. | |
| void | SetLfoFrequency (std::span< const float > frequencies) |
| Sets the LFO frequency for each rotation block. | |
| void | SetLfoAmplitude (std::span< const float > amplitudes) |
| Sets the LFO amplitude for each rotation block. | |
| void | SetLfoPhaseOffset (std::span< const float > phase_offsets) |
| Sets the LFO phase offset for each rotation block. | |
| void | SetBaseAngles (std::span< const float > radians) |
| Sets the base rotation angle for each rotation block. | |
| void | Process (const AudioBuffer &input, AudioBuffer &output) noexcept SFFDN_NONBLOCKING override |
| Processes the audio buffer. | |
| uint32_t | InputChannelCount () const noexcept SFFDN_NONBLOCKING override |
| Gets the number of input channels. | |
| uint32_t | OutputChannelCount () const noexcept SFFDN_NONBLOCKING override |
| Gets the number of output channels. | |
| uint32_t | RotationBlockCount () const noexcept SFFDN_NONBLOCKING |
| Gets the number of 2x2 rotation blocks. | |
| bool | GetMatrix (std::span< float > matrix, uint64_t sample_index=0) const |
| Materializes the feedback matrix that Process applies at a given sample index. | |
| void | Clear () override |
| Resets the phase of all LFOs to their configured phase offsets. | |
| std::unique_ptr< AudioProcessor > | Clone () const override |
| Creates a copy of the time-varying feedback matrix. | |
Public Member Functions inherited from sfFDN::AudioProcessor | |
Friends | |
| class | detail::TimeVaryingFeedbackMatrixTestAccess |
Additional Inherited Members | |
Protected Member Functions inherited from sfFDN::AudioProcessor | |
| AudioProcessor (const AudioProcessor &)=default | |
| AudioProcessor & | operator= (const AudioProcessor &)=default |
| AudioProcessor (AudioProcessor &&) noexcept=default | |
| AudioProcessor & | operator= (AudioProcessor &&) noexcept=default |
An orthogonal time-varying feedback matrix for an FDN.
At sample n, the construction is:
Each factor is orthogonal, so \(A(n)\) is exactly orthogonal at every sample. This makes a time-varying FDN stable and energy-preserving.
ModulationOptions::amplitude is normalized, with |amplitude| <= 1, following the AES paper's convention. It is multiplied by π exactly once internally to obtain the peak angular deviation in radians. Thus, amplitude = 0.7 means a peak deviation of 0.7π, approximately 2.2 radians, not 0.7 radians. The JASA paper instead uses the angular convention μ_A <= π. LFO frequency is in cycles per sample: 1 Hz at 48 kHz is 1.0f / 48000.0f.Schlecht and Habets (2015, JASA 138(3) and AES Convention paper 9255) recommend an approximately 1 Hz modulation frequency, an amplitude of approximately 0.7, random initial phases, and per-block frequencies spread by about ±50%. Frequencies below 0.2 Hz make modulation imperceptible; above 2 Hz they introduce obvious periodic temporal patterns and detuning, although up to 4 Hz can still sound smooth and natural. Do not modulate every block synchronously: the papers report easily perceivable beating.
matrix_size; RealSchur mode accepts any even size. Both reject odd sizes because an odd-dimensional orthogonal matrix necessarily has a static real eigenvalue. Modulation is full-band.
|
explicit |
Constructs a time-varying feedback matrix.
| options | The configuration options for the feedback matrix. |
| std::invalid_argument | If the matrix size or mode is invalid, the Hadamard size is not a power of two, the modulation count is invalid, a modulation parameter is non-finite, an initial phase is outside [0, 1], or an amplitude is outside [-1, 1]. |
|
overridevirtual |
Resets the phase of all LFOs to their configured phase offsets.
Implements sfFDN::AudioProcessor.
|
overridevirtual |
Creates a copy of the time-varying feedback matrix.
Implements sfFDN::AudioProcessor.
| bool sfFDN::TimeVaryingFeedbackMatrix::GetMatrix | ( | std::span< float > | matrix, |
| uint64_t | sample_index = 0 ) const |
Materializes the feedback matrix that Process applies at a given sample index.
| matrix | Destination for matrix_size * matrix_size values in row-major order, matching ScalarFeedbackMatrix::GetMatrix: matrix[row * matrix_size + column] = A[row, column], where y = A * x. |
| sample_index | The index, counted from the start of an unprocessed stream, of the sample whose matrix is wanted. Zero yields the matrix applied to the very first sample. |
matrix_size * matrix_size values.This is a pure query: it neither reads nor mutates the running LFO phases, so its result depends only on the configuration and sample_index. It allocates and is not realtime-safe; call it from a control or UI thread. Because it ignores the processing state, it is safe to call concurrently with Process.
|
overridevirtualnoexcept |
|
overridevirtualnoexcept |
|
overridevirtualnoexcept |
Processes the audio buffer.
| input | The input audio buffer. |
| output | The output audio buffer. The input and output channel counts must both equal the matrix size, and their sample counts must match. |
Implements sfFDN::AudioProcessor.
|
noexcept |
Gets the number of 2x2 rotation blocks.
time_varying_config, because its block count depends on the constructed basis. Hadamard mode always has matrix_size / 2 blocks. | void sfFDN::TimeVaryingFeedbackMatrix::SetBaseAngles | ( | std::span< const float > | radians | ) |
Sets the base rotation angle for each rotation block.
| radians | The finite base angles in radians, one per rotation block. Angles are range-reduced to [-π, π]. |
| void sfFDN::TimeVaryingFeedbackMatrix::SetLfoAmplitude | ( | std::span< const float > | amplitudes | ) |
Sets the LFO amplitude for each rotation block.
| amplitudes | The normalized LFO amplitudes, one per rotation block. Each amplitude must be in [-1, 1] and is multiplied by π once internally to obtain its peak deviation in radians. For example, 0.7 denotes 0.7π, not 0.7 radians. |
| void sfFDN::TimeVaryingFeedbackMatrix::SetLfoFrequency | ( | std::span< const float > | frequencies | ) |
Sets the LFO frequency for each rotation block.
| frequencies | The normalized LFO frequencies, one per rotation block. Frequencies are finite values in cycles per sample; for example, 1 Hz at 48 kHz is 1.0f / 48000.0f. |
| void sfFDN::TimeVaryingFeedbackMatrix::SetLfoPhaseOffset | ( | std::span< const float > | phase_offsets | ) |
Sets the LFO phase offset for each rotation block.
| phase_offsets | The normalized LFO phase offsets, one per rotation block. Each offset is finite and in [0, 1] cycles, where 1 is a full cycle. |
| void sfFDN::TimeVaryingFeedbackMatrix::SetModulation | ( | std::span< const ModulationOptions > | modulation_configs | ) |
Sets the modulation options for each rotation block.
| modulation_configs | The modulation options, one per rotation block. An empty span disables modulation. Otherwise, the span must contain exactly one configuration per rotation block. |