📄 g729ev_fec_onset.c
字号:
/* ITU-T G.729EV Optimization/Characterization Candidate *//* Version: 1.0.a *//* Revision Date: June 28, 2006 *//* ITU-T G.729EV Optimization/Characterization Candidate ANSI-C Source Code Copyright (c) 2006 France Telecom, Matsushita Electric, Mindspeed, Siemens AG, ETRI, VoiceAge Corp. All rights reserved*/#include "G729EV_MAIN_defines.h"#include "G729EV_G729_defines.h"#include "G729EV_FEC_fer.h"#include "G729EV_FEC_tools.h"#include "G729EV_G729_ld8k.h"#include "stl.h"#include "G729EV_MAIN_OPER_32B.h"#include "G729EV_MAIN_DSPFUNC.h"/************************************************************************************//* G729EV_FEC_mod_adapt_codebook : Artificial reconstruction of the adaptive *//* codebook memory after the lost of an ONSET *//* - Decode location and sign of the last pulse *//* - Reset adaptive codebook memory *//* - Find LP filter impulse response energy *//* - Scale pulse "prototype" energy *//* - Place pulse "prototype" at the right position in the adaptive codebooke memory *//* - Update adaptive codebook memory *//* - Find signal classification *//************************************************************************************/void G729EV_FEC_mod_adapt_codebook(Word16 * exc, /* i/o : exc vector to modify */ Word16 puls_pos, /* i : Last pulse position desired */ Word16 * pitch_buf, /* i : containt pitch modified in function of bfi_pitch and new pitch Q6 */ Word32 enr_q, /* i : energy provide by the encoder Q0 */ Word16 * Aq /* i : Lsp coefficient */ ){ Word16 T0, P0, onset_len, sign, i, len; Word16 h1[G729EV_G729_L_SUBFR], mem[G729EV_G729_M], exc_tmp[G729EV_FEC_L_MEM]; Word16 *pt_end, *pt_exc, enr_LP, gain, H_low_s[5], exp_gain, exp2, tmp; Word32 L_tmp; Word16 Q_exc; sign = 0; Q_exc = 0;#if(WMOPS) move16(); move16(); move16();#endif T0 = shr(pitch_buf[3], G729EV_FEC_SQPIT); IF(sub(T0, 2 * G729EV_G729_L_SUBFR) < 0) { onset_len = 2 * G729EV_G729_L_SUBFR; } ELSE { onset_len = T0; }#if(WMOPS) move16();#endif P0 = puls_pos; IF(P0 < 0) {#if(WMOPS) move16();#endif sign = (Word16) 1; P0 = negate(P0); } IF(sub(T0, 128) >= 0) { P0 = shl(P0, 2); P0 = add(P0, 2); } ELSE if (sub(T0, 64) >= 0) { P0 = shl(P0, 1); P0 = add(P0, 1); } if (sub(P0, 160) > 0) { P0 = 160; /* Should never be the case, however... */#if(WMOPS) move16();#endif } G729EV_G729_Set_zero(exc_tmp, G729EV_FEC_L_MEM); /* Reset excitation vector */ /*------------------------------------------------------------------------------------------* * Find LP filter impulse response energy *------------------------------------------------------------------------------------------*/ G729EV_G729_Set_zero(h1, G729EV_G729_L_SUBFR); /* Find the impulse response */ G729EV_G729_Set_zero(mem, G729EV_G729_M); h1[0] = 1024;#if(WMOPS) move16();#endif G729EV_G729_Syn_filt(Aq, h1, h1, G729EV_G729_L_SUBFR, mem, 0); enr_LP = extract_h(G729EV_Dot_product12(h1, h1, G729EV_G729_L_SUBFR, &exp_gain)); exp_gain = sub(exp_gain, 10 + 10); /* h1 in Q10 */ /* divide by LP filter E, scaled by transmitted E */ /* gain = (float)sqrt( enr_q / enr_LP ); */ if (enr_q == 0) { enr_q = 1L;#if(WMOPS) move32();#endif } exp2 = norm_l(enr_q); tmp = extract_h(L_shl(enr_q, exp2)); tmp = mult(tmp, 24576); /* multpiply by 1.5 */ IF(sub(tmp, 16384) < 0) { exp2 = add(exp2, 1); tmp = shl(tmp, 1); } exp2 = sub(exp2, 1); exp2 = sub(31, exp2); /* in Q15 */ IF(sub(enr_LP, tmp) > 0) { enr_LP = shr(enr_LP, 1); exp_gain = add(exp_gain, 1); } tmp = div_s(enr_LP, tmp); exp2 = sub(exp_gain, exp2); L_tmp = L_deposit_h(tmp); Isqrt_n(&L_tmp, &exp2); gain = round(L_tmp); gain = mult_r(gain, 31457); /* multiply by .96 like floating point */ exp2 = add(sub(exp2, 15), Q_exc); /* from Q15 to Q_exc */ /* Find if rescaling needed */ tmp = extract_h(L_mult(G729EV_FEC_h_low[2], gain)); exp_gain = norm_s(tmp); tmp = sub(exp_gain, exp2); /* difference */ IF(tmp < 0) /* Need to correct scaling */ { Q_exc = add(Q_exc, tmp); exp2 = add(exp2, tmp); } /* Scale pulse "prototype" energy */ /* Generate the scaled pulse */ FOR(i = 0; i < G729EV_FEC_L_FIR_FER; i++) { L_tmp = L_mult(gain, G729EV_FEC_h_low[i]); /* Q_exc*Q15 -> Q_exc */ H_low_s[i] = round(L_shl(L_tmp, exp2));#if(WMOPS) move16();#endif } /*------------------------------------------------------------------------------------------* * Place pulse "prototype" at the right position in the adaptive codebooke memory *------------------------------------------------------------------------------------------*/#if(WMOPS) move16();#endif pt_exc = exc_tmp + sub(G729EV_MAIN_L_FRAME2, add(add(1, G729EV_FEC_L_FIR_FER / 2), P0)); /* beginning of the 1st pulse */ pt_end = exc_tmp + onset_len; len = pt_exc - pt_end; if (sub(len, G729EV_FEC_L_FIR_FER) > 0) { len = G729EV_FEC_L_FIR_FER;#if(WMOPS) move16();#endif } IF(!sign) { FOR(i = 0; i < len; i++) { /* The filter response would have E=1 in full band. */ pt_exc[i] = add(pt_exc[i], H_low_s[i]);#if(WMOPS) move16();#endif } } ELSE { FOR(i = 0; i < len; i++) { /* The filter response would have E=1 in full band. */ pt_exc[i] = sub(pt_exc[i], H_low_s[i]);#if(WMOPS) move16();#endif } } G729EV_G729_Copy(&exc_tmp[G729EV_MAIN_L_FRAME2 - G729EV_G729_PIT_MAX - G729EV_G729_L_INTERPOL], exc, G729EV_G729_PIT_MAX + G729EV_G729_L_INTERPOL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -