www.pudn.com > AVS_M_ver10.rar > dec_ace.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" void decoder_acelp( int prm[], /* input: parameters */ float A[], /* input: coefficients NxAz[M+1] */ int lg, /* input: frame length */ int codec_mode, /* input: AMR-WB+ mode (see cnst.h)*/ int bfi, /* input: 1=bad frame */ float exc[], /* i/o: exc[-(PIT_MAX+L_INTERPOL)..lg] */ float synth[], /* i/o: synth[-M..lg] */ int T_out[], /* out: LTP lag for high band */ float p_out[], /* out: LTP gain for high band */ int *pT, /* out: pitch for all subframe */ float *pgainT, /* out: pitch gain for all subfr */ int pit_adj, /* input: pitch adjust */ float stab_fac, /* input: stability of isf */ Decoder_State_Plus *st) /* i/o : coder memory state */ { int i, i_subfr, select; int T0, T0_frac, index, pit_flag, T0_min, T0_max; float tmp, gain_pit, gain_code, voice_fac, ener, mean_ener_code, ener_wsyn; float code[L_SUBFR], buf[M+L_OVLP]; float fac, exc2[L_SUBFR]; float *p_A, Ap1[1+M],Ap2[1+M],Ap3[1+TILT_ORDER],Ap[1+M]; short code3GPP[L_SUBFR], prm3GPP[10]; int PIT_MIN; /* Minimum pitch lag with resolution 1/4 */ int PIT_FR2; /* Minimum pitch lag with resolution 1/2 */ int PIT_FR1; /* Minimum pitch lag with resolution 1 */ int PIT_MAX; /* Maximum pitch lag */ if(pit_adj ==0) { PIT_MIN = PIT_MIN_12k8; PIT_FR2 = PIT_FR2_12k8; PIT_FR1 = PIT_FR1_12k8; PIT_MAX = PIT_MAX_12k8; } else { i = (((pit_adj*PIT_MIN_12k8)+(FSCALE_DENOM/2))/FSCALE_DENOM)-PIT_MIN_12k8; PIT_MIN = PIT_MIN_12k8 + i; PIT_FR2 = PIT_FR2_12k8 - i; PIT_FR1 = PIT_FR1_12k8; PIT_MAX = PIT_MAX_12k8 + (6*i); } /*------------------------------------------------------------------------* * - decode mean_ener_code for gain decoder (d_gain2.c) * *------------------------------------------------------------------------*/ index = *prm++; /* decode mean energy with 2 bits : 18, 30, 42 or 54 dB */ if (!bfi) { mean_ener_code = (((float)index) * 12.0f) + 18.0f; } /*------------------------------------------------------------------------* * Loop for every subframe in the analysis frame * *------------------------------------------------------------------------* * To find the pitch and innovation parameters. The subframe size is * * L_SUBFR and the loop is repeated L_ACELP/L_SUBFR times. * * - compute impulse response of weighted synthesis filter (h1[]) * * - compute the target signal for pitch search * * - find the closed-loop pitch parameters * * - encode the pitch dealy * * - update the impulse response h1[] by including fixed-gain pitch * * - find target vector for codebook search * * - correlation between target vector and impulse response * * - codebook search * * - encode codebook address * * - VQ of pitch and codebook gains * * - find synthesis speech * * - update states of weighting filter * *------------------------------------------------------------------------*/ ener_wsyn = 0.01f; p_A = A; for (i_subfr = 0; i_subfr < lg; i_subfr += L_SUBFR) { pit_flag = i_subfr; if (i_subfr == (2*L_SUBFR)) { pit_flag = 0; } index = *prm++; /*-------------------------------------------------* * - Decode pitch lag * *-------------------------------------------------*/ if (bfi) /* 如果发生帧错误 */ { switch(st->bfi_count%4)/* 将连续坏帧数对4取模 */ { case 1:/* 模1 */ T0 = st->old_T0 + 1;/* 将上帧的基音延迟加1作为当前帧的基音延迟 */ break; case 2:/* 模2 */ T0 = st->old_T0 - 2;/* 将上帧的基音延迟减2作为当前帧的基音延迟 */ break; case 3:/* 模3 */ T0 = st->old_T0 - 1;/* 将上帧的基音延迟减1作为当前帧的基音延迟 */ break; case 0:/* 模0 */ T0 = st->old_T0 + 2;/* 将上帧的基音延迟加2作为当前帧的基音延迟 */ break; } if (T0 > PIT_MAX)/* 如果基音延迟大于上限 */ { T0 = PIT_MAX;/* 将基音延迟设为上限 */ } if (T0 < PIT_MIN)/* 如果基音延迟小于下限 */ { T0 = PIT_MIN;/* 将基音延迟设为下限 */ } T0_frac = 0;/* 基音延迟分数部分置0 */ } else { if (pit_flag == 0) { if (index < (PIT_FR2-PIT_MIN)*4) { T0 = PIT_MIN + (index/4); T0_frac = index - (T0 - PIT_MIN)*4; } else if (index < ( (PIT_FR2-PIT_MIN)*4 + (PIT_FR1-PIT_FR2)*2) ) { index -= (PIT_FR2-PIT_MIN)*4; T0 = PIT_FR2 + (index/2); T0_frac = index - (T0 - PIT_FR2)*2; T0_frac *= 2; } else { T0 = index + PIT_FR1 - ((PIT_FR2-PIT_MIN)*4) - ((PIT_FR1-PIT_FR2)*2); T0_frac = 0; } /* find T0_min and T0_max for subframe 2 or 4 */ T0_min = T0 - 8; if (T0_min < PIT_MIN) { T0_min = PIT_MIN; } T0_max = T0_min + 15; if (T0_max > PIT_MAX) { T0_max = PIT_MAX; T0_min = T0_max - 15; } } else /* if subframe 2 or 4 */ { T0 = T0_min + index/4; T0_frac = index - (T0 - T0_min)*4; } } /*-------------------------------------------------* * - Find the pitch gain, the interpolation filter * * and the adaptive codebook vector. * *-------------------------------------------------*/ pred_lt4(&exc[i_subfr], T0, T0_frac, L_SUBFR+1); select = *prm++; if (bfi) { select = 1; } if (select == 0) { /* ADAPTIVE_EXCITATION_SEARCH */ /* find pitch excitation with lp filter */ for (i=0; i seed_ace)); } } /*-------------------------------------------------------* * - Add the fixed-gain pitch contribution to code[]. * *-------------------------------------------------------*/ tmp = 0.0; #ifndef PW_UPDATE E_UTIL_f_preemph(code, TILT_CODE, L_SUBFR, &tmp); #endif i = T0; if (T0_frac > 2) { i++; } E_GAIN_f_pitch_sharpening(code, i); /*-------------------------------------------------* * - Decode codebooks gains. * *-------------------------------------------------*/ index = *prm++; st->mem_gain_code[i_subfr/L_SUBFR] = d_gain2_plus(index, code, L_SUBFR, &gain_pit, &gain_code, bfi, mean_ener_code, &(st->past_gpit), &(st->past_gcode)); /*----------------------------------------------------------* * Update parameters for the next subframe. * * - tilt of code: 0.0 (unvoiced) to 0.5 (voiced) * *----------------------------------------------------------*/ /* energy of pitch excitation */ ener = 0.0; for (i=0; i 2) { i++; } if (i > PIT_MAX) { i = PIT_MAX; } *pT++ = i; *pgainT++ = gain_pit; if (pit_adj == 0) { E_UTIL_synthesis(p_A, &exc[i_subfr], &synth[i_subfr], L_SUBFR, &synth[i_subfr-M], 0); } else { /*------------------------------------------------------------* * noise enhancer * * ~~~~~~~~~~~~~~ * * - Enhance excitation on noise. (modify gain of code) * * If signal is noisy and LPC filter is stable, move gain * * of code 1.5 dB toward gain of code threshold. * * This decrease by 3 dB noise energy variation. * *------------------------------------------------------------*/ fac = stab_fac; //ISF稳定性因子 /* 固定码本增益初始化修正 */ tmp = gain_code; if (tmp < st->gc_threshold) { tmp = (float)(tmp*1.06); if (tmp > st->gc_threshold) { tmp = st->gc_threshold; } } else { tmp = (float)(tmp/1.06); if (tmp < st->gc_threshold) { tmp = st->gc_threshold; } } st->gc_threshold = tmp; /* 固定码本平滑增益的计算 */ if(fac>0.58) gain_code = (float)((0.17*tmp) + (0.83*gain_code)); else gain_code = (float)((0.83*tmp) + (0.17*gain_code)); /* 固定码本增益平滑,将固定码本乘以平滑增益 */ for (i=0; i mem_formant); E_UTIL_tilt(code,Ap3,L_SUBFR,st->mem_tilt); #endif #ifndef PW_UPDATE E_LPC_a_weight(p_A, Ap, GAMMA1, M); E_UTIL_residu(Ap, &synth[i_subfr], code, L_SUBFR); E_UTIL_deemph(code, TILT_FAC, L_SUBFR, &(st->mem_wsyn)); #endif #ifdef NEW_TVC #ifdef PW_UPDATE if (i_subfr==192){ mvr2r(Ap1, &st->wovlp[83], M+1); mvr2r(Ap2, st->wovlp_ap2, M+1); mvr2r(Ap3, st->wovlp_ap3, TILT_ORDER+1); st->wovlp[80]= code[47]; st->wovlp[81]= code[31]; } if (i_subfr==128){ st->wovlp[82]= code[63]; } #else if (i_subfr==192){ mvr2r(Ap, &st->wovlp[83], M+1); st->wovlp[80]= code[47]; st->wovlp[81]= code[31]; } if (i_subfr==128){ st->wovlp[82]= code[63]; } #endif #endif for (i=0; i wsyn_rms = (float)sqrt(ener_wsyn/(float)lg); /*----------------------------------------------------------* * find 10ms ZIR in weighted domain for next tcx frame * *----------------------------------------------------------*/ #ifndef NEW_TVC mvr2r(&synth[lg-M], buf, M); set_zero(buf+M, L_OVLP); E_UTIL_synthesis(p_A, buf+M, buf+M, L_OVLP, buf, 0); #ifdef PW_UPDATE { float mem_temp1[M],mem_temp2[TILT_ORDER]; mvr2r(st->mem_formant,mem_temp1,M); mvr2r(st->mem_tilt,mem_temp2,TILT_ORDER); paraChoose(p_A,&gamma1,&gamma2,&gamma3); E_LPC_a_weight(p_A, Ap1, gamma1, M); E_LPC_a_weight(p_A, Ap2, gamma2, M); E_LPC_a_weight(p_A, Ap3, gamma3,TILT_ORDER); E_UTIL_residu(Ap1, buf+M, st->wovlp, L_OVLP); E_UTIL_formant(st->wovlp,Ap2,L_OVLP,mem_temp1); E_UTIL_tilt(st->wovlp,Ap3,L_OVLP,mem_temp2); } #else E_LPC_a_weight(p_A, Ap, GAMMA1, M); /* wAi of tcx is quantized */ E_UTIL_residu(Ap, buf+M, st->wovlp, L_OVLP); tmp = st->mem_wsyn; E_UTIL_deemph(st->wovlp, TILT_FAC, L_OVLP, &tmp); #endif for (i=1; i<(L_OVLP/2); i++) { st->wovlp[L_OVLP-i] *= ((float)i)/((float)(L_OVLP/2)); } #endif #ifdef NEW_TVC mvr2r(&synth[176], st->wovlp, 80); set_zero(&st->wovlp[100], 28); st->gw_flg=1; #endif st->ovlp_size = 0; /* indicate ACELP frame to TCX */ /* update pitch value for bfi procedure */ st->old_T0_frac = T0_frac; st->old_T0 = T0; return; }