#ifndef __FILTER_H__
#define __FILTER_H__
/* Macro Declaration ---------------------------------------------------------------------------- */
#define FILTER_COEF_MAX_LENGTH              71
#define FILTER_FIR_COEF_MAX_LENGTH          71

/* Structure Declaration ------------------------------------------------------------------------ */
typedef struct FILTER {                     // iir or fir filter
    int    reset;                           // reset flag
    int    order;                           // coefficient array length, not filter order
    double H0;                              // dc signal gain
    double b[FILTER_COEF_MAX_LENGTH];       // b coefficient
    double a[FILTER_COEF_MAX_LENGTH];       // a coefficient
    double yout[FILTER_COEF_MAX_LENGTH];    // yout buffer
    double xin[FILTER_COEF_MAX_LENGTH];     // xin buffer
} FILTER;

typedef struct FILTER_FIR {                 // fir filter
    int    reset;                           // reset flag
    int    order;                           // coefficient array length, not filter order
    double H0;                              // dc signal gain
    double b[FILTER_FIR_COEF_MAX_LENGTH];   // b coefficient
    double xin[FILTER_FIR_COEF_MAX_LENGTH]; // xin buffer
} FILTER_FIR;

typedef struct DELAYER {                    // delayer
    int    reset;
    int    delay;                           // delay point number
    double xin[FILTER_FIR_COEF_MAX_LENGTH]; // xin buffer
} DELAYER;

/* Function Declaration ------------------------------------------------------------------------- */
extern void FILTER_reset(FILTER *f);
extern void FILTER_FIR_reset(FILTER_FIR *f);
extern void FILTER_setCoef(FILTER *f, int order, double *b, double *a, double H0);
extern void FILTER_FIR_setCoef(FILTER_FIR *f, int order, double *b, double H0);
extern double FILTER_filter(FILTER *f, double x);
extern double FILTER_FIR_filter(FILTER_FIR *f, double x);
extern void DELAY_reset(DELAYER *d);
extern void DELAY_setCoef(DELAYER *d, int delay);
extern double DELAY_delay(DELAYER *d, double x);

#endif
