DSPark 1.6.1
Header-only audio DSP framework in pure C++20 — zero dependencies
Loading...
Searching...
No Matches
CrossoverFilter.h File Reference

Linkwitz-Riley crossover filter for multi-band audio processing. More...

#include "../Core/AudioBuffer.h"
#include "../Core/AudioSpec.h"
#include "../Core/Biquad.h"
#include "../Core/DspMath.h"
#include "../Core/DenormalGuard.h"
#include "../Core/FFT.h"
#include "../Core/SmoothedValue.h"
#include "../Core/StateBlob.h"
#include <algorithm>
#include <array>
#include <atomic>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <memory>
#include <numbers>
#include <vector>
Include dependency graph for CrossoverFilter.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

class  dspark::CrossoverFilter< T, MaxBands >
 Linkwitz-Riley crossover with 2-12 bands, LR12/LR24/LR48. More...
 

Namespaces

namespace  dspark
 Main namespace for the DSPark framework.
 

Detailed Description

Linkwitz-Riley crossover filter for multi-band audio processing.

Splits an audio signal into 2-12 frequency bands using Linkwitz-Riley crossover filters. Supports three slope options (LR12, LR24, LR48) and two processing modes: minimum-phase IIR with allpass phase correction, and linear-phase FFT-based processing with zero phase distortion.

Linkwitz-Riley crossovers guarantee that all bands sum to an allpass (flat magnitude response) at every frequency, making them the standard for professional multi-band processing. In the IIR tree, band b passes through one allpass section per split above it (LR12/LR24) or two sections (LR48) so the phase of every branch matches at the summing point. LR12 additionally bakes a polarity inversion into the high-pass branch of each split (the textbook LR2 convention): odd-numbered bands come out polarity-inverted so the tree sums flat instead of notching at every crossover. The linear-phase path needs neither (zero-phase magnitudes sum to unity by construction).

The linear-phase FIR length equals the prepared maxBlockSize, so its low-frequency resolution scales with the block size: very low crossover frequencies need large blocks to be resolved. Kernel recomputation after a frequency/order/band-count change runs on the audio thread from pre-allocated scratch (no allocation, but it is a CPU spike of 2 x numBands FFTs for that block).

Threading model:

  • prepare() / reset() / getState() / setState(): setup or UI threads only (prepare and getState allocate), never concurrently with processBlock().
  • setNumBands / setCrossoverFrequency / setOrder / setFilterMode: RT-safe atomic publications from any thread; the audio thread applies them at the next block. Frequency changes are smoothed (5 ms) in IIR mode and applied instantly in linear-phase mode (kernels are rebuilt per change).
  • getLatency() and the getters are safe from any thread.

Dependencies: Biquad.h, AudioBuffer.h, AudioSpec.h, DspMath.h, FFT.h, DenormalGuard.h, SmoothedValue.h, StateBlob.h.

Definition in file CrossoverFilter.h.