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_rrrf
object
firfilt_crcf = firfilt_crcf_create(float * _h, unsigned int _n);
float * _h
: filter coefficientsunsigned int _n
: number of filter coefficientsreturns new
firfilt_crcf
object
firfilt_cccf = firfilt_cccf_create(float complex * _h, unsigned int _n);
float complex * _h
: filter coefficientsunsigned int _n
: number of filter coefficientsreturns new
firfilt_cccf
object
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_rrrf
object
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_crcf
object
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_cccf
object
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_rrrf
object
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_crcf
object
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_cccf
object
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_rrrf
object
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_crcf
object
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_cccf
object
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_rrrf
object
firfilt_crcf = firfilt_crcf_create_rect(unsigned int _n);
unsigned int _n
: length of filterreturns new
firfilt_crcf
object
firfilt_cccf = firfilt_cccf_create_rect(unsigned int _n);
unsigned int _n
: length of filterreturns new
firfilt_cccf
object
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_rrrf
object
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_crcf
object
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_cccf
object
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_rrrf
object
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_crcf
object
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_cccf
object
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_rrrf
object
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_crcf
object
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_cccf
object
copy()
¶
Copy object including all internal objects and state
firfilt_rrrf = firfilt_rrrf_copy(firfilt_rrrf _q);
firfilt_rrrf _q
:returns new
firfilt_rrrf
object
firfilt_crcf = firfilt_crcf_copy(firfilt_crcf _q);
firfilt_crcf _q
:returns new
firfilt_crcf
object
firfilt_cccf = firfilt_cccf_copy(firfilt_cccf _q);
firfilt_cccf _q
:returns new
firfilt_cccf
object
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