📄 cod_amr.cpp
字号:
CAUTION [optional] [State any special notes, constraints or cautions for users of this function]------------------------------------------------------------------------------*/Word16 cod_amr( cod_amrState *st, /* i/o : State struct */ enum Mode mode, /* i : AMR mode */ Word16 new_speech[], /* i : speech input (L_FRAME) */ Word16 ana[], /* o : Analysis parameters */ enum Mode *usedMode, /* o : used mode */ Word16 synth[] /* o : Local synthesis */){ /* LPC coefficients */ Word16 A_t[(MP1) * 4]; /* A(z) unquantized for the 4 subframes */ Word16 Aq_t[(MP1) * 4]; /* A(z) quantized for the 4 subframes */ Word16 *A, *Aq; /* Pointer on A_t and Aq_t */ Word16 lsp_new[M]; /* Other vectors */ 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 gCoeff[6]; /* Correlations between xn, y1, & y2: */ Word16 res[L_SUBFR]; /* Short term (LPC) prediction residual */ Word16 res2[L_SUBFR]; /* Long term (LTP) prediction residual */ /* Vector and scalars needed for the MR475 */ Word16 xn_sf0[L_SUBFR]; /* Target vector for pitch search */ Word16 y2_sf0[L_SUBFR]; /* Filtered codebook innovation */ Word16 code_sf0[L_SUBFR]; /* Fixed codebook excitation */ Word16 h1_sf0[L_SUBFR]; /* The impulse response of sf0 */ Word16 mem_syn_save[M]; /* Filter memory */ Word16 mem_w0_save[M]; /* Filter memory */ Word16 mem_err_save[M]; /* Filter memory */ Word16 sharp_save; /* Sharpening */ Word16 evenSubfr; /* Even subframe indicator */ Word16 T0_sf0 = 0; /* Integer pitch lag of sf0 */ Word16 T0_frac_sf0 = 0; /* Fractional pitch lag of sf0 */ Word16 i_subfr_sf0 = 0; /* Position in exc[] for sf0 */ Word16 gain_pit_sf0; /* Quantized pitch gain for sf0 */ Word16 gain_code_sf0; /* Quantized codebook gain for sf0 */ /* Scalars */ Word16 i_subfr, subfrNr; Word16 T_op[L_FRAME/L_FRAME_BY2]; Word16 T0, T0_frac; Word16 gain_pit, gain_code; /* Flags */ Word16 lsp_flag = 0; /* indicates resonance in LPC filter */ Word16 gp_limit; /* pitch gain limit value */ Word16 vad_flag; /* VAD decision flag */ Word16 compute_sid_flag; /* SID analysis flag */ Flag *pOverflow = &(st->overflow); /* Overflow flag */ oscl_memcpy(st->new_speech, new_speech, L_FRAME*sizeof(Word16)); *usedMode = mode; /* DTX processing */ if (st->dtx) { /* Find VAD decision */#ifdef VAD2 vad_flag = vad2(st->new_speech, st->vadSt, pOverflow); vad_flag = vad2(st->new_speech + 80, st->vadSt, pOverflow) || vad_flag;#else vad_flag = vad1(st->vadSt, st->new_speech, pOverflow);#endif /* NB! usedMode may change here */ compute_sid_flag = tx_dtx_handler(st->dtx_encSt, vad_flag, usedMode, pOverflow); } else { compute_sid_flag = 0; } /*------------------------------------------------------------------------* * - 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 all * * subframes (both quantized and unquantized) * *------------------------------------------------------------------------*/ /* LP analysis */ lpc(st->lpcSt, mode, st->p_window, st->p_window_12k2, A_t, pOverflow); /* From A(z) to lsp. LSP quantization and interpolation */ lsp(st->lspSt, mode, *usedMode, A_t, Aq_t, lsp_new, &ana, pOverflow); /* Buffer lsp's and energy */ dtx_buffer(st->dtx_encSt, lsp_new, st->new_speech, pOverflow); /* Check if in DTX mode */ if (*usedMode == MRDTX) { dtx_enc(st->dtx_encSt, compute_sid_flag, st->lspSt->qSt, &(st->gainQuantSt->gc_predSt), &ana, pOverflow); oscl_memset(st->old_exc, 0, sizeof(Word16)*(PIT_MAX + L_INTERPOL)); oscl_memset(st->mem_w0, 0, sizeof(Word16)*M); oscl_memset(st->mem_err, 0, sizeof(Word16)*M); oscl_memset(st->zero, 0, sizeof(Word16)*L_SUBFR); oscl_memset(st->hvec, 0, sizeof(Word16)*L_SUBFR); /* set to zero "h1[-L_SUBFR..-1]" */ /* Reset lsp states */ lsp_reset(st->lspSt); oscl_memcpy(st->lspSt->lsp_old, lsp_new, M*sizeof(Word16)); oscl_memcpy(st->lspSt->lsp_old_q, lsp_new, M*sizeof(Word16)); /* Reset clLtp states */ cl_ltp_reset(st->clLtpSt); st->sharp = SHARPMIN; } else { /* check resonance in the filter */ lsp_flag = check_lsp(st->tonStabSt, st->lspSt->lsp_old, pOverflow); } /*----------------------------------------------------------------------* * - Find the weighted input speech w_sp[] for the whole speech frame * * - Find the open-loop pitch delay for first 2 subframes * * - Set the range for searching closed-loop pitch in 1st subframe * * - Find the open-loop pitch delay for last 2 subframes * *----------------------------------------------------------------------*/#ifdef VAD2 if (st->dtx) { st->vadSt->L_Rmax = 0; st->vadSt->L_R0 = 0; }#endif for (subfrNr = 0, i_subfr = 0; subfrNr < L_FRAME / L_FRAME_BY2; subfrNr++, i_subfr += L_FRAME_BY2) { /* Pre-processing on 80 samples */ pre_big(mode, gamma1, gamma1_12k2, gamma2, A_t, i_subfr, st->speech, st->mem_w, st->wsp, pOverflow); if ((mode != MR475) && (mode != MR515)) { /* Find open loop pitch lag for two subframes */ ol_ltp(st->pitchOLWghtSt, st->vadSt, mode, &st->wsp[i_subfr], &T_op[subfrNr], st->old_lags, st->ol_gain_flg, subfrNr, st->dtx, pOverflow); } } if ((mode == MR475) || (mode == MR515)) { /* Find open loop pitch lag for ONE FRAME ONLY */ /* search on 160 samples */ ol_ltp(st->pitchOLWghtSt, st->vadSt, mode, &st->wsp[0], &T_op[0], st->old_lags, st->ol_gain_flg, 1, st->dtx, pOverflow); T_op[1] = T_op[0]; }#ifdef VAD2 if (st->dtx) { LTP_flag_update(st->vadSt, (Word16) mode, pOverflow); }#endif#ifndef VAD2 /* run VAD pitch detection */ if (st->dtx) { vad_pitch_detection(st->vadSt, T_op, pOverflow); }#endif if (*usedMode == MRDTX) { goto the_end; } /*------------------------------------------------------------------------* * 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 L_FRAME/L_SUBFR 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 dealy * * - 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 * *------------------------------------------------------------------------*/ A = A_t; /* pointer to interpolated LPC parameters */ Aq = Aq_t; /* pointer to interpolated quantized LPC parameters */ evenSubfr = 0; subfrNr = -1; for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { subfrNr++; evenSubfr = 1 - evenSubfr; /* Save states for the MR475 mode */ if ((evenSubfr != 0) && (*usedMode == MR475)) { oscl_memcpy(mem_syn_save, st->mem_syn, M*sizeof(Word16)); oscl_memcpy(mem_w0_save, st->mem_w0, M*sizeof(Word16)); oscl_memcpy(mem_err_save, st->mem_err, M*sizeof(Word16)); sharp_save = st->sharp; } /*-----------------------------------------------------------------* * - Preprocessing of subframe * *-----------------------------------------------------------------*/ if (*usedMode != MR475) { subframePreProc(*usedMode, gamma1, gamma1_12k2, gamma2, A, Aq, &st->speech[i_subfr], st->mem_err, st->mem_w0, st->zero, st->ai_zero, &st->exc[i_subfr], st->h1, xn, res, st->error); } else { /* MR475 */ subframePreProc(*usedMode, gamma1, gamma1_12k2, gamma2, A, Aq, &st->speech[i_subfr], st->mem_err, mem_w0_save, st->zero, st->ai_zero, &st->exc[i_subfr], st->h1, xn, res, st->error); /* save impulse response (modified in cbsearch) */ if (evenSubfr != 0) { oscl_memcpy(h1_sf0, st->h1, L_SUBFR*sizeof(Word16)); } } /* copy the LP residual (res2 is modified in the CL LTP search) */ oscl_memcpy(res2, res, L_SUBFR*sizeof(Word16)); /*-----------------------------------------------------------------* * - Closed-loop LTP search * *-----------------------------------------------------------------*/ cl_ltp(st->clLtpSt, st->tonStabSt, *usedMode, i_subfr, T_op, st->h1, &st->exc[i_subfr], res2, xn, lsp_flag, xn2, y1, &T0, &T0_frac, &gain_pit, gCoeff, &ana, &gp_limit, pOverflow); /* update LTP lag history */ if ((subfrNr == 0) && (st->ol_gain_flg[0] > 0)) { st->old_lags[1] = T0; } if ((subfrNr == 3) && (st->ol_gain_flg[1] > 0)) { st->old_lags[0] = T0; } /*-----------------------------------------------------------------* * - Inovative codebook search (find index and gain) * *-----------------------------------------------------------------*/ cbsearch(xn2, st->h1, T0, st->sharp, gain_pit, res2, code, y2, &ana, *usedMode, subfrNr, pOverflow); /*------------------------------------------------------* * - Quantization of gains. * *------------------------------------------------------*/ gainQuant(st->gainQuantSt, *usedMode, res, &st->exc[i_subfr], code, xn, xn2, y1, y2, gCoeff, evenSubfr, gp_limit, &gain_pit_sf0, &gain_code_sf0, &gain_pit, &gain_code, &ana, pOverflow); /* update gain history */ update_gp_clipping(st->tonStabSt, gain_pit, pOverflow); if (*usedMode != MR475) { /* Subframe Post Porcessing */ subframePostProc(st->speech, *usedMode, i_subfr, gain_pit, gain_code, Aq, synth, xn, code, y1, y2, st->mem_syn, st->mem_err, st->mem_w0, st->exc, &st->sharp, pOverflow); } else { if (evenSubfr != 0) { i_subfr_sf0 = i_subfr; oscl_memcpy(xn_sf0, xn, L_SUBFR*sizeof(Word16)); oscl_memcpy(y2_sf0, y2, L_SUBFR*sizeof(Word16)); oscl_memcpy(code_sf0, code, L_SUBFR*sizeof(Word16)); T0_sf0 = T0; T0_frac_sf0 = T0_frac; /* Subframe Post Porcessing */ subframePostProc(st->speech, *usedMode, i_subfr, gain_pit, gain_code, Aq, synth, xn, code, y1, y2, mem_syn_save, st->mem_err, mem_w0_save, st->exc, &st->sharp, pOverflow); st->sharp = sharp_save; } else { /* update both subframes for the MR475 */ /* Restore states for the MR475 mode */ oscl_memcpy(st->mem_err, mem_err_save, M*sizeof(Word16)); /* re-build excitation for sf 0 */ Pred_lt_3or6(&st->exc[i_subfr_sf0], T0_sf0, T0_frac_sf0, L_SUBFR, 1, pOverflow); Convolve(&st->exc[i_subfr_sf0], h1_sf0, y1, L_SUBFR); Aq -= MP1; subframePostProc(st->speech, *usedMode, i_subfr_sf0, gain_pit_sf0, gain_code_sf0, Aq, synth, xn_sf0, code_sf0, y1, y2_sf0, st->mem_syn, st->mem_err, st->mem_w0, st->exc, &sharp_save, pOverflow); /* overwrites sharp_save */ Aq += MP1; /* re-run pre-processing to get xn right (needed by postproc) */ /* (this also reconstructs the unsharpened h1 for sf 1) */ subframePreProc(*usedMode, gamma1, gamma1_12k2, gamma2, A, Aq, &st->speech[i_subfr], st->mem_err, st->mem_w0, st->zero, st->ai_zero, &st->exc[i_subfr], st->h1, xn, res, st->error); /* re-build excitation sf 1 (changed if lag < L_SUBFR) */ Pred_lt_3or6(&st->exc[i_subfr], T0, T0_frac, L_SUBFR, 1, pOverflow); Convolve(&st->exc[i_subfr], st->h1, y1, L_SUBFR); subframePostProc(st->speech, *usedMode, i_subfr, gain_pit, gain_code, Aq, synth, xn, code, y1, y2, st->mem_syn, st->mem_err, st->mem_w0, st->exc, &st->sharp, pOverflow); } } A += MP1; /* interpolated LPC parameters for next subframe */ Aq += MP1; } oscl_memcpy(&st->old_exc[0], &st->old_exc[L_FRAME], (PIT_MAX + L_INTERPOL)*sizeof(Word16));the_end: /*--------------------------------------------------* * Update signal for next frame. * *--------------------------------------------------*/ oscl_memcpy(&st->old_wsp[0], &st->old_wsp[L_FRAME], PIT_MAX*sizeof(Word16)); oscl_memcpy(&st->old_speech[0], &st->old_speech[L_FRAME], (L_TOTAL - L_FRAME)*sizeof(Word16)); return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -