/************************************************************************ * * FILENAME : sdec_tet.c * * DESCRIPTION : Main routines for speech source decoding * ************************************************************************ * * SUB-ROUTINES : - Init_Decod_Tetra() * - Decod_Tetra() * ************************************************************************ * * INCLUDED FILES : source.h * ************************************************************************/ #include "source.h" /*--------------------------------------------------------* * Decoder constants parameters. * * * * L_frame : Frame size. * * L_subfr : Sub-frame size. * * p : LPC order. * * pp1 : LPC order+1 * * pit_min : Minimum pitch lag. * * pit_max : Maximum pitch lag. * * L_inter : Length of filter for interpolation * * parm_size : Lenght of vector parm[] * *--------------------------------------------------------*/ #define L_frame (Word16)240 #define L_subfr (Word16)60 #define p (Word16)10 #define pp1 (Word16)11 #define pit_min (Word16)20 #define pit_max (Word16)143 #define L_inter (Word16)15 #define parm_size (Word16)23 /*--------------------------------------------------------* * LPC bandwidth expansion factors for noise filter. * * In Q15 = 0.75, 0.85 * *--------------------------------------------------------*/ #define gamma3 (Word16)24576 #define gamma4 (Word16)27853 /*--------------------------------------------------------* * Static memory allocation. * *--------------------------------------------------------*/ /* Excitation vector */ static Word16 old_exc[L_frame+pit_max+L_inter]; static Word16 *exc; /* Spectral expansion factors */ static Word16 F_gamma3[p]; static Word16 F_gamma4[p]; /* Lsp (Line spectral pairs in the cosine domain) */ static Word16 lspold[p]={ 30000, 26000, 21000, 15000, 8000, 0, -8000,-15000,-21000, -26000}; static Word16 lspnew[p]; /* Initial lsp values used after each time */ /* a reset is executed */ static Word16 lspold_init[p]={ 30000, 26000, 21000, 15000, 8000, 0, -8000,-15000,-21000,-26000}; /* Filter's memory */ static Word16 mem_syn[p]; /* Default parameters */ static Word16 old_parm[parm_size], old_T0; /* Global definition */ Word16 last_ener_cod; Word16 last_ener_pit; /************************************************************************** * * ROUTINE : Init_Decod_Tetra * * DESCRIPTION : Initialization of variables for the speech decoder * ************************************************************************** * * USAGE : Init_Decod_Tetra() * * INPUT ARGUMENT(S) : None * * OUTPUT ARGUMENT(S) : None * * RETURNED VALUE : None * **************************************************************************/ void Init_Decod_Tetra(void) { Word16 i; old_T0 = 60; for(i=0; i<23; i++) old_parm[i] = 0; /* Initialize static pointer */ exc = old_exc + pit_max + L_inter; /* Initialize global variables */ last_ener_cod = 0; last_ener_pit = 0; /* Static vectors to zero */ for(i=0; i pit_max) { T0_max = pit_max; T0_min = sub(T0_max, (Word16)9); } } else /* other subframes */ { if (bfi == 0) /* if bfi == 0 decode pitch */ { /* T0 = (index+2)/3 - 1 + T0_min; */ i = add(index, (Word16)2); i = mult(i, (Word16)10923); /* 10923 = 1/3 in Q15 */ i = sub(i, (Word16)1); T0 = add(T0_min, i); /* T0_frac = index - 2 - i*3; */ i = add(i, add(i,i) ); /* i*3 */ T0_frac = sub( index , add(i, (Word16)2) ); } } /*-------------------------------------------------* * - Find the adaptive codebook vector. * *-------------------------------------------------*/ Pred_Lt(&exc[i_subfr], T0, T0_frac, L_subfr); /*-----------------------------------------------------* * - Compute noise filter F[]. * * - Decode codebook sign and index. * * - Find the algebraic codeword. * *-----------------------------------------------------*/ Pond_Ai(A, F_gamma3, Ap3); Pond_Ai(A, F_gamma4, Ap4); for (i = 0; i <= p; i++) F[i] = Ap3[i]; for (i = pp1; i < L_subfr; i++) F[i] = 0; Syn_Filt(Ap4, F, F, L_subfr, &F[pp1], (Word16)0); /* Introduce pitch contribution with fixed gain of 0.8 to F[] */ for (i = T0; i < L_subfr; i++) { temp = mult(F[i-T0], (Word16)26216); F[i] = add(F[i], temp); } index = *parm++; sign_code = *parm++; shift_code = *parm++; D_D4i60(index, sign_code, shift_code, F, code); /*-------------------------------------------------* * - Decode pitch and codebook gains. * *-------------------------------------------------*/ index = *parm++; /* index of energy VQ */ Dec_Ener(index,bfi,A,&exc[i_subfr],code, L_subfr, &gain_pit, &gain_code); /*-------------------------------------------------------* * - Find the total excitation. * * - Find synthesis speech corresponding to exc[]. * *-------------------------------------------------------*/ for (i = 0; i < L_subfr; i++) { /* exc[i] = gain_pit*exc[i] + gain_code*code[i]; */ /* exc[i] in Q0 gain_pit in Q12 */ /* code[i] in Q12 gain_cod in Q0 */ L_temp = L_mult0(exc[i+i_subfr], gain_pit); L_temp = L_mac0(L_temp, code[i], gain_code); exc[i+i_subfr] = L_shr_r(L_temp, (Word16)12); } Syn_Filt(A, &exc[i_subfr], &synth[i_subfr], L_subfr, mem_syn, (Word16)1); A += pp1; /* interpolated LPC parameters for next subframe */ } /*--------------------------------------------------* * Update signal for next frame. * * -> shift to the left by L_frame exc[] * *--------------------------------------------------*/ for(i=0; i