// --------------------------------------------------------------
// --------------------------------------------------------------
#ifndef _FILTER_H_
#define	_FILTER_H_

#include "synth_defs.h"

#define FILTER_RECALC_F_THRESH		(0.000)
#define FILTER_RECALC_Q_THRESH		(0.000)

// --------------------------------------------------------------
// Types
// --------------------------------------------------------------
enum
{
	VCF_FILTERTYPE_LOWPASS = 0,
	VCF_FILTERTYPE_HIGHPASS,
	VCF_FILTERTYPE_BANDPASS,
	VCF_NUM_FILTERTYPES
};

enum
{
	VCF_FILTERORDER_2 = 0,
	VCF_FILTERORDER_4,
	VCF_NUM_FILTERORDER
};

typedef struct _svcf_coef_t
{

	synth_float_t ak0, ak1, ak2;
	synth_float_t bk0, bk1, bk2;

} vcf_coef_t;

typedef struct _svcf_state_t
{

	synth_float_t xn1, xn2;
	synth_float_t yn1, yn2;

} vcf_state_t;

typedef struct _svcf_common_t
{
	synth_float_t *pLUT_cos;
	synth_float_t *pLUT_sin;

} vcf_common_t;

typedef struct _svcf_t
{
	vcf_common_t *pCom;
	UINT32 id;
	UINT32 type;
	UINT32 order;
	UINT32 num_sections;
	synth_float_t fs;
	vcf_coef_t *pCoef;
	vcf_coef_t *pCoeff_last;
	vcf_state_t pState[FILTER_MAX_ORDER/2];
	synth_float_t pQP_inv[FILTER_MAX_ORDER/2];
	synth_float_t *pOut;
	synth_float_t cv_f_bias;
	synth_float_t cv_q_bias;
	synth_float_t cv_f_last;
	synth_float_t cv_q_last;
	UINT32 req_filter_update;
	UINT32 bufsize;
	synth_float_t num_octaves;
	synth_float_t omega_min;
	synth_float_t omega_max;

} vcf_t;

// --------------------------------------------------------------
#if defined(__cplusplus)
extern "C" {
#endif

// --------------------------------------------------------------
// Exported functions
// --------------------------------------------------------------
void VCF_ModInit(vcf_t *pObj);
void VCF_ModFree(vcf_t *pObj);
void VCF_Init(vcf_t *pObj, UINT32 id, vcf_common_t *pCom, synth_float_t fs);
void VCF_Free(vcf_t *pObj);
void VCF_SetBufsize(vcf_t *pObj, UINT32 bufsize);
void VCF_FilterParamUpdate(vcf_t *pObj);
void VCF_Coeff_update(vcf_t *pObj);
void VCF_SetFS(vcf_t *pObj, synth_float_t fs);
void VCF_SetF(vcf_t *pObj, synth_float_t f);
void VCF_SetQ(vcf_t *pObj, synth_float_t q);
void VCF_SetType(vcf_t *pObj, UINT32 type);
void VCF_SetOrder(vcf_t *pObj, UINT32 order);
synth_float_t VCF_cv2omega(vcf_t *pObj, synth_float_t omega);
synth_float_t VCF_omega2cv(vcf_t *pObj, synth_float_t cv);
void VCF_clear_state(vcf_t *pObj);
void VCF_CalcCoeff(vcf_t *pObj, vcf_coef_t *pCoeff, synth_float_t *pCV_f, synth_float_t *pCV_q, UINT32 len);
synth_float_t* VCF_ProcessDataV(vcf_t *pObj, synth_float_t *pCV_f, synth_float_t *pCV_q, synth_float_t *pX, UINT32 len);

#if defined(__cplusplus)
}

#endif
// --------------------------------------------------------------

#endif // _FILTER_H_
