/*  iir.h

This file is part of a program that implements a Software-Defined Radio.

Copyright (C) 2014, 2022, 2023 Warren Pratt, NR0V

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

The author can be reached by email at

warren@wpratt.com

*/

/********************************************************************************************************
*                                                                                                       *
*                                           Bi-Quad Notch                                               *
*                                                                                                       *
********************************************************************************************************/

#ifndef _snotch_h
#define _snotch_h

typedef struct _snotch
{
    int run;
    int size;
    double* in;
    double* out;
    double rate;
    double f;
    double bw;
    double a0, a1, a2, b1, b2;
    double x0, x1, x2, y1, y2;
    CRITICAL_SECTION cs_update;
} snotch, *SNOTCH;

extern SNOTCH create_snotch (int run, int size, double* in, double* out, int rate, double f, double bw);

extern void destroy_snotch (SNOTCH a);

extern void flush_snotch (SNOTCH a);

extern void xsnotch (SNOTCH a);

extern void setBuffers_snotch (SNOTCH a, double* in, double* out);

extern void setSamplerate_snotch (SNOTCH a, int rate);

extern void setSize_snotch (SNOTCH a, int size);

extern void SetSNCTCSSFreq (SNOTCH a, double freq);

extern void SetSNCTCSSRun (SNOTCH a, int run);

#endif

/********************************************************************************************************
*                                                                                                       *
*                                           Complex Bi-Quad Peaking                                     *
*                                                                                                       *
********************************************************************************************************/

#ifndef _speak_h
#define _speak_h

typedef struct _speak
{
    int run;
    int size;
    double* in;
    double* out;
    double rate;
    double f;
    double bw;
    double cbw;
    double gain;
    double fgain;
    int nstages;
    int design;
    double a0, a1, a2, b1, b2;
    double *x0, *x1, *x2, *y0, *y1, *y2;
    CRITICAL_SECTION cs_update;
} speak, *SPEAK;

extern SPEAK create_speak (int run, int size, double* in, double* out, int rate, double f, double bw, double gain, int nstages, int design);

extern void destroy_speak (SPEAK a);

extern void flush_speak (SPEAK a);

extern void xspeak (SPEAK a);

extern void setBuffers_speak (SPEAK a, double* in, double* out);

extern void setSamplerate_speak (SPEAK a, int rate);

extern void setSize_speak (SPEAK a, int size);

#endif

/********************************************************************************************************
*                                                                                                       *
*                                       Complex Multiple Peaking                                        *
*                                                                                                       *
********************************************************************************************************/

#ifndef _mpeak_h
#define _mpeak_h

typedef struct _mpeak
{
    int run;
    int size;
    double* in;
    double* out;
    int rate;
    int npeaks;
    int* enable;
    double* f;
    double* bw;
    double* gain;
    int nstages;
    SPEAK* pfil;
    double* tmp;
    double* mix;
    CRITICAL_SECTION cs_update;
} mpeak, *MPEAK;

extern MPEAK create_mpeak (int run, int size, double* in, double* out, int rate, int npeaks, int* enable, double* f, double* bw, double* gain, int nstages);

extern void destroy_mpeak (MPEAK a);

extern void flush_mpeak (MPEAK a);

extern void xmpeak (MPEAK a);

extern void setBuffers_mpeak (MPEAK a, double* in, double* out);

extern void setSamplerate_mpeak (MPEAK a, int rate);

extern void setSize_mpeak (MPEAK a, int size);

#endif

/********************************************************************************************************
*                                                                                                       *
*                                            Phase Rotator                                              *
*                                                                                                       *
********************************************************************************************************/

#ifndef _phrot_h
#define _phrot_h

typedef struct _phrot
{
    int reverse;
    int run;
    int size;
    double* in;
    double* out;
    int rate;
    double fc;
    int nstages;
    // normalized such that a0 = 1
    double a1, b0, b1;
    double *x0, *x1, *y0, *y1;
    CRITICAL_SECTION cs_update;
} phrot, *PHROT;

extern PHROT create_phrot (int run, int size, double* in, double* out, int rate, double fc, int nstages);

extern void destroy_phrot (PHROT a);

extern void flush_phrot (PHROT a);

extern void xphrot (PHROT a);

extern void setBuffers_phrot (PHROT a, double* in, double* out);

extern void setSamplerate_phrot (PHROT a, int rate);

extern void setSize_phrot (PHROT a, int size);

#endif

/********************************************************************************************************
*                                                                                                       *
*                                   Complex Bi-Quad Low-Pass                                            *
*                                                                                                       *
********************************************************************************************************/

#ifndef _bqlp_h
#define _bqlp_h

typedef struct _bqlp
{
    int run;
    int size;
    double* in;
    double* out;
    double rate;
    double fc;
    double Q;
    double gain;
    int nstages;
    double a0, a1, a2, b1, b2;
    double* x0, * x1, * x2, * y0, * y1, * y2;
    CRITICAL_SECTION cs_update;
} bqlp, *BQLP;

extern BQLP create_bqlp(int run, int size, double* in, double* out, double rate, double fc, double Q, double gain, int nstages);

extern void destroy_bqlp(BQLP a);

extern void flush_bqlp(BQLP a);

extern void xbqlp(BQLP a);

extern void setBuffers_bqlp(BQLP a, double* in, double* out);

extern void setSamplerate_bqlp(BQLP a, int rate);

extern void setSize_bqlp(BQLP a, int size);

#endif

/********************************************************************************************************
*                                                                                                       *
*                                      Double Bi-Quad Low-Pass                                          *
*                                                                                                       *
********************************************************************************************************/

#ifndef _dbqlp_h
#define _dbqlp_h

extern BQLP create_dbqlp(int run, int size, double* in, double* out, double rate, double fc, double Q, double gain, int nstages);

extern void destroy_dbqlp(BQLP a);

extern void flush_dbqlp(BQLP a);

extern void xdbqlp(BQLP a);

extern void setBuffers_dbqlp(BQLP a, double* in, double* out);

extern void setSamplerate_dbqlp(BQLP a, int rate);

extern void setSize_dbqlp(BQLP a, int size);

#endif

/********************************************************************************************************
*                                                                                                       *
*                                   Complex Bi-Quad Band-Pass                                           *
*                                                                                                       *
********************************************************************************************************/

#ifndef _bqbp_h
#define _bqbp_h

typedef struct _bqbp
{
    int run;
    int size;
    double* in;
    double* out;
    double rate;
    double f_low;
    double f_high;
    double gain;
    int nstages;
    double a0, a1, a2, b1, b2;
    double* x0, * x1, * x2, * y0, * y1, * y2;
    CRITICAL_SECTION cs_update;
} bqbp, * BQBP;

extern BQBP create_bqbp(int run, int size, double* in, double* out, double rate, double f_low, double f_high, double gain, int nstages);

extern void destroy_bqbp(BQBP a);

extern void flush_bqbp(BQBP a);

extern void xbqbp(BQBP a);

extern void setBuffers_bqbp(BQBP a, double* in, double* out);

extern void setSamplerate_bqbp(BQBP a, int rate);

extern void setSize_bqbp(BQBP a, int size);

#endif

/********************************************************************************************************
*                                                                                                       *
*                                     Double Bi-Quad Band-Pass                                          *
*                                                                                                       *
********************************************************************************************************/

#ifndef _dbqbp_h
#define _dbqbp_h

extern BQBP create_dbqbp(int run, int size, double* in, double* out, double rate, double f_low, double f_high, double gain, int nstages);

extern void destroy_dbqbp(BQBP a);

extern void flush_dbqbp(BQBP a);

extern void xdbqbp(BQBP a);

extern void setBuffers_dbqbp(BQBP a, double* in, double* out);

extern void setSamplerate_dbqbp(BQBP a, int rate);

extern void setSize_dbqbp(BQBP a, int size);

#endif

/********************************************************************************************************
*                                                                                                       *
*                                      Double Single-Pole High-Pass                                     *
*                                                                                                       *
********************************************************************************************************/

#ifndef _dsphp_h
#define _dsphp_h

typedef struct _sphp
{
    int run;
    int size;
    double* in;
    double* out;
    double rate;
    double fc;
    int nstages;
    double a1, b0, b1;
    double* x0, * x1, * y0, * y1;
    CRITICAL_SECTION cs_update;
} sphp, * SPHP;

extern SPHP create_dsphp(int run, int size, double* in, double* out, double rate, double fc, int nstages);

extern void destroy_dsphp(SPHP a);

extern void flush_dsphp(SPHP a);

extern void xdsphp(SPHP a);

extern void setBuffers_dsphp(SPHP a, double* in, double* out);

extern void setSamplerate_dsphp(SPHP a, int rate);

extern void setSize_dsphp(SPHP a, int size);

#endif

/********************************************************************************************************
*                                                                                                       *
*                                    Complex Single-Pole High-Pass                                      *
*                                                                                                       *
********************************************************************************************************/

#ifndef _dphp_h
#define _dphp_h

extern SPHP create_sphp(int run, int size, double* in, double* out, double rate, double fc, int nstages);

extern void destroy_sphp(SPHP a);

extern void flush_sphp(SPHP a);

extern void xsphp(SPHP a);

extern void setBuffers_sphp(SPHP a, double* in, double* out);

extern void setSamplerate_sphp(SPHP a, int rate);

extern void setSize_sphp(SPHP a, int size);

#endif
