Finite Impulse Reseponse Decimator (firdecim
)¶
The firdecim
object family implements a basic decimator with an
integer output-to-input resampling ratio \(D\).
For example, an input signal sampled at 96 MHz is decimated by a factor
\(D=25\) results in an output signal with a sample rate 3.84 MHz.
It is essentially just a firfilt
object which operates on a block
of samples at a time.
An example of the firdecimator can be seen in [fig-filter-firdecim-crcf].

Figure 1 firdecim_crcf
example with \(D=4\), compensating for filter delay.¶
Filter Delay¶
The delay of the decimator will depend upon the filter coefficients themselves. Normally, an FIR filter has symmetric coefficients and has a length \(2Mm+1\) in which case the output delay is \(Mm\) samples, where \(M\) is the decimation rate and \(m\) is the filter semi-length. But if the filter coefficients are _not_ symmetric or if the filter length follows a different length, the delay will be something different. Unfortunately the decimator cannot compensate for this automatically since it doesn’t know the filter response. The delay could even be a fraction of a sample.
If the filter does have a length \(2Mm+1\) then the output delay will be \(m\) samples; this is one of the reasons designing a filter of this length is convenient. If this is the case, you can then just ignore the first \(m\) output samples (e.g. after decimation), and then flush \(m\) blocks of \(M\) samples each through the filter to compensate for that delay.
Example¶
An example of the firdecim
interface is listed below.
#include <liquid/liquid.h>
int main() {
// options
unsigned int M = 4; // decimation factor
unsigned int h_len = 21; // filter length
// design filter and create decimator object
float h[h_len]; // filter coefficients
firdecim_crcf q = firdecim_crcf_create(M,h,h_len);
// generate input signal and decimate
float complex x[M]; // input samples
float complex y; // output sample
// run decimator (repeat as necessary)
{
firdecim_crcf_execute(q, x, &y);
}
// destroy decimator object
firdecim_crcf_destroy(q);
}
Interface¶
Listed below is the full interface to the firdecim
family of
objects.
create()
¶
Create decimator from external coefficients
firdecim_rrrf = firdecim_rrrf_create(unsigned int _M, float * _h, unsigned int _h_len);
unsigned int _M
: decimation factorfloat * _h
: filter coefficientsunsigned int _h_len
: filter lengthreturns new
firdecim_rrrf
object
firdecim_crcf = firdecim_crcf_create(unsigned int _M, float * _h, unsigned int _h_len);
unsigned int _M
: decimation factorfloat * _h
: filter coefficientsunsigned int _h_len
: filter lengthreturns new
firdecim_crcf
object
firdecim_cccf = firdecim_cccf_create(unsigned int _M, float complex * _h, unsigned int _h_len);
unsigned int _M
: decimation factorfloat complex * _h
: filter coefficientsunsigned int _h_len
: filter lengthreturns new
firdecim_cccf
object
create_kaiser()
¶
Create decimator from filter prototype prototype (Kaiser-Bessel windowed-sinc function)
firdecim_rrrf = firdecim_rrrf_create_kaiser(unsigned int _M, unsigned int _m, float _as);
unsigned int _M
: decimation factorunsigned int _m
: filter delayfloat _as
: stop-band attenuationreturns new
firdecim_rrrf
object
firdecim_crcf = firdecim_crcf_create_kaiser(unsigned int _M, unsigned int _m, float _as);
unsigned int _M
: decimation factorunsigned int _m
: filter delayfloat _as
: stop-band attenuationreturns new
firdecim_crcf
object
firdecim_cccf = firdecim_cccf_create_kaiser(unsigned int _M, unsigned int _m, float _as);
unsigned int _M
: decimation factorunsigned int _m
: filter delayfloat _as
: stop-band attenuationreturns new
firdecim_cccf
object
create_prototype()
¶
Create decimator object from filter prototype
firdecim_rrrf = firdecim_rrrf_create_prototype(int _type, unsigned int _M, unsigned int _m, float _beta, float _dt);
int _type
: filter type (e.g. LIQUID_FIRFILT_RCOS)unsigned int _M
: interpolation factorunsigned int _m
: filter delay (symbols)float _beta
: excess bandwidth factorfloat _dt
: fractional sample delayreturns new
firdecim_rrrf
object
firdecim_crcf = firdecim_crcf_create_prototype(int _type, unsigned int _M, unsigned int _m, float _beta, float _dt);
int _type
: filter type (e.g. LIQUID_FIRFILT_RCOS)unsigned int _M
: interpolation factorunsigned int _m
: filter delay (symbols)float _beta
: excess bandwidth factorfloat _dt
: fractional sample delayreturns new
firdecim_crcf
object
firdecim_cccf = firdecim_cccf_create_prototype(int _type, unsigned int _M, unsigned int _m, float _beta, float _dt);
int _type
: filter type (e.g. LIQUID_FIRFILT_RCOS)unsigned int _M
: interpolation factorunsigned int _m
: filter delay (symbols)float _beta
: excess bandwidth factorfloat _dt
: fractional sample delayreturns new
firdecim_cccf
object
copy()
¶
Copy object including all internal objects and state
firdecim_rrrf = firdecim_rrrf_copy(firdecim_rrrf _q);
firdecim_rrrf _q
:returns new
firdecim_rrrf
object
firdecim_crcf = firdecim_crcf_copy(firdecim_crcf _q);
firdecim_crcf _q
:returns new
firdecim_crcf
object
firdecim_cccf = firdecim_cccf_copy(firdecim_cccf _q);
firdecim_cccf _q
:returns new
firdecim_cccf
object
destroy()
¶
Destroy decimator object, freeing all internal memory
int = firdecim_rrrf_destroy(firdecim_rrrf _q);
firdecim_rrrf _q
:returns standard error code
int = firdecim_crcf_destroy(firdecim_crcf _q);
firdecim_crcf _q
:returns standard error code
int = firdecim_cccf_destroy(firdecim_cccf _q);
firdecim_cccf _q
:returns standard error code
print()
¶
Print decimator object properties to stdout
int = firdecim_rrrf_print(firdecim_rrrf _q);
firdecim_rrrf _q
:returns standard error code
int = firdecim_crcf_print(firdecim_crcf _q);
firdecim_crcf _q
:returns standard error code
int = firdecim_cccf_print(firdecim_cccf _q);
firdecim_cccf _q
:returns standard error code
reset()
¶
Reset decimator object internal state
int = firdecim_rrrf_reset(firdecim_rrrf _q);
firdecim_rrrf _q
:returns standard error code
int = firdecim_crcf_reset(firdecim_crcf _q);
firdecim_crcf _q
:returns standard error code
int = firdecim_cccf_reset(firdecim_cccf _q);
firdecim_cccf _q
:returns standard error code
get_decim_rate()
¶
Get decimation rate
unsigned int = firdecim_rrrf_get_decim_rate(firdecim_rrrf _q);
firdecim_rrrf _q
:returns something good
unsigned int = firdecim_crcf_get_decim_rate(firdecim_crcf _q);
firdecim_crcf _q
:returns something good
unsigned int = firdecim_cccf_get_decim_rate(firdecim_cccf _q);
firdecim_cccf _q
:returns something good
set_scale()
¶
Set output scaling for decimator
int = firdecim_rrrf_set_scale(firdecim_rrrf _q, float _scale);
firdecim_rrrf _q
: decimator objectfloat _scale
: scaling factor to apply to each output samplereturns standard error code
int = firdecim_crcf_set_scale(firdecim_crcf _q, float _scale);
firdecim_crcf _q
: decimator objectfloat _scale
: scaling factor to apply to each output samplereturns standard error code
int = firdecim_cccf_set_scale(firdecim_cccf _q, float complex _scale);
firdecim_cccf _q
: decimator objectfloat complex _scale
: scaling factor to apply to each output samplereturns standard error code
get_scale()
¶
Get output scaling for decimator
int = firdecim_rrrf_get_scale(firdecim_rrrf _q, float * _scale);
firdecim_rrrf _q
: decimator objectfloat * _scale
: scaling factor to apply to each output samplereturns standard error code
int = firdecim_crcf_get_scale(firdecim_crcf _q, float * _scale);
firdecim_crcf _q
: decimator objectfloat * _scale
: scaling factor to apply to each output samplereturns standard error code
int = firdecim_cccf_get_scale(firdecim_cccf _q, float complex * _scale);
firdecim_cccf _q
: decimator objectfloat complex * _scale
: scaling factor to apply to each output samplereturns standard error code
freqresp()
¶
Compute complex frequency response (H) of decimator on prototype filter coefficients at a specific frequency (f_c)
int = firdecim_rrrf_freqresp(firdecim_rrrf _q, float _fc, liquid_float_complex * _H);
firdecim_rrrf _q
: decimator objectfloat _fc
: normalized frequency for evaluationliquid_float_complex * _H
: pointer to output complex frequency responsereturns standard error code
int = firdecim_crcf_freqresp(firdecim_crcf _q, float _fc, liquid_float_complex * _H);
firdecim_crcf _q
: decimator objectfloat _fc
: normalized frequency for evaluationliquid_float_complex * _H
: pointer to output complex frequency responsereturns standard error code
int = firdecim_cccf_freqresp(firdecim_cccf _q, float _fc, liquid_float_complex * _H);
firdecim_cccf _q
: decimator objectfloat _fc
: normalized frequency for evaluationliquid_float_complex * _H
: pointer to output complex frequency responsereturns standard error code
execute()
¶
Execute decimator on _M input samples
int = firdecim_rrrf_execute(firdecim_rrrf _q, float * _x, float * _y);
firdecim_rrrf _q
: decimator objectfloat * _x
: input samplesfloat * _y
: output sample pointerreturns standard error code
int = firdecim_crcf_execute(firdecim_crcf _q, float complex * _x, float complex * _y);
firdecim_crcf _q
: decimator objectfloat complex * _x
: input samplesfloat complex * _y
: output sample pointerreturns standard error code
int = firdecim_cccf_execute(firdecim_cccf _q, float complex * _x, float complex * _y);
firdecim_cccf _q
: decimator objectfloat complex * _x
: input samplesfloat complex * _y
: output sample pointerreturns standard error code
execute_block()
¶
Execute decimator on block of _n*_M input samples
int = firdecim_rrrf_execute_block(firdecim_rrrf _q, float * _x, unsigned int _n, float * _y);
firdecim_rrrf _q
: decimator objectfloat * _x
: input arrayunsigned int _n
: number of _output_ samplesfloat * _y
: output array,returns standard error code
int = firdecim_crcf_execute_block(firdecim_crcf _q, float complex * _x, unsigned int _n, float complex * _y);
firdecim_crcf _q
: decimator objectfloat complex * _x
: input arrayunsigned int _n
: number of _output_ samplesfloat complex * _y
: output array,returns standard error code
int = firdecim_cccf_execute_block(firdecim_cccf _q, float complex * _x, unsigned int _n, float complex * _y);
firdecim_cccf _q
: decimator objectfloat complex * _x
: input arrayunsigned int _n
: number of _output_ samplesfloat complex * _y
: output array,returns standard error code