|
DSPark 1.8.0
Header-only C++20 DSP for real-time and offline audio
|
Parametric multi-band EQ using cascaded biquads or FFT overlap-save convolution. More...
#include <Equalizer.h>

Classes | |
| struct | BandConfig |
| Full configuration for a single EQ band. More... | |
| struct | StagedBand |
| One band's published configuration: a seqlock over atomic words. More... | |
Public Types | |
| enum class | FilterMode { MinimumPhase , LinearPhase } |
| Filter processing mode. More... | |
| enum class | BandType { Peak , LowShelf , HighShelf , LowPass , HighPass , Notch , BandPass , Tilt } |
| Filter type for each EQ band. More... | |
Public Member Functions | |
| ~Equalizer ()=default | |
| Non-virtual destructor to prevent vtable instantiation (zero virtual dispatch). | |
| void | prepare (const AudioSpec &spec) |
| Prepares all bands and allocates necessary resources for processing. | |
| void | processBlock (AudioBufferView< T > buffer) noexcept |
| Processes an audio buffer in-place. | |
| T | processSample (T input, int channel) noexcept |
| Processes a single sample through all enabled bands (IIR mode only). | |
| void | reset () noexcept |
| Resets all filter states to zero to prevent ringing on playback start. | |
| void | setBand (int index, T frequency, T gainDb) |
| Configures a band with frequency and gain (Peak filter). | |
| void | setBand (int index, T frequency, T gainDb, T q) |
| Configures a band with frequency, gain, and Q. | |
| void | setBand (int index, const BandConfig &config) |
| Configures a band with full control over all parameters. Thread-safe. | |
| void | setNumBands (int count) |
| Sets the number of active bands with auto-logarithmic spacing. | |
| int | getNumBands () const noexcept |
| Returns the number of active bands. | |
| void | setMatchedBells (bool enabled) noexcept |
| Switches Peak bands to the analog-matched (de-cramped) design. | |
| bool | isMatchedBells () const noexcept |
| Returns whether Peak bands use the matched design (setMatchedBells()). | |
| BandConfig | getBandConfig (int index) const noexcept |
| Returns the current configuration of a band. | |
| void | setBandEnabled (int index, bool enabled) noexcept |
| Enables or disables a band without changing its parameters. | |
| void | setFilterMode (FilterMode mode) noexcept |
| Sets the filter processing mode (Minimum Phase or Linear Phase). | |
| FilterMode | getFilterMode () const noexcept |
| Returns the current filter mode. | |
| int | getLatency () const noexcept |
| Returns the latency in samples. | |
| void | setSoftMode (bool enabled) noexcept |
| Enables soft mode (anti-ringing Q reduction dynamically based on gain). | |
| bool | getSoftMode () const noexcept |
| Returns whether soft mode is enabled. | |
| void | getMagnitudeForFrequencyArray (const T *frequencies, T *magnitudes, int numPoints) const noexcept |
| Computes the combined magnitude response of all enabled bands. | |
| FilterEngine< T > & | getBandFilter (int index) noexcept |
| Direct access to a band's underlying FilterEngine. | |
| const FilterEngine< T > & | getBandFilter (int index) const noexcept |
| Const overload. Same clamping contract. | |
| std::vector< uint8_t > | getState () const |
| Serializes bands and modes (setup/UI threads; allocates). | |
| bool | setState (const uint8_t *data, size_t size) |
| Restores bands and modes from a blob (tolerant; rejects foreign ids). | |
| int | buildBandStages (const BandConfig &cfg, BiquadCoeffs *stages) const noexcept |
Fills stages with the ACTUAL biquad cascade for a band (per-stage Butterworth Q for multi-stage LP/HP, single biquad otherwise) and returns the stage count. Public analysis API: UIs use it to draw a magnitude response that matches what the IIR FilterEngine really applies, including the user's resonance on LP/HP cascades, soft mode's Q cap and the matched-bell design. Mirrors the engine's own parameter sanitization (frequency and Q floors). Requires prepare(). | |
Protected Member Functions | |
| T | effectiveQ (const BandConfig &cfg) const noexcept |
| The band Q the audio path actually uses (soft mode caps it by gain). | |
| void | updateActiveFilters () noexcept |
| Translates BandConfigs into internal FilterEngine parameters safely. | |
| BiquadCoeffs | computeBandCoeffs (const BandConfig &cfg) const noexcept |
| Computes single-biquad coefficients for a band (analysis/kernel). | |
| void | recomputeLinearPhaseKernel () noexcept |
| Mathematically robust Linear Phase kernel computation. | |
| void | processLinearPhase (AudioBufferView< T > buffer) noexcept |
| Linear-phase processing via overlap-save FFT convolution. | |
Static Protected Member Functions | |
| static double | shelfSlopeFromQ (double q, double gainDb) noexcept |
| Converts a user-facing shelf Q into the RBJ shelf slope S. | |
Protected Attributes | |
| AudioSpec | spec_ {} |
| std::atomic< int > | numBands_ { 0 } |
| std::array< FilterEngine< T >, MaxBands > | bands_ {} |
| std::array< StagedBand, MaxBands > | staged_ {} |
| Published band configurations. The ONLY band storage both threads reach. | |
| std::array< BandConfig, MaxBands > | masterConfigs_ {} |
| std::array< std::atomic< bool >, MaxBands > | bandEnabled_ {} |
| std::atomic< bool > | softMode_ { false } |
| std::atomic< bool > | configDirty_ { false } |
| std::atomic< bool > | matchedBells_ { true } |
| Matched (de-cramped) bells by default. | |
| std::atomic< FilterMode > | filterMode_ { FilterMode::MinimumPhase } |
| std::atomic< bool > | lpDirty_ { true } |
| std::unique_ptr< FFTReal< T > > | lpFft_ |
| int | lpFftSize_ = 0 |
| int | lpBlock_ = 0 |
| Max block size the LP engine was sized for (= its latency). | |
| std::vector< T > | lpKernel_ |
| std::vector< std::vector< T > > | lpPrevBlock_ |
| std::vector< T > | lpFftIn_ |
| std::vector< T > | lpFftOut_ |
| std::vector< T > | lpMagScratch_ |
| std::vector< T > | lpTempFreq_ |
| std::vector< T > | lpImpulse_ |
| std::vector< T > | lpKernelSpace_ |
Static Protected Attributes | |
| static constexpr int | kLpMaxBlockSize = 1 << 18 |
Parametric multi-band EQ using cascaded biquads or FFT overlap-save convolution.
| T | Sample type (float or double). |
| MaxBands | Maximum number of EQ bands (compile-time, default 16). |
Definition at line 71 of file Equalizer.h.
|
strong |
Filter type for each EQ band.
Definition at line 85 of file Equalizer.h.
|
strong |
Filter processing mode.
| Enumerator | |
|---|---|
| MinimumPhase | IIR biquads (zero latency, minimum phase shift). Default. |
| LinearPhase | FFT-based overlap-save (block-size latency, zero phase distortion). |
Definition at line 75 of file Equalizer.h.
|
default |
Non-virtual destructor to prevent vtable instantiation (zero virtual dispatch).
|
inlinenoexcept |
Fills stages with the ACTUAL biquad cascade for a band (per-stage Butterworth Q for multi-stage LP/HP, single biquad otherwise) and returns the stage count. Public analysis API: UIs use it to draw a magnitude response that matches what the IIR FilterEngine really applies, including the user's resonance on LP/HP cascades, soft mode's Q cap and the matched-bell design. Mirrors the engine's own parameter sanitization (frequency and Q floors). Requires prepare().
| cfg | Band configuration to translate into processing stages. |
| stages | Output buffer (capacity >= 5). |
Definition at line 758 of file Equalizer.h.
|
inlineprotectednoexcept |
Computes single-biquad coefficients for a band (analysis/kernel).
| cfg | Band configuration (its q must already be the effective one). |
Definition at line 722 of file Equalizer.h.
|
inlineprotectednoexcept |
The band Q the audio path actually uses (soft mode caps it by gain).
Definition at line 631 of file Equalizer.h.
|
inlinenoexcept |
Returns the current configuration of a band.
Safe from any thread: the band is read through its seqlock into a private copy, so a configuration being published concurrently is either fully seen or fully missed, never mixed with the previous one.
| index | Band index. |
Definition at line 428 of file Equalizer.h.
|
inlinenoexcept |
Const overload. Same clamping contract.
Definition at line 556 of file Equalizer.h.
|
inlinenoexcept |
Direct access to a band's underlying FilterEngine.
The index is clamped, so an out-of-range one returns band 0 or the last band instead of binding a reference past the end of the band array. A debug build asserts first: clamping keeps a release build defined, it does not make a wrong index mean anything.
| index | Band index. Clamped, not validated – see the note above. |
Definition at line 549 of file Equalizer.h.
|
inlinenoexcept |
Returns the current filter mode.
Definition at line 469 of file Equalizer.h.
|
inlinenoexcept |
Returns the latency in samples.
0 for MinimumPhase; the prepared max block size for LinearPhase. Reports 0 when the linear-phase engine is unavailable (not prepared yet), so the value always matches the path that actually runs.
Definition at line 481 of file Equalizer.h.
|
inlinenoexcept |
Computes the combined magnitude response of all enabled bands.
Evaluates the same per-stage cascade the audio path applies (including soft mode's Q cap and the matched-bell design), so the drawn curve matches what is heard in both filter modes.
| frequencies | Array of frequencies in Hz. |
| magnitudes | Output array (same size, linear scale). |
| numPoints | Number of frequency points. |
Definition at line 514 of file Equalizer.h.
|
inlinenoexcept |
Returns the number of active bands.
Definition at line 389 of file Equalizer.h.
|
inlinenoexcept |
Returns whether soft mode is enabled.
Definition at line 498 of file Equalizer.h.
|
inline |
Serializes bands and modes (setup/UI threads; allocates).
Definition at line 564 of file Equalizer.h.
|
inlinenoexcept |
Returns whether Peak bands use the matched design (setMatchedBells()).
Definition at line 413 of file Equalizer.h.
|
inline |
Prepares all bands and allocates necessary resources for processing.
Must be called from the host's prepareToPlay/setup method. Performs all memory allocations, including the linear-phase engine, so setFilterMode(LinearPhase) works even when called after prepare(). An invalid spec (non-positive or non-finite fields) is a no-op that keeps the previous state.
| spec | Audio environment (sample rate, max block size, channels). |
Definition at line 127 of file Equalizer.h.
|
inlinenoexcept |
Processes an audio buffer in-place.
Guarantees zero allocations. Checks atomic flags lock-free to update DSP state if the host changed parameters. In LinearPhase mode a pending band change recomputes the FIR kernel on this thread (a bounded, allocation- free spike); switching modes changes getLatency(), so notify the host and consider reset() to clear the other path's tail.
| buffer | Audio data to process. |
Definition at line 193 of file Equalizer.h.
|
inlineprotectednoexcept |
Linear-phase processing via overlap-save FFT convolution.
Blocks larger than the prepared max block size pass through unprocessed (the engine's buffers are sized in prepare(); hosts honour maxBlockSize).
| buffer | Audio buffer. |
Definition at line 884 of file Equalizer.h.
|
inlinenoexcept |
Processes a single sample through all enabled bands (IIR mode only).
Pending band changes are consumed here too (applied immediately, without the block path's parameter smoothing), so per-sample streams that never call processBlock() still pick up setBand() and friends.
| input | Input sample. |
| channel | Channel index (out-of-range channels pass through). |
Definition at line 250 of file Equalizer.h.
|
inlineprotectednoexcept |
Mathematically robust Linear Phase kernel computation.
Constructs a true zero-phase impulse response by evaluating the H(k) magnitude, performing IFFT, shifting by M/2 to make it causal, windowing it with Blackman-Harris to reduce truncation artifacts, zero-padding to N, and converting back to FFT for overlap-save.
Definition at line 799 of file Equalizer.h.
|
inlinenoexcept |
Resets all filter states to zero to prevent ringing on playback start.
Definition at line 278 of file Equalizer.h.
|
inline |
Configures a band with full control over all parameters. Thread-safe.
Non-finite frequency/gain/Q fields fall back to the band's current values (they would otherwise poison the serialized state, the analysis curve, and the linear-phase kernel); wild type/slope values clamp.
| index | Band index. |
| config | Complete band configuration. |
Definition at line 329 of file Equalizer.h.
|
inline |
Configures a band with frequency and gain (Peak filter).
| index | Band index (0 to MaxBands-1). |
| frequency | Center frequency in Hz. |
| gainDb | Boost/cut in dB. |
Definition at line 295 of file Equalizer.h.
|
inline |
Configures a band with frequency, gain, and Q.
| index | Band index. |
| frequency | Center frequency in Hz. |
| gainDb | Boost/cut in dB. |
| q | Quality factor. |
Definition at line 307 of file Equalizer.h.
|
inlinenoexcept |
Enables or disables a band without changing its parameters.
| index | Band index. |
| enabled | True to enable, false to bypass. |
Definition at line 439 of file Equalizer.h.
|
inlinenoexcept |
Sets the filter processing mode (Minimum Phase or Linear Phase).
Works before or after prepare() (the linear-phase engine is always pre-allocated by prepare()). Wild enum values clamp. Switching modes changes getLatency(): hosts must be notified.
| mode | Filter mode. |
Definition at line 459 of file Equalizer.h.
|
inlinenoexcept |
Switches Peak bands to the analog-matched (de-cramped) design.
Bilinear bells cramp near Nyquist (narrower, response pinned at fs/2); the matched design (BiquadCoeffs::makePeakMatched, impulse-invariant poles with a magnitude-matched numerator) keeps high bells on their analog shape, the state-of-the-art digital EQ behaviour. Applies to the IIR engines, the linear-phase kernel, and the analysis curve alike. On by default (worst audible-band deviation from the analog bell at 48 kHz: 2.9 dB matched vs 11 dB bilinear); set false for the classic bilinear (cookbook) bells.
Definition at line 406 of file Equalizer.h.
|
inline |
Sets the number of active bands with auto-logarithmic spacing.
| count | Number of bands (1 to MaxBands). |
Definition at line 361 of file Equalizer.h.
|
inlinenoexcept |
Enables soft mode (anti-ringing Q reduction dynamically based on gain).
| enabled | True to enable soft mode. |
Definition at line 491 of file Equalizer.h.
|
inline |
Restores bands and modes from a blob (tolerant; rejects foreign ids).
Definition at line 593 of file Equalizer.h.
|
inlinestaticprotectednoexcept |
Converts a user-facing shelf Q into the RBJ shelf slope S.
RBJ relation: 1/Q^2 = (A + 1/A) * (1/S - 1) + 2 with A = 10^(dB/40). Q = 0.7071 maps to S = 1 (the standard shelf). Out-of-domain values are clamped to the stable (0, 1] range that the coefficient factory accepts.
Definition at line 707 of file Equalizer.h.
|
inlineprotectednoexcept |
Translates BandConfigs into internal FilterEngine parameters safely.
Audio thread; called by processBlock()/processSample() when configDirty_ is true. Each band is pulled through its seqlock into a plain local, so the filter is configured from ONE publication. Reading the band by reference instead would let a concurrent setBand() land between two field reads and configure a filter with a frequency from one call and a slope from the next. That is not a theoretical hazard: before this was a seqlock, roughly one adoption in thirty was such a mixture.
The pull is bounded (tryRead): a band whose read gives up is left with the coefficients it already has, and configDirty_ is re-armed so the whole set is retried on a later call. Reconfiguring a band from its published config is idempotent, so retrying all of them costs nothing but the work.
Definition at line 659 of file Equalizer.h.
|
protected |
Definition at line 1109 of file Equalizer.h.
|
protected |
Definition at line 955 of file Equalizer.h.
|
protected |
Definition at line 1112 of file Equalizer.h.
|
protected |
Definition at line 1116 of file Equalizer.h.
|
staticconstexprprotected |
Definition at line 950 of file Equalizer.h.
|
protected |
Max block size the LP engine was sized for (= its latency).
Definition at line 1121 of file Equalizer.h.
|
protected |
Definition at line 1117 of file Equalizer.h.
|
protected |
Definition at line 1119 of file Equalizer.h.
|
protected |
Definition at line 1125 of file Equalizer.h.
|
protected |
Definition at line 1125 of file Equalizer.h.
|
protected |
Definition at line 1120 of file Equalizer.h.
|
protected |
Definition at line 1127 of file Equalizer.h.
|
protected |
Definition at line 1123 of file Equalizer.h.
|
protected |
Definition at line 1127 of file Equalizer.h.
|
protected |
Definition at line 1127 of file Equalizer.h.
|
protected |
Definition at line 1124 of file Equalizer.h.
|
protected |
Definition at line 1127 of file Equalizer.h.
|
protected |
Control-thread-private master copy. Never read by the audio thread or by any readout: it exists so a setter can fall back to the band's current value for a non-finite field without reading published storage. Single writer by contract, so it needs no synchronization of its own.
Definition at line 1104 of file Equalizer.h.
|
protected |
Matched (de-cramped) bells by default.
Definition at line 1113 of file Equalizer.h.
|
protected |
Definition at line 953 of file Equalizer.h.
|
protected |
Definition at line 1111 of file Equalizer.h.
|
protected |
Definition at line 952 of file Equalizer.h.
|
protected |
Published band configurations. The ONLY band storage both threads reach.
Definition at line 1098 of file Equalizer.h.