CUGL 2.0
Cornell University Game Library
Public Member Functions | Static Public Attributes | List of all members
cugl::dsp::TwoPoleIIR Class Reference

#include <CUTwoPoleIIR.h>

Public Member Functions

 TwoPoleIIR ()
 
 TwoPoleIIR (unsigned channels)
 
 TwoPoleIIR (unsigned channels, float b0, float a1, float a2)
 
 TwoPoleIIR (const TwoPoleIIR &copy)
 
 TwoPoleIIR (TwoPoleIIR &&filter)
 
 ~TwoPoleIIR ()
 
unsigned getChannels () const
 
void setChannels (unsigned channels)
 
void setCoeff (const std::vector< float > &bvals, const std::vector< float > &avals)
 
const std::vector< float > getBCoeff () const
 
const std::vector< float > getACoeff () const
 
void setTransfer (const Polynomial &p, const Polynomial &q)
 
Polynomial getNumerator () const
 
Polynomial getDenominator () const
 
void setBCoeff (float b0)
 
void setACoeff (float a1, float a2)
 
void setResonance (float frequency, float radius, bool normalize=false)
 
void setPoles (float pole1, float pole2)
 
void step (float gain, float *input, float *output)
 
void calculate (float gain, float *input, float *output, size_t size)
 
void clear ()
 
size_t flush (float *output)
 

Static Public Attributes

static bool VECTORIZE
 

Detailed Description

This class implements a two-pole digital filter.

This is the simplest class for implementing a resonance in a frequency while maintaining a constant filter gain. There is a convenience method for defining this resonance. However, filters are not intended to be model classes, and so it does not save the defining frequency.

Frequencies are specified in "normalized" format. A normalized frequency is frequency/sample rate. For example, a 7 kHz frequency with a 44100 Hz sample rate has a normalized value 7000/44100 = 0.15873.

This class supports vector optimizations for SSE and Neon 64. In timed simulations, these optimizations provide at least a 3-4x performance increase (and for 4 or 8 channel audio, much higher). These optimizations make use of the matrix precomputation outlined in "Implementation of Recursive Digital Filters into Vector SIMD DSP Architectures".

https://pdfs.semanticscholar.org/d150/a3f75dc033916f14029cd9101a8ea1d050bb.pdf

The algorithm in this paper performs extremely well in our tests, and even out-performs Apple's Acceleration library. However, our implementation is limited to 128-bit words as 256-bit (e.g. AVX) and higher show no significant increase in performance.

For performance reasons, this class does not have a (virtualized) subclass relationship with other IIR or FIR filters. However, the signature of the the calculation and coefficient methods has been standardized so that it can support templated polymorphism.

This class is not thread safe. External locking may be required when the filter is shared between multiple threads (such as between an audio thread and the main thread).

Constructor & Destructor Documentation

◆ TwoPoleIIR() [1/5]

cugl::dsp::TwoPoleIIR::TwoPoleIIR ( )

Creates a second-order pass-through filter for a single channel.

◆ TwoPoleIIR() [2/5]

cugl::dsp::TwoPoleIIR::TwoPoleIIR ( unsigned  channels)

Creates a second-order pass-through filter for the given number of channels.

Parameters
channelsThe number of channels

◆ TwoPoleIIR() [3/5]

cugl::dsp::TwoPoleIIR::TwoPoleIIR ( unsigned  channels,
float  b0,
float  a1,
float  a2 
)

Creates an IIR filter with the given coefficients and number of channels.

This filter implements the standard difference equation:

 y[n] = b[0]*x[n]-a[1]*y[n-1]-a[2]*y[n-2]

where y is the output and x in the input.

Parameters
channelsThe number of channels
b0The upper zero-order coefficient
a1The lower first-order coefficient
a2The lower second-order coefficient

◆ TwoPoleIIR() [4/5]

cugl::dsp::TwoPoleIIR::TwoPoleIIR ( const TwoPoleIIR copy)

Creates a copy of the two-pole filter.

Parameters
copyThe filter to copy

◆ TwoPoleIIR() [5/5]

cugl::dsp::TwoPoleIIR::TwoPoleIIR ( TwoPoleIIR &&  filter)

Creates a two-pole filter with the resources of the original.

Parameters
filterThe filter to acquire

◆ ~TwoPoleIIR()

cugl::dsp::TwoPoleIIR::~TwoPoleIIR ( )

Destroys the filter, releasing all resources.

Member Function Documentation

◆ calculate()

void cugl::dsp::TwoPoleIIR::calculate ( float  gain,
float *  input,
float *  output,
size_t  size 
)

Performs a filter of interleaved input data.

The output is written to the given output array, which should be the same size as the input array. The size is the number of frames, not samples. Hence the arrays must be size times the number of channels in size.

To provide real time processing, the output is delayed by the number of a-coefficients. Delayed results are buffered to be used the next time the filter is used (though they may be extracted with the flush method). The gain parameter is applied at the filter input, but does not affect the filter coefficients.

Parameters
gainThe input gain factor
inputThe array of input samples
outputThe array to write the sample output
sizeThe input size in frames

◆ clear()

void cugl::dsp::TwoPoleIIR::clear ( )

Clears the filter buffer of any delayed outputs or cached inputs

◆ flush()

size_t cugl::dsp::TwoPoleIIR::flush ( float *  output)

Flushes any delayed outputs to the provided array

The array size should be twice the number of channels. This method will also clear the buffer.

Returns
The number of frames (not samples) written

◆ getACoeff()

const std::vector<float> cugl::dsp::TwoPoleIIR::getACoeff ( ) const

Returns the lower coefficients for this IIR filter.

This filter implements the standard difference equation:

a[0]*y[n] = b[0]*x[n]+...+b[nb]*x[n-nb]-a[1]*y[n-1]-...-a[na]*y[n-na]

where y is the output and x in the input.

Returns
The lower coefficients

◆ getBCoeff()

const std::vector<float> cugl::dsp::TwoPoleIIR::getBCoeff ( ) const

Returns the upper coefficients for this IIR filter.

This filter implements the standard difference equation:

a[0]*y[n] = b[0]*x[n]+...+b[nb]*x[n-nb]-a[1]*y[n-1]-...-a[na]*y[n-na]

where y is the output and x in the input.

Returns
The upper coefficients

◆ getChannels()

unsigned cugl::dsp::TwoPoleIIR::getChannels ( ) const
inline

Returns the number of channels for this filter

The data buffers depend on the number of channels. Changing this value will reset the data buffers to 0.

Returns
the number of channels for this filter

◆ getDenominator()

Polynomial cugl::dsp::TwoPoleIIR::getDenominator ( ) const

Returns the denominator polynomail for the filter transfer function.

Every digital filter is defined by by a z-domain transfer function. This function has the form

H(z) = p(z)/q(z)

where p(z) and q(z) are polynomials of z^-1. This function uniquely determines the coefficients of the digital filter. In particular, the the coefficients of p are the b-coefficients and the coefficients of q are the q-coefficients.

Returns
The denominator polynomail for the filter transfer function.

◆ getNumerator()

Polynomial cugl::dsp::TwoPoleIIR::getNumerator ( ) const

Returns the numerator polynomail for the filter transfer function.

Every digital filter is defined by by a z-domain transfer function. This function has the form

H(z) = p(z)/q(z)

where p(z) and q(z) are polynomials of z^-1. This function uniquely determines the coefficients of the digital filter. In particular, the the coefficients of p are the b-coefficients and the coefficients of q are the q-coefficients.

Returns
The numerator polynomail for the filter transfer function.

◆ setACoeff()

void cugl::dsp::TwoPoleIIR::setACoeff ( float  a1,
float  a2 
)

Sets the lower coefficients.

Parameters
a1The lower first-order coefficient
a2The lower second-order coefficient

◆ setBCoeff()

void cugl::dsp::TwoPoleIIR::setBCoeff ( float  b0)

Sets the upper zero-order coefficient.

Parameters
b0The upper zero-order coefficient

◆ setChannels()

void cugl::dsp::TwoPoleIIR::setChannels ( unsigned  channels)

Sets the number of channels for this filter

The data buffers depend on the number of channels. Changing this value will reset the data buffers to 0.

Parameters
channelsThe number of channels for this filter

◆ setCoeff()

void cugl::dsp::TwoPoleIIR::setCoeff ( const std::vector< float > &  bvals,
const std::vector< float > &  avals 
)

Sets the coefficients for this IIR filter.

This filter implements the standard difference equation:

a[0]*y[n] = b[0]*x[n]+...+b[nb]*x[n-nb]-a[1]*y[n-1]-...-a[na]*y[n-na]

where y is the output and x in the input. If a[0] is not equal to 1, the filter coeffcients are normalized by a[0].

All b-coefficients after the first, and all a-coefficients after the third are ignored. If any coefficients are missing, they are replaced with 1 for b[0] and a[0], and 0 otherwise.

Parameters
bvalsThe upper coefficients
avalsThe lower coefficients

◆ setPoles()

void cugl::dsp::TwoPoleIIR::setPoles ( float  pole1,
float  pole2 
)

Sets this filter to have the specified poles.

Parameters
pole1The first filter pole
pole2The second filter pole

◆ setResonance()

void cugl::dsp::TwoPoleIIR::setResonance ( float  frequency,
float  radius,
bool  normalize = false 
)

Sets the coefficients for a resonance at the (normalized) frequency.

A normalized frequency is defined as frequency/sample rate. For example, a 7 kHz frequency with a 44100 Hz sample rate has a normalized value of 7000/44100 = 0.15873.

This method determines the filter coefficients corresponding to two complex-conjugate poles with the given frequency and radius from the z-plane origin. If normalize is true, the coefficients are then normalized to produce unity gain at the frequency (the actual maximum filter gain tends to be slightly greater than unity when radius is not close to one).

The resulting filter frequency response has a resonance at the given frequency. The closer the poles are to the unit-circle (radius close to one), the narrower the resulting resonance width. An unstable filter will result for radius >= 1.0. The frequency value should be between zero and half the sample rate.

This filter is not intended to be a model class. Neither the frequency nor the radius is retained. Instead, this method computes the relative coefficients and forgets the frequence and radius values.

For a better resonance filter, {

See also
BiquadIIR}.
Parameters
frequencyThe (normalized) resonance frequency
radiusThe resonance radius
normalizeWhether to normalize the coefficients

◆ setTransfer()

void cugl::dsp::TwoPoleIIR::setTransfer ( const Polynomial p,
const Polynomial q 
)

Sets the transfer function for this IIR filter.

Every digital filter is defined by by a z-domain transfer function. This function has the form

H(z) = p(z)/q(z)

where p(z) and q(z) are polynomials of z^-1. This function uniquely determines the coefficients of the digital filter. In particular, the the coefficients of p are the b-coefficients and the coefficients of q are the q-coefficients.

We provide this setter method because filter chaining corresponds to multiplication in the transfer domain. Hence complex filter chains can be collapsed into a single filter for optimization.

Parameters
pThe numerator polynomial
qThe denominator polynomial

◆ step()

void cugl::dsp::TwoPoleIIR::step ( float  gain,
float *  input,
float *  output 
)

Performs a filter of single frame of data.

The output is written to the given output array, which should be the same size as the input array. The size should be the number of channels.

To provide real time processing, the output is delayed by the number of a-coefficients. Delayed results are buffered to be used the next time the filter is used (though they may be extracted with the flush method). The gain parameter is applied at the filter input, but does not affect the filter coefficients.

Parameters
gainThe input gain factor
inputThe input frame
outputThe frame to receive the output

Member Data Documentation

◆ VECTORIZE

bool cugl::dsp::TwoPoleIIR::VECTORIZE
static

Whether to use a vectorization algorithm (Access not thread safe)


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