Finite Impulse Reseponse Interpolator (firinterp)

The interp object implements a basic interpolator with an integer output-to-input resampling ratio.

Operation

Interpolation in liquid-dsp is accomplished with a polyphase filter-bank channelizer.

An example of the interp interface is listed below.

#include <liquid/liquid.h>

int main() {
    unsigned int M=4;       // interpolation factor
    unsigned int h_len;     // interpolation filter length

    // design filter and create interpolator
    float h[h_len];         // filter coefficients
    firinterp_crcf q = firinterp_crcf_create(M,h,h_len);

    // generate input signal and interpolate
    float complex x;        // input sample
    float complex y[M];     // output samples

    // run interpolator (repeat as necessary)
    {
        firinterp_crcf_execute(q, x, y);
    }

    // destroy the interpolator object
    firinterp_crcf_destroy(q);
}

Examples

Listed below is the full interface to the interp family of objects. While each method is listed for firinterp_crcf, the same functionality applies to interp_rrrf and interp_cccf.

../_images/firinterp-0.png

Figure 4 firinterp_crcf (interpolator) example with \(M=4\), compensating for filter delay.

A graphical example of the interpolator can be seen in Figure 4. A detailed example program is given in examples/firinterp_crcf_example.c, located under the main liquid-dsp project directory.

Interface

Listed below is the full interface to the firinterp family of objects.

create()

Create interpolator from external coefficients. Internally the interpolator creates a polyphase filter bank to efficiently realize resampling of the input signal. If the input filter length is not a multiple of the interpolation factor (M), the object internally pads the coefficients with zeros to compensate.

firinterp_rrrf = firinterp_rrrf_create(unsigned int _interp, float * _h, unsigned int _h_len);
  • unsigned int _interp: interpolation factor (M)

  • float * _h: filter coefficients

  • unsigned int _h_len: filter length

  • returns new firinterp_rrrf object

firinterp_crcf = firinterp_crcf_create(unsigned int _interp, float * _h, unsigned int _h_len);
  • unsigned int _interp: interpolation factor (M)

  • float * _h: filter coefficients

  • unsigned int _h_len: filter length

  • returns new firinterp_crcf object

firinterp_cccf = firinterp_cccf_create(unsigned int _interp, float complex * _h, unsigned int _h_len);
  • unsigned int _interp: interpolation factor (M)

  • float complex * _h: filter coefficients

  • unsigned int _h_len: filter length

  • returns new firinterp_cccf object

create_kaiser()

Create interpolator from filter prototype prototype (Kaiser-Bessel windowed-sinc function)

firinterp_rrrf = firinterp_rrrf_create_kaiser(unsigned int _interp, unsigned int _m, float _as);
  • unsigned int _interp: interpolation factor (M)

  • unsigned int _m: filter delay

  • float _as: stop-band attenuation

  • returns new firinterp_rrrf object

firinterp_crcf = firinterp_crcf_create_kaiser(unsigned int _interp, unsigned int _m, float _as);
  • unsigned int _interp: interpolation factor (M)

  • unsigned int _m: filter delay

  • float _as: stop-band attenuation

  • returns new firinterp_crcf object

firinterp_cccf = firinterp_cccf_create_kaiser(unsigned int _interp, unsigned int _m, float _as);
  • unsigned int _interp: interpolation factor (M)

  • unsigned int _m: filter delay

  • float _as: stop-band attenuation

  • returns new firinterp_cccf object

create_prototype()

Create interpolator object from filter prototype

firinterp_rrrf = firinterp_rrrf_create_prototype(int _type, unsigned int _interp, unsigned int _m, float _beta, float _dt);
  • int _type: filter type (e.g. LIQUID_FIRFILT_RCOS)

  • unsigned int _interp: interpolation factor (M)

  • unsigned int _m: filter delay (symbols)

  • float _beta: excess bandwidth factor

  • float _dt: fractional sample delay

  • returns new firinterp_rrrf object

firinterp_crcf = firinterp_crcf_create_prototype(int _type, unsigned int _interp, unsigned int _m, float _beta, float _dt);
  • int _type: filter type (e.g. LIQUID_FIRFILT_RCOS)

  • unsigned int _interp: interpolation factor (M)

  • unsigned int _m: filter delay (symbols)

  • float _beta: excess bandwidth factor

  • float _dt: fractional sample delay

  • returns new firinterp_crcf object

firinterp_cccf = firinterp_cccf_create_prototype(int _type, unsigned int _interp, unsigned int _m, float _beta, float _dt);
  • int _type: filter type (e.g. LIQUID_FIRFILT_RCOS)

  • unsigned int _interp: interpolation factor (M)

  • unsigned int _m: filter delay (symbols)

  • float _beta: excess bandwidth factor

  • float _dt: fractional sample delay

  • returns new firinterp_cccf object

create_linear()

Create linear interpolator object

firinterp_rrrf = firinterp_rrrf_create_linear(unsigned int _interp);
  • unsigned int _interp: interpolation factor (M)

  • returns new firinterp_rrrf object

firinterp_crcf = firinterp_crcf_create_linear(unsigned int _interp);
  • unsigned int _interp: interpolation factor (M)

  • returns new firinterp_crcf object

firinterp_cccf = firinterp_cccf_create_linear(unsigned int _interp);
  • unsigned int _interp: interpolation factor (M)

  • returns new firinterp_cccf object

create_window()

Create window interpolator object

firinterp_rrrf = firinterp_rrrf_create_window(unsigned int _interp, unsigned int _m);
  • unsigned int _interp: interpolation factor (M)

  • unsigned int _m: filter semi-length

  • returns new firinterp_rrrf object

firinterp_crcf = firinterp_crcf_create_window(unsigned int _interp, unsigned int _m);
  • unsigned int _interp: interpolation factor (M)

  • unsigned int _m: filter semi-length

  • returns new firinterp_crcf object

firinterp_cccf = firinterp_cccf_create_window(unsigned int _interp, unsigned int _m);
  • unsigned int _interp: interpolation factor (M)

  • unsigned int _m: filter semi-length

  • returns new firinterp_cccf object

copy()

Copy object including all internal objects and state

firinterp_rrrf = firinterp_rrrf_copy(firinterp_rrrf _q);
  • firinterp_rrrf _q:

  • returns new firinterp_rrrf object

firinterp_crcf = firinterp_crcf_copy(firinterp_crcf _q);
  • firinterp_crcf _q:

  • returns new firinterp_crcf object

firinterp_cccf = firinterp_cccf_copy(firinterp_cccf _q);
  • firinterp_cccf _q:

  • returns new firinterp_cccf object

destroy()

Destroy firinterp object, freeing all internal memory

int = firinterp_rrrf_destroy(firinterp_rrrf _q);
  • firinterp_rrrf _q:

  • returns standard error code

int = firinterp_crcf_destroy(firinterp_crcf _q);
  • firinterp_crcf _q:

  • returns standard error code

int = firinterp_cccf_destroy(firinterp_cccf _q);
  • firinterp_cccf _q:

  • returns standard error code

print()

Print firinterp object’s internal properties to stdout

int = firinterp_rrrf_print(firinterp_rrrf _q);
  • firinterp_rrrf _q:

  • returns standard error code

int = firinterp_crcf_print(firinterp_crcf _q);
  • firinterp_crcf _q:

  • returns standard error code

int = firinterp_cccf_print(firinterp_cccf _q);
  • firinterp_cccf _q:

  • returns standard error code

reset()

Reset internal state

int = firinterp_rrrf_reset(firinterp_rrrf _q);
  • firinterp_rrrf _q:

  • returns standard error code

int = firinterp_crcf_reset(firinterp_crcf _q);
  • firinterp_crcf _q:

  • returns standard error code

int = firinterp_cccf_reset(firinterp_cccf _q);
  • firinterp_cccf _q:

  • returns standard error code

get_interp_rate()

Get interpolation rate

unsigned int = firinterp_rrrf_get_interp_rate(firinterp_rrrf _q);
  • firinterp_rrrf _q:

  • returns something good

unsigned int = firinterp_crcf_get_interp_rate(firinterp_crcf _q);
  • firinterp_crcf _q:

  • returns something good

unsigned int = firinterp_cccf_get_interp_rate(firinterp_cccf _q);
  • firinterp_cccf _q:

  • returns something good

get_sub_len()

Get sub-filter length (length of each poly-phase filter)

unsigned int = firinterp_rrrf_get_sub_len(firinterp_rrrf _q);
  • firinterp_rrrf _q:

  • returns something good

unsigned int = firinterp_crcf_get_sub_len(firinterp_crcf _q);
  • firinterp_crcf _q:

  • returns something good

unsigned int = firinterp_cccf_get_sub_len(firinterp_cccf _q);
  • firinterp_cccf _q:

  • returns something good

set_scale()

Set output scaling for interpolator

int = firinterp_rrrf_set_scale(firinterp_rrrf _q, float _scale);
  • firinterp_rrrf _q: interpolator object

  • float _scale: scaling factor to apply to each output sample

  • returns standard error code

int = firinterp_crcf_set_scale(firinterp_crcf _q, float _scale);
  • firinterp_crcf _q: interpolator object

  • float _scale: scaling factor to apply to each output sample

  • returns standard error code

int = firinterp_cccf_set_scale(firinterp_cccf _q, float complex _scale);
  • firinterp_cccf _q: interpolator object

  • float complex _scale: scaling factor to apply to each output sample

  • returns standard error code

get_scale()

Get output scaling for interpolator

int = firinterp_rrrf_get_scale(firinterp_rrrf _q, float * _scale);
  • firinterp_rrrf _q: interpolator object

  • float * _scale: scaling factor to apply to each output sample

  • returns standard error code

int = firinterp_crcf_get_scale(firinterp_crcf _q, float * _scale);
  • firinterp_crcf _q: interpolator object

  • float * _scale: scaling factor to apply to each output sample

  • returns standard error code

int = firinterp_cccf_get_scale(firinterp_cccf _q, float complex * _scale);
  • firinterp_cccf _q: interpolator object

  • float complex * _scale: scaling factor to apply to each output sample

  • returns standard error code

execute()

Execute interpolation on single input sample and write (M) output samples ((M) is the interpolation factor)

int = firinterp_rrrf_execute(firinterp_rrrf _q, float _x, float * _y);
  • firinterp_rrrf _q: firinterp object

  • float _x: input sample

  • float * _y: output sample array

  • returns standard error code

int = firinterp_crcf_execute(firinterp_crcf _q, float complex _x, float complex * _y);
  • firinterp_crcf _q: firinterp object

  • float complex _x: input sample

  • float complex * _y: output sample array

  • returns standard error code

int = firinterp_cccf_execute(firinterp_cccf _q, float complex _x, float complex * _y);
  • firinterp_cccf _q: firinterp object

  • float complex _x: input sample

  • float complex * _y: output sample array

  • returns standard error code

execute_block()

Execute interpolation on block of input samples, increasing the sample rate of the input by the interpolation factor (M).

int = firinterp_rrrf_execute_block(firinterp_rrrf _q, float * _x, unsigned int _n, float * _y);
  • firinterp_rrrf _q: firinterp object

  • float * _x: input array

  • unsigned int _n: size of input array

  • float * _y: output sample array

  • returns standard error code

int = firinterp_crcf_execute_block(firinterp_crcf _q, float complex * _x, unsigned int _n, float complex * _y);
  • firinterp_crcf _q: firinterp object

  • float complex * _x: input array

  • unsigned int _n: size of input array

  • float complex * _y: output sample array

  • returns standard error code

int = firinterp_cccf_execute_block(firinterp_cccf _q, float complex * _x, unsigned int _n, float complex * _y);
  • firinterp_cccf _q: firinterp object

  • float complex * _x: input array

  • unsigned int _n: size of input array

  • float complex * _y: output sample array

  • returns standard error code

flush()

Execute interpolation with zero-valued input (e.g. flush internal state)

int = firinterp_rrrf_flush(firinterp_rrrf _q, float * _y);
  • firinterp_rrrf _q: firinterp object

  • float * _y: output sample array

  • returns standard error code

int = firinterp_crcf_flush(firinterp_crcf _q, float complex * _y);
  • firinterp_crcf _q: firinterp object

  • float complex * _y: output sample array

  • returns standard error code

int = firinterp_cccf_flush(firinterp_cccf _q, float complex * _y);
  • firinterp_cccf _q: firinterp object

  • float complex * _y: output sample array

  • returns standard error code