#include "Define_config.h"
#include "SamsungSolomonVoiceW.h"

#include "resample_typedefs.h"
#include "SamsungSolomonVoiceW_basic_op.h"

#ifndef SolmonVoice_INT_H_
#define SolmonVoice_INT_H_


#if 0//#ifdef __EXE_ANC__
//#define BSH_ANC_OUT
//#define __SV_USE_ANC_RESULT__
//#define __SV_USE_ANC_BASED_VAD__
//#define __SV_PHASE_ENH__
//#define __ANC_XCORR_BASED_VAD__
#ifdef __ANC_XCORR_BASED_VAD__
//#define __ANC_XCORR_BASED_VAD_IN_BF__ // ºöÆ÷¸Ó¿¡¼­ ANC VAD »ç¿ë
//#define __ANC_XCORR_BASED_VAD_IN_PF__ // _RES_NS ¿¡¼­ ANC VAD »ç¿ë
#endif
#endif


#define Fs  16000

#define WINDOWLEN 512
#define LPCORDER 16
#define LPCORDER_NB 10
#define WINDOWLEN_NB 256

#define MINPITCHLAG 48
#define MAXPITCHLAG 240

#define FRAMELEN 320
#define OVERLAPLEN (WINDOWLEN-FRAMELEN)

#define	DVTX_FRAME_LENGTH_SWB				640// DVTXECNS_Talble.h ¿¡ °°Àº ¿ëµµÀÇ Á¤ÀÇ ¶Ç ÀÖÀ½.. ÇÏ³ª »èÁ¦ ÇÊ¿ä
#define	DVTX_FRAME_LENGTH_WB				320// DVTXECNS_Talble.h ¿¡ °°Àº ¿ëµµÀÇ Á¤ÀÇ ¶Ç ÀÖÀ½.. ÇÏ³ª »èÁ¦ ÇÊ¿ä
#define	DVTX_FRAME_LENGTH_NB				160// DVTXECNS_Talble.h ¿¡ °°Àº ¿ëµµÀÇ Á¤ÀÇ ¶Ç ÀÖÀ½.. ÇÏ³ª »èÁ¦ ÇÊ¿ä

#define	DVTX_FFT_SIZE_512							512
#define	DVTX_FFT_SIZE_256							256
#define	DVTX_FFT_SIZE_128							128
#define	DVTX_FFT_SIZE_64							64
#define	DVTX_FFT_SIZE_32							32

#define FFT_RESOL									64

#define	DVTX_TRUE									1
#define	DVTX_FALSE									0

typedef struct {

	short mbdrcBandLimit[MBDRC_NUM];
	short smfactor_pre_ener[MBDRC_NUM][2];
	long smfactor_ener_band[MBDRC_NUM];

} MBDRC_Noise_Param;

#if(FLAG_SELECT_C_DSP == 0)
#ifndef NULL
#define NULL 0
#endif
#endif
/* SamsungSolomonVoiceW */
extern int SolomonVoiceECNSINIT(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars);
#if(FLAG_SELECT_C_DSP == 1)
extern void SamsungTxECNSInOutConfig(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars, short* Speech_Tx_Inner, short* Speech_Tx_Outer_1, short* Speech_Tx_Outer_2, short* Speech_rx_Inner, short* Speech_rx_Outer, short *Speech_tx_Acc, short* OutSignal, short *Output_buf_Inner_NB, short *Output_buf_Inner_WB, short *Output_buf_Outer);
#else
extern void SamsungTxECNSInOutConfig(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars, short* Speech_Tx_Inner, short* Speech_Tx_Outer_1, short* Speech_Tx_Outer_2, short* Speech_rx_Inner, short* Speech_rx_Outer, short *Speech_tx_Acc, short* OutSignal);
#endif
extern int SolomonVoiceWParamConfig(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars, SamsungSolomonVoiceParam* SamsungDiamondParam_varsTx);
extern int FN_NBcall_ParaConfig(SamsungSolomonVoiceWTxNSParam* NS_Outer_param, SamsungSolomonVoiceWTxAECParam* AEC_Outer_param);
extern int SolomonVoiceWECNSExe(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars);

/* SamsungSolomonVoiceW_RES_NS */
//extern void fn_FrmVAD(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars);
//extern int fn_Adaptive_NC(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars, short flag_inner, short flag_outer);
//extern int FN_f0_based_pre_Noise_suppression(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars, short F0flag);
extern int FN_SOLOMONVOICEW_TX_RES_NS_NBBT(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars, CHANNEL channel);
extern int FN_SOLOMONVOICEW_TX_RES_NS(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars, CHANNEL channel);
extern void SolomonVoiceW_NS_ParamConfig(SamsungSolomonVoiceWTxNSParam* NS_param, SamsungSolomonVoiceWTxNSParam* param);
extern void SolomonVoiceWRESInit(RESStatus *RES_buf, SamsungSolomonVoiceWTxRESParam* RES_param, COMMONBUF* common_buf, CHANNEL channel);
extern void SolomonVoiceWNSInit(NSStatus* NS_buf, SamsungSolomonVoiceWTxNSParam* NS_param, COMMONBUF* common_buf, CHANNEL channel);
extern void SolomonVoiceW_RES_ParamConfig(SamsungSolomonVoiceWTxRESParam* RES_param, RESStatus *RES_buf, SamsungSolomonVoiceWTxRESParam* param, CHANNEL channel);
extern void SolomonVoiceW_PreNS_ParamConfig(SamsungSolomonVoiceWTxPRENSParam* PreNS_param, SamsungSolomonVoiceWTxPRENSParam* param);
extern void SolomonVoiceW_ANC_ParamConfig(SamsungSolomonVoiceWTxANCParam* ANC_param, SamsungSolomonVoiceWTxANCParam* param);
extern int fx_SolomonVoice_recursiveAVG_ls(int OldVal, int NewVal, short beOld, short beNew, short blk_norm, short Q);

/* SamsungSolomonVoiceW_Default_functions */
extern void Fx_vector_gain(short* A, short gain, short gain_q, short N);
extern void Fx_vector_copy_s(short *Out, short *A, short N);
extern short Fx_time_vector_power_dB(short *A, short N);
extern int Fx_vector_sum_squares(short *A, short N, short *sum_q);
extern short Fx_10log10(int pwr, short pwr_q);

#ifndef	Fx_convolve_OPT_DSP
extern int Fx_convolve(const short *signal, const short *filter, const short signal_length, const short filter_length);
#else
extern int Fx_convolve_optimized(const short *signal, const short *filter, const short filter_length);
#endif

extern int Fx_recursive_avg(int A, int B, short beta);
extern void FFT_functions(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars);
extern void IFFT_functions(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars);
extern void IOLA_functions(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars);
extern void fx_SolomonVoice_FFT_to_FFTpwr_ave(int *FFTpwrVecAve, int *FFTpwrVec, short *FFTbinVec, short shift, short alpha, short oneminusalpha, short Nffthalf);
extern void fx_SolomonVoice_FFT_to_Phi_ave(int *phi_cross_r, int *phi_cross_i, short *data_buffer_WB_main, short *data_buffer_WB_sub, short shift_main, short shift_sub, short alpha, short oneminusalpha, short Nffthalf);
extern void fx_SolomonVoice_FFT_to_FFTpwr(int *FFTpwrVec, short *FFTbinVec, short Nffthalf);
extern void fx_SolomonVoice_FFTpwr_to_FFTband(int *FFTband, int *FFTbin, short CHindex[][2], short CHbin[][2], short Nband);
extern void fx_SolomonVoice_PwrBin_FixQ_BlkDeNorm(int *out, int *in, short blk_norm, short Q, short minval, short NhalfFFT);
extern int HysteresisHangoverThresholding_MultiState(int val, int thr_table[][2], int table_length, int hangover_up, int hangover_down, int state, short *p_cnt_up, short *p_cnt_down);
extern int FN_2ndIIR_FILTERING(short(*inout), short n, int* coeffs, int *state);
extern void Fn_vector_smoothing_over_3_rectangularwin_length(int *Out, int* A, short N, short LEN);
extern int fx_SolomonVoice_peak_peaking_based_Harmonic_Contour_estimation(short *f0Contour, short SPPminlocal, short VAD, int *EEii, int *EXooS, short wl, short fh, short NfftHalf);
extern void fx_SolomonVoice_VectorAdd_ll(int *Out, int *A, int *B, short N);
extern void fx_SolomonVoice_64point_cepstrum_transform(int *inSNR, short *outCeps, short Nband);
extern void fx_SolomonVoice_64point_INVERSE_cepstrum_transform(int *outSNR, short *inCeps, short Nband);
extern void fx_SolomonVoice_cepstral_smoothing_softForgetting(short *outSNRcepsAvg, short *outSNRcepsAvgTMP, short *inSNRceps, short *forgetVec);
extern void fx_SolomonVoice_cepstral_smoothing_FixForgetting(short Flag_loud, short *outSNRcepsAvg, short *outSNRcepsAvgTMP, short *inSNRceps,
			short BetaBand1_slow, short BetaBand2_slow, short BetaBand3_slow, short BetaBand1_fast, short BetaBand2_fast, short BetaBand3_fast);
extern int HysteresisHangoverThresholding(int a, int hangover_up, int hangover_down, int s, int* p_cnt);
extern short bayes_prob(int rg, short xi_db, int zeta, short increase_flag);  //zeta:[0~8) Q12

extern void fx_SolomonVoice_PwrBand_FixQ_BlkDeNorm(int *out, int *in, short blk_norm, short Q, short Nband);
extern void fx_SolomonVoice_Rx_ringbacktone_bandpwr_estimation(AECStatus* AEC_buf, int *L_DDBin2, short FFT_HALFLEN, short BLK_NORM);
extern void Fn_vector_smoothing_over_3_win_length(int *Out, int* A, short N, short LEN);

/* AEC */
extern void FN_SOLOMONVOICEW_TX_AEC(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars, CHANNEL channel);
extern void SolomonVoiceWAECInit(AECStatus* AEC_buf, SamsungSolomonVoiceWTxAECParam* AEC_param, COMMONBUF* common_buf, CHANNEL channel);
extern void SolomonVoiceW_AEC_ParamConfig(SamsungSolomonVoiceWTxAECParam* AEC_param, SamsungSolomonVoiceWTxAECParam* param);

/* PreNS */
extern void SolomonVoiceWPreNSInit(PRENSStatus* PRENS_buf, SamsungSolomonVoiceWTxPRENSParam* PreNS_param, COMMONBUF* common_buf, CHANNEL channel);
#if 0//#ifdef __EXE_ANC__
extern void SolomonVoiceWANCInit(ANCStatus* ANC_buf, SamsungSolomonVoiceWTxANCParam* ANC_param, COMMONBUF* common_buf, CHANNEL channel);
#endif

/* Mixing */
extern short FN_Wind_Detection(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars_outer);
extern void FN_SOLOMONVOICEW_TX_MIXING_SET(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars);
extern void FN_Mixing_FreqDomain(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars);
extern void SolomonVoiceWMixingInit(MixingStatus* Mix_buf, SamsungSolomonVoiceWTxMixParam* Mix_param, COMMONBUF* COMMON_buf);
extern void SolomonVoiceW_Mix_ParamConfig(SamsungSolomonVoiceWTxMixParam* Mix_param, SamsungSolomonVoiceWTxMixParam* param);

extern void FN_Mixing_FreqDomain_ACC(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars);
extern void FN_Gain_LowBand_0_to_200Hz(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars);
extern void FN_CONTEXT_BASED_OUPUT_GAIN_CONTROL(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars);
extern void FN_CONTEXT_BASED_SIGNAL_MIX_MIC_BF(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars);

/* AGC */
extern void SolomonVoiceWAGCInit(AGCStatus* AGC_buf, SamsungSolomonVoiceWTxAGCParam* AGC_param);
extern void SolomonVoiceW_AGC_ParamConfig(SamsungSolomonVoiceWTxAGCParam* AGC_param, SamsungSolomonVoiceWTxAGCParam* param);
extern void FN_SOLOMONVOICEW_TX_AGC(short *In, AGCStatus* AGC_buf, SamsungSolomonVoiceWTxAGCParam* AGC_param);
extern void FN_SOLOMONVOICEW_TX_AGC_2ch(short *In1, short *In2, AGCStatus* AGC_buf, SamsungSolomonVoiceWTxAGCParam* AGC_param);

/* MBDRC */
extern void SolomonVoiceWMBDRCInit(MBDRCStatus* MBDRC_buf, SamsungSolomonVoiceWTxMBDRCParam* MBDRC_param);
extern void SolomonVoiceW_MBDRC_ParamConfig(SamsungSolomonVoiceWTxMBDRCParam* MBDRC_param, SamsungSolomonVoiceWTxMBDRCParam* param);
extern void fn_MBDRC_Noise_Param(SamsungSolomonVoiceWTxMBDRCParam* MBDRC_param, MBDRC_Noise_Param* param);
extern void FN_SOLOMONVOICEW_TX_MBDRC_2ch(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars);

/* EQ */
extern void SolomonVoiceWFIRFilterInit(FIRStatus* FIR_buf, SamsungSolomonVoiceWTxFIRParam* FIR_param);
extern void SolomonVoiceW_FIR_ParamConfig(SamsungSolomonVoiceWTxFIRParam* FIR_param, SamsungSolomonVoiceWTxFIRParam* param);
extern void FN_SOLOMONVOICEW_TX_FirCoefConfig(short *SF_FIRCoef, short *rxfircoef);
extern int FN_SOLOMONVOICEW_TX_FilterUpdate(short* cur_coeff, short* dst_coeff, short flag);
extern void FN_SOLOMONVOICEW_TX_FIRFilter(short* Input, short* FIRCoeff, short* FIRFiltBuff, short size);

/* resample */
void WebRtcSpl_DownsampleBy2(const int16_t* in, uint32_t len, int16_t* out, int32_t* filtState);
void WebRtcSpl_UpsampleBy2(const int16_t* in, uint32_t len, int16_t* out, int32_t* filtState);

/* Inter-channel ANC */
#if 0//#ifdef __EXE_ANC__
void *SolomonVoiceInterChannelANCInit();
#endif
void FN_InterChannelANC_main(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars);

extern void SolomonVoiceWBFInit(BFStatus* BF_buf, SamsungSolomonVoiceWTxBFParam* BF_param, COMMONBUF* common_buf);
extern void SolomonVoiceW_BF_ParamConfig(SamsungSolomonVoiceWTxBFParam* BF_param, SamsungSolomonVoiceWTxBFParam* param);
extern void FN_BF(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars);

extern void SolomonVoiceWVADACCInit(VADACCStatus* VADACC_buf, SamsungSolomonVoiceWTxVADACCParam* VADACC_param, COMMONBUF* common_buf);
extern void SolomonVoiceW_VADACC_ParamConfig(SamsungSolomonVoiceWTxVADACCParam* VADACC_param, SamsungSolomonVoiceWTxVADACCParam* param);
extern void FN_VADACC(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars);

extern void FN_BACKGROUND_NOISE_CONTEXT_FROM_BF_NS_AEC_ACCELEROMETER(DVTX_ECNS_Cfg_t* DVTX_ECNS_vars);


/*RNN*/
#if 1//#ifdef __EXE_RNN__
extern int rnnnoise_init(DenoiseState *st);
extern int fx_rnnoise_process_frame(DenoiseState *st, short *in, short *denoiseout);
#endif

#endif