File fir_core.h¶
File List > doppler > fir > fir_core.h
Go to the documentation of this file
#ifndef DP_FIR_CORE_H
#define DP_FIR_CORE_H
#include "doppler/clib_common.h"
#include "doppler/dp_state.h"
#include "doppler/jm_perf.h"
#include "doppler/dp_complex.h"
#include <stddef.h>
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct
{
float _Complex *taps; /* complex taps (NULL for real-tap filter) */
float *rtaps; /* real taps (NULL for complex-tap filter) */
float _Complex *delay; /* delay line, length num_taps - 1 */
float _Complex *scratch; /* [delay | input] workspace, grown on demand */
size_t scratch_cap;
size_t num_taps;
} dp_fir_state_t;
JM_FORCEINLINE JM_HOT float _Complex
fir_step (dp_fir_state_t *s, float _Complex x)
{
size_t M = s->num_taps;
const float _Complex *d = s->delay; /* length M-1 (NULL when M == 1) */
const float *h = s->rtaps; /* real taps (dp_fir_create_real) */
float re = 0.0f, im = 0.0f;
for (size_t k = 0; k < M; k++)
{
float _Complex cf = (k == 0) ? x : d[M - 1 - k];
re += h[k] * crealf (cf);
im += h[k] * cimagf (cf);
}
if (M > 1)
{
float _Complex *dl = s->delay; /* shift left, append x as newest */
for (size_t i = 0; i + 2 < M; i++)
dl[i] = dl[i + 1];
dl[M - 2] = x;
}
return CMPLXF (re, im);
}
dp_fir_state_t *dp_fir_create (const float _Complex *taps, size_t taps_len);
dp_fir_state_t *dp_fir_create_real (const float *taps, size_t num_taps);
void dp_fir_reset (dp_fir_state_t *state);
/* Serializable state (standard bytes interface; see dp_state.h): the delay
* line (num_taps-1 samples) after the envelope; taps/scratch are config. */
#define FIR_STATE_MAGIC DP_FOURCC ('F', 'I', 'R', '_')
#define FIR_STATE_VERSION 1u
size_t dp_fir_state_bytes (const dp_fir_state_t *state);
void dp_fir_get_state (const dp_fir_state_t *state, void *blob);
int dp_fir_set_state (dp_fir_state_t *state, const void *blob);
void dp_fir_destroy (dp_fir_state_t *state);
size_t dp_fir_get_num_taps (const dp_fir_state_t *state);
int dp_fir_get_is_real (const dp_fir_state_t *state);
double dp_fir_dc_gain (const dp_fir_state_t *state);
size_t dp_fir_execute_max_out (dp_fir_state_t *state);
size_t dp_fir_execute (dp_fir_state_t *state, const float _Complex *in, size_t n_in,
float _Complex *out);
#ifdef __cplusplus
}
#endif
#endif /* FIR_CORE_H */