Skip to content

File fir_core.h

FileList > fir > fir_core.h

Go to the source code of this file

Direct-form FIR filter — real-tap and complex-tap variants. More...

  • #include "clib_common.h"
  • #include <stdint.h>

Public Types

Type Name
typedef struct fir_state fir_state_t
Opaque FIR filter state.

Public Functions

Type Name
fir_state_t * fir_create (const float _Complex * taps, size_t num_taps)
Create a FIR filter from complex CF32 tap coefficients.
fir_state_t * fir_create_real (const float * taps, size_t num_taps)
Create a FIR filter from real float tap coefficients.
void fir_destroy (fir_state_t * f)
Destroy the filter and release all associated memory.
int fir_execute_cf32 (fir_state_t * f, const float _Complex * in, float _Complex * out, size_t num_samples)
Filter CF32 samples through a complex-tap filter.
int fir_execute_ci16 (fir_state_t * f, const int16_t * in, float _Complex * out, size_t num_samples)
Filter CI16 (interleaved int16_t I/Q, len=2×n) → CF32.
int fir_execute_ci32 (fir_state_t * f, const int32_t * in, float _Complex * out, size_t num_samples)
Filter CI32 (interleaved int32_t I/Q, len=2×n) → CF32.
int fir_execute_ci8 (fir_state_t * f, const int8_t * in, float _Complex * out, size_t num_samples)
Filter CI8 (interleaved int8_t I/Q, len=2×n) → CF32.
int fir_execute_real_cf32 (fir_state_t * f, const float _Complex * in, float _Complex * out, size_t num_samples)
Filter CF32 → CF32 through a real-tap filter. In-place safe.
int fir_execute_real_ci16 (fir_state_t * f, const int16_t * in, float _Complex * out, size_t num_samples)
Filter CI16 → CF32 through a real-tap filter.
int fir_execute_real_ci32 (fir_state_t * f, const int32_t * in, float _Complex * out, size_t num_samples)
Filter CI32 → CF32 through a real-tap filter.
int fir_execute_real_ci8 (fir_state_t * f, const int8_t * in, float _Complex * out, size_t num_samples)
Filter CI8 → CF32 through a real-tap filter.
int fir_is_real (const fir_state_t * f)
1 if filter was created with real taps, 0 if complex.
size_t fir_num_taps (const fir_state_t * f)
Number of tap coefficients.
void fir_reset (fir_state_t * f)
Zero the delay line without freeing the filter.

Detailed Description

Two constructors select the C backend at creation time:

fir_create() — complex CF32 taps (general case) fir_create_real() — real float taps (DDC/DUC common case; 1 FMA/tap)

All execute functions accept CF32, CI8, CI16, or CI32 input and write CF32 output. Integer inputs are upcasted to CF32 inside the hot loop. The internal scratch buffer [delay | input] is allocated lazily on the first execute call and reused on all subsequent calls.

Return value convention: 0 = success, -1 = allocation failure.

// DDC low-pass — real taps, CI16 input (LimeSDR / USRP)
float taps[63] = { ... };        // designed with scipy.signal.firwin
fir_state_t *fir = fir_create_real(taps, 63);

int16_t raw[2 * 4096];           // 2 int16_t per complex sample
float _Complex out[4096];
fir_execute_real_ci16(fir, raw, out, 4096);

// Complex taps (Hilbert transformer, frequency-shifted filter)
float _Complex ctaps[63] = { ... };
fir_state_t *cfir = fir_create(ctaps, 63);
fir_execute_cf32(cfir, out, out, 4096);  // in-place OK

fir_destroy(fir);
fir_destroy(cfir);

Public Types Documentation

typedef fir_state_t

Opaque FIR filter state.

typedef struct fir_state fir_state_t;


Public Functions Documentation

function fir_create

Create a FIR filter from complex CF32 tap coefficients.

fir_state_t * fir_create (
    const float _Complex * taps,
    size_t num_taps
) 

Allocates an internal delay line of num_taps − 1 complex samples, initialised to zero. The scratch buffer is allocated lazily on the first execute call.

Parameters:

  • taps Pointer to num_taps complex tap coefficients.
  • num_taps Filter length (≥ 1).

Returns:

Heap-allocated state, or NULL on failure.


function fir_create_real

Create a FIR filter from real float tap coefficients.

fir_state_t * fir_create_real (
    const float * taps,
    size_t num_taps
) 

Real taps cost 1 FMA per tap instead of 2 FMA + permute + mul, halving the multiply count for filters designed in the real domain (e.g. scipy.signal.firwin). Use fir_execute_real_*() to run the filter; fir_reset() and fir_destroy() work identically for both real-tap and complex-tap filters.

Parameters:

  • taps Pointer to num_taps real-valued tap coefficients.
  • num_taps Filter length (≥ 1).

Returns:

Heap-allocated state, or NULL on failure.


function fir_destroy

Destroy the filter and release all associated memory.

void fir_destroy (
    fir_state_t * f
) 

Parameters:

  • f Filter state (may be NULL — safe no-op).

function fir_execute_cf32

Filter CF32 samples through a complex-tap filter.

int fir_execute_cf32 (
    fir_state_t * f,
    const float _Complex * in,
    float _Complex * out,
    size_t num_samples
) 

Dispatches to AVX-512F+DQ (8 outputs/iter, 2 FMA + permute + mul per tap) or scalar fallback at compile time. In-place (out == in) is safe.

Parameters:

  • f Complex-tap filter (from fir_create).
  • in Input array of num_samples float _Complex.
  • out Output array (may alias in).
  • num_samples Number of complex samples to filter.

Returns:

0 on success, -1 on allocation failure.


function fir_execute_ci16

Filter CI16 (interleaved int16_t I/Q, len=2×n) → CF32.

int fir_execute_ci16 (
    fir_state_t * f,
    const int16_t * in,
    float _Complex * out,
    size_t num_samples
) 


function fir_execute_ci32

Filter CI32 (interleaved int32_t I/Q, len=2×n) → CF32.

int fir_execute_ci32 (
    fir_state_t * f,
    const int32_t * in,
    float _Complex * out,
    size_t num_samples
) 


function fir_execute_ci8

Filter CI8 (interleaved int8_t I/Q, len=2×n) → CF32.

int fir_execute_ci8 (
    fir_state_t * f,
    const int8_t * in,
    float _Complex * out,
    size_t num_samples
) 


function fir_execute_real_cf32

Filter CF32 → CF32 through a real-tap filter. In-place safe.

int fir_execute_real_cf32 (
    fir_state_t * f,
    const float _Complex * in,
    float _Complex * out,
    size_t num_samples
) 


function fir_execute_real_ci16

Filter CI16 → CF32 through a real-tap filter.

int fir_execute_real_ci16 (
    fir_state_t * f,
    const int16_t * in,
    float _Complex * out,
    size_t num_samples
) 


function fir_execute_real_ci32

Filter CI32 → CF32 through a real-tap filter.

int fir_execute_real_ci32 (
    fir_state_t * f,
    const int32_t * in,
    float _Complex * out,
    size_t num_samples
) 


function fir_execute_real_ci8

Filter CI8 → CF32 through a real-tap filter.

int fir_execute_real_ci8 (
    fir_state_t * f,
    const int8_t * in,
    float _Complex * out,
    size_t num_samples
) 


function fir_is_real

1 if filter was created with real taps, 0 if complex.

int fir_is_real (
    const fir_state_t * f
) 


function fir_num_taps

Number of tap coefficients.

size_t fir_num_taps (
    const fir_state_t * f
) 


function fir_reset

Zero the delay line without freeing the filter.

void fir_reset (
    fir_state_t * f
) 

Use after a stream discontinuity to prevent history contamination. Tap coefficients and scratch capacity are preserved.

Parameters:

  • f Filter state (must be non-NULL).


The documentation for this class was generated from the following file native/inc/fir/fir_core.h