DSPark 1.8.0
Header-only C++20 DSP for real-time and offline audio
Loading...
Searching...
No Matches
dspark::DCBlocker< T > Class Template Reference

DC blocking filter with configurable Butterworth order (1-10). More...

#include <DCBlocker.h>

Classes

struct  Section
 Second-order section: b0 * (1 - z^-1)^2 / (1 + a1 z^-1 + a2 z^-2). More...
 
struct  SectionState
 

Public Member Functions

 DCBlocker () noexcept
 Builds a filter coherent with the documented defaults (5 Hz @ 48 kHz).
 
 ~DCBlocker ()=default
 
void prepare (double sampleRate, int numChannels=2, double cutoffHz=-1.0)
 Prepares the DC blocker, resetting internal states and precalculating coefficients.
 
void prepare (const AudioSpec &spec)
 Prepares from AudioSpec (unified API); keeps the configured cutoff.
 
void setOrder (int order) noexcept
 Sets the filter order (1-10). Thread-safe.
 
int getOrder () const noexcept
 Returns the current filter order.
 
void setCutoff (T hz) noexcept
 Requests a cutoff frequency update.
 
T getCutoff () const noexcept
 Returns the requested cutoff frequency in Hz.
 
void processBlock (AudioBufferView< T > buffer) noexcept
 Processes an AudioBufferView in-place.
 
void processBlock (int channel, T *data, int numSamples) noexcept
 Processes a block of samples for one channel in-place.
 
T processSample (int channel, T input) noexcept
 Processes a single sample for a given channel.
 
void reset () noexcept
 Clears the internal history states to zero.
 
std::vector< uint8_t > getState () const
 Serializes the parameter state (setup/UI threads; allocates).
 
bool setState (const uint8_t *data, size_t size)
 Restores parameters from a blob (tolerant; rejects foreign ids).
 

Static Public Attributes

static constexpr int kMaxBiquadStages = 5
 
static constexpr int kMaxChannels = 16
 

Protected Types

using OnePoleState = detail::DcBlockState
 

Protected Member Functions

void updateCoefficientsIfNeeded () noexcept
 
void forceUpdateCoefficients (T explicitCutoff=T(0)) noexcept
 
void runOnePole (T *data, int numSamples, int channel) noexcept
 
void runCascade (T *data, int numSamples, int channel, int numStages) noexcept
 

Static Protected Member Functions

static double stepOnePole (double r, OnePoleState &z, double x) noexcept
 y[n] = (x[n] - x[n-1]) + R*y[n-1]; the difference zeroes DC exactly.
 
static double stepSection (double b0, double a1, double a2, SectionState &z, double x) noexcept
 Direct Form I with the numerator applied as a second difference.
 
static void flushDenormals (OnePoleState &z) noexcept
 
static void flushDenormals (SectionState &z) noexcept
 

Protected Attributes

double sampleRate_ = 48000.0
 
int numChannels_ = 2
 
double onePoleR_ = 0.0
 Derived from the documented defaults in the constructor.
 
std::atomic< int > order_ { 1 }
 
std::atomic< T > cutoffHz_ { T(5) }
 
T lastCutoff_ = T(-1)
 
int lastOrder_ = -1
 
std::array< OnePoleState, kMaxChannels > onePole_ {}
 
std::array< Section, kMaxBiquadStages > sections_ {}
 

Static Protected Attributes

static constexpr double kDenormalFloor = 1e-30
 Flushes a fully decayed state to zero at the end of a block.
 

Detailed Description

template<FloatType T>
class dspark::DCBlocker< T >

DC blocking filter with configurable Butterworth order (1-10).

Designed for strict real-time processing: zero allocations and tight scalar inner loops (the recursive filter state rules out SIMD vectorization).

The filter core (coefficients, history and recursion) is always double precision, independent of the sample type: see the file-level documentation for the measurements behind that decision. Rejection is therefore rate-independent

  • a DC-free signal picks up less than 1e-9 of DC and a steady DC input decays to exactly zero at every rate from 44.1 kHz to 768 kHz.
Warning
Do not modulate the cutoff frequency at audio rates, as updating biquad coefficients triggers trigonometric functions.
Template Parameters
TSample type (float or double).

Definition at line 87 of file DCBlocker.h.

Member Typedef Documentation

◆ OnePoleState

template<FloatType T>
using dspark::DCBlocker< T >::OnePoleState = detail::DcBlockState
protected

Definition at line 366 of file DCBlocker.h.

Constructor & Destructor Documentation

◆ DCBlocker()

template<FloatType T>
dspark::DCBlocker< T >::DCBlocker ( )
inlinenoexcept

Builds a filter coherent with the documented defaults (5 Hz @ 48 kHz).

Definition at line 94 of file DCBlocker.h.

◆ ~DCBlocker()

template<FloatType T>
dspark::DCBlocker< T >::~DCBlocker ( )
default

Member Function Documentation

◆ flushDenormals() [1/2]

template<FloatType T>
static void dspark::DCBlocker< T >::flushDenormals ( OnePoleState &  z)
inlinestaticprotectednoexcept

Definition at line 407 of file DCBlocker.h.

◆ flushDenormals() [2/2]

template<FloatType T>
static void dspark::DCBlocker< T >::flushDenormals ( SectionState &  z)
inlinestaticprotectednoexcept

Definition at line 413 of file DCBlocker.h.

◆ forceUpdateCoefficients()

template<FloatType T>
void dspark::DCBlocker< T >::forceUpdateCoefficients ( T  explicitCutoff = T(0))
inlineprotectednoexcept

Definition at line 319 of file DCBlocker.h.

◆ getCutoff()

template<FloatType T>
T dspark::DCBlocker< T >::getCutoff ( ) const
inlinenoexcept

Returns the requested cutoff frequency in Hz.

Definition at line 174 of file DCBlocker.h.

◆ getOrder()

template<FloatType T>
int dspark::DCBlocker< T >::getOrder ( ) const
inlinenoexcept

Returns the current filter order.

Definition at line 151 of file DCBlocker.h.

◆ getState()

template<FloatType T>
std::vector< uint8_t > dspark::DCBlocker< T >::getState ( ) const
inline

Serializes the parameter state (setup/UI threads; allocates).

Definition at line 285 of file DCBlocker.h.

◆ prepare() [1/2]

template<FloatType T>
void dspark::DCBlocker< T >::prepare ( const AudioSpec &  spec)
inline

Prepares from AudioSpec (unified API); keeps the configured cutoff.

Definition at line 125 of file DCBlocker.h.

◆ prepare() [2/2]

template<FloatType T>
void dspark::DCBlocker< T >::prepare ( double  sampleRate,
int  numChannels = 2,
double  cutoffHz = -1.0 
)
inline

Prepares the DC blocker, resetting internal states and precalculating coefficients.

Parameters
sampleRateSample rate in Hz. Non-positive or NaN rates are ignored.
numChannelsNumber of audio channels (max 16, default: 2).
cutoffHzCutoff frequency in Hz (clamped to min 1 Hz). Leave it out (or pass a non-positive value) to KEEP the cutoff currently configured, which is what a host re-activating the plugin wants: re-preparing used to silently drop a setCutoff() back to the 5 Hz default. A freshly built instance still starts at 5 Hz.

Definition at line 110 of file DCBlocker.h.

◆ processBlock() [1/2]

template<FloatType T>
void dspark::DCBlocker< T >::processBlock ( AudioBufferView< T >  buffer)
inlinenoexcept

Processes an AudioBufferView in-place.

Checks for parameter updates and applies the appropriate filter topology across all channels using tight scalar inner loops.

Parameters
bufferAudio buffer to process.

Definition at line 187 of file DCBlocker.h.

◆ processBlock() [2/2]

template<FloatType T>
void dspark::DCBlocker< T >::processBlock ( int  channel,
T *  data,
int  numSamples 
)
inlinenoexcept

Processes a block of samples for one channel in-place.

Parameters
channelChannel index. Out-of-range indices leave the data untouched (the per-channel state is bounded to kMaxChannels).
dataAudio samples (modified in-place).
numSamplesNumber of samples to process.

Definition at line 221 of file DCBlocker.h.

◆ processSample()

template<FloatType T>
T dspark::DCBlocker< T >::processSample ( int  channel,
T  input 
)
inlinenoexcept

Processes a single sample for a given channel.

Note
For processing multiple samples, prefer processBlock() to avoid overhead: this path re-checks the published parameters on every call so that a per-sample-only caller still sees setOrder()/setCutoff() (two relaxed loads and two compares; a pending change pays the coefficient rebuild on the sample that observes it, same
Warning
as the block path). Bit-identical to the block paths sample for sample, except that those flush a fully decayed state (below 1e-30, i.e. after seconds of silence) to zero at the end of the block to keep the recursion out of denormal territory; a per-sample caller owns that decision through its own loop.
Parameters
channelChannel index. Out-of-range indices return the input unprocessed.
inputInput sample.
Returns
Sample with DC offset removed.

Definition at line 253 of file DCBlocker.h.

◆ reset()

template<FloatType T>
void dspark::DCBlocker< T >::reset ( )
inlinenoexcept

Clears the internal history states to zero.

Definition at line 276 of file DCBlocker.h.

◆ runCascade()

template<FloatType T>
void dspark::DCBlocker< T >::runCascade ( T *  data,
int  numSamples,
int  channel,
int  numStages 
)
inlineprotectednoexcept

Definition at line 429 of file DCBlocker.h.

◆ runOnePole()

template<FloatType T>
void dspark::DCBlocker< T >::runOnePole ( T *  data,
int  numSamples,
int  channel 
)
inlineprotectednoexcept

Definition at line 419 of file DCBlocker.h.

◆ setCutoff()

template<FloatType T>
void dspark::DCBlocker< T >::setCutoff ( T  hz)
inlinenoexcept

Requests a cutoff frequency update.

Coefficients are recomputed lazily on the next processing call to ensure thread safety, but beware that calculating high-order biquads involves trigonometric operations.

Parameters
hzCutoff frequency in Hz (clamped to min 1.0). Non-finite values are ignored (std::max(NaN, 1) returns the NaN, which would poison every coefficient on the next rebuild).

Definition at line 167 of file DCBlocker.h.

◆ setOrder()

template<FloatType T>
void dspark::DCBlocker< T >::setOrder ( int  order)
inlinenoexcept

Sets the filter order (1-10). Thread-safe.

  • Order 1: efficient 1-pole filter (6 dB/oct).
  • Order 2-10: cascaded Butterworth biquad HPFs (12*N dB/oct for even orders).
Warning
Changing order during playback may result in audio clicks, as filter states are not dynamically crossfaded. Best used during prepare() or silence.
Note
Order 1 = 1-pole (6 dB/oct). Orders >= 2 use floor(order/2) cascaded Butterworth biquads, so ODD orders behave like the next lower even order (e.g. 3 == 2, 5 == 4). Prefer 1 or even values for predictable slopes.
Parameters
orderFilter order (1-10).

Definition at line 145 of file DCBlocker.h.

◆ setState()

template<FloatType T>
bool dspark::DCBlocker< T >::setState ( const uint8_t *  data,
size_t  size 
)
inline

Restores parameters from a blob (tolerant; rejects foreign ids).

Definition at line 294 of file DCBlocker.h.

◆ stepOnePole()

template<FloatType T>
static double dspark::DCBlocker< T >::stepOnePole ( double  r,
OnePoleState &  z,
double  x 
)
inlinestaticprotectednoexcept

y[n] = (x[n] - x[n-1]) + R*y[n-1]; the difference zeroes DC exactly.

Definition at line 377 of file DCBlocker.h.

◆ stepSection()

template<FloatType T>
static double dspark::DCBlocker< T >::stepSection ( double  b0,
double  a1,
double  a2,
SectionState &  z,
double  x 
)
inlinestaticprotectednoexcept

Direct Form I with the numerator applied as a second difference.

Definition at line 383 of file DCBlocker.h.

◆ updateCoefficientsIfNeeded()

template<FloatType T>
void dspark::DCBlocker< T >::updateCoefficientsIfNeeded ( )
inlineprotectednoexcept

Definition at line 304 of file DCBlocker.h.

Member Data Documentation

◆ cutoffHz_

template<FloatType T>
std::atomic<T> dspark::DCBlocker< T >::cutoffHz_ { T(5) }
protected

Definition at line 465 of file DCBlocker.h.

◆ kDenormalFloor

template<FloatType T>
constexpr double dspark::DCBlocker< T >::kDenormalFloor = 1e-30
staticconstexprprotected

Flushes a fully decayed state to zero at the end of a block.

A 5 Hz pole holds energy for seconds: without this, a silent passage walks the state down through the denormal range and parks both the recursion and the emitted samples on the CPU's slow path (the float cascade this replaced was measured at 1e-42 after four seconds of DC). The floor sits ~600 dB below full scale and above the smallest normal float, and only fires when the input history is negligible too, so it can never truncate a live signal.

Definition at line 405 of file DCBlocker.h.

◆ kMaxBiquadStages

template<FloatType T>
constexpr int dspark::DCBlocker< T >::kMaxBiquadStages = 5
staticconstexpr

Definition at line 90 of file DCBlocker.h.

◆ kMaxChannels

template<FloatType T>
constexpr int dspark::DCBlocker< T >::kMaxChannels = 16
staticconstexpr

Definition at line 91 of file DCBlocker.h.

◆ lastCutoff_

template<FloatType T>
T dspark::DCBlocker< T >::lastCutoff_ = T(-1)
protected

Definition at line 466 of file DCBlocker.h.

◆ lastOrder_

template<FloatType T>
int dspark::DCBlocker< T >::lastOrder_ = -1
protected

Definition at line 467 of file DCBlocker.h.

◆ numChannels_

template<FloatType T>
int dspark::DCBlocker< T >::numChannels_ = 2
protected

Definition at line 461 of file DCBlocker.h.

◆ onePole_

template<FloatType T>
std::array<OnePoleState, kMaxChannels> dspark::DCBlocker< T >::onePole_ {}
protected

Definition at line 470 of file DCBlocker.h.

◆ onePoleR_

template<FloatType T>
double dspark::DCBlocker< T >::onePoleR_ = 0.0
protected

Derived from the documented defaults in the constructor.

Definition at line 462 of file DCBlocker.h.

◆ order_

template<FloatType T>
std::atomic<int> dspark::DCBlocker< T >::order_ { 1 }
protected

Definition at line 464 of file DCBlocker.h.

◆ sampleRate_

template<FloatType T>
double dspark::DCBlocker< T >::sampleRate_ = 48000.0
protected

Definition at line 460 of file DCBlocker.h.

◆ sections_

template<FloatType T>
std::array<Section, kMaxBiquadStages> dspark::DCBlocker< T >::sections_ {}
protected

Definition at line 471 of file DCBlocker.h.


The documentation for this class was generated from the following file: