Repository navigation
Feedforward Compensator
Relevant source files
The following files were used as context for generating this wiki page:
- .gitignore
- docs/calibration.en.md
- docs/calibration.md
- docs/measurement_recipes/noise_measurement.en.md
- docs/measurement_recipes/noise_measurement.md
- docs/widgets/feedforward_compensator.en.md
- docs/widgets/feedforward_compensator.md
- scripts/optimize_hammerstein_real_device.py
- scripts/verify_lock_in_modeler_hammerstein_real_device.py
- src/core/hammerstein_model.py
- src/gui/widgets/feedforward_compensator.py
- tests/logic_verification/core/test_hammerstein_model.py
- tests/logic_verification/gui/widgets/test_feedforward_compensator.py
The Feedforward Compensator is a high-performance signal processing module designed to apply real-time or offline nonlinear distortion compensation to audio signals. It utilizes a Parallel Hammerstein Model (consisting of 1st to 5th order impulse response kernels) to generate an inverse-distorted signal that actively cancels the physical distortion produced by audio hardware docs/widgets/feedforward_compensator.en.md:3-7.
The module implements the Linear-Inverse Compensated Feedforward (LICFF) algorithm. This method assumes the system under test follows a Hammerstein structure, where a static nonlinearity is followed by a linear filter docs/widgets/feedforward_compensator.en.md:11-13.
The frequency response of the 1st-order (linear) kernel docs/widgets/feedforward_compensator.en.md:15-22:
-
Regularization (
$\epsilon_f$ ): A frequency-dependent parameter. It is kept small ($\epsilon_{in} \approx 10^{-6}$ ) within the active band and large ($\epsilon_{out} \approx 0.5$ ) outsidedocs/widgets/feedforward_compensator.en.md:26. -
Bandpass Filter (
$bp_filter$ ): Applies a smooth cosine roll-off outside the user-defined$f_{min}$ and$f_{max}$ to protect the system from subsonic and ultrasonic noisedocs/widgets/feedforward_compensator.en.md:27.
To compensate for nonlinearities, the engine performs the following steps docs/widgets/feedforward_compensator.en.md:29-42:
-
Baseline: Initialize
$u_{comp}^{(0)}$ by band-limiting the input signal. -
Prediction: Predict the distortion spectrum
$Y_{nl}(f)$ by running the current compensated signal through the 2nd–5th order Hammerstein kernels. -
Subtraction: Apply the linear inverse filter to the predicted distortion and subtract it from the input side:
$$u_{comp}^{(k+1)} = u_{comp}^{(0)} - \text{IFFT}(Y_{nl}(f) \cdot F_{inv}(f))$$ - Convergence: Repeat for a specified number of iterations (typically 3–5).
Sources: src/gui/widgets/feedforward_compensator.py:36-52, docs/widgets/feedforward_compensator.en.md:11-43
The compensation logic is split between the LICFFEngine (mathematical core) and the FeedforwardCompensator (GUI and management).
The following diagram illustrates how a Hammerstein model flows from measurement to the compensation engine.
Hammerstein Model Integration
graph TD
subgraph "Measurement Space"
NA["Nonlinear Analyzer"] -- "Export JSON (h1-h5)" --> JSON[".json Model File"]
end
subgraph "LICFFEngine (Code Entity)"
JSON -- "parse_model()" --> PE["Power Series Kernels (q1-q5)"]
PE -- "rebuild_filter()" --> LIN["Linear Inverse Filter (F_inv_lin)"]
PE -- "rebuild_filter()" --> NL["Nonlinear Predictor (F_inv_nl)"]
end
subgraph "Processing Loop"
Input["Input Signal (u)"] --> Iter["Iterative Loop (compensate)"]
Iter -- "forward_model()" --> Pred["Distortion Prediction"]
Pred -- "F_inv_lin" --> Corr["Correction Signal"]
Corr -- "Subtract" --> Iter
Iter --> Final["Compensated Output"]
end
style LICFFEngine stroke-width:2px
Sources: src/gui/widgets/feedforward_compensator.py:36-134, src/gui/widgets/feedforward_compensator.py:331-364
The LICFFEngine maps measured Hammerstein kernels (src/gui/widgets/feedforward_compensator.py:98-104. It includes a threshold_db feature to zero out high-order kernels that fall below the noise floor relative to the linear peak src/gui/widgets/feedforward_compensator.py:107-121.
During iterative compensation, the engine monitors the signal for "runaway" oscillations. If the amplitude exceeds a safety limit (e.g., 5.0 FS), the LICFFEngine can abort the process to prevent hardware damage or software crashes src/gui/widgets/feedforward_compensator.py:350-360.
The module supports three modes for handling frequencies outside the active band (src/gui/widgets/feedforward_compensator.py:59:
- Cut: Frequencies outside the band are completely attenuated.
- Bypass (Pure): Original signal is passed through without any filtering.
-
Bypass (Aligned): Original signal is passed through but delayed to match the group delay of the inverse filter, preventing phase misalignment at the crossover
docs/widgets/feedforward_compensator.en.md:62.
The OfflineFFCompWorker handles batch processing of .wav files src/gui/widgets/feedforward_compensator.py:700-705. It utilizes a segmented approach with overlapping blocks to prevent boundary artifacts (spectral leakage) during the IFFT/FFT cycles docs/widgets/feedforward_compensator.md:122.
Sources: src/gui/widgets/feedforward_compensator.py:36-150, src/gui/widgets/feedforward_compensator.py:700-750
The following diagram maps natural language compensation concepts to specific classes and methods in the codebase.
Compensation Entity Mapping
classDiagram
class LICFFEngine {
+parse_model()
+rebuild_filter()
+compensate(u, iterative, iters)
+forward_model(u)
+linear_output(u)
+solve_eps_in(target_boost_db)
}
class OfflineFFCompWorker {
+run()
+process_segment()
}
class FeedforwardCompensator {
+load_model(path)
+run_simulation()
}
FeedforwardCompensator *-- LICFFEngine : owns
OfflineFFCompWorker o-- LICFFEngine : uses
LICFFEngine --|> AudioCalc : uses DSP helpers
Sources: src/gui/widgets/feedforward_compensator.py:36-40, src/gui/widgets/feedforward_compensator.py:700-710, src/gui/widgets/feedforward_compensator.py:850-860
The module provides extensive simulation tools before applying compensation to live hardware:
-
Simulation Tab: Displays the predicted THD reduction for various test signals (1kHz, Multi-tone, etc.)
docs/widgets/feedforward_compensator.en.md:71-83. -
Transient Simulation: Visualizes the step and impulse response to check for Gibbs ringing caused by the active band filter
docs/widgets/feedforward_compensator.en.md:90-101. -
Linear Response Tab: Shows the magnitude and phase of the designed inverse filter. Phase rotation is automatically corrected to the
$h_1$ peak position to make physical phase changes easier to observedocs/widgets/feedforward_compensator.md:112.
Sources: src/gui/widgets/feedforward_compensator.py:900-1100, docs/widgets/feedforward_compensator.en.md:71-112