/*-----------------------------------------------------------* * procedure Calc_exc_rand * * ~~~~~~~~~~~~~ * * Computes comfort noise excitation * * for SID and not-transmitted frames * *-----------------------------------------------------------*/ void Calc_exc_rand( Word16 cur_gain, /* (i) : target sample gain */ Word16 *exc, /* (i/o) : excitation array */ Word16 *seed, /* (i) : current Vad decision */ Flag flag_cod /* (i) : encoder/decoder flag */ ) { Word16 i, j, i_subfr; Word16 temp1, temp2; Word16 pos[4]; Word16 sign[4]; Word16 t0, frac; Word16 *cur_exc; Word16 g, Gp, Gp2; Word16 excg[L_SUBFR], excs[L_SUBFR]; Word32 L_acc, L_ener, L_k; Word16 max, hi, lo, inter_exc; Word16 sh; Word16 x1, x2; if(cur_gain == 0) { for(i=0; i<L_FRAME; i++) { exc[i] = 0; } Gp = 0; t0 = add(L_SUBFR,1); for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { if(flag_cod != FLAG_DEC) update_exc_err(Gp, t0); else Update_PhDisp(Gp,cur_gain); } return; } /* Loop on subframes */ cur_exc = exc; for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { /* generate random adaptive codebook & fixed codebook parameters */ /*****************************************************************/ temp1 = Random_g729cp(seed); frac = sub((temp1 & (Word16)0x0003), 1); if(sub(frac, 2) == 0) frac = 0; temp1 = shr(temp1, 2); t0 = add((temp1 & (Word16)0x003F), 40); temp1 = shr(temp1, 6); temp2 = temp1 & (Word16)0x0007; pos[0] = add(shl(temp2, 2), temp2); /* 5 * temp2 */ temp1 = shr(temp1, 3); sign[0] = temp1 & (Word16)0x0001; temp1 = shr(temp1, 1); temp2 = temp1 & (Word16)0x0007; temp2 = add(shl(temp2, 2), temp2); pos[1] = add(temp2, 1); /* 5 * x + 1 */ temp1 = shr(temp1, 3); sign[1] = temp1 & (Word16)0x0001; temp1 = Random_g729cp(seed); temp2 = temp1 & (Word16)0x0007; temp2 = add(shl(temp2, 2), temp2); pos[2] = add(temp2, 2); /* 5 * x + 2 */ temp1 = shr(temp1, 3); sign[2] = temp1 & (Word16)0x0001; temp1 = shr(temp1, 1); temp2 = temp1 & (Word16)0x000F; pos[3] = add((temp2 & (Word16)1), 3); /* j+3*/ temp2 = (shr(temp2, 1)) & (Word16)7; temp2 = add(shl(temp2, 2), temp2); /* 5i */ pos[3] = add(pos[3], temp2); temp1 = shr(temp1, 4); sign[3] = temp1 & (Word16)0x0001; Gp = Random_g729cp(seed) & (Word16)0x1FFF; /* < 0.5 Q14 */ Gp2 = shl(Gp, 1); /* Q15 */ /* Generate gaussian excitation */ /********************************/ L_acc = 0L; for(i=0; i<L_SUBFR; i++) { temp1 = Gauss(seed); L_acc = L_mac(L_acc, temp1, temp1); excg[i] = temp1; } /* Compute fact = alpha x cur_gain * sqrt(L_SUBFR / Eg) with Eg = SUM(i=0->39) excg[i]^2 and alpha = 0.5 alpha x sqrt(L_SUBFR)/2 = 1 + FRAC1 */ L_acc = Inv_sqrt(L_shr(L_acc,1)); /* Q30 */ L_Extract(L_acc, &hi, &lo); /* cur_gain = cur_gainR << 3 */ temp1 = mult_r(cur_gain, FRAC1); temp1 = add(cur_gain, temp1); /* <=> alpha x cur_gainR x 2^2 x sqrt(L_SUBFR) */ L_acc = Mpy_32_16(hi, lo, temp1); /* fact << 17 */ sh = norm_l(L_acc); temp1 = extract_h(L_shl(L_acc, sh)); /* fact << (sh+1) */ sh = sub(sh, 14); for(i=0; i<L_SUBFR; i++) { temp2 = mult_r(excg[i], temp1); temp2 = shr_r(temp2, sh); /* shl if sh < 0 */ excg[i] = temp2; } /* generate random adaptive excitation */ /****************************************/ Pred_lt_3(cur_exc, t0, frac, L_SUBFR); /* compute adaptive + gaussian exc -> cur_exc */ /**********************************************/ max = 0; for(i=0; i<L_SUBFR; i++) { temp1 = mult_r(cur_exc[i], Gp2); temp1 = add(temp1, excg[i]); /* may overflow */ cur_exc[i] = temp1; temp1 = abs_s(temp1); if(sub(temp1,max) > 0) max = temp1; } /* rescale cur_exc -> excs */ if(max == 0) sh = 0; else { sh = sub(3, norm_s(max)); if(sh <= 0) sh = 0; } for(i=0; i<L_SUBFR; i++) { excs[i] = shr(cur_exc[i], sh); } /* Compute fixed code gain */ /***************************/ /**********************************************************/ /*** Solve EQ(X) = 4 X**2 + 2 b X + c */ /**********************************************************/ L_ener = 0L; for(i=0; i<L_SUBFR; i++) { L_ener = L_mac(L_ener, excs[i], excs[i]); } /* ener x 2^(-2sh + 1) */ /* inter_exc = b >> sh */ inter_exc = 0; for(i=0; i<4; i++) { j = pos[i]; if(sign[i] == 0) { inter_exc = sub(inter_exc, excs[j]); } else { inter_exc = add(inter_exc, excs[j]); } } /* Compute k = cur_gainR x cur_gainR x L_SUBFR */ L_acc = L_mult(cur_gain, L_SUBFR); L_acc = L_shr(L_acc, 6); temp1 = extract_l(L_acc); /* cur_gainR x L_SUBFR x 2^(-2) */ L_k = L_mult(cur_gain, temp1); /* k << 2 */ temp1 = add(1, shl(sh,1)); L_acc = L_shr(L_k, temp1); /* k x 2^(-2sh+1) */ /* Compute delta = b^2 - 4 c */ L_acc = L_sub(L_acc, L_ener); /* - 4 c x 2^(-2sh-1) */ inter_exc = shr(inter_exc, 1); L_acc = L_mac(L_acc, inter_exc, inter_exc); /* 2^(-2sh-1) */ sh = add(sh, 1); /* inter_exc = b x 2^(-sh) */ /* L_acc = delta x 2^(-2sh+1) */ if(L_acc < 0) { /* adaptive excitation = 0 */ Copy(excg, cur_exc, L_SUBFR); temp1 = abs_s(excg[(int)pos[0]]) | abs_s(excg[(int)pos[1]]); temp2 = abs_s(excg[(int)pos[2]]) | abs_s(excg[(int)pos[3]]); temp1 = temp1 | temp2; sh = ((temp1 & (Word16)0x4000) == 0) ? (Word16)1 : (Word16)2; inter_exc = 0; for(i=0; i<4; i++) { temp1 = shr(excg[(int)pos[i]], sh); if(sign[i] == 0) { inter_exc = sub(inter_exc, temp1); } else { inter_exc = add(inter_exc, temp1); } } /* inter_exc = b >> sh */ L_Extract(L_k, &hi, &lo); L_acc = Mpy_32_16(hi, lo, K0); /* k x (1- alpha^2) << 2 */ temp1 = sub(shl(sh, 1), 1); /* temp1 > 0 */ L_acc = L_shr(L_acc, temp1); /* 4k x (1 - alpha^2) << (-2sh+1) */ L_acc = L_mac(L_acc, inter_exc, inter_exc); /* delta << (-2sh+1) */ Gp = 0; } temp2 = Sqrt(L_acc); /* >> sh */ x1 = sub(temp2, inter_exc); x2 = negate(add(inter_exc, temp2)); /* x 2^(-sh+2) */ if(sub(abs_s(x2),abs_s(x1)) < 0) x1 = x2; temp1 = sub(2, sh); g = shr_r(x1, temp1); /* shl if temp1 < 0 */ if(g >= 0) { if(sub(g, G_MAX) > 0) g = G_MAX; } else { if(add(g, G_MAX) < 0) g = negate(G_MAX); } /* Update cur_exc with ACELP excitation */ for(i=0; i<4; i++) { j = pos[i]; if(sign[i] != 0) { cur_exc[j] = add(cur_exc[j], g); } else { cur_exc[j] = sub(cur_exc[j], g); } } if(flag_cod != FLAG_DEC) update_exc_err(Gp, t0); else { if(g >= 0) Update_PhDisp(Gp,g); else Update_PhDisp(Gp,(Word16)-g); } cur_exc += L_SUBFR; } /* end of loop on subframes */ return; }
void Decod_ld8c ( Word16 parm[], /* (i) : vector of synthesis parameters parm[0] = bad frame indicator (bfi) */ Word16 voicing, /* (i) : voicing decision from previous frame */ Word16 synth_buf[], /* (i/o) : synthesis speech */ Word16 Az_dec[], /* (o) : decoded LP filter in 2 subframes */ Word16 *T0_first, /* (o) : decoded pitch lag in first subframe */ Word16 *bwd_dominant, /* (o) : */ Word16 *m_pst, /* (o) : LPC order for postfilter */ Word16 *Vad ) { /* Scalars */ Word16 i, j, i_subfr; Word16 T0, T0_frac, index; Word16 bfi; Word16 lp_mode; /* Backward / Forward mode indication */ Word16 g_p, g_c; /* fixed and adaptive codebook gain */ Word16 bad_pitch; /* bad pitch indicator */ Word16 tmp, tmp1, tmp2; Word16 sat_filter; Word32 L_temp; Word32 energy; Word16 temp; /* Tables */ Word16 A_t_bwd[2*M_BWDP1]; /* LPC Backward filter */ Word16 A_t_fwd[2*MP1]; /* LPC Forward filter */ Word16 rc_bwd[M_BWD]; /* LPC backward reflection coefficients */ Word32 r_bwd[M_BWDP1]; /* Autocorrelations (backward) */ Word16 r_l_bwd[M_BWDP1]; /* Autocorrelations low (backward) */ Word16 r_h_bwd[M_BWDP1]; /* Autocorrelations high (backward) */ Word16 lsp_new[M]; /* LSPs */ Word16 code[L_SUBFR]; /* ACELP codevector */ Word16 *pA_t; /* Pointer on A_t */ Word16 stationnary; Word16 m_aq; Word16 *synth; Word16 exc_phdisp[L_SUBFR]; /* excitation after phase dispersion */ extern Flag Overflow; Word16 rate; /* for G.729B */ Word16 ftyp; Word16 lsfq_mem[MA_NP][M]; synth = synth_buf + MEM_SYN_BWD; /* Test bad frame indicator (bfi) */ bfi = *parm++; /* Test frame type */ ftyp = *parm++; if(bfi == 1) { ftyp = past_ftyp; if(ftyp == 1) ftyp = 0; if(ftyp > 2) { /* G.729 maintenance */ if(ftyp == 3) parm[4] = 1; else { if(prev_lp_mode == 0) parm[5] = 1; else parm[3] = 1; } } parm[-1] = ftyp; } *Vad = ftyp; rate = ftyp - (Word16)2; /* Decoding the Backward/Forward LPC decision */ /* ------------------------------------------ */ if( rate != G729E) lp_mode = 0; else { if (bfi != 0) { lp_mode = prev_lp_mode; /* Frame erased => mode = previous mode */ *parm++ = lp_mode; } else { lp_mode = *parm++; } if(prev_bfi != 0) voicing = prev_voicing; } if( bfi == 0) { c_muting = 32767; count_bfi = 0; } /* -------------------- */ /* Backward LP analysis */ /* -------------------- */ if (rate == G729E) { /* LPC recursive Window as in G728 */ autocorr_hyb_window(synth_buf, r_bwd, rexp); /* Autocorrelations */ Lag_window_bwd(r_bwd, r_h_bwd, r_l_bwd); /* Lag windowing */ /* Fixed Point Levinson (as in G729) */ Levinsoncp(M_BWD, r_h_bwd, r_l_bwd, &A_t_bwd[M_BWDP1], rc_bwd, old_A_bwd, old_rc_bwd, &temp); /* Tests saturation of A_t_bwd */ sat_filter = 0; for (i=M_BWDP1; i<2*M_BWDP1; i++) if (A_t_bwd[i] >= 32767) sat_filter = 1; if (sat_filter == 1) Copy(A_t_bwd_mem, &A_t_bwd[M_BWDP1], M_BWDP1); else Copy(&A_t_bwd[M_BWDP1], A_t_bwd_mem, M_BWDP1); /* Additional bandwidth expansion on backward filter */ Weight_Az(&A_t_bwd[M_BWDP1], GAMMA_BWD, M_BWD, &A_t_bwd[M_BWDP1]); } /*--------------------------------------------------* * Update synthesis signal for next frame. * *--------------------------------------------------*/ Copy(&synth_buf[L_FRAME], &synth_buf[0], MEM_SYN_BWD); if(lp_mode == 1) { if ((C_fe_fix != 0)) { /* Interpolation of the backward filter after a bad frame */ /* A_t_bwd(z) = C_fe . A_bwd_mem(z) + (1 - C_fe) . A_t_bwd(z) */ /* ---------------------------------------------------------- */ tmp = sub(4096, C_fe_fix); pA_t = A_t_bwd + M_BWDP1; for (i=0; i<M_BWDP1; i++) { L_temp = L_mult(pA_t[i], tmp); L_temp = L_shr(L_temp, 13); tmp1 = extract_l(L_temp); L_temp = L_mult(A_bwd_mem[i], C_fe_fix); L_temp = L_shr(L_temp, 13); tmp2 = extract_l(L_temp); pA_t[i] = add(tmp1, tmp2); } } } /* Memorize the last good backward filter when the frame is erased */ if ((bfi != 0)&&(prev_bfi == 0) && (past_ftyp >3)) for (i=0; i<M_BWDP1; i++) A_bwd_mem[i] = A_t_bwd[i+M_BWDP1]; /* for G.729B */ /* Processing non active frames (SID & not transmitted: ftyp = 1 or 0) */ if(ftyp < 2) { /* get_decfreq_prev(lsfq_mem); */ for (i=0; i<MA_NP; i++) Copy(&freq_prev[i][0], &lsfq_mem[i][0], M); Dec_cng(past_ftyp, sid_sav, sh_sid_sav, &parm[-1], exc, lsp_old, A_t_fwd, &seed, lsfq_mem); /* update_decfreq_prev(lsfq_mem); */ for (i=0; i<MA_NP; i++) Copy(&lsfq_mem[i][0], &freq_prev[i][0], M); pA_t = A_t_fwd; for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { Overflow = 0; Syn_filte(M, pA_t, &exc[i_subfr], &synth[i_subfr], L_SUBFR, &mem_syn[M_BWD-M], 0); if(Overflow != 0) { /* In case of overflow in the synthesis */ /* -> Scale down vector exc[] and redo synthesis */ for(i=0; i<PIT_MAX+L_INTERPOL+L_FRAME; i++) old_exc[i] = shr(old_exc[i], 2); Syn_filte(M, pA_t, &exc[i_subfr], &synth[i_subfr], L_SUBFR, &mem_syn[M_BWD-M], 0); } Copy(&synth[i_subfr+L_SUBFR-M_BWD], mem_syn, M_BWD); pA_t += MP1; } *T0_first = prev_T0; sharp = SHARPMIN; C_int = 4506; /* for gain decoding in case of frame erasure */ stat_bwd = 0; stationnary = 0; /* for pitch tracking in case of frame erasure */ stat_pitch = 0; /* update the previous filter for the next frame */ Copy(&A_t_fwd[MP1], prev_filter, MP1); for(i=MP1; i<M_BWDP1; i++) prev_filter[i] = 0; } else { /***************************/ /* Processing active frame */ /***************************/ seed = INIT_SEED; /* ---------------------------- */ /* LPC decoding in forward mode */ /* ---------------------------- */ if (lp_mode == 0) { /* Decode the LSPs */ D_lspe(parm, lsp_new, bfi, freq_prev, prev_lsp, &prev_ma); parm += 2; if( prev_lp_mode == 0) { /* Interpolation of LPC for the 2 subframes */ Int_qlpc(lsp_old, lsp_new, A_t_fwd); } else { /* no interpolation */ Lsp_Az(lsp_new, A_t_fwd); /* Subframe 1*/ Copy(A_t_fwd, &A_t_fwd[MP1], MP1); /* Subframe 2 */ } /* update the LSFs for the next frame */ Copy(lsp_new, lsp_old, M); C_int = 4506; pA_t = A_t_fwd; m_aq = M; /* update the previous filter for the next frame */ Copy(&A_t_fwd[MP1], prev_filter, MP1); for(i=MP1; i<M_BWDP1; i++) prev_filter[i] = 0; } else { Int_bwd(A_t_bwd, prev_filter, &C_int); pA_t = A_t_bwd; m_aq = M_BWD; /* update the previous filter for the next frame */ Copy(&A_t_bwd[M_BWDP1], prev_filter, M_BWDP1); } /*------------------------------------------------------------------------* * Loop for every subframe in the analysis frame * *------------------------------------------------------------------------* * The subframe size is L_SUBFR and the loop is repeated L_FRAME/L_SUBFR * * times * * - decode the pitch delay * * - decode algebraic code * * - decode pitch and codebook gains * * - find the excitation and compute synthesis speech * *------------------------------------------------------------------------*/ for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { index = *parm++; /* pitch index */ if(i_subfr == 0) { if (rate == G729D) i = 0; /* no pitch parity at 6.4 kb/s */ else i = *parm++; /* get parity check result */ bad_pitch = add(bfi, i); if( bad_pitch == 0) { Dec_lag3cp(index, PIT_MIN, PIT_MAX, i_subfr, &T0, &T0_frac,rate); prev_T0 = T0; prev_T0_frac = T0_frac; } else { /* Bad frame, or parity error */ if (bfi == 0) printf(" ! Wrong Pitch 1st subfr. ! "); T0 = prev_T0; if (rate == G729E) { T0_frac = prev_T0_frac; } else { T0_frac = 0; prev_T0 = add( prev_T0, 1); if( sub(prev_T0, PIT_MAX) > 0) { prev_T0 = PIT_MAX; } } } *T0_first = T0; /* If first frame */ } else { /* second subframe */ if( bfi == 0) { Dec_lag3cp(index, PIT_MIN, PIT_MAX, i_subfr, &T0, &T0_frac, rate); prev_T0 = T0; prev_T0_frac = T0_frac; } else { T0 = prev_T0; if (rate == G729E) { T0_frac = prev_T0_frac; } else { T0_frac = 0; prev_T0 = add( prev_T0, 1); if( sub(prev_T0, PIT_MAX) > 0) prev_T0 = PIT_MAX; } } } /*-------------------------------------------------* * - Find the adaptive codebook vector. * *-------------------------------------------------*/ Pred_lt_3(&exc[i_subfr], T0, T0_frac, L_SUBFR); /* --------------------------------- */ /* pitch tracking for frame erasures */ /* --------------------------------- */ if( rate == G729E) { track_pit(&prev_T0, &prev_T0_frac, &prev_pitch, &stat_pitch, &pitch_sta, &frac_sta); } else { i = prev_T0; j = prev_T0_frac; track_pit(&i, &j, &prev_pitch, &stat_pitch, &pitch_sta, &frac_sta); } /*-------------------------------------------------------* * - Decode innovative codebook. * *-------------------------------------------------------*/ if(bfi != 0) { /* Bad frame */ parm[0] = Random_g729cp(&seed_fer); parm[1] = Random_g729cp(&seed_fer); if (rate == G729E) { parm[2] = Random_g729cp(&seed_fer); parm[3] = Random_g729cp(&seed_fer); parm[4] = Random_g729cp(&seed_fer); } } stationnary = 0; /* to avoid visual warning */ if (rate == G729) { /* case 8 kbps */ Decod_ACELP(parm[1], parm[0], code); parm += 2; /* for gain decoding in case of frame erasure */ stat_bwd = 0; stationnary = 0; } else if (rate == G729D) { /* case 6.4 kbps */ Decod_ACELP64(parm[1], parm[0], code); parm += 2; /* for gain decoding in case of frame erasure */ stat_bwd = 0; stationnary = 0; } else if (rate == G729E) { /* case 11.8 kbps */ if (lp_mode == 0) { Dec_ACELP_10i40_35bits(parm, code); /* for gain decoding in case of frame erasure */ stat_bwd = 0; stationnary = 0; } else { Dec_ACELP_12i40_44bits(parm, code); /* for gain decoding in case of frame erasure */ stat_bwd = add(stat_bwd,1); if (sub(stat_bwd,30) >= 0) { stationnary = 1; stat_bwd = 30; } else stationnary = 0; } parm += 5; } /*-------------------------------------------------------* * - Add the fixed-gain pitch contribution to code[]. * *-------------------------------------------------------*/ 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 */ if (rate == G729D) Dec_gain_6k(index, code, L_SUBFR, bfi, &gain_pitch, &gain_code); else Dec_gaine(index, code, L_SUBFR, bfi, &gain_pitch, &gain_code, rate, gain_pit_mem, gain_cod_mem, &c_muting, count_bfi, stationnary); /*-------------------------------------------------------------* * - Update previous gains *-------------------------------------------------------------*/ gain_pit_mem = gain_pitch; gain_cod_mem = 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 */ count_bfi = add(count_bfi,1); 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); } /* Test whether synthesis yields overflow or not */ Overflow = 0; Syn_filte(m_aq, pA_t, &exc[i_subfr], &synth[i_subfr], L_SUBFR, &mem_syn[M_BWD-m_aq], 0); /* In case of overflow in the synthesis */ /* -> Scale down vector exc[] and redo synthesis */ if(Overflow != 0) { for(i=0; i<PIT_MAX+L_INTERPOL+L_FRAME; i++) old_exc[i] = shr(old_exc[i], 2); } if (rate == G729D) { PhDisp(&exc[i_subfr], exc_phdisp, gain_code, gain_pitch, code); Syn_filte(m_aq, pA_t, exc_phdisp, &synth[i_subfr], L_SUBFR, &mem_syn[M_BWD-m_aq], 0); } else { Syn_filte(m_aq, pA_t, &exc[i_subfr], &synth[i_subfr], L_SUBFR, &mem_syn[M_BWD-m_aq], 0); /* Updates state machine for phase dispersion in 6.4 kbps mode, if running at other rate */ Update_PhDisp(gain_pitch, gain_code); } pA_t += m_aq+1; /* interpolated LPC parameters for next subframe */ Copy(&synth[i_subfr+L_SUBFR-M_BWD], mem_syn, M_BWD); } } /*------------* * For G729b *-----------*/ if(bfi == 0) { L_temp = 0L; for(i=0; i<L_FRAME; i++) { L_temp = L_mac(L_temp, exc[i], exc[i]); } /* may overflow => 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); } past_ftyp = ftyp; /*------------* * For G729E *-----------*/ energy = ener_dB(synth, L_FRAME); if (energy >= 8192) tst_bwd_dominant(bwd_dominant, lp_mode); /*--------------------------------------------------* * 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); if( lp_mode == 0) { Copy(A_t_fwd, Az_dec, 2*MP1); *m_pst = M; } else { Copy(A_t_bwd, Az_dec, 2*M_BWDP1); *m_pst = M_BWD; } prev_bfi = bfi; prev_lp_mode = lp_mode; prev_voicing = voicing; if (bfi != 0) C_fe_fix = 4096; else { if (lp_mode == 0) C_fe_fix = 0; else { if (*bwd_dominant == 1) C_fe_fix = sub(C_fe_fix, 410); else C_fe_fix = sub(C_fe_fix, 2048); if (C_fe_fix < 0) C_fe_fix= 0; } } return; }
/*-------------------------------------------------------------------------- * decod_ld8c - decoder *-------------------------------------------------------------------------- */ void decod_ld8c( int parm[], /* (i) : vector of synthesis parameters parm[0] = bad frame indicator (bfi) */ int voicing, /* (i) : voicing decision from previous frame */ FLOAT synth_buf[], /* (i/o) : synthesis speech */ FLOAT Az_dec[], /* (o) : decoded LP filter in 2 subframes */ int *t0_first, /* (o) : decoded pitch lag in first subframe */ int *bwd_dominant,/* (o) : bwd dominant indicator */ int *m_pst, /* (o) : LPC order for postfilter */ int *Vad /* output: decoded frame type */ ) { /* Scalars */ int i, j, i_subfr; int t0, t0_frac, index; int bfi; int lp_mode; /* Backward / Forward mode indication */ FLOAT g_p, g_c; /* fixed and adaptive codebook gain */ int bad_pitch; /* bad pitch indicator */ FLOAT tmp; FLOAT energy; int rate; /* Tables */ FLOAT A_t_bwd[2*M_BWDP1]; /* LPC Backward filter */ FLOAT A_t_fwd[2*MP1]; /* LPC Forward filter */ FLOAT rc_bwd[M_BWD]; /* LPC backward reflection coefficients */ FLOAT r_bwd[M_BWDP1]; /* Autocorrelations (backward) */ FLOAT lsp_new[M]; /* LSPs */ FLOAT code[L_SUBFR]; /* ACELP codevector */ FLOAT exc_phdisp[L_SUBFR]; /* excitation after phase dispersion */ FLOAT *pA_t; /* Pointer on A_t */ int stationnary; int m_aq; FLOAT *synth; int sat_filter; /* for G.729B */ int ftyp; FLOAT lsfq_mem[MA_NP][M]; synth = synth_buf + MEM_SYN_BWD; /* Test bad frame indicator (bfi) */ bfi = *parm++; /* Test frame type */ ftyp = *parm++; if(bfi == 1) { ftyp = past_ftyp; if(ftyp == 1) ftyp = 0; if(ftyp > 2) { /* G.729 maintenance */ if(ftyp == 3) parm[4] = 1; else { if(prev_lp_mode == 0) parm[5] = 1; else parm[3] = 1; } } parm[-1] = ftyp; } *Vad = ftyp; rate = ftyp - 2; /* Decoding the Backward/Forward LPC decision */ /* ------------------------------------------ */ if( rate != G729E) lp_mode = 0; else { if (bfi != 0) { lp_mode = prev_lp_mode; /* Frame erased => lp_mode = previous lp_mode */ *parm++ = lp_mode; } else { lp_mode = *parm++; } if(prev_bfi != 0) voicing = prev_voicing; } if( bfi == 0) { c_muting = (F)1.; count_bfi = 0; } /* -------------------- */ /* Backward LP analysis */ /* -------------------- */ if (rate == G729E) { /* LPC recursive Window as in G728 */ autocorr_hyb_window(synth_buf, r_bwd, rexp); /* Autocorrelations */ lag_window_bwd(r_bwd); /* Lag windowing */ /* Levinson (as in G729) */ levinsone(M_BWD, r_bwd, &A_t_bwd[M_BWDP1], rc_bwd, old_A_bwd, old_rc_bwd ); /* Tests saturation of A_t_bwd */ sat_filter = 0; for (i=M_BWDP1; i<2*M_BWDP1; i++) if (A_t_bwd[i] >= (F)8.) sat_filter = 1; if (sat_filter == 1) copy(A_t_bwd_mem, &A_t_bwd[M_BWDP1], M_BWDP1); else copy(&A_t_bwd[M_BWDP1], A_t_bwd_mem, M_BWDP1); /* Additional bandwidth expansion on backward filter */ weight_az(&A_t_bwd[M_BWDP1], GAMMA_BWD, M_BWD, &A_t_bwd[M_BWDP1]); } /*--------------------------------------------------* * Update synthesis signal for next frame. * *--------------------------------------------------*/ copy(&synth_buf[L_FRAME], &synth_buf[0], MEM_SYN_BWD); if(lp_mode == 1) { if ((c_fe != (F)0.)) { /* Interpolation of the backward filter after a bad frame */ /* A_t_bwd(z) = c_fe . A_bwd_mem(z) + (1 - c_fe) . A_t_bwd(z) */ /* ---------------------------------------------------------- */ tmp = (F)1. - c_fe; pA_t = A_t_bwd + M_BWDP1; for (i=0; i<M_BWDP1; i++) { pA_t[i] *= tmp; pA_t[i] += c_fe * A_bwd_mem[i]; } } } /* Memorize the last good backward filter when the frame is erased */ if ((bfi != 0)&&(prev_bfi == 0) && (past_ftyp >3)) copy(&A_t_bwd[M_BWDP1], A_bwd_mem, M_BWDP1); /* for G.729B */ /* Processing non active frames (SID & not transmitted: ftyp = 1 or 0) */ if(ftyp < 2) { /* get_decfreq_prev(lsfq_mem); */ for (i=0; i<MA_NP; i++) copy(&freq_prev[i][0], &lsfq_mem[i][0], M); dec_cng(past_ftyp, sid_sav, &parm[-1], exc, lsp_old, A_t_fwd, &seed, lsfq_mem); /* update_decfreq_prev(lsfq_mem); */ for (i=0; i<MA_NP; i++) copy(&lsfq_mem[i][0], &freq_prev[i][0], M); pA_t = A_t_fwd; for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { syn_filte(M, pA_t, &exc[i_subfr], &synth[i_subfr], L_SUBFR, &mem_syn[M_BWD-M], 0); copy(&synth[i_subfr+L_SUBFR-M_BWD], mem_syn, M_BWD); *t0_first = prev_t0; pA_t += MP1; } sharp = SHARPMIN; c_int = (F)1.1; /* for gain decoding in case of frame erasure */ stat_bwd = 0; stationnary = 0; /* for pitch tracking in case of frame erasure */ stat_pitch = 0; /* update the previous filter for the next frame */ copy(&A_t_fwd[MP1], prev_filter, MP1); for(i=MP1; i<M_BWDP1; i++) prev_filter[i] = (F)0.; } /***************************/ /* Processing active frame */ /***************************/ else { seed = INIT_SEED; /* ---------------------------- */ /* LPC decoding in forward mode */ /* ---------------------------- */ if (lp_mode == 0) { /* Decode the LSPs */ d_lspe(parm, lsp_new, bfi, freq_prev, prev_lsp, &prev_ma); parm += 2; if( prev_lp_mode == 0) { /* Interpolation of LPC for the 2 subframes */ int_qlpc(lsp_old, lsp_new, A_t_fwd); } else { /* no interpolation */ lsp_az(lsp_new, A_t_fwd); /* Subframe 1*/ copy(A_t_fwd, &A_t_fwd[MP1], MP1); /* Subframe 2 */ } /* update the LSFs for the next frame */ copy(lsp_new, lsp_old, M); c_int = (F)1.1; pA_t = A_t_fwd; m_aq = M; /* update the previous filter for the next frame */ copy(&A_t_fwd[MP1], prev_filter, MP1); for(i=MP1; i<M_BWDP1; i++) prev_filter[i] = (F)0.; } else { int_bwd(A_t_bwd, prev_filter, &c_int); pA_t = A_t_bwd; m_aq = M_BWD; /* update the previous filter for the next frame */ copy(&A_t_bwd[M_BWDP1], prev_filter, M_BWDP1); } /*------------------------------------------------------------------------* * Loop for every subframe in the analysis frame * *------------------------------------------------------------------------* * The subframe size is L_SUBFR and the loop is repeated L_FRAME/L_SUBFR * * times * * - decode the pitch delay * * - decode algebraic code * * - decode pitch and codebook gains * * - find the excitation and compute synthesis speech * *------------------------------------------------------------------------*/ for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { index = *parm++; /* pitch index */ if(i_subfr == 0) { if (rate == G729D) i = 0; /* no pitch parity at 6.4 kb/s */ else i = *parm++; /* get parity check result */ bad_pitch = bfi + i; if( bad_pitch == 0) { dec_lag3cp(index, PIT_MIN, PIT_MAX, i_subfr, &t0, &t0_frac, rate); prev_t0 = t0; prev_t0_frac = t0_frac; } else { /* Bad frame, or parity error */ if (bfi == 0) printf(" ! Wrong Pitch 1st subfr. ! "); t0 = prev_t0; if (rate == G729E) { t0_frac = prev_t0_frac; } else { t0_frac = 0; prev_t0++; if(prev_t0 > PIT_MAX) { prev_t0 = PIT_MAX; } } } *t0_first = t0; /* If first frame */ } else { /* second subframe */ if( bfi == 0) { dec_lag3cp(index, PIT_MIN, PIT_MAX, i_subfr, &t0, &t0_frac, rate); prev_t0 = t0; prev_t0_frac = t0_frac; } else { t0 = prev_t0; if (rate == G729E) { t0_frac = prev_t0_frac; } else { t0_frac = 0; prev_t0++; if(prev_t0 > PIT_MAX) prev_t0 = PIT_MAX; } } } /*-------------------------------------------------* * - Find the adaptive codebook vector. * *-------------------------------------------------*/ pred_lt_3(&exc[i_subfr], t0, t0_frac, L_SUBFR); /* --------------------------------- */ /* pitch tracking for frame erasures */ /* --------------------------------- */ if( rate == G729E) { track_pit(&prev_t0, &prev_t0_frac, &prev_pitch, &stat_pitch, &pitch_sta, &frac_sta); } else { i = prev_t0; j = prev_t0_frac; track_pit(&i, &j, &prev_pitch, &stat_pitch, &pitch_sta, &frac_sta); } /*-------------------------------------------------------* * - Decode innovative codebook. * *-------------------------------------------------------*/ if(bfi != 0) { /* Bad frame */ parm[0] = (int)random_g729c(&seed_fer); parm[1] = (int)random_g729c(&seed_fer); if (rate == G729E) { parm[2] = (int)random_g729c(&seed_fer); parm[3] = (int)random_g729c(&seed_fer); parm[4] = (int)random_g729c(&seed_fer); } } stationnary = 0; /* to avoid visual warning */ if (rate == G729) { /* case 8 kbps */ decod_ACELP(parm[1], parm[0], code); parm += 2; /* for gain decoding in case of frame erasure */ stat_bwd = 0; stationnary = 0; } else if (rate == G729D) { /* case 8 kbps */ decod_ACELP64(parm[1], parm[0], code); parm += 2; /* for gain decoding in case of frame erasure */ stat_bwd = 0; stationnary = 0; } else if (rate == G729E) { /* case 11.8 kbps */ if (lp_mode == 0) { dec_ACELP_10i40_35bits(parm, code); /* for gain decoding in case of frame erasure */ stat_bwd = 0; stationnary = 0; } else { dec_ACELP_12i40_44bits(parm, code); /* for gain decoding in case of frame erasure */ stat_bwd++; if (stat_bwd >= 30) { stationnary = 1; stat_bwd = 30; } else stationnary = 0; } parm += 5; } /*-------------------------------------------------------* * - Add the fixed-gain pitch contribution to code[]. * *-------------------------------------------------------*/ for (i = t0; i < L_SUBFR; i++) code[i] += sharp * code[i-t0]; /*-------------------------------------------------* * - Decode pitch and codebook gains. * *-------------------------------------------------*/ index = *parm++; /* index of energy VQ */ if (rate == G729D) dec_gain_6k(index, code, L_SUBFR, bfi, &gain_pitch, &gain_code); else dec_gaine(index, code, L_SUBFR, bfi, &gain_pitch, &gain_code, rate, gain_pit_mem, gain_cod_mem, &c_muting, count_bfi, stationnary); /*-------------------------------------------------------------* * - Update previous gains *-------------------------------------------------------------*/ gain_pit_mem = gain_pitch; gain_cod_mem = gain_code; /*-------------------------------------------------------------* * - Update pitch sharpening "sharp" with quantized gain_pitch * *-------------------------------------------------------------*/ sharp = gain_pitch; if (sharp > SHARPMAX) sharp = SHARPMAX; if (sharp < SHARPMIN) sharp = SHARPMIN; /*-------------------------------------------------------* * - Find the total excitation. * * - Find synthesis speech corresponding to exc[]. * *-------------------------------------------------------*/ if(bfi != 0) { /* Bad frame */ count_bfi++; if (voicing == 0 ) { g_p = (F)0.; g_c = gain_code; } else { g_p = gain_pitch; g_c = (F)0.; } } else { g_p = gain_pitch; g_c = gain_code; } for (i = 0; i < L_SUBFR; i++) { exc[i+i_subfr] = g_p * exc[i+i_subfr] + g_c * code[i]; } if (rate == G729D) { PhDisp(&exc[i_subfr], exc_phdisp, gain_code, gain_pitch, code); syn_filte(m_aq, pA_t, exc_phdisp, &synth[i_subfr], L_SUBFR, &mem_syn[M_BWD-m_aq], 0); } else { syn_filte(m_aq, pA_t, &exc[i_subfr], &synth[i_subfr], L_SUBFR, &mem_syn[M_BWD-m_aq], 0); /* Updates state machine for phase dispersion in 6.4 kbps mode, if running at other rate */ Update_PhDisp(gain_pitch, gain_code); } copy(&synth[i_subfr+L_SUBFR-M_BWD], mem_syn, M_BWD); pA_t += m_aq+1; /* interpolated LPC parameters for next subframe */ } } /*------------* * For G729b *-----------*/ if(bfi == 0) { sid_sav = (FLOAT)0.0; for(i=0; i<L_FRAME; i++) { sid_sav += exc[i] * exc[i]; } } past_ftyp = ftyp; /*------------* * For G729E *-----------*/ energy = ener_dB(synth, L_FRAME); if (energy >= (F)40.) tst_bwd_dominant(bwd_dominant, lp_mode); /*--------------------------------------------------* * 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); if( lp_mode == 0) { copy(A_t_fwd, Az_dec, 2*MP1); *m_pst = M; } else { copy(A_t_bwd, Az_dec, 2*M_BWDP1); *m_pst = M_BWD; } prev_bfi = bfi; prev_lp_mode = lp_mode; prev_voicing = voicing; if (bfi != 0) c_fe = (F)1.; else { if (lp_mode == 0) c_fe = 0; else { if (*bwd_dominant == 1) c_fe -= (F)0.1; else c_fe -= (F)0.5; if (c_fe < 0) c_fe= 0; } } return; }