www.pudn.com > AVS_M_ver10.rar > dec_new_stereo.c


/* 
*********************************************************************** 
* COPYRIGHT AND WARRANTY INFORMATION 
* 
* Copyright 2007  Audio Video Coding Standard, Part ¢ú 
* 
* This software module was developed by AVS Audio sub-group 
* 
* DISCLAIMER OF WARRANTY 
* 
* These software programs are available to the users without any 
* license fee or royalty on an "as is" basis. The AVS disclaims 
* any and all warranties, whether express, implied, or statutory, 
* including any implied warranties of merchantability or of fitness 
* for a particular purpose. In no event shall the contributors or  
* the AVS be liable for any incidental, punitive, or consequential 
* damages of any kind whatsoever arising from the use of this program. 
* 
* This disclaimer of warranty extends to the user of this program 
* and user's customers, employees, agents, transferees, successors, 
* and assigns. 
* 
* The AVS does not represent or warrant that the program furnished 
* hereunder are free of infringement of any third-party patents. 
* Commercial implementations of AVS, including shareware, may be 
* subject to royalty fees to patent holders. Information regarding 
* the AVS patent policy is available from the AVS Web site at 
* http://www.avs.org.cn 
* 
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY. 
************************************************************************ 
*/ 
 
#include  
#include  
#include  
#include  
#include "../include/amr_plus.h" 
#include "../include/s_util.h" 
#include "../include/table_decl.h" 
 
/* NEW_STEREO */ 
/* TO BOTTOM OF THIS FILE */ 
 
// initial stereo struction and parameter 
void init_new_stereo_decoder(NEW_STEREO_DATA_DEC *newStereo, float old_bitrate) 
{ 
	int i; 
 
	set_zero(newStereo->old_speech_mono, M+NEW_STEREO_DECODER_DELAY); 
	set_zero(newStereo->old_speech_left, 512-NEW_STEREO_DELAY); 
	set_zero(newStereo->old_speech_right, 512-NEW_STEREO_DELAY); 
 
	set_zero(newStereo->old_AqLF, 5*(M+1)); 
	for (i = 0;i < 5;i++) 
	{ 
		newStereo->old_AqLF[i*(M+1)]=1.0f; 
	} 
 
	newStereo->bitrate = old_bitrate; 
 
	if (old_bitrate <= 32.0f) 
	{ 
		newStereo->lowfreq_end_num_l = 128; 
		newStereo->lowfreq_end_num_s = newStereo->lowfreq_end_num_l / 4; 
	} 
	else 
	{ 
		newStereo->lowfreq_end_num_l = 192;  
		newStereo->lowfreq_end_num_s = newStereo->lowfreq_end_num_l / 4; 
	} 
 
	set_zero(newStereo->pre_left_gain, MF_GAIN_NUM); 
	set_zero(newStereo->pre_right_gain, MF_GAIN_NUM); 
 
	set_zero(newStereo->old_left_freq_gain, MF_GAIN_NUM); 
	set_zero(newStereo->old_right_freq_gain, MF_GAIN_NUM); 
 
	newStereo->isTransientFrame = 0; 
 
	newStereo->mem_ovlp_size_enc = 0; 
	newStereo->mem_ovlp_size_dec = 0; 
 
#ifdef LOW_COMPLEXITY 
	set_zero(newStereo->mem_side_ovlp, L_OVLP); 
	set_zero(newStereo->mem_synth_side, M); 
#else 
	set_zero(newStereo->mem_left_ovlp, L_OVLP); 
	set_zero(newStereo->mem_right_ovlp, L_OVLP); 
#endif 
	set_zero(newStereo->mem_mono_error, 4); 
 
	set_zero(newStereo->mem_synth_left, M); 
	set_zero(newStereo->mem_synth_right, M); 
 
	set_zero(newStereo->old_mono_exc, HI_FILT_ORDER); 
	set_zero(newStereo->old_wh_q, HI_FILT_ORDER); 
} 
 
// decode wiener filter coefficients 
static void dec_filt(int **prm, 
					 float wh[], 
					 float old_wh[], 
					 int bfi, 
					 const PMSVQ*	filt_hi_pmsvq 
					 ) 
{ 
	pmsvq_inv(wh, prm, old_wh, bfi, filt_hi_pmsvq); 
} 
 
// high pass filter 
static void hp1K_12k8(const float *orig_signal, 
					  float *filted_signal, 
					  float *mem, 
					  int lg) 
{ 
	int i; 
	float x0, x1, x2; 
	float y0, y1, y2; 
 
	y1 = mem[0]; 
	y2 = mem[1]; 
	x0 = mem[2]; 
	x1 = mem[3]; 
 
	for (i = 0; i < lg; i++) 
	{ 
		x2 = x1; 
		x1 = x0; 
		x0 = orig_signal[i]; 
		y0 = y1 * 1.85229f + y2 * -0.86314f + x0 * 0.9278487343389f + x1 * -1.8556974686778f + x2 * 0.9278487343389f; 
		filted_signal[i] = y0; 
		y2 = y1;                                                               
		y1 = y0; 
	} 
 
	mem[0] = ((y1 > 1e-10) | (y1 < -1e-10)) ? y1 : 0; 
	mem[1] = ((y2 > 1e-10) | (y2 < -1e-10)) ? y2 : 0; 
	mem[2] = ((x0 > 1e-10) | (x0 < -1e-10)) ? x0 : 0; 
	mem[3] = ((x1 > 1e-10) | (x1 < -1e-10)) ? x1 : 0; 
} 
 
static void GetEstimatedSideExc(NEW_STEREO_DATA_DEC *newStereo, 
								int nIsTransient, 
								const float *mono_exc,  
								float *est_side_exc,  
								int est_len, 
								int *param) 
{ 
	int i; 
	float tmp_mono_exc[L_FRAME_PLUS+L_OVLP+HI_FILT_ORDER]; 
	float filted_mono_exc[L_FRAME_PLUS+L_OVLP]; 
	float *p_h; 
	float *x; 
	int *prm; 
 
	if (nIsTransient == 0) 
	{ 
		prm = param; 
		 
		newStereo->filt_hi_pmsvq = &filt_hi_pmsvq7; 
 
		dec_filt(&prm, newStereo->wiener_filter, newStereo->old_wh_q, 0, newStereo->filt_hi_pmsvq); 
	} 
	else 
	{ 
		if (newStereo->bitrate < 32.0) 
		{ 
			newStereo->filt_hi_pmsvq = &filt_hi_pmsvq4; 
		} 
		else 
		{ 
			newStereo->filt_hi_pmsvq = &filt_hi_pmsvq7; 
		} 
 
		for (i = 0; i < 4; i++) 
		{ 
			prm = param + i * 2;	// maximum: 2 msvq stages (filt) 
 
			dec_filt(&prm, &newStereo->wiener_filter[i*HI_FILT_ORDER], newStereo->old_wh_q, 0, newStereo->filt_hi_pmsvq); 
		} 
	} 
 
#if 1 
	hp1K_12k8(mono_exc, filted_mono_exc, newStereo->mem_mono_error, est_len); 
#else 
	mvr2r(mono_exc, filted_mono_exc, est_len); 
#endif 
 
	mvr2r(newStereo->old_mono_exc, tmp_mono_exc, HI_FILT_ORDER); 
	mvr2r(filted_mono_exc, tmp_mono_exc+HI_FILT_ORDER, est_len); 
	mvr2r(filted_mono_exc+L_FRAME_PLUS-HI_FILT_ORDER, newStereo->old_mono_exc, HI_FILT_ORDER); 
 
	p_h = newStereo->wiener_filter; 
	if (nIsTransient == 0) 
	{ 
		/* set signal pointers */ 
		x = tmp_mono_exc+HI_FILT_ORDER; 
 
		/* local synthesis */ 
		fir_filt(p_h, HI_FILT_ORDER, x, est_side_exc, est_len); 
	} 
	else 
	{ 
		int est_len_quick = est_len / 4; 
		for (i = 0; i < 4; i++) 
		{ 
			/* set signal pointers */ 
			x = tmp_mono_exc + HI_FILT_ORDER + i*256; 
 
			/* local synthesis */ 
			fir_filt(p_h, HI_FILT_ORDER, x, est_side_exc+i*est_len_quick, est_len_quick); 
 
			p_h += HI_FILT_ORDER; 
		} 
	} 
} 
 
static void MakeFFTTransform(NEW_STEREO_DATA_DEC *newStereo, 
							 int   is_transient, 
							 const float *est_side_ch, 
							 const float *mono_ch, 
							 float *mono_fft, 
							 float *est_side_fft, 
							 float *est_left_fft, 
							 float *est_right_fft) 
{ 
	int i, w; 
	int L_frame, lext, lg; 
	float  window[256]; 
	int ovlp_size; 
	float est_xn_side[L_FRAME_PLUS+L_OVLP]; 
	float xn_mono[L_FRAME_PLUS+L_OVLP]; 
//	float est_side_fft[L_FRAME_PLUS+L_OVLP]; 
 
	if (is_transient == 0)	// smooth 
	{ 
		mvr2r(est_side_ch, est_xn_side, L_FRAME_PLUS+L_OVLP); 
		mvr2r(mono_ch, xn_mono, L_FRAME_PLUS+L_OVLP); 
 
		lext = L_OVLP; 
		L_frame =L_FRAME_PLUS; 
 
		ovlp_size = newStereo->mem_ovlp_size_enc; 
		lg = L_frame + lext; 
		/* built window for overlaps section */ 
		cos_window(window, ovlp_size, lext); 
 
		/* xn[] windowing for TCX overlap */ 
		for (i = 0; i < ovlp_size; i++)  
		{ 
			est_xn_side[i] *= window[i]; 
			xn_mono[i] *= window[i]; 
		} 
		for (i = 0; i < lext; i++)  
		{ 
			est_xn_side[L_frame+i] *= window[ovlp_size+i]; 
			xn_mono[L_frame+i] *= window[ovlp_size+i]; 
		} 
 
		/*-----------------------------------------------------------* 
		* Compute the FFT of xn[].                                  * 
		* Coefficients (xri[]) order are                            * 
		*    re[0], re[n/2], re[1], re[2], ... re[n/2-1], im[n/2-1] * 
		* Note that last FFT element (re[n/2]) is zeroed.           * 
		*-----------------------------------------------------------*/ 
		fft9(est_xn_side, est_side_fft, (short)lg); 
		est_side_fft[1] = 0.0f;    /* freq bin    at 6400 Hz zeroed */ 
 
		fft9(xn_mono, mono_fft, (short)lg); 
		mono_fft[1] = 0.0f;       /* freq bin at 6400 Hz zeroed */ 
 
		newStereo->mem_ovlp_size_enc = L_OVLP; 
	} 
	else 
	{ 
		lext = L_OVLP/4; 
		L_frame =L_FRAME_PLUS/4; 
		lg = L_frame + lext; 
 
		for (w = 0; w < 4; w++) 
		{ 
			float *cur_est_side_fft = est_side_fft + w * lg; 
			float *cur_mono_fft = mono_fft + w * lg; 
 
			mvr2r(est_side_ch + w * lg, est_xn_side, lg);	// correspond to ENCODER 
			mvr2r(mono_ch + w * L_frame, xn_mono, lg); 
 
			ovlp_size = newStereo->mem_ovlp_size_enc; 
 
			cos_window(window, ovlp_size, lext); 
 
			/* xn[] windowing for TCX overlap */ 
			for (i = 0; i < ovlp_size; i++)  
			{ 
				est_xn_side[i] *= window[i]; 
				xn_mono[i] *= window[i]; 
			} 
			for (i = 0; i < lext; i++)  
			{ 
				est_xn_side[L_frame+i] *= window[ovlp_size+i]; 
				xn_mono[L_frame+i] *= window[ovlp_size+i]; 
			} 
 
			fft9(est_xn_side, cur_est_side_fft, (short)lg); 
			cur_est_side_fft[1] = 0.0f;    /* freq bin    at 6400 Hz zeroed */ 
 
			fft9(xn_mono, cur_mono_fft, (short)lg); 
			cur_mono_fft[1] = 0.0f;       /* freq bin at 6400 Hz zeroed */ 
 
			newStereo->mem_ovlp_size_enc = L_OVLP/4; 
		} 
	} 
 
	// get left & right signal 
	for (i = 0; i < L_FRAME_PLUS+L_OVLP; i++) 
	{ 
		est_left_fft[i] = mono_fft[i] + est_side_fft[i]; 
		est_right_fft[i] = mono_fft[i] - est_side_fft[i]; 
	} 
} 
 
// decode gain of AVQ 
static float d_gain_new_tcx(int index, 
						  float code[], 
						  int lcode 
						  ) 
{ 
	int    i; 
	float  tmp, gcode0, gcode; 
	/* energy */ 
	tmp = 0.01f; 
	for(i=0; iisTransientFrame == 0) 
	{ 
		for (b = 0; b < gain_num; b++) 
		{ 
			d_VQ_gain(tmpGain, dico_gain_side_hf_smooth, HI_GAIN_ORDER, param+b); 
 
			left_gain[b] = tmpGain[0] + cb_gain_hi_mean_smooth[0] + 0.5f*newStereo->pre_left_gain[b];  
			right_gain[b] = tmpGain[1] + cb_gain_hi_mean_smooth[1] + 0.5f*newStereo->pre_right_gain[b];  
 
			newStereo->pre_left_gain[b] = tmpGain[0] + 0.5f*newStereo->pre_left_gain[b];  
			newStereo->pre_right_gain[b] = tmpGain[1] + 0.5f*newStereo->pre_right_gain[b]; 
		} 
	} 
	else 
	{ 
		for (b = 0; b < gain_num; b++) 
		{			 
			d_VQ_gain(tmpGain, dico_gain_side_hf_quick, HI_GAIN_ORDER, param+b); 
 
			left_gain[b] = tmpGain[0] + cb_gain_hi_mean_quick[0];  
			right_gain[b] = tmpGain[1] + cb_gain_hi_mean_quick[1];  
		} 
	} 
 
	for (b = 0; b < gain_num; b++) 
	{ 
#if 1	// smooth gains  
		if (newStereo->isTransientFrame == 0) 
		{ 
			if (left_gain[b] > 0.0f) 
			{ 
				left_gain[b] = min(left_gain[b], newStereo->old_left_freq_gain[b]+3.0f); 
				newStereo->old_left_freq_gain[b] = left_gain[b]; 
			} 
			else 
			{ 
				newStereo->old_left_freq_gain[b] = 0.0f; 
			} 
 
			if (right_gain[b] > 0.0f) 
			{ 
				right_gain[b] = min(right_gain[b], newStereo->old_right_freq_gain[b]+3.0f); 
				newStereo->old_right_freq_gain[b] = right_gain[b]; 
			} 
			else 
			{ 
				newStereo->old_right_freq_gain[b] = 0.0f; 
			} 
		} 
#endif 
		quant_left_gain[b] = (float)pow(10.0, 0.05*left_gain[b]); 
		quant_right_gain[b] = (float)pow(10.0, 0.05*right_gain[b]); 
	} 
 
#ifdef LOW_COMPLEXITY 
	for (b = 0; b < gain_num; b++) 
	{ 
		for (i = b * gain_len; i < (b+1) * gain_len; i++) 
		{ 
			syn_side_fft[2*i] = quant_left_gain[b]*est_left_fft[2*i] - quant_right_gain[b]*est_right_fft[2*i]; 
			syn_side_fft[2*i+1] = quant_left_gain[b]*est_left_fft[2*i+1] - quant_right_gain[b]*est_right_fft[2*i+1]; 
		} 
	} 
#else 
	for (b = 0; b < gain_num; b++) 
	{ 
		for (i = b * gain_len; i < (b+1) * gain_len; i++) 
		{ 
			est_left_fft[2*i] = quant_left_gain[b] * est_left_fft[2*i]; 
			est_left_fft[2*i+1] = quant_left_gain[b] * est_left_fft[2*i+1]; 
 
			est_right_fft[2*i] = quant_right_gain[b] * est_right_fft[2*i]; 
			est_right_fft[2*i+1] = quant_right_gain[b] * est_right_fft[2*i+1]; 
		} 
	} 
#endif 
} 
 
static void MakeStereoDecoding(NEW_STEREO_DATA_DEC *newStereo, 
							   int isTransientFrame,  
							   float *mono_fft, 
#ifdef LOW_COMPLEXITY 
							   float *syn_side_fft, 
#endif 
							   float *est_side_fft, 
							   float *est_left_fft, 
							   float *est_right_fft, 
							   int *param) 
{ 
	int low_freq_num; 
	int mid_freq_num; 
	int w, lg; 
	int   *prm; 
	int gain_num; 
 
	prm = param + 8; // 8 mid-freq's gain 
 
	if (isTransientFrame == 0)	// smooth frame 
	{ 
		low_freq_num = newStereo->lowfreq_end_num_l; 
		mid_freq_num = L_FRAME_PLUS + L_OVLP - low_freq_num; 
		gain_num = MF_GAIN_NUM; 
 
		MakeLowFreqDecoding(mono_fft, 
#ifdef LOW_COMPLEXITY 
							syn_side_fft, 
#else 
							est_left_fft, 
							est_right_fft, 
#endif 
							low_freq_num, 
							prm); 
 
		MakeMidFreqDecoding(newStereo, 
							mono_fft+low_freq_num, 
#ifdef LOW_COMPLEXITY 
							syn_side_fft+low_freq_num, 
#endif 
							est_side_fft+low_freq_num, 
							est_left_fft+low_freq_num, 
							est_right_fft+low_freq_num, 
							mid_freq_num, 
							0, 
							gain_num, 
							param); 
	} 
	else 
	{ 
		lg = (L_FRAME_PLUS+L_OVLP)/4; 
		low_freq_num = newStereo->lowfreq_end_num_s; 
		mid_freq_num = lg - low_freq_num; 
		gain_num = MF_GAIN_NUM/4; 
 
		for (w = 0; w < 4; w++) 
		{ 
			float *cur_est_left_fft = est_left_fft + w * lg; 
			float *cur_est_right_fft = est_right_fft + w * lg; 
			float *cur_mono_fft = mono_fft + w * lg; 
			float *cur_est_side_fft = est_side_fft + w * lg; 
#ifdef LOW_COMPLEXITY 
			float *cur_syn_side_fft = syn_side_fft + w * lg; 
#endif 
			int *cur_prm = prm + w * (1+low_freq_num+low_freq_num/8); //1 global gain 
 
			MakeLowFreqDecoding(cur_mono_fft, 
#ifdef LOW_COMPLEXITY 
								cur_syn_side_fft, 
#else 
								cur_est_left_fft, 
								cur_est_right_fft, 
#endif 
								low_freq_num,  
								cur_prm); 
 
			MakeMidFreqDecoding(newStereo, 
								cur_mono_fft+low_freq_num, 
#ifdef LOW_COMPLEXITY 
								cur_syn_side_fft+low_freq_num, 
#endif 
								cur_est_side_fft+low_freq_num, 
								cur_est_left_fft+low_freq_num, 
								cur_est_right_fft+low_freq_num, 
								mid_freq_num, 
								w, 
								gain_num, 
								param+w*gain_num 
								); 
		} 
	} 
 
} 
 
#ifdef LOW_COMPLEXITY 
static void MakeIFFTTransform(NEW_STEREO_DATA_DEC *newStereo, 
							  int is_transient, 
							  float *syn_side_fft, 
							  float *syn_side_ch,							   
							  float *ovlp_side 
							  ) 
{ 
	int i, w; 
	int L_frame, lext, lg; 
	float  window[256]; 
	int ovlp_size; 
 
	if (is_transient == 0)	// smooth 
	{ 
		lext = L_OVLP; 
		L_frame =L_FRAME_PLUS; 
 
		ovlp_size = newStereo->mem_ovlp_size_dec; 
		lg = L_frame + lext; 
		/* built window for overlaps section */ 
		cos_window(window, ovlp_size, lext); 
 
		syn_side_fft[1] = 0.0f; 
		ifft9(syn_side_fft, syn_side_ch, lg); 
 
		/* xn[] windowing for TCX overlap */ 
		for (i = 0; i < ovlp_size; i++)  
		{ 
			syn_side_ch[i] *= window[i]; 
		} 
		for (i = 0; i < lext; i++) 
		{ 
			syn_side_ch[L_frame+i] *= window[ovlp_size+i]; 
		} 
 
		for (i = 0; i < L_OVLP; i++) 
		{ 
			syn_side_ch[i] += ovlp_side[i];			 
		} 
		/* save overlap for next frame */ 
		for (i = 0; i < lext; i++) 
		{ 
			ovlp_side[i] = syn_side_ch[i+L_frame]; 
		} 
		for (i = lext; i < L_OVLP; i++) 
		{ 
			ovlp_side[i] = 0.0f; 
		} 
 
		newStereo->mem_ovlp_size_dec = L_OVLP; 
	} 
	else 
	{ 
		lext = L_OVLP/4; 
		L_frame =L_FRAME_PLUS/4; 
		lg = L_frame + lext; 
 
		for (w = 0; w < 4; w++) 
		{ 
			float *cur_syn_side_fft = syn_side_fft + w * lg; 
			float *cur_syn_side_ch = syn_side_ch + w * L_frame; 
 
			ovlp_size = newStereo->mem_ovlp_size_dec; 
 
			cos_window(window, ovlp_size, lext); 
 
			cur_syn_side_fft[1] = 0.0f; 
			ifft9(cur_syn_side_fft, cur_syn_side_ch, lg); 
 
			/* xn[] windowing for TCX overlap */ 
			for (i = 0; i < ovlp_size; i++)  
			{ 
				cur_syn_side_ch[i] *= window[i]; 
			} 
			for (i = 0; i < lext; i++)  
			{ 
				cur_syn_side_ch[L_frame+i] *= window[ovlp_size+i]; 
			} 
 
			for (i = 0; i < L_OVLP; i++)  
			{ 
				cur_syn_side_ch[i] += ovlp_side[i]; 
			} 
			/* save overlap for next frame */ 
			for (i = 0; i < lext; i++)  
			{ 
				ovlp_side[i] = cur_syn_side_ch[i+L_frame]; 
			} 
			for (i = lext; i < L_OVLP; i++)  
			{ 
				ovlp_side[i] = 0.0f; 
			} 
 
			newStereo->mem_ovlp_size_dec = L_OVLP/4; 
		} 
	} 
} 
#else	// #ifdef LOW_COMPLEXITY 
static void MakeIFFTTransform(NEW_STEREO_DATA_DEC *newStereo, 
							  int is_transient, 
							  float *syn_left_fft,	// changed 
							  float *syn_right_fft,	// changed 
							  float *syn_left_ch, 
							  float *syn_right_ch, 
							  float *ovlp_left, 
							  float *ovlp_right 
							  ) 
{ 
	int i, w; 
	int L_frame, lext, lg; 
	float  window[256]; 
	int ovlp_size; 
 
	if (is_transient == 0)	// smooth 
	{ 
		lext = L_OVLP; 
		L_frame =L_FRAME_PLUS; 
 
		ovlp_size = newStereo->mem_ovlp_size_dec; 
		lg = L_frame + lext; 
		/* built window for overlaps section */ 
		cos_window(window, ovlp_size, lext); 
 
		syn_left_fft[1] = 0.0f; 
		ifft9(syn_left_fft, syn_left_ch, lg); 
 
		syn_right_fft[1] = 0.0f; 
		ifft9(syn_right_fft, syn_right_ch, lg); 
 
		/* xn[] windowing for TCX overlap */ 
		for (i = 0; i < ovlp_size; i++)  
		{ 
			syn_left_ch[i] *= window[i]; 
			syn_right_ch[i] *= window[i]; 
		} 
		for (i = 0; i < lext; i++) 
		{ 
			syn_left_ch[L_frame+i] *= window[ovlp_size+i]; 
			syn_right_ch[L_frame+i] *= window[ovlp_size+i]; 
		} 
 
		for (i = 0; i < L_OVLP; i++) 
		{ 
			syn_left_ch[i] += ovlp_left[i]; 
			syn_right_ch[i] += ovlp_right[i]; 
		} 
		/* save overlap for next frame */ 
		for (i = 0; i < lext; i++) 
		{ 
			ovlp_left[i] = syn_left_ch[i+L_frame]; 
			ovlp_right[i] = syn_right_ch[i+L_frame]; 
		} 
		for (i = lext; i < L_OVLP; i++) 
		{ 
			ovlp_left[i] = 0.0f; 
			ovlp_right[i] = 0.0f; 
		} 
 
		newStereo->mem_ovlp_size_dec = L_OVLP; 
	} 
	else 
	{ 
		lext = L_OVLP/4; 
		L_frame =L_FRAME_PLUS/4; 
		lg = L_frame + lext; 
 
		for (w = 0; w < 4; w++) 
		{ 
			float *cur_syn_left_fft = syn_left_fft + w * lg; 
			float *cur_syn_left_ch = syn_left_ch + w * L_frame; 
			float *cur_syn_right_fft = syn_right_fft + w * lg; 
			float *cur_syn_right_ch = syn_right_ch + w * L_frame; 
 
			ovlp_size = newStereo->mem_ovlp_size_dec; 
 
			cos_window(window, ovlp_size, lext); 
 
			cur_syn_left_fft[1] = 0.0f; 
			ifft9(cur_syn_left_fft, cur_syn_left_ch, lg); 
 
			cur_syn_right_fft[1] = 0.0f; 
			ifft9(cur_syn_right_fft, cur_syn_right_ch, lg); 
 
			/* xn[] windowing for TCX overlap */ 
			for (i = 0; i < ovlp_size; i++)  
			{ 
				cur_syn_left_ch[i] *= window[i]; 
				cur_syn_right_ch[i] *= window[i]; 
			} 
			for (i = 0; i < lext; i++)  
			{ 
				cur_syn_left_ch[L_frame+i] *= window[ovlp_size+i]; 
				cur_syn_right_ch[L_frame+i] *= window[ovlp_size+i]; 
			} 
 
			for (i = 0; i < L_OVLP; i++)  
			{ 
				cur_syn_left_ch[i] += ovlp_left[i]; 
				cur_syn_right_ch[i] += ovlp_right[i]; 
			} 
			/* save overlap for next frame */ 
			for (i = 0; i < lext; i++)  
			{ 
				ovlp_left[i] = cur_syn_left_ch[i+L_frame]; 
				ovlp_right[i] = cur_syn_right_ch[i+L_frame]; 
			} 
			for (i = lext; i < L_OVLP; i++)  
			{ 
				ovlp_left[i] = 0.0f; 
				ovlp_right[i] = 0.0f; 
			} 
 
			newStereo->mem_ovlp_size_dec = L_OVLP/4; 
		} 
	} 
} 
#endif // #ifdef LOW_COMPLEXITY 
 
// wlei [20070601] 
static void dec_stereo( 
					   int param_stereo[],  
					   float *speech_mono, 
					   float *speech_right, 
					   float AqLF[], 
					   NEW_STEREO_DATA_DEC *newStereo) 
{ 
	int i_subfr, k; 
	float *p_Aq; 
	float mono_exc[L_FRAME_PLUS+L_OVLP]; 
	float left_exc[L_FRAME_PLUS+L_OVLP]; 
	float right_exc[L_FRAME_PLUS+L_OVLP]; 
	float est_side_exc[L_FRAME_PLUS+L_OVLP]; 
	int *prm = NULL; 
 
	////////////////////////////////////////////////////////////////////////// 
	newStereo->isTransientFrame = param_stereo[0]; 
	////////////////////////////////////////////////////////////////////////// 
 
	// get mono lf exc 
	// get old mono lf exc 
	p_Aq = newStereo->old_AqLF; 
	E_UTIL_residu(p_Aq, &speech_mono[0], &mono_exc[0], L_SUBFR/2); 
	p_Aq += (M+1); 
	for (i_subfr = L_SUBFR/2; i_subfr < 4*L_SUBFR+L_SUBFR/2; i_subfr+=L_SUBFR) 
	{		 
		E_UTIL_residu(p_Aq, &speech_mono[i_subfr], &mono_exc[i_subfr], L_SUBFR); 
		p_Aq += (M+1); 
	} 
 
	// get mono lf exc, forced delay 288 in order to synchonize with decoder 
	p_Aq = AqLF; 
	for (i_subfr = L_SUBFR/2+4*L_SUBFR; i_subfr < L_FRAME_PLUS+L_SUBFR/2+L_SUBFR; i_subfr+=L_SUBFR) 
	{ 
		E_UTIL_residu(p_Aq, &speech_mono[i_subfr], &mono_exc[i_subfr], L_SUBFR); 
		p_Aq += (M+1); 
	} 
	E_UTIL_residu(p_Aq, &speech_mono[L_FRAME_PLUS+L_SUBFR/2+L_SUBFR], &mono_exc[L_FRAME_PLUS+L_SUBFR/2+L_SUBFR], L_SUBFR/2); 
 
	// signal estimation 
	prm = param_stereo + 1; 
	//	prm = tmp_param_stereo + 1; 
	GetEstimatedSideExc(newStereo, newStereo->isTransientFrame, mono_exc, est_side_exc, L_FRAME_PLUS+L_OVLP, prm); 
 
 
	// time-frequency transform 
	MakeFFTTransform(newStereo, 
		newStereo->isTransientFrame,  
		est_side_exc,  
		mono_exc, 
		newStereo->mono_fft, 
		newStereo->est_side_fft, 
		newStereo->est_left_fft, 
		newStereo->est_right_fft); 
 
	// reconstruct low-frequency and mid-frequency  
	prm = param_stereo + (1+8); // 1: signal type; 8: wiener VQ 
	MakeStereoDecoding(newStereo, 
		newStereo->isTransientFrame, 
		newStereo->mono_fft, 
#ifdef LOW_COMPLEXITY 
		newStereo->syn_side_fft, 
#endif 
		newStereo->est_side_fft, 
		newStereo->est_left_fft, 
		newStereo->est_right_fft, 
		prm); 
 
#ifdef LOW_COMPLEXITY 
	////////////////////////////////////////////////////////////////////////// 
	// module 315 
	////////////////////////////////////////////////////////////////////////// 
	MakeIFFTTransform(newStereo,  
		newStereo->isTransientFrame, 				  
		newStereo->syn_side_fft, 
		right_exc,	// side_exc 
		newStereo->mem_side_ovlp); 
 
	// get real left_exc and right_exc 
	for (k = 0; k < L_FRAME_PLUS; k++) 
	{ 
		left_exc[k] = mono_exc[k] + right_exc[k]; 
		right_exc[k] = mono_exc[k] - right_exc[k]; 
	} 
 
	p_Aq = newStereo->old_AqLF; 
	syn_filt(p_Aq, M, &left_exc[0], &left_exc[0], L_SUBFR/2, newStereo->mem_synth_left, 1); 
	syn_filt(p_Aq, M, &right_exc[0], &right_exc[0], L_SUBFR/2, newStereo->mem_synth_right, 1); 
 
	p_Aq += (M+1); 
	for (i_subfr = L_SUBFR/2; i_subfr < 4*L_SUBFR+L_SUBFR/2; i_subfr+=L_SUBFR) 
	{ 
		syn_filt(p_Aq, M, &left_exc[i_subfr], &left_exc[i_subfr], L_SUBFR, newStereo->mem_synth_left, 1); 
		syn_filt(p_Aq, M, &right_exc[i_subfr], &right_exc[i_subfr], L_SUBFR, newStereo->mem_synth_right, 1); 
		p_Aq += (M+1); 
	} 
 
	p_Aq = AqLF; 
	for (i_subfr = 4*L_SUBFR+L_SUBFR/2; i_subfr < L_FRAME_PLUS-L_SUBFR/2; i_subfr+=L_SUBFR) 
	{ 
		syn_filt(p_Aq, M, &left_exc[i_subfr], &left_exc[i_subfr], L_SUBFR, newStereo->mem_synth_left, 1); 
		syn_filt(p_Aq, M, &right_exc[i_subfr], &right_exc[i_subfr], L_SUBFR, newStereo->mem_synth_right, 1); 
		p_Aq += (M+1); 
	} 
	syn_filt(p_Aq, M, &left_exc[L_FRAME_PLUS-L_SUBFR/2], &left_exc[L_FRAME_PLUS-L_SUBFR/2], 
		L_SUBFR/2, newStereo->mem_synth_left, 1); 
	syn_filt(p_Aq, M, &right_exc[L_FRAME_PLUS-L_SUBFR/2], &right_exc[L_FRAME_PLUS-L_SUBFR/2], 
		L_SUBFR/2, newStereo->mem_synth_right, 1); 
 
	mvr2r(&AqLF[11*(M+1)], newStereo->old_AqLF, 5*(M+1)); 
 
#else //#ifdef LOW_COMPLEXITY 
	// frequency-time transform 
	MakeIFFTTransform(newStereo,  
		newStereo->isTransientFrame,  
		newStereo->est_left_fft,  
		newStereo->est_right_fft,  
		left_exc, 
		right_exc, 
		newStereo->mem_left_ovlp, 
		newStereo->mem_right_ovlp); 
 
	// synthesis filter 
	p_Aq = newStereo->old_AqLF; 
	syn_filt(p_Aq, M, &left_exc[0], &left_exc[0], L_SUBFR/2, newStereo->mem_synth_left, 1); 
	syn_filt(p_Aq, M, &right_exc[0], &right_exc[0], L_SUBFR/2, newStereo->mem_synth_right, 1); 
 
	p_Aq += (M+1); 
	for (i_subfr = L_SUBFR/2; i_subfr < 4*L_SUBFR+L_SUBFR/2; i_subfr+=L_SUBFR) 
	{ 
		syn_filt(p_Aq, M, &left_exc[i_subfr], &left_exc[i_subfr], L_SUBFR, newStereo->mem_synth_left, 1); 
		syn_filt(p_Aq, M, &right_exc[i_subfr], &right_exc[i_subfr], L_SUBFR, newStereo->mem_synth_right, 1); 
		p_Aq += (M+1); 
	} 
 
	p_Aq = AqLF; 
	for (i_subfr = 4*L_SUBFR+L_SUBFR/2; i_subfr < L_FRAME_PLUS-L_SUBFR/2; i_subfr+=L_SUBFR) 
	{ 
		syn_filt(p_Aq, M, &left_exc[i_subfr], &left_exc[i_subfr], L_SUBFR, newStereo->mem_synth_left, 1); 
		syn_filt(p_Aq, M, &right_exc[i_subfr], &right_exc[i_subfr], L_SUBFR, newStereo->mem_synth_right, 1); 
		p_Aq += (M+1); 
	} 
	syn_filt(p_Aq, M, &left_exc[L_FRAME_PLUS-L_SUBFR/2], &left_exc[L_FRAME_PLUS-L_SUBFR/2], 
		L_SUBFR/2, newStereo->mem_synth_left, 1); 
	syn_filt(p_Aq, M, &right_exc[L_FRAME_PLUS-L_SUBFR/2], &right_exc[L_FRAME_PLUS-L_SUBFR/2], 
		L_SUBFR/2, newStereo->mem_synth_right, 1); 
 
	mvr2r(&AqLF[11*(M+1)], newStereo->old_AqLF, 5*(M+1)); 
#endif	// #ifdef LOW_COMPLEXITY 
 
	for (k = 0; k < L_FRAME_PLUS; k++) 
	{ 
		speech_mono[k] = left_exc[k]; 
		speech_right[k] = right_exc[k]; 
	} 
} 
 
void dec_new_stereo_side( 
						int param_stereo[],	// (i)stereo bits stream 
						float *sig_left,	// (o) decoded right channel 
						float *synth,		// (i) decoded mono channel; (o) decoded left channel 
						float AqLF[],		// (i) quantized predictive coefficients of mono channel 
						int StbrMode,		// wlei [20070601] 
						NEW_STEREO_DATA_DEC *newStereo)	// (i) stereo struction 
{ 
	float *speech_mono; 
	float old_speech_mono[M+L_FRAME_PLUS+NEW_STEREO_DECODER_DELAY]; 
	float speech_right[L_FRAME_PLUS]; 
 
	speech_mono = old_speech_mono + M; 
 
	mvr2r(newStereo->old_speech_mono, old_speech_mono, M+NEW_STEREO_DECODER_DELAY); 
	mvr2r(synth, speech_mono+NEW_STEREO_DECODER_DELAY, L_FRAME_PLUS); 
	mvr2r(old_speech_mono+L_FRAME_PLUS, newStereo->old_speech_mono, M+NEW_STEREO_DECODER_DELAY); 
 
	if (StbrMode < 0) // wlei[20070601] 
	{ 
		mvr2r(speech_mono, speech_right, L_FRAME_PLUS); 
	} 
	else 
	{ 
		dec_stereo(param_stereo, speech_mono, speech_right, AqLF, newStereo); 
	} 
 
	mvr2r(newStereo->old_speech_left, sig_left, NEW_STEREO_DECODER_COMP); 
	mvr2r(speech_mono, sig_left+NEW_STEREO_DECODER_COMP, L_FRAME_PLUS-NEW_STEREO_DECODER_COMP); 
	mvr2r(speech_mono+L_FRAME_PLUS-NEW_STEREO_DECODER_COMP, newStereo->old_speech_left, NEW_STEREO_DECODER_COMP); 
 
	mvr2r(newStereo->old_speech_right, synth, NEW_STEREO_DECODER_COMP);	   
	mvr2r(speech_right, synth+NEW_STEREO_DECODER_COMP, L_FRAME_PLUS-NEW_STEREO_DECODER_COMP);	   
	mvr2r(speech_right+L_FRAME_PLUS-NEW_STEREO_DECODER_COMP, newStereo->old_speech_right, NEW_STEREO_DECODER_COMP); 
} 
 
static int pack4bits_d(int nbits, short *ptr, int *prm) 
{ 
	int i; 
	i=0; 
	while (nbits > 4) 
	{	 
		prm[i] = bin2int(4, ptr); 
		ptr += 4; 
		nbits -= 4; 
		i++; 
	} 
	prm[i] = bin2int(nbits, ptr); 
	i++;	 
	return(i); 
} 
 
void dec_prm_new_stereo(int bad_frame[],   /* (i) : bfi for 4 frames (bad_frame[4])  */ 
						short serial[],    /* (i) : serial bits stream               */ 
						int nbits_pack,    /* (i) : number of bits per packet of 20ms*/ 
						int nbits_bwe,     /* (i) : number of BWE bits per 20ms */ 
						int param[],       /* (o) : decoded parameters               */ 
						int brMode, 
						NEW_STEREO_DATA_DEC *newStereo) 
{ 
	int nbits, *prm; 
	int k; 
	int nbits_AVQ[NB_DIV]; 
	int  prm_AVQ[NBITS_MAX+N_PACK_MAX]; 
	short *ptr; 
	float tmp_prm[NBITS_MAX+N_PACK_MAX]; 
	int i,j,n_pack; 
	int si_bits = 16; 
	int signal_type; 
 
	int lowfreq_end_num_l = newStereo->lowfreq_end_num_l; 
	int lowfreq_end_num_s = newStereo->lowfreq_end_num_s; 
	/*----------------------------------------------------------* 
	* Set number of bits used for stereo (per packet of 20 ms) * 
	* When stereo is transmitted, the bit ordering is:         * 
	* serial: mode (2bits), core, stereo, 2xBWE(2x16bits)      * 
	*----------------------------------------------------------*/ 
	nbits = (StereoNbits[brMode] + (2*nbits_bwe))/4; 
 
	ptr = serial + nbits_pack - nbits; 
	signal_type = bin2int(1, ptr); 
 
	if (signal_type == 0)  // smooth type 
	{ 
		k = 0; 
		prm = param + 17; // skip to AVQ param 
		n_pack = 4; 
		nbits_AVQ[0] = ((StereoNbits[brMode])/4)-1-4-3-5-5;	// 
		nbits_AVQ[1] = ((StereoNbits[brMode])/4)-1-7-5-5; 
		nbits_AVQ[2] = ((StereoNbits[brMode])/4)-5-5; 
		nbits_AVQ[3] = ((StereoNbits[brMode])/4)-5-5; 
 
		/* set pointer to bit stream */ 
		ptr = serial + (k+1)*nbits_pack - nbits; 
 
		/* encode first 20 ms frame */ 
		param[0] = bin2int(1, ptr);		ptr += 1;	// signal type 
		param[1] = bin2int(4, ptr);		ptr += 4;	// 1st FIR coef 
		param[2] = bin2int(3, ptr);		ptr += 3;	// 2nd FIR coef 
		param[9] = bin2int(5, ptr);		ptr += 5;	// 1st mid-freq's gain 
		param[10]= bin2int(5, ptr);		ptr += 5;	// 2nd mid-freq's gain 
		j = pack4bits_d(nbits_AVQ[0], ptr, prm_AVQ);// AVQ 
 
		/* set pointer to bit stream */ 
		ptr = serial + (k+2)*nbits_pack - nbits; 
 
		/* encode second 20 ms frame */ 
		ptr += 1;	// unused bits 
		param[17] = bin2int(7, ptr);		ptr += 7;	// global gain 
		param[11] = bin2int(5, ptr);		ptr += 5;	// 3rd mid-freq's gain 
		param[12] = bin2int(5, ptr);		ptr += 5;	// 4th mid-freq's gain 
		j += pack4bits_d(nbits_AVQ[1], ptr, prm_AVQ+j); 
 
		/* set pointer to bit stream */ 
		ptr = serial + (k+3)*nbits_pack - nbits; 
 
		/* encode third 20 ms frame */	 
		param[13] = bin2int(5, ptr);		ptr += 5;	// 5th mid-freq's gain 
		param[14] = bin2int(5, ptr);		ptr += 5;	// 6th mid-freq's gain 
		j += pack4bits_d(nbits_AVQ[2], ptr, prm_AVQ+j); 
 
		/* set pointer to bit stream */ 
		ptr = serial + (k+4)*nbits_pack - nbits; 
		/* encode forth 20 ms frame */ 
		param[15] = bin2int(5, ptr);		ptr += 5;	// 7th mid-freq's gain 
		param[16] = bin2int(5, ptr);		ptr += 5;	// 8th mid-freq's gain 
		pack4bits_d(nbits_AVQ[3], ptr, prm_AVQ+j); 
 
		AVQ_demuxdec(n_pack, prm_AVQ, nbits_AVQ, tmp_prm, lowfreq_end_num_l/8, bad_frame); 
		/* convert to integer */ 
		for (i = 0;i < lowfreq_end_num_l; i++)  
		{ 
			prm[i+1] = (int)tmp_prm[i]; 
		} 
	} 
	else 
	{ 
		// side information 
		// 1st packet 
		/* set pointer to bit stream */ 
		ptr = serial + nbits_pack - nbits; 
		param[0] = bin2int(1, ptr);	ptr += 1;	// signal type 
		if (newStereo->bitrate < 32.0f) 
		{ 
			param[1] = bin2int(4, ptr); ptr += 4;	// 1st FIR coef 
		} 
		else  
		{ 
			param[1] = bin2int(4, ptr); ptr += 4;	// 1st FIR coef 
			param[2] = bin2int(3, ptr); ptr += 3;	// 2nd FIR coef 
		} 
		param[9]  = bin2int(5, ptr);	ptr += 5;	// 1st mid-freq's gain 
		param[10] = bin2int(5, ptr);	ptr += 5;	// 2nd mid-freq's gain 
 
		// 2nd packet 
		ptr = serial + 2*nbits_pack - nbits; 
		ptr += 1;	// reserved bit 
		if (newStereo->bitrate < 32.0f) 
		{ 
			param[3] = bin2int(4, ptr); ptr += 4;	// 1st FIR coef 
		} 
		else  
		{ 
			param[3] = bin2int(4, ptr); ptr += 4;	// 1st FIR coef 
			param[4] = bin2int(3, ptr); ptr += 3;	// 2nd FIR coef 
		} 
		param[11] = bin2int(5, ptr);	ptr += 5;	// 5th mid-freq's gain 
		param[12] = bin2int(5, ptr);	ptr += 5;	// 6th mid-freq's gain 
 
		// 3rd packet 
		ptr = serial + 3*nbits_pack - nbits; 
		ptr += 1;	// reserved bit 
		if (newStereo->bitrate < 32.0f) 
		{ 
			param[5] = bin2int(4, ptr); ptr += 4;	// 1st FIR coef 
		} 
		else  
		{ 
			param[5] = bin2int(4, ptr); ptr += 4;	// 1st FIR coef 
			param[6] = bin2int(3, ptr); ptr += 3;	// 2nd FIR coef 
		} 
		param[13] = bin2int(5, ptr);	ptr += 5;	// 7th mid-freq's gain 
		param[14] = bin2int(5, ptr);	ptr += 5;	// 8th mid-freq's gain 
 
		// 4th packet 
		ptr = serial + 4*nbits_pack - nbits; 
		ptr += 1;	// reserved bit 
		if (newStereo->bitrate < 32.0f) 
		{ 
			param[7] = bin2int(4, ptr); ptr += 4;	// 1st FIR coef 
		} 
		else  
		{ 
			param[7] = bin2int(4, ptr); ptr += 4;	// 1st FIR coef 
			param[8] = bin2int(3, ptr); ptr += 3;	// 2nd FIR coef 
		} 
		param[15] = bin2int(5, ptr);	ptr += 5;	// 7th mid-freq's gain 
		param[16] = bin2int(5, ptr);	ptr += 5;	// 8th mid-freq's gain		 
 
		if (newStereo->bitrate < 32.0f) 
		{ 
			si_bits = 15; 
		} 
		else 
		{ 
			si_bits = 18; 
		} 
 
		prm = param + 17; // 17 side info used 
 
		// core (SplitVQ + global gain) 
		for (k = 0; k < 4; k++)	// 4 packets 
		{ 
			n_pack = 1; 
			nbits_AVQ[0] = ((StereoNbits[brMode])/4) - si_bits - 7; // 7 global gain 
 
			/* set pointer to bit stream */ 
			ptr = serial + (k+1)*nbits_pack - nbits + si_bits; 
 
			prm[0] = bin2int(7, ptr); ptr += 7;	// global gain 
 
			pack4bits_d(nbits_AVQ[0], ptr, prm_AVQ); 
 
			/* demultiplex and decode */ 
			AVQ_demuxdec(n_pack, prm_AVQ, nbits_AVQ, tmp_prm, lowfreq_end_num_s/8, bad_frame+k); 
			/* convert to integer */ 
			for (i = 0;i < lowfreq_end_num_s; i++) 
			{ 
				prm[i+1] = (int)tmp_prm[i]; 
			} 
 
			//	ptr += nbits_AVQ[0]; 
			prm += (1+(lowfreq_end_num_s+lowfreq_end_num_s/8)); 
		} 
	} 
 
	return; 
} 
 
/* END_NEW_STEREO */ 
/* FROM TOP OF THIS FILE */