



#include "RNN.h"



#if 1//#ifdef __EXE_RNN__

#define MIN16(a,b) ((a) < (b) ? (a) : (b))   /**< Minimum 16-bit value.   */
#define MAX16(a,b) ((a) > (b) ? (a) : (b))   /**< Maximum 16-bit value.   */
#define MIN32(a,b) ((a) < (b) ? (a) : (b))   /**< Minimum 32-bit value.   */
#define MAX32(a,b) ((a) > (b) ? (a) : (b))   /**< Maximum 32-bit value.   */

#define INPUT_SIZE 35


//#if(FLAG_SELECT_C_DSP == 1)
//#include <stdio.h>
//#include <stdlib.h>
//extern FILE     *fp_deg_2micBF[N_fp_2micBF_debuffiles];
//#endif

const DenseLayer input_dense = {
   35,
   16,
   ACTIVATION_TANH
};

const GRULayer vad_gru = {
   16,
   16,
   ACTIVATION_TANH
};


const GRULayer noise_gru = {
   67,
   16,
   ACTIVATION_RELU
};

const GRULayer denoise_gru = {
   67,
   36,
   ACTIVATION_TANH
};


const DenseLayer denoise_output = {
   36,
   22,
   ACTIVATION_SIGMOID
};


const DenseLayer vad_output = {
   16,
   1,
   ACTIVATION_SIGMOID
};

//#define INPUT_DENSE_SIZE 16
extern const DenseLayer input_dense;
//#define VAD_GRU_SIZE 16
extern const GRULayer vad_gru;
//#define NOISE_GRU_SIZE 16
extern const GRULayer noise_gru;
//#define DENOISE_GRU_SIZE 36
extern const GRULayer denoise_gru;
//#define DENOISE_OUTPUT_SIZE 22
extern const DenseLayer denoise_output;
//#define VAD_OUTPUT_SIZE 1
extern const DenseLayer vad_output;


static __inline int DVTXOP_L_mpy_32_16(int L_var2, short var1)
{

	int result;
	long long int L_varOut = (long long int)L_var2 * var1;

	L_varOut = L_varOut >> 15;

	if (L_varOut > DVTX_MAX_32)
	{
		result = DVTX_MAX_32;
	}
	else if (L_varOut < DVTX_MIN_32)
	{
		result = DVTX_MIN_32;
	}
	else
	{
		result = (int)L_varOut;
	}
	return (result);


}

static __inline int DVTXOP_LL_mpy_high(int L_var1, int L_var2)
{

	long long int result = (long long int)L_var1 * L_var2;

	result = result >> 32;
	return (int)result;

}



static __inline int tansig_approx_fix(int x_fix) //input in Q19, return in Q19
{
	int rtn_fix;
	int i, f;
	int tmp1, tmp2;
	int sign;

	if (x_fix >= DVTXOP_L_shl(8, 19))
		return DVTXOP_L_shl(1, 19);
	if (x_fix <= DVTXOP_L_negate(DVTXOP_L_shl(8, 19)))
		return DVTXOP_L_shl(-1, 19);
	if (x_fix == 0)
		return 0;

	sign = 1;
	if (x_fix < 0)
	{
		x_fix = DVTXOP_L_negate(x_fix);
		sign = -1;
	}

	i = DVTXOP_L_shr(x_fix, 14);
	f = DVTXOP_L_sub(x_fix, DVTXOP_L_shl(i, 14));
	f = DVTXOP_L_shl(f, 17);

	tmp1 = tansig_table_fix[i];
	tmp2 = tansig_table_fix[i + 1] - tmp1;
	tmp2 = DVTXOP_LL_mpy_high(f, tmp2);
	rtn_fix = DVTXOP_L_shr(DVTXOP_L_add(tmp1, DVTXOP_L_add(tmp2, tmp2)), 4);
	if (sign == (-1))
		rtn_fix = DVTXOP_L_negate(rtn_fix);

	return rtn_fix;
}

static __inline int sigmoid_approx_fix(int x_fix)  //input in Q19, output in Q19
{
	int rtn_fix;

	x_fix = DVTXOP_L_shr(x_fix, 1);
	rtn_fix = tansig_approx_fix(x_fix);
	rtn_fix = DVTXOP_L_add(DVTXOP_L_shl(1, 18), DVTXOP_L_shr(rtn_fix, 1));

	return rtn_fix;
}


static __inline int relu_fix(int x_fix)
{
	return x_fix < 0 ? 0 : x_fix;
}

static __inline long long DVTXOP_Mpy_Ls_32bit(int Lvar1, short var2)
{

	long long int tmp;

	tmp = (long long int)Lvar1 * (int)var2;
	return tmp;

}


void compute_dense_fx(const DenseLayer *layer, const rnn_weight *fx_w, const rnn_weight *fx_b, int *output_fx, const int *input_fx)
{
	short i, idx;
	short N, M;
	long long sum = 0;

	M = layer->nb_inputs;
	N = layer->nb_neurons;



	for (i = 0; i < N; i++) {
		sum = 0;
		for (idx = 0; idx < M; idx++) {
			sum += DVTXOP_Mpy_Ls_32bit(input_fx[idx], DVTXOP_shl((short)fx_w[idx], 7));
		}

		output_fx[i] = (int)(sum >> 15);

		fx_w += M;

	}
	for (i = 0; i < N; i++)
	{
		output_fx[i] = DVTXOP_L_add(DVTXOP_L_shl((int)fx_b[i], 11), output_fx[i]);
	}

	if (layer->activation == ACTIVATION_SIGMOID)
	{
		for (i = 0; i < N; i++)
			output_fx[i] = sigmoid_approx_fix(output_fx[i]);
	}
	else if (layer->activation == ACTIVATION_TANH)
	{
		for (i = 0; i < N; i++)
			output_fx[i] = tansig_approx_fix(output_fx[i]);
	}
	else if (layer->activation == ACTIVATION_RELU)
	{
		for (i = 0; i < N; i++)
			output_fx[i] = relu_fix(output_fx[i]);
	}


}

void compute_gru_fx(RNNState *rnn, const GRULayer *gru, const rnn_weight *fx_kernel_w, const rnn_weight *fx_re_kernel_w, const rnn_weight *fx_b, short *state_fx, const int *input_fx)
{
	short i, idx;
	short N, M;
	int sum_fx;
	int ltmp, ltmp2, ltmp3;
	short norm_shift, norm_shift1;
	long long sum = 0;

	const rnn_weight *fx_kernel_z;
	const rnn_weight *fx_kernel_r;
	const rnn_weight *fx_kernel_h;
	const rnn_weight *fx_re_kernel_z;
	const rnn_weight *fx_re_kernel_r;
	const rnn_weight *fx_re_kernel_h;
	const rnn_weight *fx_bias_z;
	const rnn_weight *fx_bias_r;
	const rnn_weight *fx_bias_h;

	M = gru->nb_inputs;
	N = gru->nb_neurons;

	fx_kernel_z = fx_kernel_w;
	fx_kernel_r = fx_kernel_w + M * N;
	fx_kernel_h = fx_kernel_w + 2 * M * N;
	fx_re_kernel_z = fx_re_kernel_w;
	fx_re_kernel_r = fx_re_kernel_w + N * N;
	fx_re_kernel_h = fx_re_kernel_w + 2 * N * N;

	fx_bias_z = fx_b;
	fx_bias_r = fx_b + N;
	fx_bias_h = fx_b + 2 * N;

	//fx_rnn_gru_preh_FCN_c(input_fx, fx_kernel_z, M, N, rnn->z_fx, 7);		//Q:19+7-15=11
	for (i = 0; i < N; i++) {
		sum = 0;
		for (idx = 0; idx < M; idx++) {
			sum += DVTXOP_Mpy_Ls_32bit(input_fx[idx], DVTXOP_shl((short)fx_kernel_z[idx], 7));
		}

		rnn->z_fx[i] = (int)(sum >> 15);

		fx_kernel_z += M;

	}


	for (i = 0; i < N; ++i)
	{
		sum_fx = 0;
		for (idx = 0; idx < N; ++idx)
		{
			sum_fx = DVTXOP_L_add(sum_fx, DVTXOP_L_mult(state_fx[idx], (short)fx_re_kernel_z[idx + i * N])); ///Q_GRU_w + output_Q+1
			rnn->fx_re_z[i] = sum_fx;//Q_GRU_w + output_Q+1

		}
	}

	for (i = 0; i < N; i++)
	{
		/* Compute update gate. */
		sum_fx = DVTXOP_L_add(DVTXOP_L_shl((int)fx_bias_z[i], 11), rnn->z_fx[i]); //q11
		sum_fx = DVTXOP_L_add(sum_fx, rnn->fx_re_z[i]);		 //q11
		rnn->z_fx[i] = sigmoid_approx_fix(sum_fx);	 //q19
	}




	for (i = 0; i < N; i++) {
		sum = 0;
		for (idx = 0; idx < M; idx++) {
			sum += DVTXOP_Mpy_Ls_32bit(input_fx[idx], DVTXOP_shl((short)fx_kernel_r[idx], 7));
		}

		rnn->r_fx[i] = (int)(sum >> 15);

		fx_kernel_r += M;

	}

	for (i = 0; i < N; ++i)
	{
		sum_fx = 0;
		for (idx = 0; idx < N; ++idx)
		{
			sum_fx = DVTXOP_L_add(sum_fx, DVTXOP_L_mult(state_fx[idx], (short)fx_re_kernel_r[idx + i * N])); ///Q_GRU_w + output_Q+1
			rnn->fx_re_r[i] = sum_fx;//Q_GRU_w + output_Q+1

		}
	}

	for (i = 0; i < N; i++)
	{
		/* Compute reset gate. */
		sum_fx = DVTXOP_L_add(DVTXOP_L_shl((int)fx_bias_r[i], 11), rnn->r_fx[i]);                //q11
		sum_fx = DVTXOP_L_add(sum_fx, rnn->fx_re_r[i]);                     //q11
		rnn->r_fx[i] = sigmoid_approx_fix(sum_fx);					//q19
	}


	for (i = 0; i < N; i++)
	{
		sum = 0;
		for (idx = 0; idx < M; idx++)
		{
			sum += DVTXOP_Mpy_Ls_32bit(input_fx[idx], DVTXOP_shl((short)fx_kernel_h[idx], 7));
		}

		rnn->h_fx[i] = (int)(sum >> 15);
		fx_kernel_h += M;

	}
	for (i = 0; i < N; ++i)
	{
		rnn->r_fx[i] = DVTXOP_L_shl(DVTXOP_L_mpy_32_16(rnn->r_fx[i], state_fx[i]), 4); //q:19+10-15+4=18
	}


	for (i = 0; i < N; i++)
	{
		sum = 0;
		for (idx = 0; idx < N; idx++)
		{
			sum += DVTXOP_Mpy_Ls_32bit(rnn->r_fx[idx], DVTXOP_shl((short)fx_re_kernel_h[idx], 8));
		}

		rnn->fx_re_h[i] = (int)(sum >> 15);
		fx_re_kernel_h += N;

	}

	for (i = 0; i < N; i++)
	{
		/* Compute output. */
		sum_fx = DVTXOP_L_add(DVTXOP_L_shl((int)fx_bias_h[i], 11), rnn->h_fx[i]);
		sum_fx = DVTXOP_L_add(sum_fx, rnn->fx_re_h[i]);
		if (gru->activation == ACTIVATION_SIGMOID)
			rnn->h_fx[i] = sigmoid_approx_fix(sum_fx);
		else if (gru->activation == ACTIVATION_TANH)
			rnn->h_fx[i] = tansig_approx_fix(sum_fx);
		else if (gru->activation == ACTIVATION_RELU)
			rnn->h_fx[i] = relu_fix(sum_fx);

	}

	for (i = 0; i < N; i++)
	{

		norm_shift = DVTXOP_norm_l(rnn->h_fx[i]);
		ltmp = DVTXOP_L_shl(rnn->h_fx[i], norm_shift);

		ltmp2 = DVTXOP_L_sub(1 << 19, rnn->z_fx[i]);
		norm_shift1 = DVTXOP_norm_l(ltmp2);
		ltmp3 = DVTXOP_L_shl(ltmp2, norm_shift1);
		ltmp2 = DVTXOP_LL_mpy_high(ltmp, ltmp3);
		ltmp2 = DVTXOP_L_shr(ltmp2, (norm_shift + norm_shift1 + 38 - 32) - 14);


		ltmp = DVTXOP_L_add(ltmp2, DVTXOP_L_mpy_32_16(rnn->z_fx[i], state_fx[i]));			//q14

		state_fx[i] = DVTXOP_saturate(DVTXOP_L_shr(ltmp, 4));			//q10

	}

}


int rnnnoise_init(DenoiseState *st)
{
	int i, j;

	st->memid = 0;
	st->BLK_NORM = 0;


	for (i = 0; i < CEPS_MEM; i++)
		for (j = 0; j < NB_BANDS; j++)
		{
			st->fx_cepstral_mem[i][j] = 0;
		}


	for (i = 0; i < NB_BANDS; i++)
	{
		st->lastg[i] = 0;
		st->Ly_fx[i] = 0;
		st->fx_Ex[i] = 0;
		st->gn_fx[i] = 0;
		st->g_fx[i] = 0;
		st->fx_Ex_sum[i] = 0;
	}

	for (i = 0; i < FREQ_SIZE; i++)st->gf_fx[i] = 0;
	for (i = 0; i < NB_FEATURES; i++)st->fx_features[i] = 0;


	for (i = 0; i < FREQ_SIZE; i++)
	{
		st->fx_X[i].r = 0;
		st->fx_X[i].i = 0;
	}




	//init for RNNState
	for (i = 0; i < VAD_GRU_SIZE; i++) st->rnn.vad_gru_state_fx[i] = 0;
	for (i = 0; i < NOISE_GRU_SIZE; i++) st->rnn.noise_gru_state_fx[i] = 0;
	for (i = 0; i < DENOISE_GRU_SIZE; i++) st->rnn.denoise_gru_state_fx[i] = 0;

	for (i = 0; i < MAX_NEURONS; i++)
	{
		st->rnn.z_fx[i] = 0;
		st->rnn.r_fx[i] = 0;
		st->rnn.h_fx[i] = 0;
		st->rnn.fx_re_z[i] = 0;
		st->rnn.fx_re_r[i] = 0;
		st->rnn.fx_re_h[i] = 0;
		st->rnn.ltmp_arr[i] = 0;
		st->rnn.dense_out_fx[i] = 0;
	}

	for (i = 0; i < MAX_NEURONS * 3; i++)
	{
		st->rnn.noise_input_fx[i] = 0;
		st->rnn.denoise_input_fx[i] = 0;
	}




	return 0;
}



static __inline int Fx_log10_q0(int pwr)
{
	int pwrdB;

	pwr = DVTXOP_L_sub(DVTXOP_fnLog10(DVTXOP_L_add(pwr, 1)), DVTX_LOG10FIX);	//Q26
	pwrdB = DVTXOP_L_shr(pwr, 11);				//Q15
	return pwrdB;
}



int fx_rnnoise_process_frame(DenoiseState *st, short *in, short *denoiseout)
{
	short i, j, k;
	short silence = 1;
	short band_size;
	const short alpha = 19661; //0.6
	const short bands_sqrt = 9880; //q15, sqrt(2. / NB_BANDS)
	int vad_prob = 0;
	int ltmp;
	int spec_variability = 0;
	int *fx_ceps_0, *fx_ceps_1, *fx_ceps_2;
	int follow_fx, logMax_fx;
	short norm_shift1;
	short stmp;
	int offset;
	int lim;
	int mindist;
	int dist;


	st->fx_X[0].r = in[0];
	st->fx_X[256].r = in[1];
	st->fx_X[0].i = 0;
	st->fx_X[256].i = 0;
	for (i = 1; i < WINDOW_SIZE >> 1; i++)
	{
		st->fx_X[i].r = in[2 * i];
		st->fx_X[i].i = in[2 * i + 1];
	}

	//compute band energy
	for (i = 0; i < NB_BANDS; i++)
		st->fx_Ex_sum[i] = 0;

	k = 0;
	for (i = 0; i < NB_BANDS - 1; i++)
	{
		band_size = (eband5ms[i + 1] - eband5ms[i]);
		for (j = 0; j < band_size; j++)
		{
			ltmp = DVTXOP_L_mult(st->fx_X[(eband5ms[i]) + j].r, st->fx_X[(eband5ms[i]) + j].r);
			ltmp = DVTXOP_L_mac(ltmp, st->fx_X[(eband5ms[i]) + j].i, st->fx_X[(eband5ms[i]) + j].i);


			st->fx_Ex_sum[i] = DVTXOP_L_add(st->fx_Ex_sum[i], DVTXOP_L_mpy_ls(ltmp, (32767 - frac_array[k])));
			st->fx_Ex_sum[i + 1] = DVTXOP_L_add(st->fx_Ex_sum[i + 1], DVTXOP_L_mpy_ls(ltmp, frac_array[k]));
			k++;
		}
	}

	st->fx_Ex[0] = st->fx_Ex_sum[0];
	st->fx_Ex[NB_BANDS - 1] = st->fx_Ex_sum[NB_BANDS - 1];
	for (i = 1; i < NB_BANDS - 1; i++)
	{
		st->fx_Ex[i] = DVTXOP_L_shr(st->fx_Ex_sum[i], 1);
	}

	logMax_fx = -65536;
	follow_fx = -65536;			//q26   1.5->100663,296

	stmp = (st->BLK_NORM - 8 + 9) * 2;
	offset = Fx_log10_q0(DVTXOP_L_shl(1, stmp));
	lim = 10 * DVTXOP_L_shl(1, stmp - 10);
	ltmp = 0;
	for (i = 0; i < NB_BANDS; i++)
	{
		st->Ly_fx[i] = Fx_log10_q0(st->fx_Ex[i] + lim) - offset;
		st->Ly_fx[i] = DVTX_MAX((logMax_fx - 229376), DVTX_MAX((follow_fx - 49152), st->Ly_fx[i]));
		logMax_fx = DVTX_MAX(logMax_fx, st->Ly_fx[i]);
		follow_fx = DVTX_MAX((follow_fx - 49152), st->Ly_fx[i]);
		ltmp = DVTXOP_L_add(ltmp, DVTXOP_L_shr(st->fx_Ex[i], stmp - 10));		//q10
	}

	if (ltmp < 40) // 0.04->q10
	{
		/* If there's no audio, avoid messing up the state. */
		for (i = 0; i < NB_FEATURES; i++)st->fx_features[i] = 0;
		silence = 1;
	}
	else
	{
		//dct:cepstral coefficients 
		for (i = 0; i < NB_BANDS; i++)
		{
			ltmp = 0;
			for (j = 0; j < NB_BANDS; j++)
			{
				ltmp = DVTXOP_L_add(ltmp, DVTXOP_L_mpy_ls(st->Ly_fx[j], dct_table_fx[j*NB_BANDS + i]));
			}
			st->fx_features[i] = DVTXOP_L_mpy_ls(ltmp, bands_sqrt);
		}


		st->fx_features[0] -= 393216;
		st->fx_features[1] -= 131072;
		fx_ceps_0 = st->fx_cepstral_mem[st->memid];
		fx_ceps_1 = (st->memid < 1) ? st->fx_cepstral_mem[CEPS_MEM + st->memid - 1] : st->fx_cepstral_mem[st->memid - 1];
		fx_ceps_2 = (st->memid < 2) ? st->fx_cepstral_mem[CEPS_MEM + st->memid - 2] : st->fx_cepstral_mem[st->memid - 2];
		for (i = 0; i < NB_BANDS; i++) fx_ceps_0[i] = st->fx_features[i];
		st->memid++;
		for (i = 0; i < NB_DELTA_CEPS; i++)
		{
			st->fx_features[i] = fx_ceps_0[i] + fx_ceps_1[i] + fx_ceps_2[i];
			st->fx_features[NB_BANDS + i] = fx_ceps_0[i] - fx_ceps_2[i];
			st->fx_features[NB_BANDS + NB_DELTA_CEPS + i] = fx_ceps_0[i] - 2 * fx_ceps_1[i] + fx_ceps_2[i];
		}

		/* Spectral variability features. */
		if (st->memid == CEPS_MEM) st->memid = 0;
		for (i = 0; i < CEPS_MEM; i++)
		{
			mindist = 0x7fffffff;
			for (j = 0; j < CEPS_MEM; j++)
			{
				dist = 0;

				if (j != i)
				{
					for (k = 0; k < NB_BANDS; k++)
					{
						ltmp = DVTXOP_L_sub(st->fx_cepstral_mem[i][k], st->fx_cepstral_mem[j][k]);
						norm_shift1 = DVTXOP_norm_l(ltmp);
						stmp = DVTXOP_extract_h(DVTXOP_L_shl(ltmp, norm_shift1));

						ltmp = DVTXOP_L_shr(DVTXOP_L_mult(stmp, stmp), 2 * norm_shift1 - 1 - 10);
						dist = DVTXOP_L_add(dist, ltmp);
					}

					mindist = MIN32(mindist, dist);				//q15
				}
			}
			spec_variability = DVTXOP_L_add(spec_variability, mindist);
		}

		st->fx_features[NB_BANDS + 2 * NB_DELTA_CEPS] = DVTXOP_L_sub(DVTXOP_L_shr(spec_variability, -2), 68813);
		silence = 0;
	}



	if (!silence)
	{
		for (i = 0; i < NB_FEATURES; i++)st->fx_features[i] = DVTXOP_L_shl(st->fx_features[i], 4);
		compute_dense_fx(&input_dense, input_dense_w, input_dense_b, st->rnn.dense_out_fx, st->fx_features);
		compute_gru_fx(&st->rnn, &vad_gru, gru_w_vad, gru_re_w_vad, gru_b_vad, st->rnn.vad_gru_state_fx, st->rnn.dense_out_fx);
		for (i = 0; i < VAD_GRU_SIZE; i++)
			st->rnn.ltmp_arr[i] = DVTXOP_L_shl((int)st->rnn.vad_gru_state_fx[i], 9);
		compute_dense_fx(&vad_output, vad_dense_w, vad_dense_b, &vad_prob, st->rnn.ltmp_arr);
		for (i = 0; i < INPUT_DENSE_SIZE; i++) st->rnn.noise_input_fx[i] = st->rnn.dense_out_fx[i];
		for (i = 0; i < VAD_GRU_SIZE; i++) st->rnn.noise_input_fx[i + INPUT_DENSE_SIZE] = st->rnn.ltmp_arr[i];
		for (i = 0; i < INPUT_SIZE; i++) st->rnn.noise_input_fx[i + INPUT_DENSE_SIZE + VAD_GRU_SIZE] = st->fx_features[i];
		compute_gru_fx(&st->rnn, &noise_gru, gru_w_noise, gru_re_w_noise, gru_b_noise, st->rnn.noise_gru_state_fx, st->rnn.noise_input_fx);
		for (i = 0; i < VAD_GRU_SIZE; i++) st->rnn.denoise_input_fx[i] = st->rnn.ltmp_arr[i];
		for (i = 0; i < NOISE_GRU_SIZE; i++) st->rnn.denoise_input_fx[i + VAD_GRU_SIZE] = DVTXOP_L_shl((int)st->rnn.noise_gru_state_fx[i], 9);
		for (i = 0; i < INPUT_SIZE; i++) st->rnn.denoise_input_fx[i + VAD_GRU_SIZE + NOISE_GRU_SIZE] = st->fx_features[i];
		compute_gru_fx(&st->rnn, &denoise_gru, gru_w_denoise, gru_re_w_denoise, gru_b_denoise, st->rnn.denoise_gru_state_fx, st->rnn.denoise_input_fx);
		for (i = 0; i < DENOISE_GRU_SIZE; i++)
			st->rnn.ltmp_arr[i] = DVTXOP_L_shl((int)st->rnn.denoise_gru_state_fx[i], 9);
		compute_dense_fx(&denoise_output, denoise_dense_w, denoise_dense_b, st->gn_fx, st->rnn.ltmp_arr);

		for (i = 0; i < NB_BANDS; i++)
		{
			st->gn_fx[i] = DVTXOP_L_shr(st->gn_fx[i], 4);			//q15
			st->g_fx[i] = DVTXOP_extract_l(DVTXOP_L_sub(32767, st->gn_fx[i]));		//q15

			st->g_fx[i] = MAX16(st->g_fx[i], DVTXOP_mult(alpha, st->lastg[i]));
			st->g_fx[i] = MAX16(st->g_fx[i], 4096);
			st->lastg[i] = st->g_fx[i];
		}

		k = 0;
		for (i = 0; i < NB_BANDS - 1; i++)
		{

			band_size = (eband5ms[i + 1] - eband5ms[i]);
			for (j = 0; j < band_size; j++) {
				ltmp = DVTXOP_L_mac((DVTXOP_L_mult(st->g_fx[i], (32767 - frac_array[k]))), st->g_fx[i + 1], frac_array[k]);
				st->gf_fx[(eband5ms[i]) + j] = DVTXOP_extract_h(ltmp);		//q15
				k++;
			}
		}

		for (i = 0+2; i < FREQ_SIZE-2; i++)
		{
			//st->gf_fx[i] = DVTX_MAX(st->gf_fx[i], 16000);
			//st->fx_X[i].r = DVTXOP_extract_h(DVTXOP_L_mult(st->gf_fx[i], st->fx_X[i].r));
			//st->fx_X[i].i = DVTXOP_extract_h(DVTXOP_L_mult(st->gf_fx[i], st->fx_X[i].i));
			st->fx_X[i].r = DVTXOP_mult_r(st->gf_fx[i], st->fx_X[i].r);
			st->fx_X[i].i = DVTXOP_mult_r(st->gf_fx[i], st->fx_X[i].i);
		}
	}
//#if(FLAG_SELECT_C_DSP == 1)
//#if(Debug_File_Write_C == 1)
//	i = FREQ_SIZE;
//	for (i = 0; i < FREQ_SIZE; i++)	{
//
//		fprintf(fp_deg_2micBF[23], "%d\n",
//			st->gf_fx[i]			
//		);
//	}
//#endif
//#endif



	for (i = 1; i < WINDOW_SIZE >> 1; i++)
	{
		denoiseout[2 * i] = st->fx_X[i].r;
		denoiseout[2 * i + 1] = st->fx_X[i].i;
	}
	denoiseout[0] = st->fx_X[0].r;
	denoiseout[1] = st->fx_X[256].r;


	return vad_prob;
}

#endif