/************************************************************************* * FUNCTION: Q_plsf_5() * * PURPOSE: Quantization of 2 sets of LSF parameters using 1st order MA * prediction and split by 5 matrix quantization (split-MQ) * * DESCRIPTION: * * p[i] = pred_factor*past_rq[i]; i=0,...,m-1 * r1[i]= lsf1[i] - p[i]; i=0,...,m-1 * r2[i]= lsf2[i] - p[i]; i=0,...,m-1 * where: * lsf1[i] 1st mean-removed LSF vector. * lsf2[i] 2nd mean-removed LSF vector. * r1[i] 1st residual prediction vector. * r2[i] 2nd residual prediction vector. * past_r2q[i] Past quantized residual (2nd vector). * * The residual vectors r1[i] and r2[i] are jointly quantized using * split-MQ with 5 codebooks. Each 4th dimension submatrix contains 2 * elements from each residual vector. The 5 submatrices are as follows: * {r1[0], r1[1], r2[0], r2[1]}; {r1[2], r1[3], r2[2], r2[3]}; * {r1[4], r1[5], r2[4], r2[5]}; {r1[6], r1[7], r2[6], r2[7]}; * {r1[8], r1[9], r2[8], r2[9]}; * *************************************************************************/ void Q_plsf_5 ( Q_plsfState *st, Word16 *lsp1, /* i : 1st LSP vector, Q15 */ Word16 *lsp2, /* i : 2nd LSP vector, Q15 */ Word16 *lsp1_q, /* o : quantized 1st LSP vector, Q15 */ Word16 *lsp2_q, /* o : quantized 2nd LSP vector, Q15 */ Word16 *indice /* o : quantization indices of 5 matrices, Q0 */ ) { Word16 i; Word16 lsf1[M], lsf2[M], wf1[M], wf2[M], lsf_p[M], lsf_r1[M], lsf_r2[M]; Word16 lsf1_q[M], lsf2_q[M]; /* convert LSFs to normalize frequency domain 0..16384 */ Lsp_lsf (lsp1, lsf1, M); Lsp_lsf (lsp2, lsf2, M); /* Compute LSF weighting factors (Q13) */ Lsf_wt (lsf1, wf1); Lsf_wt (lsf2, wf2); /* Compute predicted LSF and prediction error */ for (i = 0; i < M; i++) { lsf_p[i] = add (mean_lsf[i], mult (st->past_rq[i], LSP_PRED_FAC_MR122)); move16 (); lsf_r1[i] = sub (lsf1[i], lsf_p[i]); move16 (); lsf_r2[i] = sub (lsf2[i], lsf_p[i]); move16 (); } /*---- Split-MQ of prediction error ----*/ indice[0] = Vq_subvec (&lsf_r1[0], &lsf_r2[0], dico1_lsf, &wf1[0], &wf2[0], DICO1_SIZE); move16 (); indice[1] = Vq_subvec (&lsf_r1[2], &lsf_r2[2], dico2_lsf, &wf1[2], &wf2[2], DICO2_SIZE); move16 (); indice[2] = Vq_subvec_s (&lsf_r1[4], &lsf_r2[4], dico3_lsf, &wf1[4], &wf2[4], DICO3_SIZE); move16 (); indice[3] = Vq_subvec (&lsf_r1[6], &lsf_r2[6], dico4_lsf, &wf1[6], &wf2[6], DICO4_SIZE); move16 (); indice[4] = Vq_subvec (&lsf_r1[8], &lsf_r2[8], dico5_lsf, &wf1[8], &wf2[8], DICO5_SIZE); move16 (); /* Compute quantized LSFs and update the past quantized residual */ for (i = 0; i < M; i++) { lsf1_q[i] = add (lsf_r1[i], lsf_p[i]); move16 (); lsf2_q[i] = add (lsf_r2[i], lsf_p[i]); move16 (); st->past_rq[i] = lsf_r2[i]; move16 (); } /* verification that LSFs has minimum distance of LSF_GAP */ Reorder_lsf (lsf1_q, LSF_GAP, M); Reorder_lsf (lsf2_q, LSF_GAP, M); /* convert LSFs to the cosine domain */ Lsf_lsp (lsf1_q, lsp1_q, M); Lsf_lsp (lsf2_q, lsp2_q, M); }
void D_plsf_5 ( INT16 *indice, /* input : quantization indices of 5 submatrices */ INT16 *lsp1_q, /* output: quantized 1st LSP vector */ INT16 *lsp2_q, /* output: quantized 2nd LSP vector */ INT16 bfi, /* input : bad frame indicator (set to 1 if a bad frame is received) */ INT16 rxdtx_ctrl, /* input : RX DTX control word */ INT16 rx_dtx_state /* input : state of the comfort noise insertion period */ ) { INT16 i; const INT16 *p_dico; INT16 temp, sign; INT16 lsf1_r[M], lsf2_r[M]; INT16 lsf1_q[M], lsf2_q[M]; VPP_EFR_PROFILE_FUNCTION_ENTER(D_plsf_5); /* Update comfort noise LSF quantizer memory */ if ((rxdtx_ctrl & RX_UPD_SID_QUANT_MEM) != 0) { update_lsf_p_CN (lsf_old_rx, lsf_p_CN); } /* Handle cases of comfort noise LSF decoding in which past valid SID frames are repeated */ if (((rxdtx_ctrl & RX_NO_TRANSMISSION) != 0) || ((rxdtx_ctrl & RX_INVALID_SID_FRAME) != 0) || ((rxdtx_ctrl & RX_LOST_SID_FRAME) != 0)) { if ((rxdtx_ctrl & RX_NO_TRANSMISSION) != 0) { /* DTX active: no transmission. Interpolate LSF values in memory */ interpolate_CN_lsf (lsf_old_CN, lsf_new_CN, lsf2_q, rx_dtx_state); } else { /* Invalid or lost SID frame: use LSFs from last good SID frame */ for (i = 0; i < M; i++) { lsf_old_CN[i] = lsf_new_CN[i]; lsf2_q[i] = lsf_new_CN[i]; past_r2_q[i] = 0; } } for (i = 0; i < M; i++) { past_lsf_q[i] = lsf2_q[i]; } /* convert LSFs to the cosine domain */ Lsf_lsp (lsf2_q, lsp2_q, M); VPP_EFR_PROFILE_FUNCTION_EXIT(D_plsf_5); return; } if (bfi != 0) /* if bad frame */ { /* use the past LSFs slightly shifted towards their mean */ for (i = 0; i < M; i++) { /* lsfi_q[i] = ALPHA*past_lsf_q[i] + ONE_ALPHA*mean_lsf[i]; */ /*lsf1_q[i] = add (mult (past_lsf_q[i], ALPHA), mult (mean_lsf[i], ONE_ALPHA));*/ lsf1_q[i] = ADD (MULT (past_lsf_q[i], ALPHA), MULT (mean_lsf[i], ONE_ALPHA)); lsf2_q[i] = lsf1_q[i]; } /* estimate past quantized residual to be used in next frame */ for (i = 0; i < M; i++) { /* temp = mean_lsf[i] + past_r2_q[i] * PRED_FAC; */ //temp = add (mean_lsf[i], mult (past_r2_q[i], PRED_FAC)); temp = ADD (mean_lsf[i], MULT (past_r2_q[i], PRED_FAC)); //past_r2_q[i] = sub (lsf2_q[i], temp); past_r2_q[i] = SUB (lsf2_q[i], temp); } } else /* if good LSFs received */ { /* decode prediction residuals from 5 received indices */ //p_dico = &dico1_lsf[shl (indice[0], 2)]; p_dico = &dico1_lsf[SHL(indice[0], 2)]; lsf1_r[0] = *p_dico++; lsf1_r[1] = *p_dico++; lsf2_r[0] = *p_dico++; lsf2_r[1] = *p_dico++; //p_dico = &dico2_lsf[shl (indice[1], 2)]; p_dico = &dico2_lsf[SHL(indice[1], 2)]; lsf1_r[2] = *p_dico++; lsf1_r[3] = *p_dico++; lsf2_r[2] = *p_dico++; lsf2_r[3] = *p_dico++; sign = indice[2] & 1; //i = shr (indice[2], 1); i = SHR_D(indice[2], 1); //p_dico = &dico3_lsf[shl (i, 2)]; p_dico = &dico3_lsf[SHL(i, 2)]; if (sign == 0) { lsf1_r[4] = *p_dico++; lsf1_r[5] = *p_dico++; lsf2_r[4] = *p_dico++; lsf2_r[5] = *p_dico++; } else { //lsf1_r[4] = negate(*p_dico++); lsf1_r[4] = NEGATE(*p_dico); *p_dico++; //lsf1_r[5] = negate(*p_dico++); lsf1_r[5] = NEGATE(*p_dico); *p_dico++; //lsf2_r[4] = negate(*p_dico++); lsf2_r[4] = NEGATE(*p_dico); *p_dico++; //lsf2_r[5] = negate(*p_dico++); lsf2_r[5] = NEGATE(*p_dico); *p_dico++; } //p_dico = &dico4_lsf[shl (indice[3], 2)]; p_dico = &dico4_lsf[SHL(indice[3], 2)]; lsf1_r[6] = *p_dico++; lsf1_r[7] = *p_dico++; lsf2_r[6] = *p_dico++; lsf2_r[7] = *p_dico++; //p_dico = &dico5_lsf[shl (indice[4], 2)]; p_dico = &dico5_lsf[SHL(indice[4], 2)]; lsf1_r[8] = *p_dico++; lsf1_r[9] = *p_dico++; lsf2_r[8] = *p_dico++; lsf2_r[9] = *p_dico++; /* Compute quantized LSFs and update the past quantized residual */ /* Use lsf_p_CN as predicted LSF vector in case of no speech activity */ if ((rxdtx_ctrl & RX_SP_FLAG) != 0) { for (i = 0; i < M; i++) { //temp = add (mean_lsf[i], mult (past_r2_q[i], PRED_FAC)); temp = ADD (mean_lsf[i], MULT (past_r2_q[i], PRED_FAC)); //lsf1_q[i] = add (lsf1_r[i], temp); lsf1_q[i] = ADD (lsf1_r[i], temp); //lsf2_q[i] = add (lsf2_r[i], temp); lsf2_q[i] = ADD (lsf2_r[i], temp); past_r2_q[i] = lsf2_r[i]; } } else { /* Valid SID frame */ for (i = 0; i < M; i++) { //lsf2_q[i] = add (lsf2_r[i], lsf_p_CN[i]); lsf2_q[i] = ADD (lsf2_r[i], lsf_p_CN[i]); /* Use the dequantized values of lsf2 also for lsf1 */ lsf1_q[i] = lsf2_q[i]; past_r2_q[i] = 0; } } } /* verification that LSFs have minimum distance of LSF_GAP Hz */ Reorder_lsf (lsf1_q, LSF_GAP, M); Reorder_lsf (lsf2_q, LSF_GAP, M); if ((rxdtx_ctrl & RX_FIRST_SID_UPDATE) != 0) { for (i = 0; i < M; i++) { lsf_new_CN[i] = lsf2_q[i]; } } if ((rxdtx_ctrl & RX_CONT_SID_UPDATE) != 0) { for (i = 0; i < M; i++) { lsf_old_CN[i] = lsf_new_CN[i]; lsf_new_CN[i] = lsf2_q[i]; } } if ((rxdtx_ctrl & RX_SP_FLAG) != 0) { /* Update lsf history with quantized LSFs when speech activity is present. If the current frame is a bad one, update with most recent good comfort noise LSFs */ if (bfi==0) { update_lsf_history (lsf1_q, lsf2_q, lsf_old_rx); } else { update_lsf_history (lsf_new_CN, lsf_new_CN, lsf_old_rx); } for (i = 0; i < M; i++) { lsf_old_CN[i] = lsf2_q[i]; } } else { interpolate_CN_lsf (lsf_old_CN, lsf_new_CN, lsf2_q, rx_dtx_state); } for (i = 0; i < M; i++) { past_lsf_q[i] = lsf2_q[i]; } /* convert LSFs to the cosine domain */ Lsf_lsp (lsf1_q, lsp1_q, M); Lsf_lsp (lsf2_q, lsp2_q, M); VPP_EFR_PROFILE_FUNCTION_EXIT(D_plsf_5); return; }
void D_plsf_3( D_plsfState *st, /* i/o: State struct */ enum Mode mode, /* i : coder mode */ Word16 bfi, /* i : bad frame indicator (set to 1 if a */ /* bad frame is received) */ Word16 * indice, /* i : quantization indices of 3 submatrices, Q0 */ Word16 * lsp1_q /* o : quantized 1st LSP vector, Q15 */ ) { Word16 i, index; Word16 *p_cb1, *p_cb2, *p_cb3, *p_dico, temp; Word16 lsf1_r[M]; Word16 lsf1_q[M]; if (bfi != 0) /* if bad frame */ { /* use the past LSFs slightly shifted towards their mean */ for (i = 0; i < M; i++) { /* lsfi_q[i] = ALPHA*past_lsf_q[i] + ONE_ALPHA*mean_lsf[i]; */ lsf1_q[i] = add(mult(st->past_lsf_q[i], ALPHA), mult(mean_lsf[i], ONE_ALPHA)); } /* estimate past quantized residual to be used in next frame */ if (mode != MRDTX) { for (i = 0; i < M; i++) { /* temp = mean_lsf[i] + past_r2_q[i] * PRED_FAC; */ temp = add(mean_lsf[i], mult(st->past_r_q[i], pred_fac[i])); st->past_r_q[i] = sub(lsf1_q[i], temp); } } else { for (i = 0; i < M; i++) { /* temp = mean_lsf[i] + past_r2_q[i]; */ temp = add(mean_lsf[i], st->past_r_q[i]); st->past_r_q[i] = sub(lsf1_q[i], temp); } } } else /* if good LSFs received */ { if (mode == MR475 || mode == MR515) { /* MR475, MR515 */ p_cb1 = dico1_lsf; p_cb2 = dico2_lsf; p_cb3 = mr515_3_lsf; } else if (mode == MR795) { /* MR795 */ p_cb1 = mr795_1_lsf; p_cb2 = dico2_lsf; p_cb3 = dico3_lsf; } else { /* MR59, MR67, MR74, MR102, MRDTX */ p_cb1 = dico1_lsf; p_cb2 = dico2_lsf; p_cb3 = dico3_lsf; } /* decode prediction residuals from 3 received indices */ index = *indice++; p_dico = &p_cb1[/*add(index, add(index, index))*/ 3 * index]; lsf1_r[0] = *p_dico++; lsf1_r[1] = *p_dico++; lsf1_r[2] = *p_dico++; index = *indice++; if (mode == MR475 || mode == MR515) { /* MR475, MR515 only using every second entry */ /*index = shl(index,1);*/ index <<= 1; } p_dico = &p_cb2[add(index, add(index, index))]; lsf1_r[3] = *p_dico++; lsf1_r[4] = *p_dico++; lsf1_r[5] = *p_dico++; index = *indice++; p_dico = &p_cb3[shl(index, 2)]; lsf1_r[6] = *p_dico++; lsf1_r[7] = *p_dico++; lsf1_r[8] = *p_dico++; lsf1_r[9] = *p_dico++; /* Compute quantized LSFs and update the past quantized residual */ if (mode != MRDTX) for (i = 0; i < M; i++) { temp = add(mean_lsf[i], mult(st->past_r_q[i], pred_fac[i])); lsf1_q[i] = add(lsf1_r[i], temp); st->past_r_q[i] = lsf1_r[i]; } else for (i = 0; i < M; i++) { temp = add(mean_lsf[i], st->past_r_q[i]); lsf1_q[i] = add(lsf1_r[i], temp); st->past_r_q[i] = lsf1_r[i]; } } /* verification that LSFs has minimum distance of LSF_GAP Hz */ Reorder_lsf(lsf1_q, LSF_GAP, M); Copy (lsf1_q, st->past_lsf_q, M); /* convert LSFs to the cosine domain */ Lsf_lsp(lsf1_q, lsp1_q, M); }
/* ************************************************************************** * * Function : dtx_dec * ************************************************************************** */ int dtx_dec( dtx_decState *st, /* i/o : State struct */ Word16 mem_syn[], /* i/o : AMR decoder state */ D_plsfState* lsfState, /* i/o : decoder lsf states */ gc_predState* predState, /* i/o : prediction states */ Cb_gain_averageState* averState, /* i/o : CB gain average states */ enum DTXStateType new_state, /* i : new DTX state */ enum Mode mode, /* i : AMR mode */ Word16 parm[], /* i : Vector of synthesis parameters */ Word16 synth[], /* o : synthesised speech */ Word16 A_t[] /* o : decoded LP filter in 4 subframes*/ ) { Word16 log_en_index; Word16 i, j; Word16 int_fac; Word32 L_log_en_int; Word16 lsp_int[M]; Word16 log_en_int_e; Word16 log_en_int_m; Word16 level; Word16 acoeff[M + 1]; Word16 refl[M]; Word16 pred_err; Word16 ex[L_SUBFR]; Word16 ma_pred_init; Word16 log_pg_e, log_pg_m; Word16 log_pg; Flag negative; Word16 lsf_mean; Word32 L_lsf_mean; Word16 lsf_variab_index; Word16 lsf_variab_factor; Word16 lsf_int[M]; Word16 lsf_int_variab[M]; Word16 lsp_int_variab[M]; Word16 acoeff_variab[M + 1]; Word16 lsf[M]; Word32 L_lsf[M]; Word16 ptr; Word16 tmp_int_length; /* This function is called if synthesis state is not SPEECH * the globally passed inputs to this function are * st->sid_frame * st->valid_data * st->dtxHangoverAdded * new_state (SPEECH, DTX, DTX_MUTE) */ test(); test(); if ((st->dtxHangoverAdded != 0) && (st->sid_frame != 0)) { /* sid_first after dtx hangover period */ /* or sid_upd after dtxhangover */ /* set log_en_adjust to correct value */ st->log_en_adjust = dtx_log_en_adjust[mode]; ptr = add(st->lsf_hist_ptr, M); move16(); test(); if (sub(ptr, 80) == 0) { ptr = 0; move16(); } Copy( &st->lsf_hist[st->lsf_hist_ptr],&st->lsf_hist[ptr],M); ptr = add(st->log_en_hist_ptr,1); move16(); test(); if (sub(ptr, DTX_HIST_SIZE) == 0) { ptr = 0; move16(); } move16(); st->log_en_hist[ptr] = st->log_en_hist[st->log_en_hist_ptr]; /* Q11 */ /* compute mean log energy and lsp * * from decoded signal (SID_FIRST) */ st->log_en = 0; move16(); for (i = 0; i < M; i++) { L_lsf[i] = 0; move16(); } /* average energy and lsp */ for (i = 0; i < DTX_HIST_SIZE; i++) { st->log_en = add(st->log_en, shr(st->log_en_hist[i],3)); for (j = 0; j < M; j++) { L_lsf[j] = L_add(L_lsf[j], L_deposit_l(st->lsf_hist[i * M + j])); } } for (j = 0; j < M; j++) { lsf[j] = extract_l(L_shr(L_lsf[j],3)); /* divide by 8 */ move16(); } Lsf_lsp(lsf, st->lsp, M); /* make log_en speech coder mode independent */ /* added again later before synthesis */ st->log_en = sub(st->log_en, st->log_en_adjust); /* compute lsf variability vector */ Copy(st->lsf_hist, st->lsf_hist_mean, 80); for (i = 0; i < M; i++) { L_lsf_mean = 0; move32(); /* compute mean lsf */ for (j = 0; j < 8; j++) { L_lsf_mean = L_add(L_lsf_mean, L_deposit_l(st->lsf_hist_mean[i+j*M])); } lsf_mean = extract_l(L_shr(L_lsf_mean, 3)); move16(); /* subtract mean and limit to within reasonable limits * * moreover the upper lsf's are attenuated */ for (j = 0; j < 8; j++) { /* subtract mean */ st->lsf_hist_mean[i+j*M] = sub(st->lsf_hist_mean[i+j*M], lsf_mean); /* attenuate deviation from mean, especially for upper lsf's */ st->lsf_hist_mean[i+j*M] = mult(st->lsf_hist_mean[i+j*M], lsf_hist_mean_scale[i]); /* limit the deviation */ test(); if (st->lsf_hist_mean[i+j*M] < 0) { negative = 1; move16(); } else { negative = 0; move16(); } st->lsf_hist_mean[i+j*M] = abs_s(st->lsf_hist_mean[i+j*M]); /* apply soft limit */ test(); if (sub(st->lsf_hist_mean[i+j*M], 655) > 0) { st->lsf_hist_mean[i+j*M] = add(655, shr(sub(st->lsf_hist_mean[i+j*M], 655), 2)); } /* apply hard limit */ test(); if (sub(st->lsf_hist_mean[i+j*M], 1310) > 0) { st->lsf_hist_mean[i+j*M] = 1310; move16(); } test(); if (negative != 0) { st->lsf_hist_mean[i+j*M] = -st->lsf_hist_mean[i+j*M];move16(); } } } } test(); if (st->sid_frame != 0 ) { /* Set old SID parameters, always shift */ /* even if there is no new valid_data */ Copy(st->lsp, st->lsp_old, M); st->old_log_en = st->log_en; move16(); test(); if (st->valid_data != 0 ) /* new data available (no CRC) */ { /* Compute interpolation factor, since the division only works * * for values of since_last_sid < 32 we have to limit the * * interpolation to 32 frames */ tmp_int_length = st->since_last_sid; move16(); st->since_last_sid = 0; move16(); test(); if (sub(tmp_int_length, 32) > 0) { tmp_int_length = 32; move16(); } test(); if (sub(tmp_int_length, 2) >= 0) { move16(); st->true_sid_period_inv = div_s(1 << 10, shl(tmp_int_length, 10)); } else { st->true_sid_period_inv = 1 << 14; /* 0.5 it Q15 */ move16(); } Init_D_plsf_3(lsfState, parm[0]); /* temporay initialization */ D_plsf_3(lsfState, MRDTX, 0, &parm[1], st->lsp); Set_zero(lsfState->past_r_q, M); /* reset for next speech frame */ log_en_index = parm[4]; move16(); /* Q11 and divide by 4 */ st->log_en = shl(log_en_index, (11 - 2)); move16(); /* Subtract 2.5 in Q11 */ st->log_en = sub(st->log_en, (2560 * 2)); /* Index 0 is reserved for silence */ test(); if (log_en_index == 0) { st->log_en = MIN_16; move16(); } /* no interpolation at startup after coder reset */ /* or when SID_UPD has been received right after SPEECH */ test(); test(); if ((st->data_updated == 0) || (sub(st->dtxGlobalState, SPEECH) == 0) ) { Copy(st->lsp, st->lsp_old, M); st->old_log_en = st->log_en; move16(); } } /* endif valid_data */ /* initialize gain predictor memory of other modes */ ma_pred_init = sub(shr(st->log_en,1), 9000); move16(); test(); if (ma_pred_init > 0) { ma_pred_init = 0; move16(); } test(); if (sub(ma_pred_init, -14436) < 0) { ma_pred_init = -14436; move16(); } predState->past_qua_en[0] = ma_pred_init; move16(); predState->past_qua_en[1] = ma_pred_init; move16(); predState->past_qua_en[2] = ma_pred_init; move16(); predState->past_qua_en[3] = ma_pred_init; move16(); /* past_qua_en for other modes than MR122 */ ma_pred_init = mult(5443, ma_pred_init); /* scale down by factor 20*log10(2) in Q15 */ predState->past_qua_en_MR122[0] = ma_pred_init; move16(); predState->past_qua_en_MR122[1] = ma_pred_init; move16(); predState->past_qua_en_MR122[2] = ma_pred_init; move16(); predState->past_qua_en_MR122[3] = ma_pred_init; move16(); } /* endif sid_frame */ /* CN generation */ /* recompute level adjustment factor Q11 * * st->log_en_adjust = 0.9*st->log_en_adjust + * * 0.1*dtx_log_en_adjust[mode]); */ move16(); st->log_en_adjust = add(mult(st->log_en_adjust, 29491), shr(mult(shl(dtx_log_en_adjust[mode],5),3277),5)); /* Interpolate SID info */ int_fac = shl(add(1,st->since_last_sid), 10); /* Q10 */ move16(); int_fac = mult(int_fac, st->true_sid_period_inv); /* Q10 * Q15 -> Q10 */ /* Maximize to 1.0 in Q10 */ test(); if (sub(int_fac, 1024) > 0) { int_fac = 1024; move16(); } int_fac = shl(int_fac, 4); /* Q10 -> Q14 */ L_log_en_int = L_mult(int_fac, st->log_en); /* Q14 * Q11->Q26 */ move32(); for(i = 0; i < M; i++) { lsp_int[i] = mult(int_fac, st->lsp[i]);/* Q14 * Q15 -> Q14 */ move16(); } int_fac = sub(16384, int_fac); /* 1-k in Q14 */ move16(); /* (Q14 * Q11 -> Q26) + Q26 -> Q26 */ L_log_en_int = L_mac(L_log_en_int, int_fac, st->old_log_en); for(i = 0; i < M; i++) { /* Q14 + (Q14 * Q15 -> Q14) -> Q14 */ lsp_int[i] = add(lsp_int[i], mult(int_fac, st->lsp_old[i])); move16(); lsp_int[i] = shl(lsp_int[i], 1); /* Q14 -> Q15 */ move16(); } /* compute the amount of lsf variability */ lsf_variab_factor = sub(st->log_pg_mean,2457); /* -0.6 in Q12 */ move16(); /* *0.3 Q12*Q15 -> Q12 */ lsf_variab_factor = sub(4096, mult(lsf_variab_factor, 9830)); /* limit to values between 0..1 in Q12 */ test(); if (sub(lsf_variab_factor, 4096) > 0) { lsf_variab_factor = 4096; move16(); } test(); if (lsf_variab_factor < 0) { lsf_variab_factor = 0; move16(); } lsf_variab_factor = shl(lsf_variab_factor, 3); /* -> Q15 */ move16(); /* get index of vector to do variability with */ lsf_variab_index = pseudonoise(&st->L_pn_seed_rx, 3); move16(); /* convert to lsf */ Lsp_lsf(lsp_int, lsf_int, M); /* apply lsf variability */ Copy(lsf_int, lsf_int_variab, M); for(i = 0; i < M; i++) { move16(); lsf_int_variab[i] = add(lsf_int_variab[i], mult(lsf_variab_factor, st->lsf_hist_mean[i+lsf_variab_index*M])); } /* make sure that LSP's are ordered */ Reorder_lsf(lsf_int, LSF_GAP, M); Reorder_lsf(lsf_int_variab, LSF_GAP, M); /* copy lsf to speech decoders lsf state */ Copy(lsf_int, lsfState->past_lsf_q, M); /* convert to lsp */ Lsf_lsp(lsf_int, lsp_int, M); Lsf_lsp(lsf_int_variab, lsp_int_variab, M); /* Compute acoeffs Q12 acoeff is used for level * * normalization and postfilter, acoeff_variab is * * used for synthesis filter * * by doing this we make sure that the level * * in high frequenncies does not jump up and down */ Lsp_Az(lsp_int, acoeff); Lsp_Az(lsp_int_variab, acoeff_variab); /* For use in postfilter */ Copy(acoeff, &A_t[0], M + 1); Copy(acoeff, &A_t[M + 1], M + 1); Copy(acoeff, &A_t[2 * (M + 1)], M + 1); Copy(acoeff, &A_t[3 * (M + 1)], M + 1); /* Compute reflection coefficients Q15 */ A_Refl(&acoeff[1], refl); /* Compute prediction error in Q15 */ pred_err = MAX_16; /* 0.99997 in Q15 */ move16(); for (i = 0; i < M; i++) { pred_err = mult(pred_err, sub(MAX_16, mult(refl[i], refl[i]))); } /* compute logarithm of prediction gain */ Log2(L_deposit_l(pred_err), &log_pg_e, &log_pg_m); /* convert exponent and mantissa to Word16 Q12 */ log_pg = shl(sub(log_pg_e,15), 12); /* Q12 */ move16(); log_pg = shr(sub(0,add(log_pg, shr(log_pg_m, 15-12))), 1); move16(); st->log_pg_mean = add(mult(29491,st->log_pg_mean), mult(3277, log_pg)); move16(); /* Compute interpolated log energy */ L_log_en_int = L_shr(L_log_en_int, 10); /* Q26 -> Q16 */ move32(); /* Add 4 in Q16 */ L_log_en_int = L_add(L_log_en_int, 4 * 65536L); move32(); /* subtract prediction gain */ L_log_en_int = L_sub(L_log_en_int, L_shl(L_deposit_l(log_pg), 4));move32(); /* adjust level to speech coder mode */ L_log_en_int = L_add(L_log_en_int, L_shl(L_deposit_l(st->log_en_adjust), 5)); move32(); log_en_int_e = extract_h(L_log_en_int); move16(); move16(); log_en_int_m = extract_l(L_shr(L_sub(L_log_en_int, L_deposit_h(log_en_int_e)), 1)); level = extract_l(Pow2(log_en_int_e, log_en_int_m)); /* Q4 */ move16(); for (i = 0; i < 4; i++) { /* Compute innovation vector */ build_CN_code(&st->L_pn_seed_rx, ex); for (j = 0; j < L_SUBFR; j++) { ex[j] = mult(level, ex[j]); move16(); } /* Synthesize */ Syn_filt(acoeff_variab, ex, &synth[i * L_SUBFR], L_SUBFR, mem_syn, 1); } /* next i */ /* reset codebook averaging variables */ averState->hangVar = 20; move16(); averState->hangCount = 0; move16(); test(); if (sub(new_state, DTX_MUTE) == 0) { /* mute comfort noise as it has been quite a long time since * last SID update was performed */ tmp_int_length = st->since_last_sid; move16(); test(); if (sub(tmp_int_length, 32) > 0) { tmp_int_length = 32; move16(); } /* safety guard against division by zero */ test(); if(tmp_int_length <= 0) { tmp_int_length = 8; move16(); } move16(); st->true_sid_period_inv = div_s(1 << 10, shl(tmp_int_length, 10)); st->since_last_sid = 0; move16(); Copy(st->lsp, st->lsp_old, M); st->old_log_en = st->log_en; move16(); /* subtract 1/8 in Q11 i.e -6/8 dB */ st->log_en = sub(st->log_en, 256); move16(); } /* reset interpolation length timer * if data has been updated. */ test(); test(); test(); test(); if ((st->sid_frame != 0) && ((st->valid_data != 0) || ((st->valid_data == 0) && (st->dtxHangoverAdded) != 0))) { st->since_last_sid = 0; move16(); st->data_updated = 1; move16(); } return 0; }
/* ************************************************************************** * * Function : D_plsf_5 * Purpose : Decodes the 2 sets of LSP parameters in a frame * using the received quantization indices. * ************************************************************************** */ int D_plsf_5 ( D_plsfState *st, /* i/o: State variables */ Word16 bfi, /* i : bad frame indicator (set to 1 if a bad frame is received) */ Word16 *indice, /* i : quantization indices of 5 submatrices, Q0 */ Word16 *lsp1_q, /* o : quantized 1st LSP vector (M), Q15 */ Word16 *lsp2_q /* o : quantized 2nd LSP vector (M), Q15 */ ) { Word16 i; const Word16 *p_dico; Word16 temp, sign; Word16 lsf1_r[M], lsf2_r[M]; Word16 lsf1_q[M], lsf2_q[M]; test (); if (bfi != 0) /* if bad frame */ { /* use the past LSFs slightly shifted towards their mean */ for (i = 0; i < M; i++) { /* lsfi_q[i] = ALPHA*st->past_lsf_q[i] + ONE_ALPHA*mean_lsf[i]; */ lsf1_q[i] = add (mult (st->past_lsf_q[i], ALPHA), mult (mean_lsf[i], ONE_ALPHA)); move16 (); lsf2_q[i] = lsf1_q[i]; move16 (); } /* estimate past quantized residual to be used in next frame */ for (i = 0; i < M; i++) { /* temp = mean_lsf[i] + st->past_r_q[i] * LSP_PRED_FAC_MR122; */ temp = add (mean_lsf[i], mult (st->past_r_q[i], LSP_PRED_FAC_MR122)); st->past_r_q[i] = sub (lsf2_q[i], temp); move16 (); } } else /* if good LSFs received */ { /* decode prediction residuals from 5 received indices */ p_dico = &dico1_lsf[shl (indice[0], 2)];move16 (); lsf1_r[0] = *p_dico++; move16 (); lsf1_r[1] = *p_dico++; move16 (); lsf2_r[0] = *p_dico++; move16 (); lsf2_r[1] = *p_dico++; move16 (); p_dico = &dico2_lsf[shl (indice[1], 2)];move16 (); lsf1_r[2] = *p_dico++; move16 (); lsf1_r[3] = *p_dico++; move16 (); lsf2_r[2] = *p_dico++; move16 (); lsf2_r[3] = *p_dico++; move16 (); sign = indice[2] & 1; logic16 (); i = shr (indice[2], 1); p_dico = &dico3_lsf[shl (i, 2)]; move16 (); test (); if (sign == 0) { lsf1_r[4] = *p_dico++; move16 (); lsf1_r[5] = *p_dico++; move16 (); lsf2_r[4] = *p_dico++; move16 (); lsf2_r[5] = *p_dico++; move16 (); } else { lsf1_r[4] = negate (*p_dico++); move16 (); lsf1_r[5] = negate (*p_dico++); move16 (); lsf2_r[4] = negate (*p_dico++); move16 (); lsf2_r[5] = negate (*p_dico++); move16 (); } p_dico = &dico4_lsf[shl (indice[3], 2)];move16 (); lsf1_r[6] = *p_dico++; move16 (); lsf1_r[7] = *p_dico++; move16 (); lsf2_r[6] = *p_dico++; move16 (); lsf2_r[7] = *p_dico++; move16 (); p_dico = &dico5_lsf[shl (indice[4], 2)];move16 (); lsf1_r[8] = *p_dico++; move16 (); lsf1_r[9] = *p_dico++; move16 (); lsf2_r[8] = *p_dico++; move16 (); lsf2_r[9] = *p_dico++; move16 (); /* Compute quantized LSFs and update the past quantized residual */ for (i = 0; i < M; i++) { temp = add (mean_lsf[i], mult (st->past_r_q[i], LSP_PRED_FAC_MR122)); lsf1_q[i] = add (lsf1_r[i], temp); move16 (); lsf2_q[i] = add (lsf2_r[i], temp); move16 (); st->past_r_q[i] = lsf2_r[i]; move16 (); } } /* verification that LSFs have minimum distance of LSF_GAP Hz */ Reorder_lsf (lsf1_q, LSF_GAP, M); Reorder_lsf (lsf2_q, LSF_GAP, M); Copy (lsf2_q, st->past_lsf_q, M); /* convert LSFs to the cosine domain */ Lsf_lsp (lsf1_q, lsp1_q, M); Lsf_lsp (lsf2_q, lsp2_q, M); return 0; }
/* ************************************************************************** * * Function : Decoder_amr * Purpose : Speech decoder routine. * ************************************************************************** */ int Decoder_amr ( Decoder_amrState *st, /* i/o : State variables */ enum Mode mode, /* i : AMR mode */ Word16 parm[], /* i : vector of synthesis parameters (PRM_SIZE) */ enum RXFrameType frame_type, /* i : received frame type */ Word16 synth[], /* o : synthesis speech (L_FRAME) */ Word16 A_t[] /* o : decoded LP filter in 4 subframes (AZ_SIZE) */ ) { /* LPC coefficients */ Word16 *Az; /* Pointer on A_t */ /* LSPs */ Word16 lsp_new[M]; Word16 lsp_mid[M]; /* LSFs */ Word16 prev_lsf[M]; Word16 lsf_i[M]; /* Algebraic codevector */ Word16 code[L_SUBFR]; /* excitation */ Word16 excp[L_SUBFR]; Word16 exc_enhanced[L_SUBFR]; /* Scalars */ Word16 i, i_subfr; Word16 T0, T0_frac, index, index_mr475 = 0; Word16 gain_pit, gain_code, gain_code_mix, pit_sharp, pit_flag, pitch_fac; Word16 t0_min, t0_max; Word16 delta_frc_low, delta_frc_range; Word16 tmp_shift; Word16 temp; Word32 L_temp; Word16 flag4; Word16 carefulFlag; Word16 excEnergy; Word16 subfrNr; Word16 evenSubfr = 0; Word16 bfi = 0; /* bad frame indication flag */ Word16 pdfi = 0; /* potential degraded bad frame flag */ enum DTXStateType newDTXState; /* SPEECH , DTX, DTX_MUTE */ /* find the new DTX state SPEECH OR DTX */ newDTXState = rx_dtx_handler(st->dtxDecoderState, frame_type); move16 (); /* function result */ /* DTX actions */ test(); if (sub(newDTXState, SPEECH) != 0 ) { Decoder_amr_reset (st, MRDTX); dtx_dec(st->dtxDecoderState, st->mem_syn, st->lsfState, st->pred_state, st->Cb_gain_averState, newDTXState, mode, parm, synth, A_t); /* update average lsp */ Lsf_lsp(st->lsfState->past_lsf_q, st->lsp_old, M); lsp_avg(st->lsp_avg_st, st->lsfState->past_lsf_q); goto the_end; } /* SPEECH action state machine */ test (); test (); test (); if ((sub(frame_type, RX_SPEECH_BAD) == 0) || (sub(frame_type, RX_NO_DATA) == 0) || (sub(frame_type, RX_ONSET) == 0)) { bfi = 1; move16 (); test(); test(); if ((sub(frame_type, RX_NO_DATA) == 0) || (sub(frame_type, RX_ONSET) == 0)) { build_CN_param(&st->nodataSeed, prmno[mode], bitno[mode], parm); } } else if (sub(frame_type, RX_SPEECH_DEGRADED) == 0) { pdfi = 1; move16 (); } test(); if (bfi != 0) { st->state = add (st->state, 1); } else if (sub (st->state, 6) == 0) { st->state = 5; move16 (); } else { st->state = 0; move16 (); } test (); if (sub (st->state, 6) > 0) { st->state = 6; move16 (); } /* If this frame is the first speech frame after CNI period, */ /* set the BFH state machine to an appropriate state depending */ /* on whether there was DTX muting before start of speech or not */ /* If there was DTX muting, the first speech frame is muted. */ /* If there was no DTX muting, the first speech frame is not */ /* muted. The BFH state machine starts from state 5, however, to */ /* keep the audible noise resulting from a SID frame which is */ /* erroneously interpreted as a good speech frame as small as */ /* possible (the decoder output in this case is quickly muted) */ test(); if (sub(st->dtxDecoderState->dtxGlobalState, DTX) == 0) { st->state = 5; move16 (); st->prev_bf = 0; move16 (); } else if (test (), sub(st->dtxDecoderState->dtxGlobalState, DTX_MUTE) == 0) { st->state = 5; move16 (); st->prev_bf = 1; move16 (); } /* save old LSFs for CB gain smoothing */ Copy (st->lsfState->past_lsf_q, prev_lsf, M); /* decode LSF parameters and generate interpolated lpc coefficients for the 4 subframes */ test (); if (sub (mode, MR122) != 0) { D_plsf_3(st->lsfState, mode, bfi, parm, lsp_new); fwc (); /* function worst case */ /* Advance synthesis parameters pointer */ parm += 3; move16 (); Int_lpc_1to3(st->lsp_old, lsp_new, A_t); } else { D_plsf_5 (st->lsfState, bfi, parm, lsp_mid, lsp_new); fwc (); /* function worst case */ /* Advance synthesis parameters pointer */ parm += 5; move16 (); Int_lpc_1and3 (st->lsp_old, lsp_mid, lsp_new, A_t); } /* update the LSPs for the next frame */ for (i = 0; i < M; i++) { st->lsp_old[i] = lsp_new[i]; move16 (); } fwc (); /* function worst case */ /*------------------------------------------------------------------------* * 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 * *------------------------------------------------------------------------*/ /* pointer to interpolated LPC parameters */ Az = A_t; move16 (); evenSubfr = 0; move16(); subfrNr = -1; move16(); for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { subfrNr = add(subfrNr, 1); evenSubfr = sub(1, evenSubfr); /* flag for first and 3th subframe */ pit_flag = i_subfr; move16 (); test(); if (sub (i_subfr, L_FRAME_BY2) == 0) { test(); test(); if (sub(mode, MR475) != 0 && sub(mode, MR515) != 0) { pit_flag = 0; move16 (); } } /* pitch index */ index = *parm++; move16 (); /*-------------------------------------------------------* * - decode pitch lag and find adaptive codebook vector. * *-------------------------------------------------------*/ test (); if (sub(mode, MR122) != 0) { /* flag4 indicates encoding with 4 bit resolution; */ /* this is needed for mode MR475, MR515, MR59 and MR67 */ flag4 = 0; move16 (); test (); test (); test (); test (); if ((sub (mode, MR475) == 0) || (sub (mode, MR515) == 0) || (sub (mode, MR59) == 0) || (sub (mode, MR67) == 0) ) { flag4 = 1; move16 (); } /*-------------------------------------------------------* * - get ranges for the t0_min and t0_max * * - only needed in delta decoding * *-------------------------------------------------------*/ delta_frc_low = 5; move16(); delta_frc_range = 9; move16(); test (); if ( sub(mode, MR795) == 0 ) { delta_frc_low = 10; move16(); delta_frc_range = 19; move16(); } t0_min = sub(st->old_T0, delta_frc_low); test (); if (sub(t0_min, PIT_MIN) < 0) { t0_min = PIT_MIN; move16(); } t0_max = add(t0_min, delta_frc_range); test (); if (sub(t0_max, PIT_MAX) > 0) { t0_max = PIT_MAX; move16(); t0_min = sub(t0_max, delta_frc_range); } Dec_lag3 (index, t0_min, t0_max, pit_flag, st->old_T0, &T0, &T0_frac, flag4); st->T0_lagBuff = T0; move16 (); test (); if (bfi != 0) { test (); if (sub (st->old_T0, PIT_MAX) < 0) { /* Graceful pitch */ st->old_T0 = add(st->old_T0, 1); /* degradation */ } T0 = st->old_T0; move16 (); T0_frac = 0; move16 (); test (); test (); test (); test (); test (); if ( st->inBackgroundNoise != 0 && sub(st->voicedHangover, 4) > 0 && ((sub(mode, MR475) == 0 ) || (sub(mode, MR515) == 0 ) || (sub(mode, MR59) == 0) ) ) { T0 = st->T0_lagBuff; move16 (); } } fwc (); /* function worst case */ Pred_lt_3or6 (st->exc, T0, T0_frac, L_SUBFR, 1); } else { Dec_lag6 (index, PIT_MIN_MR122, PIT_MAX, pit_flag, &T0, &T0_frac); test (); test (); test (); if ( bfi == 0 && (pit_flag == 0 || sub (index, 61) < 0)) { } else { st->T0_lagBuff = T0; move16 (); T0 = st->old_T0; move16 (); T0_frac = 0; move16 (); } fwc (); /* function worst case */ Pred_lt_3or6 (st->exc, T0, T0_frac, L_SUBFR, 0); } fwc (); /* function worst case */ /*-------------------------------------------------------* * - (MR122 only: Decode pitch gain.) * * - Decode innovative codebook. * * - set pitch sharpening factor * *-------------------------------------------------------*/ test (); test (); if (sub (mode, MR475) == 0 || sub (mode, MR515) == 0) { /* MR475, MR515 */ index = *parm++; /* index of position */ move16 (); i = *parm++; /* signs */ move16 (); fwc (); /* function worst case */ decode_2i40_9bits (subfrNr, i, index, code); fwc (); /* function worst case */ pit_sharp = shl (st->sharp, 1); } else if (sub (mode, MR59) == 0) { /* MR59 */ test (); index = *parm++; /* index of position */ move16 (); i = *parm++; /* signs */ move16 (); fwc (); /* function worst case */ decode_2i40_11bits (i, index, code); fwc (); /* function worst case */ pit_sharp = shl (st->sharp, 1); } else if (sub (mode, MR67) == 0) { /* MR67 */ test (); test (); index = *parm++; /* index of position */ move16 (); i = *parm++; /* signs */ move16 (); fwc (); /* function worst case */ decode_3i40_14bits (i, index, code); fwc (); /* function worst case */ pit_sharp = shl (st->sharp, 1); } else if (sub (mode, MR795) <= 0) { /* MR74, MR795 */ test (); test (); test (); index = *parm++; /* index of position */ move16 (); i = *parm++; /* signs */ move16 (); fwc (); /* function worst case */ decode_4i40_17bits (i, index, code); fwc (); /* function worst case */ pit_sharp = shl (st->sharp, 1); } else if (sub (mode, MR102) == 0) { /* MR102 */ test (); test (); test (); fwc (); /* function worst case */ dec_8i40_31bits (parm, code); parm += 7; move16 (); fwc (); /* function worst case */ pit_sharp = shl (st->sharp, 1); } else { /* MR122 */ test (); test (); test (); index = *parm++; move16 (); test(); if (bfi != 0) { ec_gain_pitch (st->ec_gain_p_st, st->state, &gain_pit); } else { gain_pit = d_gain_pitch (mode, index); move16 (); } ec_gain_pitch_update (st->ec_gain_p_st, bfi, st->prev_bf, &gain_pit); fwc (); /* function worst case */ dec_10i40_35bits (parm, code); parm += 10; move16 (); fwc (); /* function worst case */ /* pit_sharp = gain_pit; */ /* if (pit_sharp > 1.0) pit_sharp = 1.0; */ pit_sharp = shl (gain_pit, 1); } /*-------------------------------------------------------* * - Add the pitch contribution to code[]. * *-------------------------------------------------------*/ for (i = T0; i < L_SUBFR; i++) { temp = mult (code[i - T0], pit_sharp); code[i] = add (code[i], temp); move16 (); } fwc (); /* function worst case */ /*------------------------------------------------------------* * - Decode codebook gain (MR122) or both pitch * * gain and codebook gain (all others) * * - Update pitch sharpening "sharp" with quantized gain_pit * *------------------------------------------------------------*/ if (test(), sub (mode, MR475) == 0) { /* read and decode pitch and code gain */ test(); if (evenSubfr != 0) { index_mr475 = *parm++; move16 (); /* index of gain(s) */ } test(); if (bfi == 0) { Dec_gain(st->pred_state, mode, index_mr475, code, evenSubfr, &gain_pit, &gain_code); } else { ec_gain_pitch (st->ec_gain_p_st, st->state, &gain_pit); ec_gain_code (st->ec_gain_c_st, st->pred_state, st->state, &gain_code); } ec_gain_pitch_update (st->ec_gain_p_st, bfi, st->prev_bf, &gain_pit); ec_gain_code_update (st->ec_gain_c_st, bfi, st->prev_bf, &gain_code); fwc (); /* function worst case */ pit_sharp = gain_pit; move16 (); test (); if (sub (pit_sharp, SHARPMAX) > 0) { pit_sharp = SHARPMAX; move16 (); } } else if (test(), test(), (sub (mode, MR74) <= 0) || (sub (mode, MR102) == 0)) { /* read and decode pitch and code gain */ index = *parm++; move16 (); /* index of gain(s) */ test(); if (bfi == 0) { Dec_gain(st->pred_state, mode, index, code, evenSubfr, &gain_pit, &gain_code); } else { ec_gain_pitch (st->ec_gain_p_st, st->state, &gain_pit); ec_gain_code (st->ec_gain_c_st, st->pred_state, st->state, &gain_code); } ec_gain_pitch_update (st->ec_gain_p_st, bfi, st->prev_bf, &gain_pit); ec_gain_code_update (st->ec_gain_c_st, bfi, st->prev_bf, &gain_code); fwc (); /* function worst case */ pit_sharp = gain_pit; move16 (); test (); if (sub (pit_sharp, SHARPMAX) > 0) { pit_sharp = SHARPMAX; move16 (); } if (sub (mode, MR102) == 0) { if (sub (st->old_T0, add(L_SUBFR, 5)) > 0) { pit_sharp = shr(pit_sharp, 2); } } } else { /* read and decode pitch gain */ index = *parm++; move16 (); /* index of gain(s) */ test (); if (sub (mode, MR795) == 0) { /* decode pitch gain */ test(); if (bfi != 0) { ec_gain_pitch (st->ec_gain_p_st, st->state, &gain_pit); } else { gain_pit = d_gain_pitch (mode, index); move16 (); } ec_gain_pitch_update (st->ec_gain_p_st, bfi, st->prev_bf, &gain_pit); /* read and decode code gain */ index = *parm++; move16 (); test(); if (bfi == 0) { d_gain_code (st->pred_state, mode, index, code, &gain_code); } else { ec_gain_code (st->ec_gain_c_st, st->pred_state, st->state, &gain_code); } ec_gain_code_update (st->ec_gain_c_st, bfi, st->prev_bf, &gain_code); fwc (); /* function worst case */ pit_sharp = gain_pit; move16 (); test (); if (sub (pit_sharp, SHARPMAX) > 0) { pit_sharp = SHARPMAX; move16 (); } } else { /* MR122 */ test(); if (bfi == 0) { d_gain_code (st->pred_state, mode, index, code, &gain_code); } else { ec_gain_code (st->ec_gain_c_st, st->pred_state, st->state, &gain_code); } ec_gain_code_update (st->ec_gain_c_st, bfi, st->prev_bf, &gain_code); fwc (); /* function worst case */ pit_sharp = gain_pit; move16 (); } } /* store pitch sharpening for next subframe */ /* (for modes which use the previous pitch gain for pitch sharpening in the search phase) */ /* do not update sharpening in even subframes for MR475 */ test(); test(); if (sub(mode, MR475) != 0 || evenSubfr == 0) { st->sharp = gain_pit; move16 (); test (); if (sub (st->sharp, SHARPMAX) > 0) { st->sharp = SHARPMAX; move16 (); } } pit_sharp = shl (pit_sharp, 1); test (); if (sub (pit_sharp, 16384) > 0) { for (i = 0; i < L_SUBFR; i++) { temp = mult (st->exc[i], pit_sharp); L_temp = L_mult (temp, gain_pit); test (); if (sub(mode, MR122)==0) { L_temp = L_shr (L_temp, 1); } excp[i] = round (L_temp); move16 (); } } /*-------------------------------------------------------* * - Store list of LTP gains needed in the source * * characteristic detector (SCD) * *-------------------------------------------------------*/ test (); if ( bfi == 0 ) { for (i = 0; i < 8; i++) { st->ltpGainHistory[i] = st->ltpGainHistory[i+1]; move16 (); } st->ltpGainHistory[8] = gain_pit; move16 (); } /*-------------------------------------------------------* * - Limit gain_pit if in background noise and BFI * * for MR475, MR515, MR59 * *-------------------------------------------------------*/ test (); test (); test (); test (); test (); test (); if ( (st->prev_bf != 0 || bfi != 0) && st->inBackgroundNoise != 0 && ((sub(mode, MR475) == 0) || (sub(mode, MR515) == 0) || (sub(mode, MR59) == 0)) ) { test (); if ( sub (gain_pit, 12288) > 0) /* if (gain_pit > 0.75) in Q14*/ gain_pit = add( shr( sub(gain_pit, 12288), 1 ), 12288 ); /* gain_pit = (gain_pit-0.75)/2.0 + 0.75; */ test (); if ( sub (gain_pit, 14745) > 0) /* if (gain_pit > 0.90) in Q14*/ { gain_pit = 14745; move16 (); } } /*-------------------------------------------------------* * Calculate CB mixed gain * *-------------------------------------------------------*/ Int_lsf(prev_lsf, st->lsfState->past_lsf_q, i_subfr, lsf_i); gain_code_mix = Cb_gain_average( st->Cb_gain_averState, mode, gain_code, lsf_i, st->lsp_avg_st->lsp_meanSave, bfi, st->prev_bf, pdfi, st->prev_pdf, st->inBackgroundNoise, st->voicedHangover); move16 (); /* make sure that MR74, MR795, MR122 have original code_gain*/ test(); if ((sub(mode, MR67) > 0) && (sub(mode, MR102) != 0) ) /* MR74, MR795, MR122 */ { gain_code_mix = gain_code; move16 (); } /*-------------------------------------------------------* * - Find the total excitation. * * - Find synthesis speech corresponding to st->exc[]. * *-------------------------------------------------------*/ test (); if (sub(mode, MR102) <= 0) /* MR475, MR515, MR59, MR67, MR74, MR795, MR102*/ { pitch_fac = gain_pit; move16 (); tmp_shift = 1; move16 (); } else /* MR122 */ { pitch_fac = shr (gain_pit, 1); move16 (); tmp_shift = 2; move16 (); } /* copy unscaled LTP excitation to exc_enhanced (used in phase * dispersion below) and compute total excitation for LTP feedback */ for (i = 0; i < L_SUBFR; i++) { exc_enhanced[i] = st->exc[i]; move16 (); /* st->exc[i] = gain_pit*st->exc[i] + gain_code*code[i]; */ L_temp = L_mult (st->exc[i], pitch_fac); /* 12.2: Q0 * Q13 */ /* 7.4: Q0 * Q14 */ L_temp = L_mac (L_temp, code[i], gain_code); /* 12.2: Q12 * Q1 */ /* 7.4: Q13 * Q1 */ L_temp = L_shl (L_temp, tmp_shift); /* Q16 */ st->exc[i] = round (L_temp); move16 (); } /*-------------------------------------------------------* * - Adaptive phase dispersion * *-------------------------------------------------------*/ ph_disp_release(st->ph_disp_st); /* free phase dispersion adaption */ test (); test (); test (); test (); test (); test (); if ( ((sub(mode, MR475) == 0) || (sub(mode, MR515) == 0) || (sub(mode, MR59) == 0)) && sub(st->voicedHangover, 3) > 0 && st->inBackgroundNoise != 0 && bfi != 0 ) { ph_disp_lock(st->ph_disp_st); /* Always Use full Phase Disp. */ } /* if error in bg noise */ /* apply phase dispersion to innovation (if enabled) and compute total excitation for synthesis part */ ph_disp(st->ph_disp_st, mode, exc_enhanced, gain_code_mix, gain_pit, code, pitch_fac, tmp_shift); /*-------------------------------------------------------* * - The Excitation control module are active during BFI.* * - Conceal drops in signal energy if in bg noise. * *-------------------------------------------------------*/ L_temp = 0; move32 (); for (i = 0; i < L_SUBFR; i++) { L_temp = L_mac (L_temp, exc_enhanced[i], exc_enhanced[i] ); } L_temp = L_shr (L_temp, 1); /* excEnergy = sqrt(L_temp) in Q0 */ L_temp = sqrt_l_exp(L_temp, &temp); move32 (); /* function result */ L_temp = L_shr(L_temp, add( shr(temp, 1), 15)); L_temp = L_shr(L_temp, 2); /* To cope with 16-bit and */ excEnergy = extract_l(L_temp); /* scaling in ex_ctrl() */ test (); test (); test (); test (); test (); test (); test (); test (); test (); test (); if ( ((sub (mode, MR475) == 0) || (sub (mode, MR515) == 0) || (sub (mode, MR59) == 0)) && sub(st->voicedHangover, 5) > 0 && st->inBackgroundNoise != 0 && sub(st->state, 4) < 0 && ( (pdfi != 0 && st->prev_pdf != 0) || bfi != 0 || st->prev_bf != 0) ) { carefulFlag = 0; move32 (); test (); test (); if ( pdfi != 0 && bfi == 0 ) { carefulFlag = 1; move16 (); } Ex_ctrl(exc_enhanced, excEnergy, st->excEnergyHist, st->voicedHangover, st->prev_bf, carefulFlag); } test (); test (); test (); test (); if ( st->inBackgroundNoise != 0 && ( bfi != 0 || st->prev_bf != 0 ) && sub(st->state, 4) < 0 ) { ; /* do nothing! */ } else { /* Update energy history for all modes */ for (i = 0; i < 8; i++) { st->excEnergyHist[i] = st->excEnergyHist[i+1]; move16 (); } st->excEnergyHist[8] = excEnergy; move16 (); } /*-------------------------------------------------------* * Excitation control module end. * *-------------------------------------------------------*/ fwc (); /* function worst case */ test (); if (sub (pit_sharp, 16384) > 0) { for (i = 0; i < L_SUBFR; i++) { excp[i] = add (excp[i], exc_enhanced[i]); move16 (); } agc2 (exc_enhanced, excp, L_SUBFR); Overflow = 0; move16 (); Syn_filt (Az, excp, &synth[i_subfr], L_SUBFR, st->mem_syn, 0); } else { Overflow = 0; move16 (); Syn_filt (Az, exc_enhanced, &synth[i_subfr], L_SUBFR, st->mem_syn, 0); } test (); if (Overflow != 0) /* Test for overflow */ { for (i = 0; i < PIT_MAX + L_INTERPOL + L_SUBFR; i++) { st->old_exc[i] = shr(st->old_exc[i], 2); move16 (); } for (i = 0; i < L_SUBFR; i++) { exc_enhanced[i] = shr(exc_enhanced[i], 2); move16 (); } Syn_filt(Az, exc_enhanced, &synth[i_subfr], L_SUBFR, st->mem_syn, 1); } else { Copy(&synth[i_subfr+L_SUBFR-M], st->mem_syn, M); } /*--------------------------------------------------* * Update signal for next frame. * * -> shift to the left by L_SUBFR st->exc[] * *--------------------------------------------------*/ Copy (&st->old_exc[L_SUBFR], &st->old_exc[0], PIT_MAX + L_INTERPOL); fwc (); /* function worst case */ /* interpolated LPC parameters for next subframe */ Az += MP1; move16 (); /* store T0 for next subframe */ st->old_T0 = T0; move16 (); } /*-------------------------------------------------------* * Call the Source Characteristic Detector which updates * * st->inBackgroundNoise and st->voicedHangover. * *-------------------------------------------------------*/ move16 (); /* function result */ st->inBackgroundNoise = Bgn_scd(st->background_state, &(st->ltpGainHistory[0]), &(synth[0]), &(st->voicedHangover) ); dtx_dec_activity_update(st->dtxDecoderState, st->lsfState->past_lsf_q, synth); fwc (); /* function worst case */ /* store bfi for next subframe */ st->prev_bf = bfi; move16 (); st->prev_pdf = pdfi; move16 (); /*--------------------------------------------------* * Calculate the LSF averages on the eight * * previous frames * *--------------------------------------------------*/ lsp_avg(st->lsp_avg_st, st->lsfState->past_lsf_q); fwc (); /* function worst case */ the_end: st->dtxDecoderState->dtxGlobalState = newDTXState; move16(); return 0; }