📄 g729ev_fec_decbfi.c
字号:
L_tmp = L_mac(L_tmp, hp_filt[2], pt_exc[2]); L_tmp = L_mac(L_tmp, hp_filt[3], pt_exc[3]); L_tmp = L_mac(L_tmp, hp_filt[4], pt_exc[4]); pt_exc++; exc[i] = add(exc[i], round(L_tmp)); move16();#if(WMOPS) move16();#endif } } ELSE { G729EV_G729_Copy(exc2 + G729EV_FEC_L_FIR_FER / 2, exc, G729EV_MAIN_L_FRAME2); /* For purely G729EV_FEC_UNVOICED, just G729EV_G729_copy the random part */ G729EV_G729_Copy(&exc[G729EV_MAIN_L_FRAME2 - G729EV_FEC_L_EXC_MEM], exc_mem, G729EV_FEC_L_EXC_MEM); /* Update old_exc */ } G729EV_G729_Copy(exc, exc2, G729EV_MAIN_L_FRAME2); /* Update exc2 */ /*------------------------------------------------------------* Speech synthesis *------------------------------------------------------------*/ p_Az = Aq; FOR(i_subfr = 0; i_subfr < G729EV_MAIN_L_FRAME2; i_subfr += G729EV_G729_L_SUBFR) { G729EV_G729_Syn_filt2(p_Az, &exc2[i_subfr], &synth[i_subfr], G729EV_G729_L_SUBFR, mem_syn2, 1); p_Az += (G729EV_G729_M + 1); } /*------------------------------------------------------------------* * estimate the pitch-synchronous speech energy per sample * * to be used when normal operation recovers * *------------------------------------------------------------------*/ tmp16 = G729EV_FEC_energy(last_good, synth, shr(add(tmp_Tc, G729EV_FEC_QPIT2), G729EV_FEC_SQPIT), Lenr_old, 1); IF(sub(last_good, G729EV_FEC_VOICED) < 0) { /* Convert energy to Q0 */ *Lenr_old = L_mls(*Lenr_old, 26214); tmp16 = add(tmp16, 6 + 1); *Lenr_old = L_shr_r(*Lenr_old, tmp16);#if(WMOPS) move32(); move32();#endif } return;}/*************************************************************************************//* G729EV_FEC_scale_syn : Smooth energy transition between lost frame and good frame *//* - Find energy at frame end *//* - Find energy at frame beginning *//* - smooth excitation energy over all the frame *//* - redo synthesis (if needed) *//*************************************************************************************/void G729EV_FEC_scale_syn(Word16 extrate, /* i: indicate decoded bit rate */ Word16 clas, /* i/o: frame classification */ const Word16 last_good, /* i: last good frame classification */ Word16 * synth, /* i/o: synthesized speech */ const Word16 * pitch, /* i: pitch values for each subframe */ Word32 Lenr_q, /* i: transmitted energy for current frame */ const Word16 prev_bfi, /* i: previous frame BFI */ Word16 Aq[], /* i/o: LP filter coefs (can be modified if BR) */ Word16 * old_enr_LP, /* i/o: LP filter E of last good G729EV_FEC_VOICED frame Q4 */ Word16 * mem_tmp, /* i/o: temporary synthesis memory */ Word16 * exc_tmp, /* i/o: temporary excitation */ Word32 Lenr_old, /* i : energy at the end of the last frame */ Word16 * old_exc, /* i/o: excitation buffer */ Word16 * mem_syn, /* i/o: synthesis memory */ Word16 bfi_cnt /* i : Number of bad frame */ ){ Word16 i, scale_flag; Word16 gain1, gain2, tmp, exp_enr, exp2, tmp2; Word32 Lenr1, Lenr2, L_tmp; Word16 enr_LP /*Q4 */ ; Word16 i_subfr, *p_Az; scale_flag = (Word16) 0; enr_LP = (Word16) 0; gain2 = (Word16) 0; gain1 = (Word16) 0;#if(WMOPS) move16(); move16(); move16(); move16(); move32();#endif if (Lenr_old == 0) { Lenr_old = (Word16) 1; } /*-----------------------------------------------------------------* * Find the synthesis filter impulse response on G729EV_FEC_VOICED *-----------------------------------------------------------------*/ IF(sub(clas, G729EV_FEC_V_TRANSITION) >= 0) { enr_LP = G729EV_FEC_enr_1_Az(Aq + 3 * (G729EV_G729_M + 1), G729EV_G729_L_SUBFR); /*Q4 */ }#if (WMOPS) test(); test();#endif IF(sub(prev_bfi, G729EV_FEC_GOOD_FRAME) != 0 /* previous frame erased */ && (sub(last_good, G729EV_FEC_SIN_ONSET) < 0 || sub(extrate, 40) > 0) /* Do not scale if onset and energy doesnt sent by the encoder */ ) { /*-----------------------------------------------------------------* * Find the energy at the end of the frame *-----------------------------------------------------------------*/#if(WMOPS) move32();#endif tmp = G729EV_FEC_energy(clas, synth, shr(add(pitch[3], G729EV_FEC_QPIT2), G729EV_FEC_SQPIT), &Lenr2, 1); IF(sub(clas, G729EV_FEC_VOICED) < 0) { /* Convert energy to Q0 */ Lenr2 = L_mls(Lenr2, 26214); tmp = add(tmp, 6 + 1); Lenr2 = L_shr_r(Lenr2, tmp); } IF(sub(extrate, 40) <= 0) /* < 16 kbps use the nergy estimation from the decoder */ { Lenr_q = Lenr2;#if(WMOPS) move32(); test();#endif IF((sub(last_good, G729EV_FEC_V_TRANSITION) >= 0) && (sub(clas, G729EV_FEC_V_TRANSITION) >= 0)) /* G729EV_FEC_VOICED-G729EV_FEC_VOICED recovery */ { IF(sub(enr_LP, *old_enr_LP) > 0) { /*enr_q /= enr_LP; */ /*enr_q *= *old_enr_LP; */ exp_enr = norm_l(Lenr_q); tmp = extract_h(L_shl(Lenr_q, exp_enr)); exp2 = norm_s(enr_LP); tmp2 = shl(enr_LP, exp2); exp_enr = sub(exp2, exp_enr); IF(sub(tmp, tmp2) > 0) { tmp = shr(tmp, 1); exp_enr = add(exp_enr, 1); } tmp = div_s(tmp, tmp2); /* L_enr_q *= *old_enr_LP; */ Lenr_q = L_shl(L_mult(tmp, *old_enr_LP), exp_enr); if (sub(bfi_cnt, 1) <= 0) { Lenr_q = L_shl(Lenr_q, 2); } } IF(sub(enr_LP, *old_enr_LP) < 0) { IF(L_sub(Lenr_q, L_shl(Lenr_old, 2)) > 0) /* Prevent energy to increase on G729EV_FEC_VOICED */ { /*enr_q = 4*enr_old; */ Lenr_q = L_shl(Lenr_old, 2); } } ELSE if (L_sub(Lenr_q, Lenr_old) > 0) { /*enr_q = enr_old; */ Lenr_q = Lenr_old;#if(WMOPS) move32();#endif } } } if (Lenr_q == 0) { Lenr_q = (Word32) 1;#if(WMOPS) move32();#endif } exp_enr = norm_l(Lenr_q); tmp = extract_h(L_shl(Lenr_q, exp_enr)); exp2 = norm_l(Lenr2); tmp2 = extract_h(L_shl(Lenr2, exp2)); exp2 = sub(exp_enr, exp2); /* Denormalize and substract */ IF(sub(tmp2, tmp) > 0) { tmp2 = shr(tmp2, 1); exp2 = add(exp2, 1); } tmp = div_s(tmp2, tmp); L_tmp = L_deposit_h(tmp); Isqrt_n(&L_tmp, &exp2); gain2 = round(L_shl(L_tmp, sub(exp2, 1))); /* in Q14 */ /*gain2 = (float)sqrt( enr_q / enr2 ); */ /*-----------------------------------------------------------------* * Clipping of the smoothing gain at the frame end *-----------------------------------------------------------------*/ IF((L_sub(Lenr_q, 1) <= 0)) /* Do not allow E increase if enr_q index==0 (lower end Q clipping) */ { if (sub(gain2, 16384) > 0) { gain2 = (Word16) 16384; /* Gain modification clipping */#if(WMOPS) move16();#endif } } ELSE { if (sub(gain2, 19661) > 0) { gain2 = (Word16) 19661; /* Gain modification clipping */#if(WMOPS) move16();#endif } } /*-----------------------------------------------------------------* * Find the energy at the beginning of the frame to ensure smooth * transition after erasure *-----------------------------------------------------------------*/ IF(sub(clas, G729EV_FEC_SIN_ONSET) == 0) /* slow increase */ { gain1 = mult_r(gain2, 16384); scale_flag = (Word16) 1;#if(WMOPS) move16(); move16();#endif } ELSE if (((sub(last_good, G729EV_FEC_V_TRANSITION) >= 0) && (sub(clas, G729EV_FEC_UNVOICED) == 0))) { gain1 = gain2; scale_flag = (Word16) 0;#if(WMOPS) move16(); move16();#endif } ELSE {#if(WMOPS) move32();#endif /* Find the energy at the end of the frame */ tmp = G729EV_FEC_energy(clas, synth, shr(add(pitch[0], G729EV_FEC_QPIT2), G729EV_FEC_SQPIT), &Lenr1, 0); IF(sub(clas, G729EV_FEC_VOICED) < 0) { /* Convert energy to Q0 */ Lenr1 = L_mls(Lenr1, 26214); tmp = add(tmp, 6 + 1); Lenr1 = L_shr_r(Lenr1, tmp); } /* gain1 = (float)sqrt( *L_enr_old / L_enr1 ); */ exp_enr = norm_l(Lenr_old); tmp = extract_h(L_shl(Lenr_old, exp_enr)); exp2 = norm_l(Lenr1); tmp2 = extract_h(L_shl(Lenr1, exp2)); exp2 = sub(exp_enr, exp2); /* Denormalize and substract */ IF(sub(tmp2, tmp) > 0) { tmp2 = shr(tmp2, 1); exp2 = add(exp2, 1); } tmp = div_s(tmp2, tmp); /* exp_enr = sub(exp2, exp_enr); */ L_tmp = L_deposit_h(tmp); Isqrt_n(&L_tmp, &exp2); gain1 = round(L_shl(L_tmp, sub(exp2, 1))); /* in Q14 */#if(WMOPS) move32(); move16(); move16();#endif if (sub(gain1, 19661) > 0) { /*gain1 = 1.2f; */ gain1 = (Word16) 19661; /* Gain modification clipping */#if(WMOPS) move16(); test();#endif } IF((sub(clas, G729EV_FEC_ONSET) == 0) && (sub(gain1, gain2) > 0)) /* Prevent a catastrophy in case of offset followed by G729EV_FEC_ONSET */ {#if(WMOPS) move16();#endif gain1 = gain2; } scale_flag = (Word16) 1; } } /*-----------------------------------------------------------------* * Smooth the energy evolution by exponentially evolving from * gain1 to gain2 *-----------------------------------------------------------------*/ IF(scale_flag != 0) { /*gain2 *= ( 1.0f - G729EV_FEC_AGC ); */ gain2 = mult_r(gain2, (Word16) (32768 - G729EV_FEC_AGC)); FOR(i = 0; i < G729EV_MAIN_L_FRAME2; i++) { /*gain1 = gain1 * G729EV_FEC_AGC + gain2; */ gain1 = mac_r(L_shl(gain2, 16), gain1, G729EV_FEC_AGC); /* in Q14 */ /*exc_tmp[i] *= gain1; */ exc_tmp[i] = round(L_shl(L_mult(exc_tmp[i], gain1), 1));#if(WMOPS) move16();#endif } /* Update excitation memory with new excitation */ G729EV_G729_Copy(&exc_tmp[G729EV_MAIN_L_FRAME2 - (G729EV_G729_PIT_MAX + G729EV_G729_L_INTERPOL)], old_exc, G729EV_G729_PIT_MAX + G729EV_G729_L_INTERPOL); } /*-----------------------------------------------------------------* * Update the LP filter energy for G729EV_FEC_VOICED frames *-----------------------------------------------------------------*/ if (sub(clas, G729EV_FEC_V_TRANSITION) >= 0) { *old_enr_LP = enr_LP; /* Update */#if(WMOPS) move16();#endif } /*-----------------------------------------------------------------* * smoothing is done in excitation domain, so redo synthesis *-----------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -