Finite Impulse Response Filter (firfilt)¶
Finite impulse response (FIR) filters are implemented in liquid with
the firfilt family of objects.
Operation¶
FIR filters (also known as non-recursive filters) operate on discrete-time samples, computing the output \(y\) as the convolution of the input \(\vec{x}\) with the filter coefficients \(\vec{h}\) as
where \(\vec{h} = [h(0),h(1),\ldots,h(N-1)]\) is the filter impulse response. Notice that the output sample in the above equation is simply the vector dot product (see [dotprod](/doc/dotprod)) of the filter coefficients \(\vec{h}\) with the time-reversed sequence \(\vec{x}\).
Figure 2 firfilt_crcf (finite impulse response filter) demonstration¶
An example of the firfilt object can be seen in
Figure 2
in which a low-pass filter is applied to a signal to remove a
high-frequency component.
Examples¶
An example of the firfilt interface is provided in
the listing, below:
#include <liquid/liquid.h>
int main() {
// options
unsigned int h_len=21; // filter order
float h[h_len]; // filter coefficients
// ... initialize filter coefficients ...
// create filter object
firfilt_crcf q = firfilt_crcf_create(h,h_len);
float complex x; // input sample
float complex y; // output sample
// execute filter (repeat as necessary)
{
firfilt_crcf_push(q, x); // push input sample
firfilt_crcf_execute(q,&y); // compute output
}
// destroy filter object
firfilt_crcf_destroy(q);
}
Interface¶
Listed below is the full interface to the firfilt family of
objects.
create()¶
Create a finite impulse response filter (firfilt) object by directly specifying the filter coefficients in an array
firfilt_rrrf = firfilt_rrrf_create(float * _h, unsigned int _n);
float * _h: filter coefficientsunsigned int _n: number of filter coefficientsreturns new
firfilt_rrrfobject
firfilt_crcf = firfilt_crcf_create(float * _h, unsigned int _n);
float * _h: filter coefficientsunsigned int _n: number of filter coefficientsreturns new
firfilt_crcfobject
firfilt_cccf = firfilt_cccf_create(float complex * _h, unsigned int _n);
float complex * _h: filter coefficientsunsigned int _n: number of filter coefficientsreturns new
firfilt_cccfobject
create_kaiser()¶
Create object using Kaiser-Bessel windowed sinc method
firfilt_rrrf = firfilt_rrrf_create_kaiser(unsigned int _n, float _fc, float _as, float _mu);
unsigned int _n: filter lengthfloat _fc: filter normalized cut-off frequencyfloat _as: filter stop-band attenuationfloat _mu: fractional sample offsetreturns new
firfilt_rrrfobject
firfilt_crcf = firfilt_crcf_create_kaiser(unsigned int _n, float _fc, float _as, float _mu);
unsigned int _n: filter lengthfloat _fc: filter normalized cut-off frequencyfloat _as: filter stop-band attenuationfloat _mu: fractional sample offsetreturns new
firfilt_crcfobject
firfilt_cccf = firfilt_cccf_create_kaiser(unsigned int _n, float _fc, float _as, float _mu);
unsigned int _n: filter lengthfloat _fc: filter normalized cut-off frequencyfloat _as: filter stop-band attenuationfloat _mu: fractional sample offsetreturns new
firfilt_cccfobject
create_rnyquist()¶
Create object from square-root Nyquist prototype. The filter length will be (2 k m + 1 ) samples long with a delay of ( k m + 1 ) samples.
firfilt_rrrf = firfilt_rrrf_create_rnyquist(int _type, unsigned int _k, unsigned int _m, float _beta, float _mu);
int _type: filter type (e.g. LIQUID_FIRFILT_RRC)unsigned int _k: nominal samples per symbolunsigned int _m: filter delayfloat _beta: rolloff factor, 0 < beta <= 1float _mu: fractional sample offsetreturns new
firfilt_rrrfobject
firfilt_crcf = firfilt_crcf_create_rnyquist(int _type, unsigned int _k, unsigned int _m, float _beta, float _mu);
int _type: filter type (e.g. LIQUID_FIRFILT_RRC)unsigned int _k: nominal samples per symbolunsigned int _m: filter delayfloat _beta: rolloff factor, 0 < beta <= 1float _mu: fractional sample offsetreturns new
firfilt_crcfobject
firfilt_cccf = firfilt_cccf_create_rnyquist(int _type, unsigned int _k, unsigned int _m, float _beta, float _mu);
int _type: filter type (e.g. LIQUID_FIRFILT_RRC)unsigned int _k: nominal samples per symbolunsigned int _m: filter delayfloat _beta: rolloff factor, 0 < beta <= 1float _mu: fractional sample offsetreturns new
firfilt_cccfobject
create_firdespm()¶
Create object from Parks-McClellan algorithm prototype
firfilt_rrrf = firfilt_rrrf_create_firdespm(unsigned int _h_len, float _fc, float _as);
unsigned int _h_len: filter lengthfloat _fc: cutoff frequencyfloat _as: stop-band attenuationreturns new
firfilt_rrrfobject
firfilt_crcf = firfilt_crcf_create_firdespm(unsigned int _h_len, float _fc, float _as);
unsigned int _h_len: filter lengthfloat _fc: cutoff frequencyfloat _as: stop-band attenuationreturns new
firfilt_crcfobject
firfilt_cccf = firfilt_cccf_create_firdespm(unsigned int _h_len, float _fc, float _as);
unsigned int _h_len: filter lengthfloat _fc: cutoff frequencyfloat _as: stop-band attenuationreturns new
firfilt_cccfobject
create_rect()¶
Create rectangular filter prototype; that is ( vec{h} = { 1, 1, 1, ldots 1 } )
firfilt_rrrf = firfilt_rrrf_create_rect(unsigned int _n);
unsigned int _n: length of filterreturns new
firfilt_rrrfobject
firfilt_crcf = firfilt_crcf_create_rect(unsigned int _n);
unsigned int _n: length of filterreturns new
firfilt_crcfobject
firfilt_cccf = firfilt_cccf_create_rect(unsigned int _n);
unsigned int _n: length of filterreturns new
firfilt_cccfobject
create_dc_blocker()¶
Create DC blocking filter from prototype
firfilt_rrrf = firfilt_rrrf_create_dc_blocker(unsigned int _m, float _as);
unsigned int _m: prototype filter semi-length such that filter length is 2*m+1float _as: prototype filter stop-band attenuationreturns new
firfilt_rrrfobject
firfilt_crcf = firfilt_crcf_create_dc_blocker(unsigned int _m, float _as);
unsigned int _m: prototype filter semi-length such that filter length is 2*m+1float _as: prototype filter stop-band attenuationreturns new
firfilt_crcfobject
firfilt_cccf = firfilt_cccf_create_dc_blocker(unsigned int _m, float _as);
unsigned int _m: prototype filter semi-length such that filter length is 2*m+1float _as: prototype filter stop-band attenuationreturns new
firfilt_cccfobject
create_notch()¶
Create notch filter from prototype
firfilt_rrrf = firfilt_rrrf_create_notch(unsigned int _m, float _as, float _f0);
unsigned int _m: prototype filter semi-length such that filter length is 2*m+1float _as: prototype filter stop-band attenuationfloat _f0: center frequency for notch, _fc inreturns new
firfilt_rrrfobject
firfilt_crcf = firfilt_crcf_create_notch(unsigned int _m, float _as, float _f0);
unsigned int _m: prototype filter semi-length such that filter length is 2*m+1float _as: prototype filter stop-band attenuationfloat _f0: center frequency for notch, _fc inreturns new
firfilt_crcfobject
firfilt_cccf = firfilt_cccf_create_notch(unsigned int _m, float _as, float _f0);
unsigned int _m: prototype filter semi-length such that filter length is 2*m+1float _as: prototype filter stop-band attenuationfloat _f0: center frequency for notch, _fc inreturns new
firfilt_cccfobject
recreate()¶
Re-create filter object of potentially a different length with different coefficients. If the length of the filter does not change, not memory reallocation is invoked.
firfilt_rrrf = firfilt_rrrf_recreate(firfilt_rrrf _q, float * _h, unsigned int _n);
firfilt_rrrf _q: original filter objectfloat * _h: pointer to filter coefficientsunsigned int _n: filter lengthreturns new
firfilt_rrrfobject
firfilt_crcf = firfilt_crcf_recreate(firfilt_crcf _q, float * _h, unsigned int _n);
firfilt_crcf _q: original filter objectfloat * _h: pointer to filter coefficientsunsigned int _n: filter lengthreturns new
firfilt_crcfobject
firfilt_cccf = firfilt_cccf_recreate(firfilt_cccf _q, float complex * _h, unsigned int _n);
firfilt_cccf _q: original filter objectfloat complex * _h: pointer to filter coefficientsunsigned int _n: filter lengthreturns new
firfilt_cccfobject
copy()¶
Copy object including all internal objects and state
firfilt_rrrf = firfilt_rrrf_copy(firfilt_rrrf _q);
firfilt_rrrf _q:returns new
firfilt_rrrfobject
firfilt_crcf = firfilt_crcf_copy(firfilt_crcf _q);
firfilt_crcf _q:returns new
firfilt_crcfobject
firfilt_cccf = firfilt_cccf_copy(firfilt_cccf _q);
firfilt_cccf _q:returns new
firfilt_cccfobject
destroy()¶
Destroy filter object and free all internal memory
int = firfilt_rrrf_destroy(firfilt_rrrf _q);
firfilt_rrrf _q:returns standard error code
int = firfilt_crcf_destroy(firfilt_crcf _q);
firfilt_crcf _q:returns standard error code
int = firfilt_cccf_destroy(firfilt_cccf _q);
firfilt_cccf _q:returns standard error code
reset()¶
Reset filter object’s internal buffer
int = firfilt_rrrf_reset(firfilt_rrrf _q);
firfilt_rrrf _q:returns standard error code
int = firfilt_crcf_reset(firfilt_crcf _q);
firfilt_crcf _q:returns standard error code
int = firfilt_cccf_reset(firfilt_cccf _q);
firfilt_cccf _q:returns standard error code
print()¶
Print filter object information to stdout
int = firfilt_rrrf_print(firfilt_rrrf _q);
firfilt_rrrf _q:returns standard error code
int = firfilt_crcf_print(firfilt_crcf _q);
firfilt_crcf _q:returns standard error code
int = firfilt_cccf_print(firfilt_cccf _q);
firfilt_cccf _q:returns standard error code
set_scale()¶
Set output scaling for filter
int = firfilt_rrrf_set_scale(firfilt_rrrf _q, float _scale);
firfilt_rrrf _q: filter objectfloat _scale: scaling factor to apply to each output samplereturns standard error code
int = firfilt_crcf_set_scale(firfilt_crcf _q, float _scale);
firfilt_crcf _q: filter objectfloat _scale: scaling factor to apply to each output samplereturns standard error code
int = firfilt_cccf_set_scale(firfilt_cccf _q, float complex _scale);
firfilt_cccf _q: filter objectfloat complex _scale: scaling factor to apply to each output samplereturns standard error code
get_scale()¶
Get output scaling for filter
int = firfilt_rrrf_get_scale(firfilt_rrrf _q, float * _scale);
firfilt_rrrf _q: filter objectfloat * _scale: scaling factor applied to each output samplereturns standard error code
int = firfilt_crcf_get_scale(firfilt_crcf _q, float * _scale);
firfilt_crcf _q: filter objectfloat * _scale: scaling factor applied to each output samplereturns standard error code
int = firfilt_cccf_get_scale(firfilt_cccf _q, float complex * _scale);
firfilt_cccf _q: filter objectfloat complex * _scale: scaling factor applied to each output samplereturns standard error code
push()¶
Push sample into filter object’s internal buffer
int = firfilt_rrrf_push(firfilt_rrrf _q, float _x);
firfilt_rrrf _q: filter objectfloat _x: single input samplereturns standard error code
int = firfilt_crcf_push(firfilt_crcf _q, float complex _x);
firfilt_crcf _q: filter objectfloat complex _x: single input samplereturns standard error code
int = firfilt_cccf_push(firfilt_cccf _q, float complex _x);
firfilt_cccf _q: filter objectfloat complex _x: single input samplereturns standard error code
write()¶
Write block of samples into filter object’s internal buffer
int = firfilt_rrrf_write(firfilt_rrrf _q, float * _x, unsigned int _n);
firfilt_rrrf _q: filter objectfloat * _x: buffer of input samplesunsigned int _n: number of input samplesreturns standard error code
int = firfilt_crcf_write(firfilt_crcf _q, float complex * _x, unsigned int _n);
firfilt_crcf _q: filter objectfloat complex * _x: buffer of input samplesunsigned int _n: number of input samplesreturns standard error code
int = firfilt_cccf_write(firfilt_cccf _q, float complex * _x, unsigned int _n);
firfilt_cccf _q: filter objectfloat complex * _x: buffer of input samplesunsigned int _n: number of input samplesreturns standard error code
execute()¶
Execute vector dot product on the filter’s internal buffer and coefficients
int = firfilt_rrrf_execute(firfilt_rrrf _q, float * _y);
firfilt_rrrf _q: filter objectfloat * _y: pointer to single output samplereturns standard error code
int = firfilt_crcf_execute(firfilt_crcf _q, float complex * _y);
firfilt_crcf _q: filter objectfloat complex * _y: pointer to single output samplereturns standard error code
int = firfilt_cccf_execute(firfilt_cccf _q, float complex * _y);
firfilt_cccf _q: filter objectfloat complex * _y: pointer to single output samplereturns standard error code
execute_one()¶
Execute filter on one sample, equivalent to push() and execute()
int = firfilt_rrrf_execute_one(firfilt_rrrf _q, float _x, float * _y);
firfilt_rrrf _q: filter objectfloat _x: single input samplefloat * _y: pointer to single output samplereturns standard error code
int = firfilt_crcf_execute_one(firfilt_crcf _q, float complex _x, float complex * _y);
firfilt_crcf _q: filter objectfloat complex _x: single input samplefloat complex * _y: pointer to single output samplereturns standard error code
int = firfilt_cccf_execute_one(firfilt_cccf _q, float complex _x, float complex * _y);
firfilt_cccf _q: filter objectfloat complex _x: single input samplefloat complex * _y: pointer to single output samplereturns standard error code
execute_block()¶
Execute the filter on a block of input samples; in-place operation is permitted (_x and _y may point to the same place in memory)
int = firfilt_rrrf_execute_block(firfilt_rrrf _q, float * _x, unsigned int _n, float * _y);
firfilt_rrrf _q: filter objectfloat * _x: pointer to input arrayunsigned int _n: number of input, output samplesfloat * _y: pointer to output arrayreturns standard error code
int = firfilt_crcf_execute_block(firfilt_crcf _q, float complex * _x, unsigned int _n, float complex * _y);
firfilt_crcf _q: filter objectfloat complex * _x: pointer to input arrayunsigned int _n: number of input, output samplesfloat complex * _y: pointer to output arrayreturns standard error code
int = firfilt_cccf_execute_block(firfilt_cccf _q, float complex * _x, unsigned int _n, float complex * _y);
firfilt_cccf _q: filter objectfloat complex * _x: pointer to input arrayunsigned int _n: number of input, output samplesfloat complex * _y: pointer to output arrayreturns standard error code
get_length()¶
Get length of filter object (number of internal coefficients)
unsigned int = firfilt_rrrf_get_length(firfilt_rrrf _q);
firfilt_rrrf _q:returns something good
unsigned int = firfilt_crcf_get_length(firfilt_crcf _q);
firfilt_crcf _q:returns something good
unsigned int = firfilt_cccf_get_length(firfilt_cccf _q);
firfilt_cccf _q:returns something good
get_coefficients()¶
Get pointer to coefficients array
const float * = firfilt_rrrf_get_coefficients(firfilt_rrrf _q);
firfilt_rrrf _q:returns something good
const float * = firfilt_crcf_get_coefficients(firfilt_crcf _q);
firfilt_crcf _q:returns something good
const float complex * = firfilt_cccf_get_coefficients(firfilt_cccf _q);
firfilt_cccf _q:returns something good
copy_coefficients()¶
Copy internal coefficients to external buffer
int = firfilt_rrrf_copy_coefficients(firfilt_rrrf _q, float * _h);
firfilt_rrrf _q: filter objectfloat * _h: pointer to output coefficients arrayreturns standard error code
int = firfilt_crcf_copy_coefficients(firfilt_crcf _q, float * _h);
firfilt_crcf _q: filter objectfloat * _h: pointer to output coefficients arrayreturns standard error code
int = firfilt_cccf_copy_coefficients(firfilt_cccf _q, float complex * _h);
firfilt_cccf _q: filter objectfloat complex * _h: pointer to output coefficients arrayreturns standard error code
freqresponse()¶
Compute complex frequency response of filter object
int = firfilt_rrrf_freqresponse(firfilt_rrrf _q, float _fc, liquid_float_complex * _H);
firfilt_rrrf _q: filter objectfloat _fc: normalized frequency for evaluationliquid_float_complex * _H: pointer to output complex frequency responsereturns standard error code
int = firfilt_crcf_freqresponse(firfilt_crcf _q, float _fc, liquid_float_complex * _H);
firfilt_crcf _q: filter objectfloat _fc: normalized frequency for evaluationliquid_float_complex * _H: pointer to output complex frequency responsereturns standard error code
int = firfilt_cccf_freqresponse(firfilt_cccf _q, float _fc, liquid_float_complex * _H);
firfilt_cccf _q: filter objectfloat _fc: normalized frequency for evaluationliquid_float_complex * _H: pointer to output complex frequency responsereturns standard error code
groupdelay()¶
Compute and return group delay of filter object
float = firfilt_rrrf_groupdelay(firfilt_rrrf _q, float _fc);
firfilt_rrrf _q: filter objectfloat _fc: frequency to evaluatereturns something good
float = firfilt_crcf_groupdelay(firfilt_crcf _q, float _fc);
firfilt_crcf _q: filter objectfloat _fc: frequency to evaluatereturns something good
float = firfilt_cccf_groupdelay(firfilt_cccf _q, float _fc);
firfilt_cccf _q: filter objectfloat _fc: frequency to evaluatereturns something good