CComplexVector CChannelEstimation::FreqOptimalFilter(int iFreqInt, int iDiff, CReal rSNR, CReal rRatPDSLen, CReal rRatPDSOffs, int iLength) { int i; int iCurPos; CComplexVector veccReturn(iLength); CComplexVector veccRpp(iLength); CComplexVector veccRhp(iLength); /* Calculation of R_hp, this is the SHIFTED correlation function */ for (i = 0; i < iLength; i++) { iCurPos = i * iFreqInt - iDiff; veccRhp[i] = FreqCorrFct(iCurPos, rRatPDSLen, rRatPDSOffs); } /* Calculation of R_pp */ for (i = 0; i < iLength; i++) { iCurPos = i * iFreqInt; veccRpp[i] = FreqCorrFct(iCurPos, rRatPDSLen, rRatPDSOffs); } /* Add SNR at first tap */ veccRpp[0] += (CReal) 1.0 / rSNR; /* Call levinson algorithm to solve matrix system for optimal solution */ veccReturn = Levinson(veccRpp, veccRhp); return veccReturn; }
/*-----------------------------------------------------------* * procedure Cod_cng: * * ~~~~~~~~ * * computes DTX decision * * encodes SID frames * * computes CNG excitation for encoder update * *-----------------------------------------------------------*/ void Cod_cng( DtxStatus *handle, Word16 *exc, /* (i/o) : excitation array */ Word16 pastVad, /* (i) : previous VAD decision */ Word16 *lsp_old_q, /* (i/o) : previous quantized lsp */ Word16 *Aq, /* (o) : set of interpolated LPC coefficients */ Word16 *ana, /* (o) : coded SID parameters */ Word16 freq_prev[MA_NP][M], /* (i/o) : previous LPS for quantization */ Word16 *seed /* (i/o) : random generator seed */ ) { Word16 i; Word16 curAcf[MP1]; Word16 bid[M], zero[MP1]; Word16 curCoeff[MP1]; Word16 lsp_new[M]; Word16 *lpcCoeff; Word16 cur_igain; Word16 energyq, temp; /* Update Ener and sh_ener */ for(i = NB_GAIN-1; i>=1; i--) { handle->ener[i] = handle->ener[i-1]; handle->sh_ener[i] = handle->sh_ener[i-1]; } /* Compute current Acfs */ Calc_sum_acf(handle->Acf, handle->sh_Acf, curAcf, &(handle->sh_ener[0]), NB_CURACF); /* Compute LPC coefficients and residual energy */ if(curAcf[0] == 0) { handle->ener[0] = 0; /* should not happen */ } else { Set_zero(zero, MP1); Levinson(handle, curAcf, zero, curCoeff, bid, &(handle->ener[0])); } /* if first frame of silence => SID frame */ if(pastVad != 0) { ana[0] = 2; handle->count_fr0 = 0; handle->nb_ener = 1; Qua_Sidgain(handle->ener, handle->sh_ener, handle->nb_ener, &energyq, &cur_igain); } else { handle->nb_ener = add(handle->nb_ener, 1); if(sub(handle->nb_ener, NB_GAIN) > 0) handle->nb_ener = NB_GAIN; Qua_Sidgain(handle->ener, handle->sh_ener, handle->nb_ener, &energyq, &cur_igain); /* Compute stationarity of current filter */ /* versus reference filter */ if(Cmp_filt(handle->RCoeff, handle->sh_RCoeff, curAcf, handle->ener[0], FRAC_THRESH1) != 0) { handle->flag_chang = 1; } /* compare energy difference between current frame and last frame */ temp = abs_s(sub(handle->prev_energy, energyq)); temp = sub(temp, 2); if (temp > 0) handle->flag_chang = 1; handle->count_fr0 = add(handle->count_fr0, 1); if(sub(handle->count_fr0, FR_SID_MIN) < 0) { ana[0] = 0; /* no transmission */ } else { if(handle->flag_chang != 0) { ana[0] = 2; /* transmit SID frame */ } else{ ana[0] = 0; } handle->count_fr0 = FR_SID_MIN; /* to avoid overflow */ } } if(sub(ana[0], 2) == 0) { /* Reset frame count and change flag */ handle->count_fr0 = 0; handle->flag_chang = 0; /* Compute past average filter */ Calc_pastfilt(handle, handle->pastCoeff); Calc_RCoeff(handle->pastCoeff, handle->RCoeff, &(handle->sh_RCoeff)); /* Compute stationarity of current filter */ /* versus past average filter */ /* if stationary */ /* transmit average filter => new ref. filter */ if(Cmp_filt(handle->RCoeff, handle->sh_RCoeff, curAcf, handle->ener[0], FRAC_THRESH2) == 0) { lpcCoeff = handle->pastCoeff; } /* else */ /* transmit current filter => new ref. filter */ else { lpcCoeff = curCoeff; Calc_RCoeff(curCoeff, handle->RCoeff, &(handle->sh_RCoeff)); } /* Compute SID frame codes */ Az_lsp(lpcCoeff, lsp_new, lsp_old_q); /* From A(z) to lsp */ /* LSP quantization */ lsfq_noise(lsp_new, handle->lspSid_q, freq_prev, &ana[1]); handle->prev_energy = energyq; ana[4] = cur_igain; handle->sid_gain = tab_Sidgain[cur_igain]; } /* end of SID frame case */ /* Compute new excitation */ if(pastVad != 0) { handle->cur_gain = handle->sid_gain; } else { handle->cur_gain = mult_r(handle->cur_gain, A_GAIN0); handle->cur_gain = add(handle->cur_gain, mult_r(handle->sid_gain, A_GAIN1)); } Calc_exc_rand(handle->L_exc_err, handle->cur_gain, exc, seed, FLAG_COD); Int_qlpc(lsp_old_q, handle->lspSid_q, Aq); for(i=0; i<M; i++) { lsp_old_q[i] = handle->lspSid_q[i]; } /* Update sumAcf if fr_cur = 0 */ if(handle->fr_cur == 0) { Update_sumAcf(handle); } 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_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); }