/****************************************
        SV_common_include.h
*****************************************/

#include <string.h>
#include <math.h>
#include "Define_config.h"

#ifndef __COMMON_INCLUDE__
#define __COMMON_INCLUDE__

typedef long long INT64;
#define SMULL( a,   b )    ((INT64)(a)*(INT64)(b))
#define SMLAL( c,   a,   b )    (c + ((INT64)(a)*(INT64)(b)))
#define ABS(a) (((a)>0)?(a):(-a))
#ifndef NULL
#define NULL ((void*)0)
#endif

typedef struct{
    int re, im;
}ComplexInt;

typedef struct {
	INT64 re, im;
}ComplexInt64;

typedef struct {
	float re, im;
}ComplexFloat;

#define FFTLOGLEN 9
#define FFTLEN (1<<FFTLOGLEN)			// 512
#define HFFTLEN (FFTLEN>>1)+1			// 257
#define FFTOVERLAP (FFTLEN*3/8)			// 192

#define FRAMELEN (FFTLEN-FFTOVERLAP)    // 320

#define HEADROOM_NS		1

#define MAX(a,b) ((a>b) ? a:b)
#define MIN(a,b) ((a<b) ? a:b)

#define RECIP_LOGF10 (0.434294481903252f)  // 1/logf(10.0f)

#define SV_MAX_64 (long long)0x7fffffffffffffffLL
#define SV_MIN_64 (long long)0x8000000000000000LL
#define SV_MAX_32 (int)0x7fffffffL
#define SV_MIN_32 (int)0x80000000L
#define SV_MAX_16 (short)0x7fff
#define SV_MIN_16 (short)0x8000

#define SV_M_ACC_MAXFREQ  22 // Max accelerometer freq. 1000Hz/31.25 = 32bin

#define MMSE_DYNAMIC_Q 1

#define BANDV 1 // 1: overlab (need memory optimization), 2: simple version(no overlap)

#define WB_FREQ_SIZE 257
#define BAND_PWR_Q (15)
#define NPSD_Q (18) // the initial value should be considered
#define SNR_Q 12
//#define band_N 20
#define band_N 12
#define DELAYSIZE 3
#define NOISELEVEL_BAND_N 10
#define NOISELEVEL_BAND_N_REV 3277 // Q15

#define NOISELEVEL0_THD 1654 // -22dB (Q18)
#define NOISELEVEL1_THD 82897 // -12dB
#define NOISELEVEL2_THD 262144 // -0dB

#define NPSD_ALPHA_MAX 29491

#define NUM_CHAN 40

extern short tx_ch_tbl[NUM_CHAN][3];

extern float Log10(float x);
extern float GetdB(float in);
extern INT64 GetPower(int* in, int n);
extern float GetPowerdB(int* in, int n);
//extern INT64 fn_convolution(int *A, int *B, int n);
extern void fn_filterUpdate(int *W, int in, int *ref, int refPwr, int stepSize, int n);
extern int GetBlockNorm64(INT64* in, int headroom, int n);
extern void Conver64toInt(int *out, INT64* in, int Q, int minVal, int n);
extern void ConverIntto64(INT64 *out, int* in, int Q, int n);
extern void GetPSD_INT64(INT64* psd, ComplexInt* rbuf, int n);
extern void GetCoh(ComplexInt64* coh, ComplexInt* rbuf1, ComplexInt* rbuf2, int n);
extern int HysteresisHangoverThresholding_MultiState(float val, float thr_table[][2], int table_length, int hangover_up, int hangover_down, int state, int *cnt_up, int *cnt_down);
extern float fn_RecursiveAverage(float newPwr, float prevPwr, float alpha_down, float alpha_up);
extern void fn_bin2band64(INT64 *band, INT64 *bin, short (*ch_bound)[3], int power, int n);
extern void fn_bin2band(int *band, int *bin, short(*ch_bound)[3], int power, int n);
extern void fn_SpectralSmoothing_double(double *out, double *in, int smFactor, int Nbin); // will be deleted
extern void fn_SpectralSmoothing64(INT64 *out, INT64 *in, int smFactor, int Nbin);
extern void fn_SpectralSmoothing(int *out, int *in, int smFactor, int Nbin);
extern void fn_TimeSmoothing_double(double *new, double *old, double *current, float alpha_old, int n);// will be deleted
extern int fn_TimeSmoothing(int *new, int *old, int Q_old, int *current, int Q_current, int alpha_old, int n);
extern void fn_TimeSmoothing64(INT64 *new, INT64 *old, INT64 *current, float alpha_old, int n);
extern void fn_ComplexFilter(ComplexInt *out, ComplexFloat *filter, ComplexInt *in, int n);
extern void fn_ComplexFilter_2ch(ComplexInt *XoutFBF, float *wBF1, float *wBF2, ComplexInt *Xo1, ComplexInt *Xo2, int n);

/* NS */
extern void fn_Get_postSNR_double(double *postSNR, INT64 *EE, INT64 *Npsd, int NpsdBias, double minSNR, double maxSNR);
extern void fn_Get_postSNR64(int *postSNR, INT64 *EE, INT64 *Npsd, int NpsdBias, int minSNR, int maxSNR);
extern void fn_Get_postSNR(int *postSNR, int *EE, int Q_EE, int *Npsd, int Q_Npsd, int NpsdBias, int minSNR, int maxSNR);
extern void fn_Get_posterioriSPP_double(double *spp, double *snr, double *xiopt, int rl, int n);
extern void fn_Get_posterioriSPP(int *spp/*Q31*/, int *snr/*Q22*/, int *xiopt/*Q25*/, int rl, int n);
extern void fn_Prevent_stagnation(int *spp, int *spp_smooth, int alpha, int n);
extern void fn_get_WienerGain(int *gain, int *prioSNR, double power, int n);
extern void fn_get_WienerGain_double(double *G_NS, double *prioSNR, double power, int n);
extern void fn_spectralavg_Soft3(int *out, int *in, int N);
extern void fn_spectralavg_Soft3_double(double *out, double *in, int N);

#endif
