www.pudn.com > AVS_M_ver10.rar > dec_hi_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" 
void init_dec_hi_stereo(Decoder_State_Plus *st) 
{ 
	int i; 
	cos_window(st->w_window,0,L_SUBFR); 
	for(i=0;iw_window[i] = st->w_window[i]*st->w_window[i]; 
	} 
	set_zero(st->old_wh,HI_FILT_ORDER); 
	set_zero(st->old_wh2,HI_FILT_ORDER); 
	set_zero(st->old_exc_mono,HI_FILT_ORDER); 
	set_zero(st->old_AqLF,5*(M+1)); 
	for(i=0;i<5;i++){ 
		st->old_AqLF[i*(M+1)]=1.0f; 
	} 
	set_zero(st->left.mem_synth_hi,M); 
	set_zero(st->right.mem_synth_hi,M); 
	set_zero(st->old_wh_q,HI_FILT_ORDER); 
	set_zero(st->old_gm_gain,2); 
	for(i=0;i<4;i++){ 
		st->old_gain_left[i]=1.0f; 
		st->old_gain_right[i]=1.0f;	 
	} 
} 
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); 
} 
static void dec_gain(int **prm, 
					 float *gain_left, 
					 float *gain_right, 
					 float *old_gain, 
					 int bfi, 
					 const PMSVQ* gain_hi_pmsvq 
					 ) 
{ 
	float tmp[2]; 
	pmsvq_inv(tmp, prm, old_gain, bfi, gain_hi_pmsvq); 
	*gain_left  = tmp[0]; 
	*gain_right = tmp[1]; 
} 
/* this supposes time alignement between encoder and decoder */ 
void dec_hi_stereo(float synth_hi_t0[], 
		   float right_hi[], 
		   float left_hi[], 
		   float AqLF[], 
		   int   param[], 
		   int bad_frame[], 
		   int fscale, 
		   Decoder_State_Plus *st) 
{ 
    float *exc_buf = right_hi;   
	float *exc_mono=exc_buf+HI_FILT_ORDER; 
	float *synth_hi_d; 
	float *p_Aq,*p_h; 
	int i,k; 
	int i_subfr; 
	int start; 
	float gain_left[NB_DIV+2]; 
	float gain_right[NB_DIV+2]; 
	float new_gain_left[NB_DIV]; 
	float new_gain_right[NB_DIV]; 
    float *left_exc, *right_exc; 
	float side_buf[L_DIV+L_SUBFR]; 
	float buf[L_SUBFR]; 
	float wh[NB_DIV*HI_FILT_ORDER]; 
	int *prm; 
   /*---------------------------------------------------------------------* 
	* Mismatch between received parameters and signal buffer              * 
	*                                                                     * 
	*                                                                     * 
	*                                                                     * 
	*	fscale=0														  * 
	*                                                                     * 
	*                  |    20ms   |    20ms   |     20ms  |   20ms    |  * 
	*        -|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|  * 
	*        <--------  Total speech buffer ---------------->			  * 
	*                                                                     * 
	*	fscale!=0                                                         * 
	*                                                                     * 
	*                  |    20ms   |    20ms   |     20ms  |   20ms    |  * 
	*     -|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|  * 
	*     <--------  Total speech buffer ---------------->                * 
	* g(-2)    g(-1)       g(0)         g(1)        g(2)        g(3)      * 
	* f(-2)    f(-1)       f(0)         f(1)        f(2)        f(3)      * 
	*---------------------------------------------------------------------*/ 
    left_exc = left_hi; 
    right_exc = right_hi; 
	/*-----------------------------------------------------------* 
	* Decode gain and filters				    		         * 
	*									                         * 
	*------------------------------------------------------------*/ 
	for(i=0;iold_wh_q, bad_frame[i], 
			st->filt_hi_pmsvq); 
		dec_gain(&prm,&new_gain_left[i],&new_gain_right[i], 
			st->old_gm_gain, bad_frame[i],st->gain_hi_pmsvq); 
		new_gain_left[i] = (float)pow(10.0f,new_gain_left[i]/20.0f); 
		new_gain_right[i] = (float)pow(10.0f,new_gain_right[i]/20.0f); 
	} 
	/*-----------------------------------------------------------* 
	* Set correct alignement of parameters	    		         * 
	*------------------------------------------------------------*/ 
	mvr2r(st->old_gain_left,gain_left,2); 
	mvr2r(st->old_gain_right,gain_right,2); 
	mvr2r(new_gain_left,gain_left+2,4); 
	mvr2r(new_gain_right,gain_right+2,4); 
	mvr2r(new_gain_left+2,st->old_gain_left,2); 
	mvr2r(new_gain_right+2,st->old_gain_right,2); 
   /*-----------------------------------------------------------* 
	* Set correct starting buffer					.           * 
	*-----------------------------------------------------------*/ 
	synth_hi_d = &synth_hi_t0[-L_BSP-D_BPF]; 
	/*-----------------------------------------------------------* 
	* Compute left right pseudo-excitation	    		         * 
	*Use the mono LPC filter for whitening                       * 
	*------------------------------------------------------------*/ 
	p_Aq = st->old_AqLF; 
	residu(p_Aq,M, synth_hi_d, exc_mono, L_SUBFR/2); 
	p_Aq += (M+1); 
	for(i_subfr=L_SUBFR/2;i_subfr<3*L_SUBFR+ L_SUBFR/2;i_subfr+=L_SUBFR){ 
		residu(p_Aq,M, &synth_hi_d[i_subfr], &exc_mono[i_subfr], L_SUBFR); 
		p_Aq += (M+1); 
	} 
	if (fscale != 0) { 
		residu(p_Aq,M, &synth_hi_d[i_subfr], &exc_mono[i_subfr], L_SUBFR); 
	} 
	p_Aq = AqLF; 
	if(fscale==0) { 
		start = 3*L_SUBFR + L_SUBFR/2; 
	} 
	else { 
		start = 4*L_SUBFR + L_SUBFR/2; 
	} 
	for (i_subfr=start; i_subfr old_exc_mono,exc_buf,HI_FILT_ORDER); 
	mvr2r(exc_buf+L_FRAME_PLUS,st->old_exc_mono,HI_FILT_ORDER); 
	/*-----------------------------------------------------------* 
	* synthesise left right pseudo excitation with interpolation * 
	*------------------------------------------------------------*/	 
	if(fscale ==0 ) { 
		fir_filt(st->old_wh,HI_FILT_ORDER,exc_mono,side_buf,L_DIV-L_SUBFR/2); 
		fir_filt(st->old_wh2,HI_FILT_ORDER,exc_mono,buf,L_SUBFR/2); 
		for(i=0;iw_window[i+L_SUBFR/2]*gain_left[0]*(buf[i]+exc_mono[i])+ 
				gain_left[1]*(1.0f-st->w_window[i+L_SUBFR/2])*(exc_mono[i] + side_buf[i]); 
			right_exc[i] = st->w_window[i+L_SUBFR/2]*gain_right[0]*(exc_mono[i]-buf[i])+ 
				gain_right[1]*(1.0f-st->w_window[i+L_SUBFR/2])*(exc_mono[i] - side_buf[i]); 
		} 
		for(i=L_SUBFR/2;iold_wh,HI_FILT_ORDER,&exc_mono[L_DIV-L_SUBFR/2],buf,L_SUBFR); 
		p_h = wh; 
		k = 1; 
		for(i_subfr=L_DIV-L_SUBFR/2;i_subfrw_window[i]*gain_left[k]*(exc_mono[i_subfr+i]+buf[i]) + 
					gain_left[k+1]*(1.0f-st->w_window[i])*(exc_mono[i_subfr+i]+side_buf[i]); 
				right_exc[i_subfr+i] = st->w_window[i]*gain_right[k]*(exc_mono[i_subfr+i]-buf[i]) + 
					gain_right[k+1]*(1.0f-st->w_window[i])*(exc_mono[i_subfr+i]-side_buf[i]); 
			} 
			for(i=L_SUBFR;iw_window[i]*gain_left[k]*(exc_mono[L_FRAME_PLUS-L_SUBFR/2+i]+buf[i]) + 
				gain_left[k+1]*(1.0f-st->w_window[i])*(exc_mono[L_FRAME_PLUS-L_SUBFR/2+i]+side_buf[i]); 
			right_exc[L_FRAME_PLUS-L_SUBFR/2+i] = st->w_window[i]*gain_right[k]*(exc_mono[i_subfr+i]-buf[i]) + 
				gain_right[k+1]*(1.0f-st->w_window[i])*(exc_mono[L_FRAME_PLUS-L_SUBFR/2+i]-side_buf[i]); 
		} 
	} 
	else { 
		fir_filt(st->old_wh2,HI_FILT_ORDER,exc_mono,buf,L_SUBFR/2); 
		for(i=0;iold_wh2,HI_FILT_ORDER,exc_mono +L_SUBFR/2,buf,L_SUBFR); 
		fir_filt(st->old_wh,HI_FILT_ORDER, exc_mono + L_SUBFR/2,side_buf,L_DIV); 
		for(i=0;iw_window[i]*gain_left[0]*(exc_mono[L_SUBFR/2+i]+buf[i]) + 
				gain_left[1]*(1.0f-st->w_window[i])*(exc_mono[L_SUBFR/2+i]+side_buf[i]); 
			right_exc[L_SUBFR/2+i] = st->w_window[i]*gain_right[0]*(exc_mono[L_SUBFR/2+i]-buf[i]) + 
				gain_right[1]*(1.0f-st->w_window[i])*(exc_mono[L_SUBFR/2+i]-side_buf[i]); 
		} 
		for(i=L_SUBFR+L_SUBFR/2;iold_wh,HI_FILT_ORDER,&exc_mono[L_DIV+L_SUBFR/2],buf,L_SUBFR); 
		p_h = wh; 
		k = 1; 
		fir_filt(p_h,HI_FILT_ORDER,&exc_mono[L_DIV+L_SUBFR/2],side_buf,L_DIV); 
		for(i=0;iw_window[i]*gain_left[k]*(exc_mono[L_DIV+L_SUBFR/2+i]+buf[i]) + 
				gain_left[k+1]*(1.0f-st->w_window[i])*(exc_mono[L_DIV+L_SUBFR/2+i]+side_buf[i]); 
			right_exc[L_DIV+L_SUBFR/2+i] = st->w_window[i]*gain_right[k]*(exc_mono[L_DIV+L_SUBFR/2+i]-buf[i]) + 
				gain_right[k+1]*(1.0f-st->w_window[i])*(exc_mono[L_DIV+L_SUBFR/2+i]-side_buf[i]); 
		} 
		for(i=L_SUBFR;iw_window[i]*gain_left[k]*(exc_mono[2*L_DIV+L_SUBFR/2+i]+buf[i]) + 
				gain_left[k+1]*(1.0f-st->w_window[i])*(exc_mono[2*L_DIV+L_SUBFR/2+i]+side_buf[i]); 
			right_exc[2*L_DIV+L_SUBFR/2+i] = st->w_window[i]*gain_right[k]*(exc_mono[2*L_DIV+L_SUBFR/2+i]-buf[i]) + 
				gain_right[k+1]*(1.0f-st->w_window[i])*(exc_mono[2*L_DIV+L_SUBFR/2+i]-side_buf[i]); 
		} 
		for(i=L_SUBFR;iw_window[i]*gain_left[k]*(exc_mono[3*L_DIV+L_SUBFR/2+i]+buf[i]) + 
				gain_left[k+1]*(1.0f-st->w_window[i])*(exc_mono[3*L_DIV+L_SUBFR/2+i]+side_buf[i]); 
			right_exc[3*L_DIV+L_SUBFR/2+i] = st->w_window[i]*gain_right[k]*(exc_mono[3*L_DIV+L_SUBFR/2+i]-buf[i]) + 
				gain_right[k+1]*(1.0f-st->w_window[i])*(exc_mono[3*L_DIV+L_SUBFR/2+i]-side_buf[i]); 
		} 
		for(i=L_SUBFR;iold_wh,HI_FILT_ORDER); 
	mvr2r(p_h-HI_FILT_ORDER,st->old_wh2,HI_FILT_ORDER); 
	/*-----------------------------------------------------------* 
	*															 * 
	* Synthesise left right mid band signals					 * 
	*															 * 
	*------------------------------------------------------------*/	 
	p_Aq = st->old_AqLF; 
	syn_filt(p_Aq,M, &left_exc[0], left_hi, L_SUBFR/2,st->left.mem_synth_hi,1); 
	syn_filt(p_Aq,M, &right_exc[0], right_hi, L_SUBFR/2,st->right.mem_synth_hi,1); 
	p_Aq += (M+1); 
	for(k=0;k<3;k++){ 
		syn_filt(p_Aq,M, &left_exc[k*L_SUBFR+L_SUBFR/2], &left_hi[k*L_SUBFR+L_SUBFR/2], 
			L_SUBFR,st->left.mem_synth_hi,1); 
		syn_filt(p_Aq,M, &right_exc[k*L_SUBFR+L_SUBFR/2], &right_hi[k*L_SUBFR+L_SUBFR/2],  
			L_SUBFR,st->right.mem_synth_hi,1); 
		p_Aq += (M+1); 
	} 
	if (fscale !=0) {	 
		syn_filt(p_Aq,M, &left_exc[k*L_SUBFR+L_SUBFR/2], &left_hi[k*L_SUBFR+L_SUBFR/2],  
			L_SUBFR,st->left.mem_synth_hi,1); 
		syn_filt(p_Aq,M, &right_exc[k*L_SUBFR+L_SUBFR/2], &right_hi[k*L_SUBFR+L_SUBFR/2],  
			L_SUBFR,st->right.mem_synth_hi,1); 
	} 
	if(fscale==0) { 
		start = 3*L_SUBFR + L_SUBFR/2; 
	} 
	else { 
		start = 4*L_SUBFR + L_SUBFR/2; 
	}		 
	p_Aq = AqLF; 
	for (i_subfr=start; i_subfr left.mem_synth_hi,1); 
		syn_filt(p_Aq,M, &right_exc[i_subfr], &right_hi[i_subfr],L_SUBFR,st->right.mem_synth_hi,1); 
		p_Aq += (M+1); 
	} 
	syn_filt(p_Aq,M, &left_exc[L_FRAME_PLUS-L_SUBFR/2], &left_hi[L_FRAME_PLUS-L_SUBFR/2], 
		L_SUBFR/2,st->left.mem_synth_hi,1); 
	syn_filt(p_Aq,M, &right_exc[L_FRAME_PLUS-L_SUBFR/2], &right_hi[L_FRAME_PLUS-L_SUBFR/2], 
		L_SUBFR/2,st->right.mem_synth_hi,1); 
	if(fscale == 0) { 
		mvr2r(p_Aq,st->old_AqLF,4*(M+1)); 
	} 
	else { 
		mvr2r(p_Aq,st->old_AqLF,5*(M+1)); 
	} 
}