/*---------------------------------------------------------------------------- * Post - adaptive postfilter main function *---------------------------------------------------------------------------- */ void Post( Word16 t0, /* input : pitch delay given by coder */ Word16 *signal_ptr, /* input : input signal (pointer to current subframe */ Word16 *coeff, /* input : LPC coefficients for current subframe */ Word16 *sig_out, /* output: postfiltered output */ Word16 *vo, /* output: voicing decision 0 = uv, > 0 delay */ Word16 Vad /* input : frame type */ ) { /* Local variables and arrays */ Word16 apond1[MP1]; /* s.t. denominator coeff. */ Word16 sig_ltp[L_SUBFRP1]; /* H0 output signal */ Word16 *sig_ltp_ptr; Word16 parcor0; /* Compute weighted LPC coefficients */ Weight_Az(coeff, GAMMA1_PST, M, apond1); Weight_Az(coeff, GAMMA2_PST, M, apond2); /* Compute A(gamma2) residual */ Residu(apond2, signal_ptr, res2_ptr, L_SUBFR); /* Harmonic filtering */ sig_ltp_ptr = sig_ltp + 1; if (sub(Vad, 1) == 0) pst_ltp(t0, res2_ptr, sig_ltp_ptr, vo); else { *vo = 0; Copy(res2_ptr, sig_ltp_ptr, L_SUBFR); } /* Save last output of 1/A(gamma1) */ /* (from preceding subframe) */ sig_ltp[0] = *ptr_mem_stp; /* Controls short term pst filter gain and compute parcor0 */ calc_st_filt(apond2, apond1, &parcor0, sig_ltp_ptr); /* 1/A(gamma1) filtering, mem_stp is updated */ Syn_filt(apond1, sig_ltp_ptr, sig_ltp_ptr, L_SUBFR, mem_stp, 1); /* Tilt filtering */ filt_mu(sig_ltp, sig_out, parcor0); /* Gain control */ scale_st(signal_ptr, sig_out, &gain_prec); /**** Update for next subframe */ Copy(&res2[L_SUBFR], &res2[0], MEM_RES2); return; }
void Post_Filter( Word16 *syn, /* in/out: synthesis speech (postfiltered is output) */ Word16 *Az_4, /* input : interpolated LPC parameters in all subframes */ Word16 *T, /* input : decoded pitch lags in all subframes */ Word16 Vad ) { /*-------------------------------------------------------------------* * Declaration of parameters * *-------------------------------------------------------------------*/ Word16 res2_pst[L_SUBFR]; /* res2[] after pitch postfiltering */ Word16 syn_pst[L_FRAME]; /* post filtered synthesis speech */ Word16 Ap3[MP1], Ap4[MP1]; /* bandwidth expanded LP parameters */ Word16 *Az; /* pointer to Az_4: */ /* LPC parameters in each subframe */ Word16 t0_max, t0_min; /* closed-loop pitch search range */ Word16 i_subfr; /* index for beginning of subframe */ Word16 h[L_H]; Word16 i, j; Word16 temp1, temp2; Word32 L_tmp; postfilt_type* ppost_filt = pg729dec->ppost_filt; /*-----------------------------------------------------* * Post filtering * *-----------------------------------------------------*/ Az = Az_4; for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { /* Find pitch range t0_min - t0_max */ t0_min = sub(*T++, 3); t0_max = add(t0_min, 6); if (sub(t0_max, PIT_MAX) > 0) { t0_max = PIT_MAX; t0_min = sub(t0_max, 6); } /* Find weighted filter coefficients Ap3[] and ap[4] */ Weight_Az(Az, GAMMA2_PST, M, Ap3); Weight_Az(Az, GAMMA1_PST, M, Ap4); /* filtering of synthesis speech by A(z/GAMMA2_PST) to find res2[] */ Residu(Ap3, &syn[i_subfr], ppost_filt->res2, L_SUBFR); /* scaling of "res2[]" to avoid energy overflow */ for (j=0; j<L_SUBFR; j++) { ppost_filt->scal_res2[j] = shr(ppost_filt->res2[j], 2); } /* pitch postfiltering */ if (sub(Vad, 1) == 0) pit_pst_filt(ppost_filt->res2, ppost_filt->scal_res2, t0_min, t0_max, L_SUBFR, res2_pst); else for (j=0; j<L_SUBFR; j++) res2_pst[j] = ppost_filt->res2[j]; /* tilt compensation filter */ /* impulse response of A(z/GAMMA2_PST)/A(z/GAMMA1_PST) */ Copy(Ap3, h, M+1); Set_zero(&h[M+1], L_H-M-1); Syn_filt(Ap4, h, h, L_H, &h[M+1], 0); /* 1st correlation of h[] */ L_tmp = L_mult(h[0], h[0]); for (i=1; i<L_H; i++) L_tmp = L_mac(L_tmp, h[i], h[i]); temp1 = extract_h(L_tmp); L_tmp = L_mult(h[0], h[1]); for (i=1; i<L_H-1; i++) L_tmp = L_mac(L_tmp, h[i], h[i+1]); temp2 = extract_h(L_tmp); if(temp2 <= 0) { temp2 = 0; } else { temp2 = mult(temp2, MU); temp2 = div_s(temp2, temp1); } preemphasis(res2_pst, temp2, L_SUBFR); /* filtering through 1/A(z/GAMMA1_PST) */ Syn_filt(Ap4, res2_pst, &syn_pst[i_subfr], L_SUBFR, ppost_filt->mem_syn_pst, 1); /* scale output to input */ agc(&syn[i_subfr], &syn_pst[i_subfr], L_SUBFR); /* update res2[] buffer; shift by L_SUBFR */ Copy(&ppost_filt->res2[L_SUBFR-PIT_MAX], &ppost_filt->res2[-PIT_MAX], PIT_MAX); Copy(&ppost_filt->scal_res2[L_SUBFR-PIT_MAX], &ppost_filt->scal_res2[-PIT_MAX], PIT_MAX); Az += MP1; } /* update syn[] buffer */ Copy(&syn[L_FRAME-M], &syn[-M], M); /* overwrite synthesis speech by postfiltered synthesis speech */ Copy(syn_pst, syn, L_FRAME); return; }
void Coder_ld8a( Word16 ana[], /* output : Analysis parameters */ Word16 frame, /* input : frame counter */ Word16 vad_enable /* input : VAD enable flag */ ) { /* LPC analysis */ Word16 Aq_t[(MP1)*2]; /* A(z) quantized for the 2 subframes */ Word16 Ap_t[(MP1)*2]; /* A(z/gamma) for the 2 subframes */ Word16 *Aq, *Ap; /* Pointer on Aq_t and Ap_t */ /* Other vectors */ Word16 h1[L_SUBFR]; /* Impulse response h1[] */ Word16 xn[L_SUBFR]; /* Target vector for pitch search */ Word16 xn2[L_SUBFR]; /* Target vector for codebook search */ Word16 code[L_SUBFR]; /* Fixed codebook excitation */ Word16 y1[L_SUBFR]; /* Filtered adaptive excitation */ Word16 y2[L_SUBFR]; /* Filtered fixed codebook excitation */ Word16 g_coeff[4]; /* Correlations between xn & y1 */ Word16 g_coeff_cs[5]; Word16 exp_g_coeff_cs[5]; /* Correlations between xn, y1, & y2 <y1,y1>, -2<xn,y1>, <y2,y2>, -2<xn,y2>, 2<y1,y2> */ /* Scalars */ Word16 i, j, k, i_subfr; Word16 T_op, T0, T0_min, T0_max, T0_frac; Word16 gain_pit, gain_code, index; Word16 temp, taming; Word32 L_temp; /*------------------------------------------------------------------------* * - Perform LPC analysis: * * * autocorrelation + lag windowing * * * Levinson-durbin algorithm to find a[] * * * convert a[] to lsp[] * * * quantize and code the LSPs * * * find the interpolated LSPs and convert to a[] for the 2 * * subframes (both quantized and unquantized) * *------------------------------------------------------------------------*/ { /* Temporary vectors */ Word16 r_l[NP+1], r_h[NP+1]; /* Autocorrelations low and hi */ Word16 rc[M]; /* Reflection coefficients. */ Word16 lsp_new[M], lsp_new_q[M]; /* LSPs at 2th subframe */ /* For G.729B */ Word16 rh_nbe[MP1]; Word16 lsf_new[M]; Word16 lsfq_mem[MA_NP][M]; Word16 exp_R0, Vad; /* LP analysis */ Autocorr(p_window, NP, r_h, r_l, &exp_R0); /* Autocorrelations */ Copy(r_h, rh_nbe, MP1); Lag_window(NP, r_h, r_l); /* Lag windowing */ Levinson(r_h, r_l, Ap_t, rc, &temp); /* Levinson Durbin */ Az_lsp(Ap_t, lsp_new, lsp_old); /* From A(z) to lsp */ /* For G.729B */ /* ------ VAD ------- */ Lsp_lsf(lsp_new, lsf_new, M); vad(rc[1], lsf_new, r_h, r_l, exp_R0, p_window, frame, pastVad, ppastVad, &Vad); Update_cng(rh_nbe, exp_R0, Vad); /* ---------------------- */ /* Case of Inactive frame */ /* ---------------------- */ if ((Vad == 0) && (vad_enable == 1)){ Get_freq_prev(lsfq_mem); Cod_cng(exc, pastVad, lsp_old_q, Aq_t, ana, lsfq_mem, &seed); Update_freq_prev(lsfq_mem); ppastVad = pastVad; pastVad = Vad; /* Update wsp, mem_w and mem_w0 */ Aq = Aq_t; for(i_subfr=0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { /* Residual signal in xn */ Residu(Aq, &speech[i_subfr], xn, L_SUBFR); Weight_Az(Aq, GAMMA1, M, Ap_t); /* Compute wsp and mem_w */ Ap = Ap_t + MP1; Ap[0] = 4096; for(i=1; i<=M; i++) /* Ap[i] = Ap_t[i] - 0.7 * Ap_t[i-1]; */ Ap[i] = sub(Ap_t[i], mult(Ap_t[i-1], 22938)); Syn_filt(Ap, xn, &wsp[i_subfr], L_SUBFR, mem_w, 1); /* Compute mem_w0 */ for(i=0; i<L_SUBFR; i++) { xn[i] = sub(xn[i], exc[i_subfr+i]); /* residu[] - exc[] */ } Syn_filt(Ap_t, xn, xn, L_SUBFR, mem_w0, 1); Aq += MP1; } sharp = SHARPMIN; /* Update memories for next frames */ Copy(&old_speech[L_FRAME], &old_speech[0], L_TOTAL-L_FRAME); Copy(&old_wsp[L_FRAME], &old_wsp[0], PIT_MAX); Copy(&old_exc[L_FRAME], &old_exc[0], PIT_MAX+L_INTERPOL); return; } /* End of inactive frame case */ /* -------------------- */ /* Case of Active frame */ /* -------------------- */ /* Case of active frame */ *ana++ = 1; seed = INIT_SEED; ppastVad = pastVad; pastVad = Vad; /* LSP quantization */ Qua_lsp(lsp_new, lsp_new_q, ana); ana += 2; /* Advance analysis parameters pointer */ /*--------------------------------------------------------------------* * Find interpolated LPC parameters in all subframes * * The interpolated parameters are in array Aq_t[]. * *--------------------------------------------------------------------*/ Int_qlpc(lsp_old_q, lsp_new_q, Aq_t); /* Compute A(z/gamma) */ Weight_Az(&Aq_t[0], GAMMA1, M, &Ap_t[0]); Weight_Az(&Aq_t[MP1], GAMMA1, M, &Ap_t[MP1]); /* update the LSPs for the next frame */ Copy(lsp_new, lsp_old, M); Copy(lsp_new_q, lsp_old_q, M); } /*----------------------------------------------------------------------* * - Find the weighted input speech w_sp[] for the whole speech frame * * - Find the open-loop pitch delay * *----------------------------------------------------------------------*/ Residu(&Aq_t[0], &speech[0], &exc[0], L_SUBFR); Residu(&Aq_t[MP1], &speech[L_SUBFR], &exc[L_SUBFR], L_SUBFR); { Word16 Ap1[MP1]; Ap = Ap_t; Ap1[0] = 4096; for(i=1; i<=M; i++) /* Ap1[i] = Ap[i] - 0.7 * Ap[i-1]; */ Ap1[i] = sub(Ap[i], mult(Ap[i-1], 22938)); Syn_filt(Ap1, &exc[0], &wsp[0], L_SUBFR, mem_w, 1); Ap += MP1; for(i=1; i<=M; i++) /* Ap1[i] = Ap[i] - 0.7 * Ap[i-1]; */ Ap1[i] = sub(Ap[i], mult(Ap[i-1], 22938)); Syn_filt(Ap1, &exc[L_SUBFR], &wsp[L_SUBFR], L_SUBFR, mem_w, 1); } /* Find open loop pitch lag */ T_op = Pitch_ol_fast(wsp, PIT_MAX, L_FRAME); /* Range for closed loop pitch search in 1st subframe */ T0_min = sub(T_op, 3); if (sub(T0_min,PIT_MIN)<0) { T0_min = PIT_MIN; } T0_max = add(T0_min, 6); if (sub(T0_max ,PIT_MAX)>0) { T0_max = PIT_MAX; T0_min = sub(T0_max, 6); } /*------------------------------------------------------------------------* * 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 2 times. * * - find the weighted LPC coefficients * * - find the LPC residual signal res[] * * - compute the target signal for pitch search * * - compute impulse response of weighted synthesis filter (h1[]) * * - find the closed-loop pitch parameters * * - encode the pitch delay * * - find target vector for codebook search * * - codebook search * * - VQ of pitch and codebook gains * * - update states of weighting filter * *------------------------------------------------------------------------*/ Aq = Aq_t; /* pointer to interpolated quantized LPC parameters */ Ap = Ap_t; /* pointer to weighted LPC coefficients */ for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { /*---------------------------------------------------------------* * Compute impulse response, h1[], of weighted synthesis filter * *---------------------------------------------------------------*/ h1[0] = 4096; Set_zero(&h1[1], L_SUBFR-1); Syn_filt(Ap, h1, h1, L_SUBFR, &h1[1], 0); /*----------------------------------------------------------------------* * Find the target vector for pitch search: * *----------------------------------------------------------------------*/ Syn_filt(Ap, &exc[i_subfr], xn, L_SUBFR, mem_w0, 0); /*---------------------------------------------------------------------* * Closed-loop fractional pitch search * *---------------------------------------------------------------------*/ T0 = Pitch_fr3_fast(&exc[i_subfr], xn, h1, L_SUBFR, T0_min, T0_max, i_subfr, &T0_frac); index = Enc_lag3(T0, T0_frac, &T0_min, &T0_max,PIT_MIN,PIT_MAX,i_subfr); *ana++ = index; if (i_subfr == 0) { *ana++ = Parity_Pitch(index); } /*-----------------------------------------------------------------* * - find filtered pitch exc * * - compute pitch gain and limit between 0 and 1.2 * * - update target vector for codebook search * *-----------------------------------------------------------------*/ Syn_filt(Ap, &exc[i_subfr], y1, L_SUBFR, mem_zero, 0); gain_pit = G_pitch(xn, y1, g_coeff, L_SUBFR); /* clip pitch gain if taming is necessary */ taming = test_err(T0, T0_frac); if( taming == 1){ if (sub(gain_pit, GPCLIP) > 0) { gain_pit = GPCLIP; } } /* xn2[i] = xn[i] - y1[i] * gain_pit */ for (i = 0; i < L_SUBFR; i++) { L_temp = L_mult(y1[i], gain_pit); L_temp = L_shl(L_temp, 1); /* gain_pit in Q14 */ xn2[i] = sub(xn[i], extract_h(L_temp)); } /*-----------------------------------------------------* * - Innovative codebook search. * *-----------------------------------------------------*/ index = ACELP_Code_A(xn2, h1, T0, sharp, code, y2, &i); *ana++ = index; /* Positions index */ *ana++ = i; /* Signs index */ /*-----------------------------------------------------* * - Quantization of gains. * *-----------------------------------------------------*/ g_coeff_cs[0] = g_coeff[0]; /* <y1,y1> */ exp_g_coeff_cs[0] = negate(g_coeff[1]); /* Q-Format:XXX -> JPN */ g_coeff_cs[1] = negate(g_coeff[2]); /* (xn,y1) -> -2<xn,y1> */ exp_g_coeff_cs[1] = negate(add(g_coeff[3], 1)); /* Q-Format:XXX -> JPN */ Corr_xy2( xn, y1, y2, g_coeff_cs, exp_g_coeff_cs ); /* Q0 Q0 Q12 ^Qx ^Q0 */ /* g_coeff_cs[3]:exp_g_coeff_cs[3] = <y2,y2> */ /* g_coeff_cs[4]:exp_g_coeff_cs[4] = -2<xn,y2> */ /* g_coeff_cs[5]:exp_g_coeff_cs[5] = 2<y1,y2> */ *ana++ = Qua_gain(code, g_coeff_cs, exp_g_coeff_cs, L_SUBFR, &gain_pit, &gain_code, taming); /*------------------------------------------------------------* * - Update pitch sharpening "sharp" with quantized gain_pit * *------------------------------------------------------------*/ sharp = gain_pit; if (sub(sharp, SHARPMAX) > 0) { sharp = SHARPMAX; } if (sub(sharp, SHARPMIN) < 0) { sharp = SHARPMIN; } /*------------------------------------------------------* * - Find the total excitation * * - update filters memories for finding the target * * vector in the next subframe * *------------------------------------------------------*/ for (i = 0; i < L_SUBFR; i++) { /* exc[i] = gain_pit*exc[i] + gain_code*code[i]; */ /* exc[i] in Q0 gain_pit in Q14 */ /* code[i] in Q13 gain_cod in Q1 */ L_temp = L_mult(exc[i+i_subfr], gain_pit); L_temp = L_mac(L_temp, code[i], gain_code); L_temp = L_shl(L_temp, 1); exc[i+i_subfr] = round(L_temp); } update_exc_err(gain_pit, T0); for (i = L_SUBFR-M, j = 0; i < L_SUBFR; i++, j++) { temp = extract_h(L_shl( L_mult(y1[i], gain_pit), 1) ); k = extract_h(L_shl( L_mult(y2[i], gain_code), 2) ); mem_w0[j] = sub(xn[i], add(temp, k)); } Aq += MP1; /* interpolated LPC parameters for next subframe */ Ap += MP1; } /*--------------------------------------------------* * Update signal for next frame. * * -> shift to the left by L_FRAME: * * speech[], wsp[] and exc[] * *--------------------------------------------------*/ Copy(&old_speech[L_FRAME], &old_speech[0], L_TOTAL-L_FRAME); Copy(&old_wsp[L_FRAME], &old_wsp[0], PIT_MAX); Copy(&old_exc[L_FRAME], &old_exc[0], PIT_MAX+L_INTERPOL); return; }
void Coder_ld8h( Word16 ana[], /* (o) : analysis parameters */ Word16 rate /* input : rate selector/frame =0 6.4kbps , =1 8kbps,= 2 11.8 kbps*/ ) { /* LPC analysis */ Word16 r_l_fwd[MP1], r_h_fwd[MP1]; /* Autocorrelations low and hi (forward) */ 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 rc_fwd[M]; /* Reflection coefficients : forward analysis */ Word16 rc_bwd[M_BWD]; /* Reflection coefficients : backward analysis */ Word16 A_t_fwd[MP1*2]; /* A(z) forward unquantized for the 2 subframes */ Word16 A_t_fwd_q[MP1*2]; /* A(z) forward quantized for the 2 subframes */ Word16 A_t_bwd[2*M_BWDP1]; /* A(z) backward for the 2 subframes */ Word16 *Aq; /* A(z) "quantized" for the 2 subframes */ Word16 *Ap; /* A(z) "unquantized" for the 2 subframes */ Word16 *pAp, *pAq; Word16 Ap1[M_BWDP1]; /* A(z) with spectral expansion */ Word16 Ap2[M_BWDP1]; /* A(z) with spectral expansion */ Word16 lsp_new[M], lsp_new_q[M]; /* LSPs at 2th subframe */ Word16 lsf_int[M]; /* Interpolated LSF 1st subframe. */ Word16 lsf_new[M]; Word16 lp_mode; /* Backward / Forward Indication mode */ Word16 m_ap, m_aq, i_gamma; Word16 code_lsp[2]; /* Other vectors */ Word16 h1[L_SUBFR]; /* Impulse response h1[] */ Word16 xn[L_SUBFR]; /* Target vector for pitch search */ Word16 xn2[L_SUBFR]; /* Target vector for codebook search */ Word16 code[L_SUBFR]; /* Fixed codebook excitation */ Word16 y1[L_SUBFR]; /* Filtered adaptive excitation */ Word16 y2[L_SUBFR]; /* Filtered fixed codebook excitation */ Word16 g_coeff[4]; /* Correlations between xn & y1 */ Word16 res2[L_SUBFR]; /* residual after long term prediction*/ Word16 g_coeff_cs[5]; Word16 exp_g_coeff_cs[5]; /* Correlations between xn, y1, & y2 <y1,y1>, -2<xn,y1>, <y2,y2>, -2<xn,y2>, 2<y1,y2> */ /* Scalars */ Word16 i, j, k, i_subfr; Word16 T_op, T0, T0_min, T0_max, T0_frac; Word16 gain_pit, gain_code, index; Word16 taming, pit_sharp; Word16 sat_filter; Word32 L_temp; Word16 freq_cur[M]; Word16 temp; /*------------------------------------------------------------------------* * - Perform LPC analysis: * * * autocorrelation + lag windowing * * * Levinson-durbin algorithm to find a[] * * * convert a[] to lsp[] * * * quantize and code the LSPs * * * find the interpolated LSPs and convert to a[] for the 2 * * subframes (both quantized and unquantized) * *------------------------------------------------------------------------*/ /* ------------------- */ /* LP Forward analysis */ /* ------------------- */ Autocorr(p_window, M, r_h_fwd, r_l_fwd); /* Autocorrelations */ Lag_window(M, r_h_fwd, r_l_fwd); /* Lag windowing */ Levinsone(M, r_h_fwd, r_l_fwd, &A_t_fwd[MP1], rc_fwd, old_A_fwd, old_rc_fwd); /* Levinson Durbin */ Az_lsp(&A_t_fwd[MP1], lsp_new, lsp_old); /* From A(z) to lsp */ /* -------------------- */ /* LP Backward analysis */ /* -------------------- */ /* -------------------- */ /* LP Backward analysis */ /* -------------------- */ if ( rate== G729E) { /* LPC recursive Window as in G728 */ autocorr_hyb_window(synth, r_bwd, rexp); /* Autocorrelations */ Lag_window_bwd(r_bwd, r_h_bwd, r_l_bwd); /* Lag windowing */ /* Fixed Point Levinson (as in G729) */ Levinsone(M_BWD, r_h_bwd, r_l_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] >= 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[L_FRAME], &synth[0], MEM_SYN_BWD); /*--------------------------------------------------------------------* * Find interpolated LPC parameters in all subframes (unquantized). * * The interpolated parameters are in array A_t[] of size (M+1)*4 * *--------------------------------------------------------------------*/ if( prev_lp_mode == 0) { Int_lpc(lsp_old, lsp_new, lsf_int, lsf_new, A_t_fwd); } else { /* no interpolation */ /* unquantized */ Lsp_Az(lsp_new, A_t_fwd); /* Subframe 1 */ Lsp_lsf(lsp_new, lsf_new, M); /* transformation from LSP to LSF (freq.domain) */ Copy(lsf_new, lsf_int, M); /* Subframe 1 */ } /* ---------------- */ /* LSP quantization */ /* ---------------- */ Qua_lspe(lsp_new, lsp_new_q, code_lsp, freq_prev, freq_cur); /*--------------------------------------------------------------------* * Find interpolated LPC parameters in all subframes (quantized) * * the quantized interpolated parameters are in array Aq_t[] * *--------------------------------------------------------------------*/ if( prev_lp_mode == 0) { Int_qlpc(lsp_old_q, lsp_new_q, A_t_fwd_q); } else { /* no interpolation */ Lsp_Az(lsp_new_q, &A_t_fwd_q[MP1]); /* Subframe 2 */ Copy(&A_t_fwd_q[MP1], A_t_fwd_q, MP1); /* Subframe 1 */ } /*---------------------------------------------------------------------* * - Decision for the switch Forward / Backward * *---------------------------------------------------------------------*/ if(rate == G729E) { set_lpc_modeg(speech, A_t_fwd_q, A_t_bwd, &lp_mode, lsp_new, lsp_old, &bwd_dominant, prev_lp_mode, prev_filter, &C_int, &glob_stat, &stat_bwd, &val_stat_bwd); } else { update_bwd( &lp_mode, &bwd_dominant, &C_int, &glob_stat); } /* ---------------------------------- */ /* update the LSPs for the next frame */ /* ---------------------------------- */ Copy(lsp_new, lsp_old, M); /*----------------------------------------------------------------------* * - Find the weighted input speech w_sp[] for the whole speech frame * *----------------------------------------------------------------------*/ if(lp_mode == 0) { m_ap = M; if (bwd_dominant == 0) Ap = A_t_fwd; else Ap = A_t_fwd_q; perc_var(gamma1, gamma2, lsf_int, lsf_new, rc_fwd); } else { if (bwd_dominant == 0) { m_ap = M; Ap = A_t_fwd; } else { m_ap = M_BWD; Ap = A_t_bwd; } perc_vare(gamma1, gamma2, bwd_dominant); } pAp = Ap; for (i=0; i<2; i++) { Weight_Az(pAp, gamma1[i], m_ap, Ap1); Weight_Az(pAp, gamma2[i], m_ap, Ap2); Residue(m_ap, Ap1, &speech[i*L_SUBFR], &wsp[i*L_SUBFR], L_SUBFR); Syn_filte(m_ap, Ap2, &wsp[i*L_SUBFR], &wsp[i*L_SUBFR], L_SUBFR, &mem_w[M_BWD-m_ap], 0); for(j=0; j<M_BWD; j++) mem_w[j] = wsp[i*L_SUBFR+L_SUBFR-M_BWD+j]; pAp += m_ap+1; } *ana++ = rate+ (Word16)2; /* bit rate mode */ if(lp_mode == 0) { m_aq = M; Aq = A_t_fwd_q; /* update previous filter for next frame */ Copy(&Aq[MP1], prev_filter, MP1); for(i=MP1; i <M_BWDP1; i++) prev_filter[i] = 0; for(j=MP1; j<M_BWDP1; j++) ai_zero[j] = 0; } else { m_aq = M_BWD; Aq = A_t_bwd; if (bwd_dominant == 0) { for(j=MP1; j<M_BWDP1; j++) ai_zero[j] = 0; } /* update previous filter for next frame */ Copy(&Aq[M_BWDP1], prev_filter, M_BWDP1); } if (rate == G729E) *ana++ = lp_mode; /*----------------------------------------------------------------------* * - Find the weighted input speech w_sp[] for the whole speech frame * * - Find the open-loop pitch delay * *----------------------------------------------------------------------*/ if( lp_mode == 0) { Copy(lsp_new_q, lsp_old_q, M); Lsp_prev_update(freq_cur, freq_prev); *ana++ = code_lsp[0]; *ana++ = code_lsp[1]; } /* Find open loop pitch lag */ T_op = Pitch_ol(wsp, PIT_MIN, PIT_MAX, L_FRAME); /* Range for closed loop pitch search in 1st subframe */ T0_min = sub(T_op, 3); if (sub(T0_min,PIT_MIN)<0) { T0_min = PIT_MIN; } T0_max = add(T0_min, 6); if (sub(T0_max ,PIT_MAX)>0) { T0_max = PIT_MAX; T0_min = sub(T0_max, 6); } /*------------------------------------------------------------------------* * 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 2 times. * * - find the weighted LPC coefficients * * - find the LPC residual signal res[] * * - compute the target signal for pitch search * * - compute impulse response of weighted synthesis filter (h1[]) * * - find the closed-loop pitch parameters * * - encode the pitch delay * * - update the impulse response h1[] by including fixed-gain pitch * * - find target vector for codebook search * * - codebook search * * - encode codebook address * * - VQ of pitch and codebook gains * * - find synthesis speech * * - update states of weighting filter * *------------------------------------------------------------------------*/ pAp = Ap; /* pointer to interpolated "unquantized"LPC parameters */ pAq = Aq; /* pointer to interpolated "quantized" LPC parameters */ i_gamma = 0; for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { /*---------------------------------------------------------------* * Find the weighted LPC coefficients for the weighting filter. * *---------------------------------------------------------------*/ Weight_Az(pAp, gamma1[i_gamma], m_ap, Ap1); Weight_Az(pAp, gamma2[i_gamma], m_ap, Ap2); /*---------------------------------------------------------------* * Compute impulse response, h1[], of weighted synthesis filter * *---------------------------------------------------------------*/ for (i = 0; i <=m_ap; i++) ai_zero[i] = Ap1[i]; Syn_filte(m_aq, pAq, ai_zero, h1, L_SUBFR, zero, 0); Syn_filte(m_ap, Ap2, h1, h1, L_SUBFR, zero, 0); /*------------------------------------------------------------------------* * * * Find the target vector for pitch search: * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * * * |------| res[n] * * speech[n]---| A(z) |-------- * * |------| | |--------| error[n] |------| * * zero -- (-)--| 1/A(z) |-----------| W(z) |-- target * * exc |--------| |------| * * * * Instead of subtracting the zero-input response of filters from * * the weighted input speech, the above configuration is used to * * compute the target vector. This configuration gives better performance * * with fixed-point implementation. The memory of 1/A(z) is updated by * * filtering (res[n]-exc[n]) through 1/A(z), or simply by subtracting * * the synthesis speech from the input speech: * * error[n] = speech[n] - syn[n]. * * The memory of W(z) is updated by filtering error[n] through W(z), * * or more simply by subtracting the filtered adaptive and fixed * * codebook excitations from the target: * * target[n] - gain_pit*y1[n] - gain_code*y2[n] * * as these signals are already available. * * * *------------------------------------------------------------------------*/ Residue(m_aq, pAq, &speech[i_subfr], &exc[i_subfr], L_SUBFR); /* LPC residual */ for (i=0; i<L_SUBFR; i++) res2[i] = exc[i_subfr+i]; Syn_filte(m_aq, pAq, &exc[i_subfr], error, L_SUBFR, &mem_err[M_BWD-m_aq], 0); Residue(m_ap, Ap1, error, xn, L_SUBFR); Syn_filte(m_ap, Ap2, xn, xn, L_SUBFR, &mem_w0[M_BWD-m_ap], 0); /* target signal xn[]*/ /*----------------------------------------------------------------------* * Closed-loop fractional pitch search * *----------------------------------------------------------------------*/ T0 = Pitch_fr3cp(&exc[i_subfr], xn, h1, L_SUBFR, T0_min, T0_max, i_subfr, &T0_frac, rate); index = Enc_lag3cp(T0, T0_frac, &T0_min, &T0_max,PIT_MIN,PIT_MAX, i_subfr, rate); *ana++ = index; if ( (i_subfr == 0) && (rate != G729D) ) { *ana = Parity_Pitch(index); if( rate == G729E) { *ana ^= (shr(index, 1) & 0x0001); } ana++; } /*-----------------------------------------------------------------* * - find unity gain pitch excitation (adaptive codebook entry) * * with fractional interpolation. * * - find filtered pitch exc. y1[]=exc[] convolve with h1[]) * * - compute pitch gain and limit between 0 and 1.2 * * - update target vector for codebook search * * - find LTP residual. * *-----------------------------------------------------------------*/ Pred_lt_3(&exc[i_subfr], T0, T0_frac, L_SUBFR); Convolve(&exc[i_subfr], h1, y1, L_SUBFR); gain_pit = G_pitch(xn, y1, g_coeff, L_SUBFR); /* clip pitch gain if taming is necessary */ taming = test_err(T0, T0_frac); if( taming == 1){ if (sub(gain_pit, GPCLIP) > 0) { gain_pit = GPCLIP; } } /* xn2[i] = xn[i] - y1[i] * gain_pit */ for (i = 0; i < L_SUBFR; i++) { L_temp = L_mult(y1[i], gain_pit); L_temp = L_shl(L_temp, 1); /* gain_pit in Q14 */ xn2[i] = sub(xn[i], extract_h(L_temp)); } /*-----------------------------------------------------* * - Innovative codebook search. * *-----------------------------------------------------*/ switch (rate) { case G729: /* 8 kbit/s */ { /* case 8 kbit/s */ index = ACELP_Codebook(xn2, h1, T0, sharp, i_subfr, code, y2, &i); *ana++ = index; /* Positions index */ *ana++ = i; /* Signs index */ break; } case G729D: /* 6.4 kbit/s */ { index = ACELP_CodebookD(xn2, h1, T0, sharp, code, y2, &i); *ana++ = index; /* Positions index */ *ana++ = i; /* Signs index */ break; } case G729E: /* 11.8 kbit/s */ { /*-----------------------------------------------------------------* * Include fixed-gain pitch contribution into impulse resp. h[] * *-----------------------------------------------------------------*/ pit_sharp = shl(sharp, 1); /* From Q14 to Q15 */ if(T0 < L_SUBFR) { for (i = T0; i < L_SUBFR; i++){ /* h[i] += pitch_sharp*h[i-T0] */ h1[i] = add(h1[i], mult(h1[i-T0], pit_sharp)); } } /* calculate residual after long term prediction */ /* res2[i] -= exc[i+i_subfr] * gain_pit */ for (i = 0; i < L_SUBFR; i++) { L_temp = L_mult(exc[i+i_subfr], gain_pit); L_temp = L_shl(L_temp, 1); /* gain_pit in Q14 */ res2[i] = sub(res2[i], extract_h(L_temp)); } if (lp_mode == 0) ACELP_10i40_35bits(xn2, res2, h1, code, y2, ana); /* Forward */ else ACELP_12i40_44bits(xn2, res2, h1, code, y2, ana); /* Backward */ ana += 5; /*-----------------------------------------------------------------* * Include fixed-gain pitch contribution into code[]. * *-----------------------------------------------------------------*/ if(T0 < L_SUBFR) { for (i = T0; i < L_SUBFR; i++) { /* code[i] += pitch_sharp*code[i-T0] */ code[i] = add(code[i], mult(code[i-T0], pit_sharp)); } } break; } default : { printf("Unrecognized bit rate\n"); exit(-1); } } /* end of switch */ /*-----------------------------------------------------* * - Quantization of gains. * *-----------------------------------------------------*/ g_coeff_cs[0] = g_coeff[0]; /* <y1,y1> */ exp_g_coeff_cs[0] = negate(g_coeff[1]); /* Q-Format:XXX -> JPN */ g_coeff_cs[1] = negate(g_coeff[2]); /* (xn,y1) -> -2<xn,y1> */ exp_g_coeff_cs[1] = negate(add(g_coeff[3], 1)); /* Q-Format:XXX -> JPN */ Corr_xy2( xn, y1, y2, g_coeff_cs, exp_g_coeff_cs ); /* Q0 Q0 Q12 ^Qx ^Q0 */ /* g_coeff_cs[3]:exp_g_coeff_cs[3] = <y2,y2> */ /* g_coeff_cs[4]:exp_g_coeff_cs[4] = -2<xn,y2> */ /* g_coeff_cs[5]:exp_g_coeff_cs[5] = 2<y1,y2> */ if (rate == G729D) index = Qua_gain_6k(code, g_coeff_cs, exp_g_coeff_cs, L_SUBFR, &gain_pit, &gain_code, taming, past_qua_en); else index = Qua_gain_8k(code, g_coeff_cs, exp_g_coeff_cs, L_SUBFR, &gain_pit, &gain_code, taming, past_qua_en); *ana++ = index; /*------------------------------------------------------------* * - Update pitch sharpening "sharp" with quantized gain_pit * *------------------------------------------------------------*/ sharp = gain_pit; if (sub(sharp, SHARPMAX) > 0) sharp = SHARPMAX; else { if (sub(sharp, SHARPMIN) < 0) sharp = SHARPMIN; } /*------------------------------------------------------* * - Find the total excitation * * - find synthesis speech corresponding to exc[] * * - update filters memories for finding the target * * vector in the next subframe * * (update error[-m..-1] and mem_w_err[]) * * update error function for taming process * *------------------------------------------------------*/ for (i = 0; i < L_SUBFR; i++) { /* exc[i] = gain_pit*exc[i] + gain_code*code[i]; */ /* exc[i] in Q0 gain_pit in Q14 */ /* code[i] in Q13 gain_cod in Q1 */ L_temp = L_mult(exc[i+i_subfr], gain_pit); L_temp = L_mac(L_temp, code[i], gain_code); L_temp = L_shl(L_temp, 1); exc[i+i_subfr] = round(L_temp); } update_exc_err(gain_pit, T0); Syn_filte(m_aq, pAq, &exc[i_subfr], &synth_ptr[i_subfr], L_SUBFR, &mem_syn[M_BWD-m_aq], 0); for(j=0; j<M_BWD; j++) mem_syn[j] = synth_ptr[i_subfr+L_SUBFR-M_BWD+j]; for (i = L_SUBFR-M_BWD, j = 0; i < L_SUBFR; i++, j++) { mem_err[j] = sub(speech[i_subfr+i], synth_ptr[i_subfr+i]); temp = extract_h(L_shl( L_mult(y1[i], gain_pit), 1) ); k = extract_h(L_shl( L_mult(y2[i], gain_code), 2) ); mem_w0[j] = sub(xn[i], add(temp, k)); } pAp += m_ap+1; pAq += m_aq+1; i_gamma = add(i_gamma,1); } /*--------------------------------------------------* * Update signal for next frame. * * -> shift to the left by L_FRAME: * * speech[], wsp[] and exc[] * *--------------------------------------------------*/ Copy(&old_speech[L_FRAME], &old_speech[0], L_TOTAL-L_FRAME); Copy(&old_wsp[L_FRAME], &old_wsp[0], PIT_MAX); Copy(&old_exc[L_FRAME], &old_exc[0], PIT_MAX+L_INTERPOL); prev_lp_mode = lp_mode; 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; }
void Coder_ld8a( g729a_encoder_state *state, Word16 ana[] /* output : Analysis parameters */ ) { /* LPC analysis */ Word16 Aq_t[(MP1)*2]; /* A(z) quantized for the 2 subframes */ Word16 Ap_t[(MP1)*2]; /* A(z/gamma) for the 2 subframes */ Word16 *Aq, *Ap; /* Pointer on Aq_t and Ap_t */ /* Other vectors */ Word16 h1[L_SUBFR]; /* Impulse response h1[] */ Word16 xn[L_SUBFR]; /* Target vector for pitch search */ Word16 xn2[L_SUBFR]; /* Target vector for codebook search */ Word16 code[L_SUBFR]; /* Fixed codebook excitation */ Word16 y1[L_SUBFR]; /* Filtered adaptive excitation */ Word16 y2[L_SUBFR]; /* Filtered fixed codebook excitation */ Word16 g_coeff[4]; /* Correlations between xn & y1 */ Word16 g_coeff_cs[5]; Word16 exp_g_coeff_cs[5]; /* Correlations between xn, y1, & y2 <y1,y1>, -2<xn,y1>, <y2,y2>, -2<xn,y2>, 2<y1,y2> */ /* Scalars */ Word16 i, j, k, i_subfr; Word16 T_op, T0, T0_min, T0_max, T0_frac; Word16 gain_pit, gain_code, index; Word16 temp, taming; Word32 L_temp; /*------------------------------------------------------------------------* * - Perform LPC analysis: * * * autocorrelation + lag windowing * * * Levinson-durbin algorithm to find a[] * * * convert a[] to lsp[] * * * quantize and code the LSPs * * * find the interpolated LSPs and convert to a[] for the 2 * * subframes (both quantized and unquantized) * *------------------------------------------------------------------------*/ { /* Temporary vectors */ Word16 r_l[MP1], r_h[MP1]; /* Autocorrelations low and hi */ Word16 rc[M]; /* Reflection coefficients. */ Word16 lsp_new[M], lsp_new_q[M]; /* LSPs at 2th subframe */ /* LP analysis */ Autocorr(state->p_window, M, r_h, r_l); /* Autocorrelations */ Lag_window(M, r_h, r_l); /* Lag windowing */ Levinson(r_h, r_l, Ap_t, rc); /* Levinson Durbin */ Az_lsp(Ap_t, lsp_new, state->lsp_old); /* From A(z) to lsp */ /* LSP quantization */ Qua_lsp(state, lsp_new, lsp_new_q, ana); ana += 2; /* Advance analysis parameters pointer */ /*--------------------------------------------------------------------* * Find interpolated LPC parameters in all subframes * * The interpolated parameters are in array Aq_t[]. * *--------------------------------------------------------------------*/ Int_qlpc(state->lsp_old_q, lsp_new_q, Aq_t); /* Compute A(z/gamma) */ Weight_Az(&Aq_t[0], GAMMA1, M, &Ap_t[0]); Weight_Az(&Aq_t[MP1], GAMMA1, M, &Ap_t[MP1]); /* update the LSPs for the next frame */ Copy(lsp_new, state->lsp_old, M); Copy(lsp_new_q, state->lsp_old_q, M); } /*----------------------------------------------------------------------* * - Find the weighted input speech w_sp[] for the whole speech frame * * - Find the open-loop pitch delay * *----------------------------------------------------------------------*/ Residu(&Aq_t[0], &(state->speech[0]), &(state->exc[0]), L_SUBFR); Residu(&Aq_t[MP1], &(state->speech[L_SUBFR]), &(state->exc[L_SUBFR]), L_SUBFR); { Word16 Ap1[MP1]; Ap = Ap_t; Ap1[0] = 4096; for(i=1; i<=M; i++) /* Ap1[i] = Ap[i] - 0.7 * Ap[i-1]; */ Ap1[i] = sub(Ap[i], mult(Ap[i-1], 22938)); Syn_filt(Ap1, &(state->exc[0]), &(state->wsp[0]), L_SUBFR, state->mem_w, 1); Ap += MP1; for(i=1; i<=M; i++) /* Ap1[i] = Ap[i] - 0.7 * Ap[i-1]; */ Ap1[i] = sub(Ap[i], mult(Ap[i-1], 22938)); Syn_filt(Ap1, &(state->exc[L_SUBFR]), &(state->wsp[L_SUBFR]), L_SUBFR, state->mem_w, 1); } /* Find open loop pitch lag */ T_op = Pitch_ol_fast(state->wsp, PIT_MAX, L_FRAME); /* Range for closed loop pitch search in 1st subframe */ T0_min = T_op - 3; T0_max = T0_min + 6; if (T0_min < PIT_MIN) { T0_min = PIT_MIN; T0_max = PIT_MIN + 6; } else if (T0_max > PIT_MAX) { T0_max = PIT_MAX; T0_min = PIT_MAX - 6; } /*------------------------------------------------------------------------* * 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 2 times. * * - find the weighted LPC coefficients * * - find the LPC residual signal res[] * * - compute the target signal for pitch search * * - compute impulse response of weighted synthesis filter (h1[]) * * - find the closed-loop pitch parameters * * - encode the pitch delay * * - find target vector for codebook search * * - codebook search * * - VQ of pitch and codebook gains * * - update states of weighting filter * *------------------------------------------------------------------------*/ Aq = Aq_t; /* pointer to interpolated quantized LPC parameters */ Ap = Ap_t; /* pointer to weighted LPC coefficients */ for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { /*---------------------------------------------------------------* * Compute impulse response, h1[], of weighted synthesis filter * *---------------------------------------------------------------*/ h1[0] = 4096; Set_zero(&h1[1], L_SUBFR-1); Syn_filt(Ap, h1, h1, L_SUBFR, &h1[1], 0); /*----------------------------------------------------------------------* * Find the target vector for pitch search: * *----------------------------------------------------------------------*/ Syn_filt(Ap, &(state->exc[i_subfr]), xn, L_SUBFR, state->mem_w0, 0); /*---------------------------------------------------------------------* * Closed-loop fractional pitch search * *---------------------------------------------------------------------*/ T0 = Pitch_fr3_fast(&(state->exc[i_subfr]), xn, h1, L_SUBFR, T0_min, T0_max, i_subfr, &T0_frac); index = Enc_lag3(T0, T0_frac, &T0_min, &T0_max,PIT_MIN,PIT_MAX,i_subfr); *ana++ = index; if (i_subfr == 0) { *ana++ = Parity_Pitch(index); } /*-----------------------------------------------------------------* * - find filtered pitch exc * * - compute pitch gain and limit between 0 and 1.2 * * - update target vector for codebook search * *-----------------------------------------------------------------*/ Syn_filt(Ap, &(state->exc[i_subfr]), y1, L_SUBFR, state->mem_zero, 0); gain_pit = G_pitch(xn, y1, g_coeff, L_SUBFR); /* clip pitch gain if taming is necessary */ taming = test_err(state, T0, T0_frac); if( taming == 1){ if (gain_pit > GPCLIP) { gain_pit = GPCLIP; } } /* xn2[i] = xn[i] - y1[i] * gain_pit */ for (i = 0; i < L_SUBFR; i++) { //L_temp = L_mult(y1[i], gain_pit); //L_temp = L_shl(L_temp, 1); /* gain_pit in Q14 */ L_temp = ((Word32)y1[i] * gain_pit) << 2; xn2[i] = sub(xn[i], extract_h(L_temp)); } /*-----------------------------------------------------* * - Innovative codebook search. * *-----------------------------------------------------*/ index = ACELP_Code_A(xn2, h1, T0, state->sharp, code, y2, &i); *ana++ = index; /* Positions index */ *ana++ = i; /* Signs index */ /*-----------------------------------------------------* * - Quantization of gains. * *-----------------------------------------------------*/ g_coeff_cs[0] = g_coeff[0]; /* <y1,y1> */ exp_g_coeff_cs[0] = negate(g_coeff[1]); /* Q-Format:XXX -> JPN */ g_coeff_cs[1] = negate(g_coeff[2]); /* (xn,y1) -> -2<xn,y1> */ exp_g_coeff_cs[1] = negate(add(g_coeff[3], 1)); /* Q-Format:XXX -> JPN */ Corr_xy2( xn, y1, y2, g_coeff_cs, exp_g_coeff_cs ); /* Q0 Q0 Q12 ^Qx ^Q0 */ /* g_coeff_cs[3]:exp_g_coeff_cs[3] = <y2,y2> */ /* g_coeff_cs[4]:exp_g_coeff_cs[4] = -2<xn,y2> */ /* g_coeff_cs[5]:exp_g_coeff_cs[5] = 2<y1,y2> */ *ana++ = Qua_gain(code, g_coeff_cs, exp_g_coeff_cs, L_SUBFR, &gain_pit, &gain_code, taming); /*------------------------------------------------------------* * - Update pitch sharpening "sharp" with quantized gain_pit * *------------------------------------------------------------*/ state->sharp = gain_pit; if (state->sharp > SHARPMAX) { state->sharp = SHARPMAX; } else if (state->sharp < SHARPMIN) { state->sharp = SHARPMIN; } /*------------------------------------------------------* * - Find the total excitation * * - update filters memories for finding the target * * vector in the next subframe * *------------------------------------------------------*/ for (i = 0; i < L_SUBFR; i++) { /* exc[i] = gain_pit*exc[i] + gain_code*code[i]; */ /* exc[i] in Q0 gain_pit in Q14 */ /* code[i] in Q13 gain_cod in Q1 */ //L_temp = L_mult(exc[i+i_subfr], gain_pit); //L_temp = L_mac(L_temp, code[i], gain_code); //L_temp = L_shl(L_temp, 1); L_temp = (Word32)(state->exc[i+i_subfr]) * (Word32)gain_pit + (Word32)code[i] * (Word32)gain_code; L_temp <<= 2; state->exc[i+i_subfr] = g_round(L_temp); } update_exc_err(state, gain_pit, T0); for (i = L_SUBFR-M, j = 0; i < L_SUBFR; i++, j++) { temp = ((Word32)y1[i] * (Word32)gain_pit) >> 14; k = ((Word32)y2[i] * (Word32)gain_code) >> 13; state->mem_w0[j] = sub(xn[i], add(temp, k)); } Aq += MP1; /* interpolated LPC parameters for next subframe */ Ap += MP1; } /*--------------------------------------------------* * Update signal for next frame. * * -> shift to the left by L_FRAME: * * speech[], wsp[] and exc[] * *--------------------------------------------------*/ Copy(&(state->old_speech[L_FRAME]), &(state->old_speech[0]), L_TOTAL-L_FRAME); Copy(&(state->old_wsp[L_FRAME]), &(state->old_wsp[0]), PIT_MAX); Copy(&(state->old_exc[L_FRAME]), &(state->old_exc[0]), PIT_MAX+L_INTERPOL); }
/*---------------------------------------------------------------------------- * Post - adaptive postfilter main function *---------------------------------------------------------------------------- */ void Poste( Word16 t0, /* input : pitch delay given by coder */ Word16 *signal_ptr, /* input : input signal (pointer to current subframe */ Word16 *coeff, /* input : LPC coefficients for current subframe */ Word16 *sig_out, /* output: postfiltered output */ Word16 *vo, /* output: voicing decision 0 = uv, > 0 delay */ Word16 gamma1, /* input: short term postfilt. den. weighting factor*/ Word16 gamma2, /* input: short term postfilt. num. weighting factor*/ Word16 gamma_harm, /* input: long term postfilter weighting factor*/ Word16 long_h_st, /* input: impulse response length*/ Word16 m_pst, /* input: LPC order */ Word16 Vad ) { /* Local variables and arrays */ Word16 apond1[M_BWDP1]; /* s.t. denominator coeff. */ Word16 sig_ltp[L_SUBFRP1]; /* H0 output signal */ Word16 *sig_ltp_ptr; Word16 parcor0; /* Compute weighted LPC coefficients */ Weight_Az(coeff, gamma1, m_pst, apond1); Weight_Az(coeff, gamma2, m_pst, apond2); Set_zero(&apond2[m_pst+1], (Word16)(M_BWD-m_pst)); /* Compute A(gamma2) residual */ Residue(m_pst, apond2, signal_ptr, res2_ptr, L_SUBFR); /* Harmonic filtering */ sig_ltp_ptr = sig_ltp + 1; if (sub(Vad,1) > 0) pst_ltpe(t0, res2_ptr, sig_ltp_ptr, vo, gamma_harm); else { *vo = 0; Copy(res2_ptr, sig_ltp_ptr, L_SUBFR); } /* Save last output of 1/A(gamma1) */ /* (from preceding subframe) */ sig_ltp[0] = *ptr_mem_stp; /* Controls short term pst filter gain and compute parcor0 */ calc_st_filte(apond2, apond1, &parcor0, sig_ltp_ptr, long_h_st, m_pst); /* 1/A(gamma1) filtering, mem_stp is updated */ Syn_filte(m_pst, apond1, sig_ltp_ptr, sig_ltp_ptr, L_SUBFR, &mem_stp[M_BWD-m_pst], 0); Copy(&sig_ltp_ptr[L_SUBFR-M_BWD], mem_stp, M_BWD); /* Tilt filtering */ filt_mu(sig_ltp, sig_out, parcor0); /* Gain control */ scale_st(signal_ptr, sig_out, &gain_prec); /**** Update for next subframe */ Copy(&res2[L_SUBFR], &res2[0], MEM_RES2); return; }