/* ******************************************************************************** * PUBLIC PROGRAM CODE ******************************************************************************** */ void ol_ltp( pitchOLWghtState *st, /* i/o : State struct */ vadState *vadSt, /* i/o : VAD state struct */ enum Mode mode, /* i : coder mode */ Word16 wsp[], /* i : signal used to compute the OL pitch, Q0 */ /* uses signal[-pit_max] to signal[-1] */ Word16 *T_op, /* o : open loop pitch lag, Q0 */ Word16 old_lags[], /* i : history with old stored Cl lags */ Word16 ol_gain_flg[], /* i : OL gain flag */ Word16 idx, /* i : index */ Flag dtx /* i : dtx flag; use dtx=1, do not use dtx=0 */ ) { if (mode != MR102) { ol_gain_flg[0] = 0; ol_gain_flg[1] = 0; } if (mode == MR475 || mode == MR515) { *T_op = Pitch_ol(vadSt, mode, wsp, PIT_MIN, PIT_MAX, L_FRAME, idx, dtx); } else { if ( mode <= MR795 ) { *T_op = Pitch_ol(vadSt, mode, wsp, PIT_MIN, PIT_MAX, L_FRAME_BY2, idx, dtx); } else if ( mode == MR102 ) { *T_op = Pitch_ol_wgh(st, vadSt, wsp, PIT_MIN, PIT_MAX, L_FRAME_BY2, old_lags, ol_gain_flg, idx, dtx); } else { *T_op = Pitch_ol(vadSt, mode, wsp, PIT_MIN_MR122, PIT_MAX, L_FRAME_BY2, idx, dtx); } } }
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; }