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;i w_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;i old_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;i w_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;i old_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_subfr w_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;i w_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;i old_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;i w_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;i old_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;i w_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;i w_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;i w_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;i old_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)); } }