📄 g729ev_g729_pst.c
字号:
*---------------------------------------------------------------------------- */Word16 G729EV_G729_select_ltp( /* output : 1 = 1st gain, 2 = 2nd gain */ Word16 num1, /* input : numerator of gain1 */ Word16 den1, /* input : denominator of gain1 */ Word16 sh_num1, /* input : just. factor for num1 */ Word16 sh_den1, /* input : just. factor for den1 */ Word16 num2, /* input : numerator of gain2 */ Word16 den2, /* input : denominator of gain2 */ Word16 sh_num2, /* input : just. factor for num2 */ Word16 sh_den2) /* input : just. factor for den2 */{ Word32 L_temp1, L_temp2; Word32 L_temp; Word16 temp1, temp2; Word16 hi, lo; if (den2 == 0) { return (1); } /* compares criteria = num**2/den */ L_temp1 = L_mult(num1, num1); L_Extract(L_temp1, &hi, &lo); L_temp1 = Mpy_32_16(hi, lo, den2); L_temp2 = L_mult(num2, num2); L_Extract(L_temp2, &hi, &lo); L_temp2 = Mpy_32_16(hi, lo, den1); /* temp1 = sh_den2 + 2 * sh_num1 */ temp1 = shl(sh_num1, 1); temp1 = add(temp1, sh_den2); /* temp2 = sh_den1 + 2 * sh_num2; */ temp2 = shl(sh_num2, 1); temp2 = add(temp2, sh_den1); IF(sub(temp2, temp1) > 0) { temp2 = sub(temp2, temp1); L_temp1 = L_shr(L_temp1, temp2); /* temp2 > 0 */ } ELSE { IF(sub(temp1, temp2) > 0) { temp1 = sub(temp1, temp2); L_temp2 = L_shr(L_temp2, temp1); /* temp1 > 0 */ } } L_temp = L_sub(L_temp2, L_temp1); IF(L_temp > 0L) { return (2); } ELSE { return (1); }}/*---------------------------------------------------------------------------- * G729EV_G729_calc_st_filt - computes impulse response of A(gamma2) / A(gamma1) * controls gain : computation of energy impulse response as * SUMn (abs (h[n])) and computes parcor0 *---------------------------------------------------------------------------- */void G729EV_G729_calc_st_filt(Word16 * apond2, /* input : coefficients of numerator */ Word16 * apond1, /* input : coefficients of denominator */ Word16 * parcor0, /* output: 1st parcor calcul. on composed filter */ Word16 * sig_ltp_ptr, /* in/out: input of 1/A(gamma1) : scaled by 1/g0 */ Word16 * mem_zero){ Word32 L_temp, L_g0; Word16 h[G729EV_G729_LONG_H_ST]; Word16 g0, temp; Word16 i; /* compute i.r. of composed filter apond2 / apond1 */ G729EV_G729_Syn_filt(apond1, apond2, h, G729EV_G729_LONG_H_ST, mem_zero, 0); /* compute 1st parcor */ G729EV_G729_calc_rc0_h(h, parcor0); /* compute g0 */#if (WMOPS) move32();#endif L_g0 = 0L; FOR(i = 0; i < G729EV_G729_LONG_H_ST; i++) { L_temp = L_deposit_l(abs_s(h[i])); L_g0 = L_add(L_g0, L_temp); } g0 = extract_h(L_shl(L_g0, 14)); /* Scale signal input of 1/A(gamma1) */ IF(sub(g0, 1024) > 0) { temp = div_s(1024, g0); /* temp = 2**15 / gain0 */ FOR(i = 0; i < G729EV_G729_L_SUBFR; i++) {#if (WMOPS) move16();#endif sig_ltp_ptr[i] = mult_r(sig_ltp_ptr[i], temp); } } return;}/*---------------------------------------------------------------------------- * G729EV_G729_calc_rc0_h - computes 1st parcor from composed filter impulse response *---------------------------------------------------------------------------- */void G729EV_G729_calc_rc0_h(Word16 * h, /* input : impulse response of composed filter */ Word16 * rc0 /* output: 1st parcor */ ){ Word32 L_acc; Word16 *ptrs; Word16 acf0, acf1; Word16 temp, sh_acf; Word16 i; /* computation of the autocorrelation function acf */#if (WMOPS) move32();#endif L_acc = 0L; FOR(i = 0; i < G729EV_G729_LONG_H_ST; i++) { L_acc = L_mac(L_acc, h[i], h[i]); } sh_acf = norm_l(L_acc); L_acc = L_shl(L_acc, sh_acf); acf0 = extract_h(L_acc);#if (WMOPS) move32();#endif L_acc = 0L; ptrs = h; FOR(i = 0; i < G729EV_G729_LONG_H_ST - 1; i++) {#if (WMOPS) move16();#endif temp = *ptrs++; L_acc = L_mac(L_acc, temp, *ptrs); } L_acc = L_shl(L_acc, sh_acf); acf1 = extract_h(L_acc); /* Compute 1st parcor */ /**********************/ if (sub(acf0, abs_s(acf1)) < 0) {#if (WMOPS) move16();#endif *rc0 = 0; return; }#if (WMOPS) move16();#endif *rc0 = div_s(abs_s(acf1), acf0); if (acf1 > 0) { *rc0 = negate(*rc0);#if (WMOPS) move16();#endif } return;}/*---------------------------------------------------------------------------- * G729EV_G729_filt_mu - tilt filtering with : (1 + mu z-1) * (1/1-|mu|) * computes y[n] = (1/1-|mu|) (x[n]+mu*x[n-1]) *---------------------------------------------------------------------------- */extern Word16 saturate(Word32 L_var1);void G729EV_G729_filt_mu(Word16 * sig_in, /* input : input signal (beginning at sample -1) */ Word16 * sig_out, /* output: output signal */ Word16 parcor0 /* input : parcor0 (mu = parcor0 * gamma3) */ ){ Word32 L_acc, L_temp, L_fact; Word16 *ptrs; Word16 n; Word16 mu, mu2, ga, temp; Word16 fact, sh_fact; Word16 temp_hi, temp_lo;#if (WMOPS) move16(); move16(); move32();#endif IF(parcor0 > 0) { mu = mult_r(parcor0, G729EV_G729_GAMMA3_PLUS); /* G729EV_G729_GAMMA3_PLUS < 0.5 */ sh_fact = 14; /* sh_fact */ fact = (Word16) 0x4000; /* 2**sh_fact */ L_fact = (Word32) 0x00002000L; /* fact >> 1 */ } ELSE { mu = mult_r(parcor0, G729EV_G729_GAMMA3_MINUS); /* G729EV_G729_GAMMA3_MINUS < 0.9375 */ sh_fact = 11; /* sh_fact */ fact = (Word16) 0x0800; /* 2**sh_fact */ L_fact = (Word32) 0x00000400L; /* fact >> 1 */ } temp = sub(1, abs_s(mu)); mu2 = add(32767, temp); /* 2**15 (1 - |mu|) */ ga = div_s(fact, mu2); /* 2**sh_fact / (1 - |mu|) */ ptrs = sig_in; /* points on sig_in(-1) */ FOR(n = 0; n < G729EV_G729_L_SUBFR; n++) {#if (WMOPS) move16();#endif temp = *ptrs++; L_temp = L_deposit_l(*ptrs); L_acc = L_shl(L_temp, 15); /* sig_in(n) * 2**15 */ L_temp = L_mac0(L_acc, mu, temp); L_Extract(L_temp, &temp_hi, &temp_lo); L_temp = L_add(Mpy_32_16(temp_hi, temp_lo, ga), L_fact); L_temp = L_shr(L_temp, sh_fact); /* mult. temp x ga */#if (WMOPS) move16();#endif sig_out[n] = saturate(L_temp); } return;}/*---------------------------------------------------------------------------- * G729EV_G729_scale_st - control of the subframe gain * gain[n] = G729EV_G729_AGC_FAC * gain[n-1] + (1 - AGC_FAC) g_in/g_out *---------------------------------------------------------------------------- */void G729EV_G729_scale_st(Word16 * sig_in, /* input : postfilter input signal */ Word16 * sig_out, /* in/out: postfilter output signal */ Word16 * gain_prec, /* in/out: last value of gain for subframe */ Word16 parcor0, Word16 PostNB, Word32 * Level_in_sm){ Word32 L_acc, L_temp; Word16 i; Word16 scal_in, scal_out; Word16 s_g_in, s_g_out, temp, sh_g0, g0; Word16 gain = 0; Word16 Cond; /* compute input gain */#if (WMOPS) move32();#endif L_acc = 0L; FOR(i = 0; i < G729EV_G729_L_SUBFR; i++) { L_temp = L_abs(L_deposit_l(sig_in[i])); L_acc = L_add(L_acc, L_temp); } /* Smooth level */#if (WMOPS) move32(); move32();#endif *Level_in_sm = L_add(L_shr(*Level_in_sm, 1), L_shr(*Level_in_sm, 2)); *Level_in_sm = L_add(*Level_in_sm, L_shr(L_acc, 2));#if (WMOPS) test(); test(); test();#endif /* Detect silence */ Cond = (L_sub(*Level_in_sm, 1024) < 0) && (L_sub(L_acc, L_shl(*Level_in_sm, 1)) < 0) && (sub(parcor0, 512) < 0); /* If silence is detected, replace the original level with smoothed level */ if (sub(Cond, 1) == 0) {#if (WMOPS) move32();#endif L_acc = *Level_in_sm; } IF(L_acc == 0L) {#if (WMOPS) move16();#endif g0 = 0; } ELSE { scal_in = norm_l(L_acc); L_acc = L_shl(L_acc, scal_in); s_g_in = extract_h(L_acc); /* normalized */ /* Compute output gain */#if (WMOPS) move32();#endif L_acc = 0L; FOR(i = 0; i < G729EV_G729_L_SUBFR; i++) { L_temp = L_abs(L_deposit_l(sig_out[i])); L_acc = L_add(L_acc, L_temp); } if (L_acc == 0L) {#if (WMOPS) move16();#endif *gain_prec = 0; return; } scal_out = norm_l(L_acc); L_acc = L_shl(L_acc, scal_out); s_g_out = extract_h(L_acc); /* normalized */ sh_g0 = add(scal_in, 1); sh_g0 = sub(sh_g0, scal_out); /* scal_in - scal_out + 1 */ IF(sub(s_g_in, s_g_out) < 0) { g0 = div_s(s_g_in, s_g_out); /* s_g_in/s_g_out in Q15 */ } ELSE { temp = sub(s_g_in, s_g_out); /* sufficient since normalized */ g0 = shr(div_s(temp, s_g_out), 1); g0 = add(g0, (Word16) 0x4000); /* s_g_in/s_g_out in Q14 */ sh_g0 = sub(sh_g0, 1); } /* L_gain_in/L_gain_out in Q14 */ /* overflows if L_gain_in > 2 * L_gain_out */ g0 = shr(g0, sh_g0); /* sh_g0 may be >0, <0, or =0 */ IF(sub(Cond, 1) == 0) { /* Apply a gain reduction for silence; the gain is defined as gain = (Level_in_sm/MAX_SILENCE_LEVEL)*k1 + (1-k1); k1 (0=<k1<=1) is a function of PARCOR0 */ /* k1 in Q15 */ temp = sub(512, parcor0); if (L_sub(temp, 2047) > 0) {#if (WMOPS) move16();#endif temp = 2047; } temp = shl(temp, 4); /* gain = (Level_in_sm/MAX_SILENCE_LEVEL) in Q15 */ IF(L_sub(*Level_in_sm, 1023) > 0) {#if (WMOPS) move16();#endif gain = 1023; } ELSE { gain = extract_l(*Level_in_sm); } gain = shl(gain, 5); /* gain = gain*k1 + 1-k1 */ gain = mult_r(gain, temp); gain = add(gain, sub(32767, temp)); gain = mult_r(gain, sub(32767, PostNB)); gain = add(gain, PostNB); g0 = mult_r(g0, gain); } g0 = mult_r(g0, G729EV_G729_AGC_FAC1); /* L_gain_in/L_gain_out * AGC_FAC1 */ } /* gain(n) = G729EV_G729_AGC_FAC gain(n-1) + G729EV_G729_AGC_FAC1 gain_in/gain_out */ /* sig_out(n) = gain(n) sig_out(n) */#if (WMOPS) move16();#endif gain = *gain_prec; FOR(i = 0; i < G729EV_G729_L_SUBFR; i++) { temp = mult_r(G729EV_G729_AGC_FAC, gain); gain = add(temp, g0); /* in Q14 */ L_temp = L_mult(gain, sig_out[i]); L_temp = L_shl(L_temp, 1);#if (WMOPS) move16();#endif sig_out[i] = round(L_temp); }#if (WMOPS) move16();#endif *gain_prec = gain; return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -