www.pudn.com > g729_audio_encode.rar > dec_ld8k.c
/* ITU-T G.729 Speech Coder with Annex B ANSI-C Source Code Version 1.3 Last modified: August 1997 Copyright (c) 1996, AT&T, France Telecom, NTT, Universite de Sherbrooke, Lucent Technologies, Rockwell International All rights reserved. */ /*-----------------------------------------------------------------* * Functions Init_Decod_ld8k and Decod_ld8k * *-----------------------------------------------------------------*/ #include#include #include "typedef.h" #include "basic_op.h" #include "ld8k.h" #include "dtx.h" #include "sid.h" /*---------------------------------------------------------------* * Decoder constant parameters (defined in "ld8k.h") * *---------------------------------------------------------------* * L_FRAME : Frame size. * * L_SUBFR : Sub-frame size. * * M : LPC order. * * MP1 : LPC order+1 * * PIT_MIN : Minimum pitch lag. * * PIT_MAX : Maximum pitch lag. * * L_INTERPOL : Length of filter for interpolation * * PRM_SIZE : Size of vector containing analysis parameters * *---------------------------------------------------------------*/ /*--------------------------------------------------------* * Static memory allocation. * *--------------------------------------------------------*/ /* Excitation vector */ static Word16 old_exc[L_FRAME+PIT_MAX+L_INTERPOL]; static Word16 *exc; /* Lsp (Line spectral pairs) */ static Word16 lsp_old[M]={ 30000, 26000, 21000, 15000, 8000, 0, -8000,-15000,-21000,-26000}; /* Filter's memory */ static Word16 mem_syn[M]; static Word16 sharp; /* pitch sharpening of previous frame */ static Word16 old_T0; /* integer delay of previous frame */ static Word16 gain_code; /* Code gain */ static Word16 gain_pitch; /* Pitch gain */ /* for G.729B */ static Word16 seed_fer; /* CNG variables */ static Word16 past_ftyp; static Word16 seed; static Word16 sid_sav, sh_sid_sav; /*-----------------------------------------------------------------* * Function Init_Decod_ld8k * * ~~~~~~~~~~~~~~~ * * * * ->Initialization of variables for the decoder section. * * * *-----------------------------------------------------------------*/ void Init_Decod_ld8k(void) { /* Initialize static pointer */ exc = old_exc + PIT_MAX + L_INTERPOL; /* Static vectors to zero */ Set_zero(old_exc, PIT_MAX+L_INTERPOL); Set_zero(mem_syn, M); sharp = SHARPMIN; old_T0 = 60; gain_code = 0; gain_pitch = 0; Lsp_decw_reset(); /* for G.729B */ seed_fer = 21845; past_ftyp = 1; seed = INIT_SEED; sid_sav = 0; sh_sid_sav = 1; Init_lsfq_noise(); return; } /*-----------------------------------------------------------------* * Function Decod_ld8k * * ~~~~~~~~~~ * * ->Main decoder routine. * * * *-----------------------------------------------------------------*/ void Decod_ld8k( Word16 parm[], /* (i) : vector of synthesis parameters parm[0] = bad frame indicator (bfi) */ Word16 voicing, /* (i) : voicing decision from previous frame */ Word16 synth[], /* (o) : synthesis speech */ Word16 A_t[], /* (o) : decoded LP filter in 2 subframes */ Word16 *T0_first, /* (o) : decoded pitch lag in first subframe */ Word16 *Vad /* (o) : frame type */ ) { Word16 *Az; /* Pointer on A_t */ Word16 lsp_new[M]; /* LSPs */ Word16 code[L_SUBFR]; /* ACELP codevector */ /* Scalars */ Word16 i, j, i_subfr; Word16 T0, T0_frac, index; Word16 bfi; Word32 L_temp; Word16 g_p, g_c; /* fixed and adaptive codebook gain */ Word16 bad_pitch; /* bad pitch indicator */ extern Flag Overflow; /* for G.729B */ Word16 ftyp; Word16 lsfq_mem[MA_NP][M]; /* Test bad frame indicator (bfi) */ bfi = *parm++; /* for G.729B */ ftyp = *parm; if(bfi == 1) { if(past_ftyp == 1) ftyp = 1; else ftyp = 0; *parm = ftyp; /* modification introduced in version V1.3 */ } *Vad = ftyp; /* Processing non active frames (SID & not transmitted) */ if(ftyp != 1) { Get_decfreq_prev(lsfq_mem); Dec_cng(past_ftyp, sid_sav, sh_sid_sav, parm, exc, lsp_old, A_t, &seed, lsfq_mem); Update_decfreq_prev(lsfq_mem); Az = A_t; for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { Overflow = 0; Syn_filt(Az, &exc[i_subfr], &synth[i_subfr], L_SUBFR, mem_syn, 0); if(Overflow != 0) { /* In case of overflow in the synthesis */ /* -> Scale down vector exc[] and redo synthesis */ for(i=0; i 0) { old_T0 = PIT_MAX; } } *T0_first = T0; /* If first frame */ } else /* second subframe */ { if( bfi == 0) { Dec_lag3(index, PIT_MIN, PIT_MAX, i_subfr, &T0, &T0_frac); old_T0 = T0; } else { T0 = old_T0; T0_frac = 0; old_T0 = add( old_T0, 1); if( sub(old_T0, PIT_MAX) > 0) { old_T0 = PIT_MAX; } } } /*-------------------------------------------------* * - Find the adaptive codebook vector. * *-------------------------------------------------*/ Pred_lt_3(&exc[i_subfr], T0, T0_frac, L_SUBFR); /*-------------------------------------------------------* * - Decode innovative codebook. * * - Add the fixed-gain pitch contribution to code[]. * *-------------------------------------------------------*/ if(bfi != 0) /* Bad frame */ { parm[0] = Random(&seed_fer) & (Word16)0x1fff; /* 13 bits random */ parm[1] = Random(&seed_fer) & (Word16)0x000f; /* 4 bits random */ } Decod_ACELP(parm[1], parm[0], code); parm +=2; j = shl(sharp, 1); /* From Q14 to Q15 */ if(sub(T0, L_SUBFR) <0 ) { for (i = T0; i < L_SUBFR; i++) { code[i] = add(code[i], mult(code[i-T0], j)); } } /*-------------------------------------------------* * - Decode pitch and codebook gains. * *-------------------------------------------------*/ index = *parm++; /* index of energy VQ */ Dec_gain(index, code, L_SUBFR, bfi, &gain_pitch, &gain_code); /*-------------------------------------------------------------* * - Update pitch sharpening "sharp" with quantized gain_pitch * *-------------------------------------------------------------*/ sharp = gain_pitch; if (sub(sharp, SHARPMAX) > 0) { sharp = SHARPMAX; } if (sub(sharp, SHARPMIN) < 0) { sharp = SHARPMIN; } /*-------------------------------------------------------* * - Find the total excitation. * * - Find synthesis speech corresponding to exc[]. * *-------------------------------------------------------*/ if(bfi != 0) /* Bad frame */ { if (voicing == 0 ) { g_p = 0; g_c = gain_code; } else { g_p = gain_pitch; g_c = 0; } } else { g_p = gain_pitch; g_c = gain_code; } for (i = 0; i < L_SUBFR; i++) { /* exc[i] = g_p*exc[i] + g_c*code[i]; */ /* exc[i] in Q0 g_p in Q14 */ /* code[i] in Q13 g_code in Q1 */ L_temp = L_mult(exc[i+i_subfr], g_p); L_temp = L_mac(L_temp, code[i], g_c); L_temp = L_shl(L_temp, 1); exc[i+i_subfr] = round(L_temp); } Overflow = 0; Syn_filt(Az, &exc[i_subfr], &synth[i_subfr], L_SUBFR, mem_syn, 0); if(Overflow != 0) { /* In case of overflow in the synthesis */ /* -> Scale down vector exc[] and redo synthesis */ for(i=0; i last level of SID quantizer */ sh_sid_sav = norm_l(L_temp); sid_sav = round(L_shl(L_temp, sh_sid_sav)); sh_sid_sav = sub(16, sh_sid_sav); } /*--------------------------------------------------* * Update signal for next frame. * * -> shift to the left by L_FRAME exc[] * *--------------------------------------------------*/ Copy(&old_exc[L_FRAME], &old_exc[0], PIT_MAX+L_INTERPOL); /* for G729b */ past_ftyp = ftyp; return; }