/************************************************
		SV_VoiceAndNoiseStatus.c
*************************************************/

#include <math.h>
#include <string.h>
#include "SV_VoiceAndNoiseStatus.h"
#include "SV_AccSensor.h"
#include "SV_Flag.h"

#ifdef Debug_File_Write_C
#include <stdio.h>
extern FILE *fp_vad, *fp_wnd, *fp_mic_check;
#endif

#define MIC_RELIABILITY_FREQ_LB 1
#define MIC_RELIABILITY_FREQ_UB 16
#define MIC_RELIABILITY_FREQ_LEN (MIC_RELIABILITY_FREQ_UB - MIC_RELIABILITY_FREQ_LB + 1)

 /*tuning paramerters*/
float Thr_VAD_Pwr_Rx_dB;
float Thr_VAD_Pwr_Tx_dB;
float Thr_Loud_Pwr_Tx_dB;
float Thr_SingleTalk_PwrDiff;
float Thr_SingleNet_PwrDiff;
INT64 Thr_VADACCmask;

 /*Init local buffer/status/variables...*/
INT64 XXrx[HFFTLEN];
INT64 XXmic1[HFFTLEN];
INT64 XXmic2[HFFTLEN];
INT64 XXacc[HFFTLEN];
ComplexInt64 XXcross[HFFTLEN];

//fn_VAD_acc
float PwrSpeech_Accel_VADon;
float PwrSpeech_Accel_VADoff;
int cnt_up_vad;
int cnt_down_vad;

//fn_DefineTxCondition
INT64 Thr_Silence_100to1k;
int HangOver_silenceOFF;
int HangOver_silenceON;
int cnt_up_silence;
int cnt_down_silence;

//noise level
float Alpha_up_noise;
float Alpha_down_noise;
float frmPwr_LowBand;
float noiseLevel_LowBand;
float noiseLevel_LowBand_longterm;
float noiseLevel_LowBand_shorterm;
int cnt_up_noise;
int cnt_down_noise;
float thr_table[4][2];
int thr_table_init[4][2] = { {80, 83}, {97, 100}, {107, 110}, {117, 119} };

//wind
float Alpha_phi;
float Alpha_msc_up;
float Alpha_msc_down;
int Thr_mscInv;
INT64 XXmic1Avg[MIC_RELIABILITY_FREQ_LEN];
INT64 XXmic2Avg[MIC_RELIABILITY_FREQ_LEN];
ComplexInt64 XXcrossAvg[MIC_RELIABILITY_FREQ_LEN];
float Pwr_wind;
float LowBandPowerAve;
float msc;
float msc_reliabilityCheck;

int flag_strong_wind_cand;
int cnt_strongWind_ON;
int cnt_strongWind_OFF;
int flag_normal_wind_cand;
int cnt_normalWind_ON;
int cnt_normalWind_OFF;
float Thr_strong_Wind[2];
float Thr_normal_Wind[2];
int Thr_strong_Wind_init[2] = { 105, 110 };
int Thr_normal_Wind_init[2] = { 87, 97 };

//1micVAD_LTSV
float LTSVthd;
int Kltsv_st;
int Kltsv_end;
int Rltsv;
INT64 SxMtxLtsv[16][113]; //[Kltsv_end-Kltsv_st+1][Rltsv]
float LTSVthdLowBound;

 /*flags*/
int frmVAD_Acc;
int frmVAD_Acc_BSH;
int frmVAD_Rx_AEC;
int VADACCmask[BIN_ACCMAX];
int flag_Wind_strong;
int flag_Wind_normal;
int flag_Tx_silence;
int flag_Tx_silence_AEC;
int flag_Tx_LoudSig;
int flag_NoiseOnly;
int flag_FrmDT;
int flag_SingleTalk;
int flag_SingleNET;
int flag_ACC_Effective;
int noiseLevel;
int state_noise2clean;
int flag_OuterMicLowReliability;
int cnt_OuterMicLowReliability_OFF;

//noise onset/offset
int noiseOnset;
int noiseOffset;

int flag_frmCnt;

// Processing
void SV_VAD_TimeDomain_Exe(INT64 PwrdB_Rx, INT64 PwrdB_Mic1)
{
	float PwrDiff_Tx_Rx_Frm;

	// process
	frmVAD_Rx_AEC = (PwrdB_Rx >= Thr_VAD_Pwr_Rx_dB)? 1 : 0;
	flag_Tx_silence_AEC = (PwrdB_Mic1 >= Thr_VAD_Pwr_Tx_dB) ? 1 : 0;
	flag_Tx_LoudSig = (PwrdB_Mic1 >= Thr_Loud_Pwr_Tx_dB) ? 1 : 0;

	// single talk
	PwrDiff_Tx_Rx_Frm = PwrdB_Mic1 - PwrdB_Rx;
	flag_SingleTalk = (PwrDiff_Tx_Rx_Frm < Thr_SingleTalk_PwrDiff) ? 1 : 0;
	flag_SingleNET = (PwrDiff_Tx_Rx_Frm < Thr_SingleNet_PwrDiff) ? 1 : 0;
	
	return;
	
}

static void fn_VAD_acc(INT64 *XXacc)
{
	int i;
	INT64 PwrXXacc;
	float LogPwrXXacc_LF, LogPwrXXacc_HF;
	float THD_LogPwrXXacc_LF, LogPwrDiffVADonoffTHD, LogPwrDiffVADonoff;
	float forgetOld, forgetNew;
	float Thr_frmVAD_Acc[1][2];

    // VAD frame
	PwrXXacc = 0;
	for (i = 3; i < BIN_ACCMAX; i++)		PwrXXacc += XXacc[i];	// 100Hz~Max 
	LogPwrXXacc_LF = GetdB((float)PwrXXacc);

	PwrXXacc = 0;
	for (i = 10; i < BIN_ACCMAX; i++)		PwrXXacc += XXacc[i];	// 300Hz~Max
	LogPwrXXacc_HF = GetdB((float)PwrXXacc);

	if(flag_Wind_strong)
		THD_LogPwrXXacc_LF = 107.5; 
	else
		THD_LogPwrXXacc_LF = 91.8; 
    
	Thr_frmVAD_Acc[0][0] = THD_LogPwrXXacc_LF;
	Thr_frmVAD_Acc[0][1] = THD_LogPwrXXacc_LF;

    if(frmVAD_Acc == 1) // rx Á¶°Ç Ãß°¡ ÇÊ¿ä (rx µé¾î¿À¸é ¾÷µ¥ÀÌÆ® ¾ÈÇÏµµ·Ï..)
        frmVAD_Acc=frmVAD_Acc;
	frmVAD_Acc = HysteresisHangoverThresholding_MultiState(LogPwrXXacc_LF, Thr_frmVAD_Acc, 1, 1, 3, frmVAD_Acc, &cnt_up_vad, &cnt_down_vad);
	
	// Decision effective Acc state  
	// Pwr Acc sig in speech interval
	forgetOld = 0.98;
	forgetNew = 0.02;
	if(frmVAD_Acc == 1)
		PwrSpeech_Accel_VADon = (PwrSpeech_Accel_VADon * forgetOld) + (LogPwrXXacc_HF * forgetNew);
	else
		PwrSpeech_Accel_VADoff = (PwrSpeech_Accel_VADoff * forgetOld) + (LogPwrXXacc_HF * forgetNew);
	
	LogPwrDiffVADonoffTHD = 7.7; // 8*2^23
	LogPwrDiffVADonoff = PwrSpeech_Accel_VADon - PwrSpeech_Accel_VADoff;
    if(LogPwrDiffVADonoff > LogPwrDiffVADonoffTHD)
        flag_ACC_Effective = 1;
    else
        flag_ACC_Effective = 0;
		
	// VAD freq mask
	for (i = 3; i < BIN_ACCMAX; i++)
		VADACCmask[i] = (XXacc[i] > Thr_VADACCmask) ? 1 : 0;
        
	return;
}

static void fn_DefineTxCondition(INT64 *XXmic1, INT64 *XXmic2)
{                    
	int i;
	INT64 Pwr_100kto1k;

    // Silence detection
	Pwr_100kto1k = 0;
	for (i = 2; i < 33; i++)
		Pwr_100kto1k += XXmic1[i];
    
	if (Pwr_100kto1k < Thr_Silence_100to1k)
	{
		cnt_up_silence = MIN(cnt_up_silence + 1, HangOver_silenceON);

		if (cnt_up_silence == HangOver_silenceON)
		{
			flag_Tx_silence = 1;
			cnt_down_silence = HangOver_silenceOFF;
		}
		else
		{
			flag_Tx_silence = 0;
			cnt_down_silence = 0;
		}
	}
	else if (cnt_down_silence > 0)
	{
		flag_Tx_silence = 1;
		cnt_down_silence = cnt_down_silence - 1;
	}
	else
	{
		flag_Tx_silence = 0;
		cnt_up_silence = 0;
		cnt_down_silence = 0;
	}
  
	return;
}

static void fn_SetMixingState(INT64 *XXmic1)
{
	int i;
	INT64 frmPwr_LowBand_tmp;
	float noise_var, Alpha_up, Alpha_down;

	if (frmVAD_Acc == 0)
	{
		frmPwr_LowBand_tmp = 0;
		for (i = 0; i < 16; i++)
			frmPwr_LowBand_tmp += XXmic1[i];
		frmPwr_LowBand = GetdB((float)frmPwr_LowBand_tmp);
	}
        
    noiseLevel_LowBand_longterm  = fn_RecursiveAverage(frmPwr_LowBand, noiseLevel_LowBand_longterm, 0.98, 0.98);
    noiseLevel_LowBand_shorterm  = fn_RecursiveAverage(frmPwr_LowBand, noiseLevel_LowBand_shorterm, 0.3, 0.3);
	
    noise_var   = noiseLevel_LowBand_shorterm - noiseLevel_LowBand_longterm;
    
    // linear regression
    // noise_var 10dB => alpha 0.98
    // noise_var 40dB => alpha 0.1
    // noise_var -40dB => alpha 0.1
    // noise_var -10dB => alpha 0.98
	if (noise_var > 10)
		Alpha_up = 0.98 - (0.0293333333333333/*(0.98-0.1)/(40-10)*/)*(noise_var - 10);
	else
		Alpha_up = Alpha_up_noise;
    
	if (noise_var < -10)
		Alpha_down = 0.1 + (0.0293333333333333/*(0.98-0.1)/(-10+40)*/)*(noise_var + 40);
	else
		Alpha_down = Alpha_down_noise;
    
    noiseLevel_LowBand  = fn_RecursiveAverage(frmPwr_LowBand, noiseLevel_LowBand, Alpha_up, Alpha_down);
    
    noiseLevel = HysteresisHangoverThresholding_MultiState(noiseLevel_LowBand, thr_table, 4, 50, 20, noiseLevel, &cnt_up_noise, &cnt_down_noise);
 
	return;
}

static void fn_WindDetection(INT64 *XXmic1, INT64 *XXmic2, ComplexInt64 *XXcross)
{
	int i;
	int Flag_wind;
	float FrmPiLowBand_wind, msc_curr, mean_phi, mscInv;
	INT64 tmp64;

    // 0. power, coherence
	for (i = 0; i < 4; i++)
	{
		XXmic1Avg[i] = Alpha_phi * XXmic1Avg[i] + (1 - Alpha_phi) * XXmic1[i];
		XXmic2Avg[i] = Alpha_phi * XXmic2Avg[i] + (1 - Alpha_phi) * XXmic2[i];
		XXcrossAvg[i].re = Alpha_phi * XXcrossAvg[i].re + (1 - Alpha_phi) * XXcross[i].re;
		XXcrossAvg[i].im = Alpha_phi * XXcrossAvg[i].im + (1 - Alpha_phi) * XXcross[i].im;
	}
    
    // 1. band energy
	tmp64 = XXmic1[0] + XXmic1[1];
    FrmPiLowBand_wind = GetdB((float)tmp64);
    
    // calculate Variable THD_Ratio_LowBandPwr
	Pwr_wind = fn_RecursiveAverage(FrmPiLowBand_wind, Pwr_wind, 0.8, 0.99);

	// 2. magnitude squared coherence (MSC) 
	mean_phi = 0;
	for (i = 0; i < 4; i++)
	{
		msc_curr = ((float)XXcrossAvg[i].re*XXcrossAvg[i].re + (float)XXcrossAvg[i].im*XXcrossAvg[i].im) / ((float)XXmic1Avg[i] * XXmic2Avg[i]);
		msc_curr = MAX(MIN(msc_curr, 1), 0);
		mean_phi += msc_curr;
	}
	mean_phi /= 4;

	msc = fn_RecursiveAverage(mean_phi, msc, Alpha_msc_up, Alpha_msc_down);
	
	mscInv = 1 - msc;

	// 3. ZCR 
	//ZCR_main = fn_WND_ZCR(WNDstr, &WNDstr->ch_main);

	// 4. wind decision 
	if (mscInv > Thr_mscInv)
		Flag_wind = 1;
	else
		Flag_wind = 0;

	flag_strong_wind_cand = HysteresisHangoverThresholding_MultiState(Pwr_wind, Thr_strong_Wind, 1, 30, 15, flag_strong_wind_cand, &cnt_strongWind_ON, &cnt_strongWind_OFF);

	flag_Wind_strong = (Flag_wind && flag_strong_wind_cand);

	flag_normal_wind_cand = HysteresisHangoverThresholding_MultiState(Pwr_wind, Thr_normal_Wind, 1, 30, 15, flag_normal_wind_cand, &cnt_normalWind_ON, &cnt_normalWind_OFF);
    
	flag_Wind_normal = (Flag_wind && flag_normal_wind_cand);

#ifdef Debug_File_Write_C
	fprintf(fp_wnd, "%f %f %f %f %d %d %d\n", mean_phi, msc, FrmPiLowBand_wind, Pwr_wind, Flag_wind, flag_strong_wind_cand, flag_normal_wind_cand);
#endif

	return;
}

static void fn_IdentifySignalReliability(INT64 *XXmic1, INT64 *XXmic2, ComplexInt64 *XXcross)
{
	int i;
	int Flag_wind;
	float LowBandPower, msc_curr, mean_phi, mscInv;
	INT64 tmp64;
	float alpha = 0.8, alpha_rev = 0.2;
	// power, coherence
	for (i = 0; i < MIC_RELIABILITY_FREQ_LEN; i++) // redundency
	{
		XXmic1Avg[i] = alpha * XXmic1Avg[i] + alpha_rev * XXmic1[i + MIC_RELIABILITY_FREQ_LB];
		XXmic2Avg[i] = alpha * XXmic2Avg[i] + alpha_rev * XXmic2[i + MIC_RELIABILITY_FREQ_LB];
		XXcrossAvg[i].re = alpha * XXcrossAvg[i].re + alpha_rev * XXcross[i + MIC_RELIABILITY_FREQ_LB].re;
		XXcrossAvg[i].im = alpha * XXcrossAvg[i].im + alpha_rev * XXcross[i + MIC_RELIABILITY_FREQ_LB].im;
	}

	// magnitude squared coherence (MSC) 
	mean_phi = 0;
	for (i = 0; i < MIC_RELIABILITY_FREQ_LEN; i++) // (0~3) redundency
	{
		msc_curr = ((float)XXcrossAvg[i].re*XXcrossAvg[i].re + (float)XXcrossAvg[i].im*XXcrossAvg[i].im) / ((float)XXmic1Avg[i] * XXmic2Avg[i]);
		msc_curr = MAX(MIN(msc_curr, 1), 0);
		mean_phi += msc_curr;
	}
	mean_phi /= MIC_RELIABILITY_FREQ_LEN;
	
	msc_reliabilityCheck = fn_RecursiveAverage(mean_phi, msc_reliabilityCheck, 0.8, 0.9);

	tmp64 = 0;
	for (i = 0; i < MIC_RELIABILITY_FREQ_LEN; i++)
	{
		tmp64 += (XXmic1[i] >> 4);
	}
	LowBandPower = GetdB((float)tmp64);
	LowBandPowerAve = fn_RecursiveAverage(LowBandPower, LowBandPowerAve, 0.95, 0.9);

	// decision 
	if (msc_reliabilityCheck < 0.8 && LowBandPowerAve > 70)
	{
		flag_OuterMicLowReliability = 1;
		cnt_OuterMicLowReliability_OFF = 0;
	}
	else
	{
		if (cnt_OuterMicLowReliability_OFF > 25) // offset delay (0.5sec)
		{
			flag_OuterMicLowReliability = 0;
			cnt_OuterMicLowReliability_OFF = 0;
		}

		if (flag_OuterMicLowReliability == 1)
		{
			cnt_OuterMicLowReliability_OFF++;
		}
		else
		{
			cnt_OuterMicLowReliability_OFF = 0;
		}
	}

	if (flag_frmCnt < 200) flag_OuterMicLowReliability = 1;
	//TODO: windÅ©±â¿¡ µû¸¥ level (ÀÛÀº ¹Ù¶÷Àº Áß°í¿ª »ç¿ëÇÒ ¼ö ÀÖÀ½)

#ifdef Debug_File_Write_C
	fprintf(fp_mic_check, "%f %f %f %f %d\n", mean_phi, msc_reliabilityCheck, LowBandPower, LowBandPowerAve, flag_OuterMicLowReliability);
#endif
	return;
}

static void fn_1micVAD_LTSV(INT64 *XX)
{//flag_NoiseOnly¸¸ º¼²¨¸é ÇÊ¿ä ¾ø°Í´Ù..
	int i, j;
	INT64 Sx_frmsum[113];
	float LTSV, tmpvec, phxixbar, phxix[113] = { 0. };

	memcpy(SxMtxLtsv + 1, SxMtxLtsv, sizeof(INT64)*(113 * 15));
	memcpy(SxMtxLtsv, XX + Kltsv_st - 1, sizeof(INT64) * 113);
    
	for (i = 0; i < 113; i++)
	{
		Sx_frmsum[i] = 0;
		for (j = 0; j < 16; j++)
			Sx_frmsum[i] += SxMtxLtsv[j][i];
	}
    
	for (i = 0; i < 113; i++)
	{
		for (j = 0; j < 16; j++)
		{
			tmpvec = (float)SxMtxLtsv[j][i] / ((float)Sx_frmsum[i] + 0.01);
			phxix[i] = phxix[i] - (float)(tmpvec*logf(tmpvec + 0.01));
		}
	}

	phxixbar = 0;
	for (i = 0; i < 113; i++)
		phxixbar += phxix[i];
	phxixbar /= (Kltsv_end - Kltsv_st + 1);

	LTSV = 0;
	for (i = 0; i < 113; i++)
		LTSV += (phxix[i] - phxixbar) * (phxix[i] - phxixbar);
	LTSV /= (Kltsv_end - Kltsv_st + 1);
//     LTSV = MIN(LTSV, 0.2);
    
	flag_NoiseOnly = (LTSV < LTSVthdLowBound) ? 1 : 0;
//     if(LTSV < 0.025)
//         frmVAD_Acc = 0;
//     end

	return;
}

void VoiceAndNoiseStatus_Exe(ComplexInt* Rx_sp, ComplexInt* Outer1_sp, ComplexInt* Outer2_sp, ComplexInt* Acc_sp, int nsp)
{
    //XXgsc               = stBF.XXgsc; // ¿Ö ÀÌ°É ¾¸??
    
    // power, coherence (peak 0.36MCPS)
	GetPSD_INT64(XXrx, Rx_sp, nsp);
	GetPSD_INT64(XXmic1, Outer1_sp, nsp);
	GetPSD_INT64(XXmic2, Outer2_sp, nsp);
	GetPSD_INT64(XXacc, Acc_sp, nsp);
	GetCoh(XXcross, Outer1_sp, Outer2_sp, nsp);

    // vad (acc) (peak 0.41MCPS)
    fn_VAD_acc(XXacc);
	SV_AccSensor_Exe((int*)Acc_sp); //(BSH)
	frmVAD_Acc_BSH = SV_AccSensor_GetVAD();
    // tx condition (peak 0.0MCPS)
    fn_DefineTxCondition(XXmic1, XXmic2);
        
    // Noise Level (for Mixing) (peak 0.28MCPS)
    fn_SetMixingState(XXmic1);
                
    // Wind Detection (peak 1.19MCPS)
    fn_WindDetection(XXmic1, XXmic2, XXcross);
    

	// Mic reliability check for outer mics (WND)
	fn_IdentifySignalReliability(XXmic1, XXmic2, XXcross);

    // Frame VAD : LTSV   (peak 391.65MCPS)
    //fn_1micVAD_LTSV(XXmic1); // XXgsc¸¦ ÀÔ·ÂÀ¸·Î? => VAD ACC ¹× Noise LevelÀÌ¿ëÇØ¼­ °£´ÜÈ÷ »êÃâÇÒ °Í. ¾îÂ÷ÇÇ InterChannelANC¿¡¼­¸¸ »ç¿ëÁß.
      
	SV_FLAG_DetectTransient(Outer1_sp, frmVAD_Acc_BSH);
	noiseOnset = SV_FLAG_GetNoiseOnset();
	noiseOffset = SV_FLAG_GetNoiseOffset();

    // TODO
    flag_FrmDT = 0;

	if (flag_frmCnt < 32767) flag_frmCnt++;

#ifdef Debug_File_Write_C
	fprintf(fp_vad, "%d %d %d %d %d %d %d %d %d %d %d\n", frmVAD_Rx_AEC, flag_Tx_silence_AEC,
		flag_Tx_LoudSig, flag_SingleTalk, flag_SingleNET, frmVAD_Acc, flag_Tx_silence, noiseLevel, flag_Wind_strong, flag_Wind_normal, flag_NoiseOnly);
#endif
	return;
}

// Get functions ("Getters")
int VoiceAndNoiseStatus_Get_frmVAD_Acc(void) { return frmVAD_Acc; }
int VoiceAndNoiseStatus_Get_frmVAD_Acc_BSH(void) { return frmVAD_Acc_BSH; }
int VoiceAndNoiseStatus_Get_frmVAD_Rx_AEC(void) { return frmVAD_Rx_AEC; }
int VoiceAndNoiseStatus_Get_VADACCmask(void) { return VADACCmask; }
int VoiceAndNoiseStatus_Get_flag_Wind_strong(void) { return flag_Wind_strong; }
int VoiceAndNoiseStatus_Get_flag_Wind_normal(void) { return flag_Wind_normal; }
int VoiceAndNoiseStatus_Get_flag_Tx_silence(void) { return flag_Tx_silence; }
int VoiceAndNoiseStatus_Get_flag_Tx_silence_AEC(void) { return flag_Tx_silence_AEC; }
int VoiceAndNoiseStatus_Get_flag_Tx_LoudSig(void) { return flag_Tx_LoudSig; }
int VoiceAndNoiseStatus_Get_flag_NoiseOnly(void) { return flag_NoiseOnly; }
int VoiceAndNoiseStatus_Get_flag_FrmDT(void) { return flag_FrmDT; }
int VoiceAndNoiseStatus_Get_flag_SingleTalk(void) { return flag_SingleTalk; }
int VoiceAndNoiseStatus_Get_flag_SingleNET(void) { return flag_SingleNET; }
int VoiceAndNoiseStatus_Get_flag_ACC_Effective(void) { return flag_ACC_Effective; }
int VoiceAndNoiseStatus_Get_noiseLevel(void) { return noiseLevel; }
int VoiceAndNoiseStatus_Get_state_noise2clean(void) { return state_noise2clean; }
int VoiceAndNoiseStatus_Get_flag_OuterMicLowReliability(void){ return flag_OuterMicLowReliability; }
int VoiceAndNoiseStatus_Get_NoiseOnset(void) { return noiseOnset; }
int VoiceAndNoiseStatus_Get_NoiseOffset(void) { return noiseOffset; }


int VoiceAndNoiseStatus_VADCorrection(short *Mask) {
	frmVAD_Acc_BSH =  SV_AccSensor_VADCorrectionByRefMask(Mask);
	return frmVAD_Acc_BSH;
}

int VoiceAndNoiseStatus_NoiseOnsetCorrection(int *noisySpec, int *enhSpec, short *refMask, short noiseLevel)
{
	int new_noiseOnset = SV_FLAG_DetectNoiseOnset(noisySpec, enhSpec, refMask, frmVAD_Acc_BSH, frmVAD_Rx_AEC, noiseLevel);
	noiseOnset = noiseOnset || new_noiseOnset;
	return noiseOnset;
}

// Init
void VoiceAndNoiseStatus_Init(int Fs)
{
	int i, j;

	// Init tuning paramerters
	Thr_VAD_Pwr_Rx_dB = 1994.26231496888; // 10^(8448/(2^8)/10)-1
	Thr_VAD_Pwr_Tx_dB = 176.827941003892; // 10^(5760/(2^8)/10)-1
	Thr_Loud_Pwr_Tx_dB = 12588.2541179417; // 10^(10496/(2^8)/10)-1
	Thr_VADACCmask = 2560000000; //10000000 * (2 ^ 8)

	Thr_SingleTalk_PwrDiff = 0.281838293126445; // 10^(-1408/(2^8)/10)
	Thr_SingleNet_PwrDiff = 630.957344480193; // 10^(7168/(2^8)/10)


	// Init local buffer/status/variables...
	PwrSpeech_Accel_VADon = 0;
	PwrSpeech_Accel_VADoff = 0;
	cnt_up_vad = 0;
	cnt_down_vad = 0;

	Thr_Silence_100to1k = 31622776;
	HangOver_silenceOFF = 100;
	HangOver_silenceON = 5;
	cnt_up_silence = 0;
	cnt_down_silence = 0;

	Alpha_up_noise = 32055. / 32768;
	Alpha_down_noise = 32055. / 32768;
	frmPwr_LowBand = 0;
	noiseLevel_LowBand = 0;
	noiseLevel_LowBand_longterm = 0;
	noiseLevel_LowBand_shorterm = 0;
	cnt_up_noise = 0;
	cnt_down_noise = 0;
	for (i = 0; i < 4; i++)
		for (j = 0; j < 2; j++)
			thr_table[i][j] = (float)thr_table_init[i][j];
	
	Alpha_phi = 0.899993896484375; // 29491 / (2 ^ 15)
	Alpha_msc_up = 0.968505859375; // 31736 / (2 ^ 15)
	Alpha_msc_down = 0.968505859375; // 31736 / (2 ^ 15)
	Thr_mscInv = 0.505199999548495; //1084908738/(2^31)
	for (i = 0; i < 4; i++)
	{
		XXmic1Avg[i] = 0;
		XXmic2Avg[i] = 0;
		XXcrossAvg[i].re = 0;
		XXcrossAvg[i].im = 0;
	}
	Pwr_wind = 0;
	LowBandPowerAve = 0;
	msc = 0;
	msc_reliabilityCheck = 0;
	flag_strong_wind_cand = 0;
	cnt_strongWind_ON = 0;
	cnt_strongWind_OFF = 0;
	flag_normal_wind_cand = 0;
	cnt_normalWind_ON = 0;
	cnt_normalWind_OFF = 0;
	for (j = 0; j < 2; j++)
	{
		Thr_strong_Wind[j] = (float)Thr_strong_Wind_init[j];
		Thr_normal_Wind[j] = (float)Thr_normal_Wind_init[j];
	}
	
	LTSVthd = 0.06;
	Kltsv_st = 16;
	Kltsv_end = 128;
	Rltsv = 16;
	for (i = 0; i < Rltsv; i++)
		for (j = 0; j < Kltsv_end - Kltsv_st + 1; j++)
			SxMtxLtsv[i][j] = 0;
	LTSVthdLowBound = 0.04;
	
	// Init flags
	frmVAD_Acc = 0;
	frmVAD_Rx_AEC = 0;
	for (i = 0; i < BIN_ACCMAX; i++)
	{
		VADACCmask[i] = 0;
	}
	flag_Wind_strong = 0;
	flag_Wind_normal = 0;
	flag_Tx_silence = 0;
	flag_Tx_silence_AEC = 0;
	flag_Tx_LoudSig = 0;
	flag_NoiseOnly = 0;
	flag_FrmDT = 0;
	flag_SingleTalk = 0;
	flag_SingleNET = 0;
	flag_ACC_Effective = 0;
	noiseLevel = 0;
	state_noise2clean = 0;
	flag_OuterMicLowReliability = 0;
	cnt_OuterMicLowReliability_OFF = 0;

	// vad acc (BSH)
	SV_AccSensor_Init();
	frmVAD_Acc_BSH = 0;

	SV_FLAG_Init();

	flag_frmCnt = 0;
	return;
}


void VoiceAndNoiseStatus_Deinit()
{
	SV_FLAG_Deinit();
}
