📄 g729ev_g729_pst.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*//************************************************************************//* Post - filtering : short term + long term *//************************************************************************/#include "stl.h"#include "G729EV_G729_ld8k.h"#include "G729EV_MAIN_OPER_32B.h"/*---------------------------------------------------------------------------- * G729EV_G729_pst_ltp - harmonic postfilter *---------------------------------------------------------------------------- */void G729EV_G729_pst_ltp(Word16 t0, /* input : pitch delay given by coder */ Word16 * ptr_sig_in, /* input : postfilter input filter (residu2) */ Word16 * ptr_sig_pst0 /* output: harmonic postfilter output */ ){/**** Declare variables */ Word32 L_temp; Word16 y_up[G729EV_G729_SIZ_Y_UP]; Word16 sig_cadr[G729EV_G729_SIZ_RES2]; Word16 *ptr_y_up; Word16 *ptr_sig; Word16 *ptr_sig_cadr; Word16 i; Word16 temp; Word16 ltpdel, phase; Word16 num_gltp, den_gltp; Word16 num2_gltp, den2_gltp; Word16 sh_num, sh_den; Word16 sh_num2, sh_den2; Word16 gain_plt; Word16 off_yup; Word16 nb_sh_sig; /* input signal justified on 13 bits */#if (WMOPS) move16();#endif ptr_sig = ptr_sig_in - G729EV_G729_MEM_RES2; temp = 0; FOR(i = 0; i < G729EV_G729_SIZ_RES2; i++) { temp = s_or(temp, abs_s(ptr_sig[i])); } nb_sh_sig = sub(3, norm_s(temp)); FOR(i = 0; i < G729EV_G729_SIZ_RES2; i++) { /* nb_sh_sig may be >0, <0 or =0 */#if (WMOPS) move16();#endif sig_cadr[i] = shr(ptr_sig[i], nb_sh_sig); } ptr_sig_cadr = sig_cadr + G729EV_G729_MEM_RES2; /* Sub optimal delay search */ G729EV_G729_search_del(t0, ptr_sig_cadr, <pdel, &phase, &num_gltp, &den_gltp, &sh_num, &sh_den, y_up, &off_yup); IF(num_gltp == 0) { G729EV_G729_Copy(ptr_sig_in, ptr_sig_pst0, G729EV_G729_L_SUBFR); } ELSE { IF(phase == 0) { ptr_y_up = ptr_sig_in - ltpdel; } ELSE { /* Filtering with long filter */ G729EV_G729_compute_ltp_l(ptr_sig_cadr, ltpdel, phase, ptr_sig_pst0, &num2_gltp, &den2_gltp, &sh_num2, &sh_den2); IF(sub(G729EV_G729_select_ltp(num_gltp, den_gltp, sh_num, sh_den, num2_gltp, den2_gltp, sh_num2, sh_den2), 1) == 0) { /* select short filter */ temp = sub(phase, 1); L_temp = L_mult(temp, G729EV_G729_L_SUBFRP1); L_temp = L_shr(L_temp, 1); temp = extract_l(L_temp); temp = add(temp, off_yup); /* ptr_y_up = y_up + (phase-1) * G729EV_G729_L_SUBFRP1 + off_yup */ ptr_y_up = y_up + temp; } ELSE {#if (WMOPS) move16(); move16(); move16(); move16();#endif /* select long filter */ num_gltp = num2_gltp; den_gltp = den2_gltp; sh_num = sh_num2; sh_den = sh_den2; ptr_y_up = ptr_sig_pst0; } /* rescale y_up */ FOR(i = 0; i < G729EV_G729_L_SUBFR; i++) { /* nb_sh_sig may be >0, <0 or =0 */#if (WMOPS) move16();#endif ptr_y_up[i] = shl(ptr_y_up[i], nb_sh_sig); } } temp = sub(sh_num, sh_den); IF(temp >= 0) { den_gltp = shr(den_gltp, temp); } ELSE { num_gltp = shl(num_gltp, temp); /* >> (-temp) */ } IF(sub(num_gltp, den_gltp) >= 0) {#if (WMOPS) move16();#endif /* beta bounded to 1 */ gain_plt = G729EV_G729_MIN_GPLT; } ELSE { /* GAMMA_G = 0.5 */ /* gain_plt = den_gltp x 2**15 / (den_gltp + 0.5 num_gltp) */ /* shift 1 bit to avoid overflows in add */ num_gltp = shr(num_gltp, 2); den_gltp = shr(den_gltp, 1); temp = add(den_gltp, num_gltp); gain_plt = div_s(den_gltp, temp); /* Q15 */ } /** filtering by H0(z) = harmonic filter **/ G729EV_G729_filt_plt(ptr_sig_in, ptr_y_up, ptr_sig_pst0, gain_plt); } return;}/*---------------------------------------------------------------------------- * search_del: computes best (shortest) integer LTP delay + fine search *---------------------------------------------------------------------------- */void G729EV_G729_search_del(Word16 t0, /* input : pitch delay given by coder */ Word16 * ptr_sig_in, /* input : input signal (with delay line) */ Word16 * ltpdel, /* output: delay = *ltpdel - *phase / f_up */ Word16 * phase, /* output: phase */ Word16 * num_gltp, /* output: 16 bits numerator of LTP gain */ Word16 * den_gltp, /* output: 16 bits denominator of LTP gain */ Word16 * sh_num_gltp, /* output: justification for num_gltp */ Word16 * sh_den_gltp, /* output: justification for den_gltp */ Word16 * y_up, /* output: LT delayed signal if fract. delay */ Word16 * off_yup /* output: offset in y_up */ ){ Word32 L_den0[G729EV_G729_F_UP_PST - 1]; Word32 L_den1[G729EV_G729_F_UP_PST - 1]; Word32 *ptr_L_den0, *ptr_L_den1; Word32 L_num_int, L_den_int, L_den_max; Word32 L_temp0, L_temp1; Word32 L_acc; Word32 L_temp; extern Word16 tab_hup_s[G729EV_G729_SIZ_TAB_HUP_S]; Word16 *ptr_h; Word16 *ptr_sig_past, *ptr_sig_past0; Word16 *ptr1, *ptr_y_up; Word16 i, n; Word16 num, den0, den1; Word16 den_max, num_max; Word16 hi_numsq, hi_numsq_max; Word16 lo_numsq, lo_numsq_max; Word16 ener; Word16 sh_num, sh_den, sh_ener; Word16 i_max, lambda, phi, phi_max, ioff; Word16 temp; /*************************************/ /* Computes energy of current signal */ /*************************************/#if (WMOPS) move32();#endif L_acc = 0L; FOR(i = 0; i < G729EV_G729_L_SUBFR; i++) { L_acc = L_mac(L_acc, ptr_sig_in[i], ptr_sig_in[i]); } if (L_acc == 0) {#if (WMOPS) move16(); move16(); move16(); move16();#endif *num_gltp = 0; *den_gltp = 1; *ltpdel = 0; *phase = 0; return; } sh_ener = sub(16, norm_l(L_acc)); /* save energy for final decision */ IF(sh_ener > 0) { ener = extract_l(L_shr(L_acc, sh_ener)); } ELSE {#if (WMOPS) move16();#endif sh_ener = 0; ener = extract_l(L_acc); } /*************************************/ /* Selects best of 3 integer delays */ /* Maximum of 3 numerators around t0 */ /*************************************/#if (WMOPS) move16(); move32();#endif lambda = sub(t0, 1); ptr_sig_past = ptr_sig_in - lambda; L_num_int = -1L; /* initialization used only to suppress Microsoft Visual C++ warnings */#if (WMOPS) move16();#endif i_max = (Word16) 0; FOR(i = 0; i < 3; i++) {#if (WMOPS) move32();#endif L_acc = 0L; FOR(n = 0; n < G729EV_G729_L_SUBFR; n++) { L_acc = L_mac(L_acc, ptr_sig_in[n], ptr_sig_past[n]); } if (L_acc < 0) {#if (WMOPS) move32();#endif L_acc = 0L; } L_temp = L_sub(L_acc, L_num_int); if (L_temp > 0L) {#if (WMOPS) move16(); move32();#endif L_num_int = L_acc; i_max = (Word16) i; } ptr_sig_past--; } if (L_num_int == 0) {#if (WMOPS) move16(); move16(); move16(); move16();#endif *num_gltp = 0; *den_gltp = 1; *ltpdel = 0; *phase = 0; return; } /* Compute den for i_max */ lambda = add(lambda, (Word16) i_max);#if (WMOPS) move32();#endif ptr_sig_past = ptr_sig_in - lambda; L_acc = 0L; FOR(i = 0; i < G729EV_G729_L_SUBFR; i++) {#if (WMOPS) move16();#endif temp = *ptr_sig_past++; L_acc = L_mac(L_acc, temp, temp); } if (L_acc == 0L) {#if (WMOPS) move16(); move16(); move16(); move16();#endif *num_gltp = 0; *den_gltp = 1; *ltpdel = 0; *phase = 0; return; }#if (WMOPS) move32();#endif L_den_int = L_acc; /***********************************/ /* Select best phase around lambda */ /***********************************/ /* Compute y_up & denominators */ /*******************************/#if (WMOPS) move32();#endif ptr_y_up = y_up; L_den_max = L_den_int; ptr_L_den0 = L_den0; ptr_L_den1 = L_den1; ptr_h = tab_hup_s; temp = sub(lambda, G729EV_G729_LH_UP_SM1); ptr_sig_past0 = ptr_sig_in - temp; /* Loop on phase */ FOR(phi = 1; phi < G729EV_G729_F_UP_PST; phi++) { /* Compute y_up for lambda+1 - phi/F_UP_PST */ /* and lambda - phi/F_UP_PST */ ptr_sig_past = ptr_sig_past0; FOR(n = 0; n <= G729EV_G729_L_SUBFR; n++) {#if (WMOPS) move16(); move32();#endif ptr1 = ptr_sig_past++; L_acc = 0L; FOR(i = 0; i < G729EV_G729_LH2_S; i++) { L_acc = L_mac(L_acc, ptr_h[i], ptr1[-i]); }#if (WMOPS) move16();#endif ptr_y_up[n] = round(L_acc); } /* compute den0 (lambda+1) and den1 (lambda) */ /* part common to den0 and den1 */#if (WMOPS) move32();#endif L_acc = 0L; FOR(n = 1; n < G729EV_G729_L_SUBFR; n++) { L_acc = L_mac(L_acc, ptr_y_up[n], ptr_y_up[n]); }#if (WMOPS) move32();#endif L_temp0 = L_acc; /* saved for den1 */ /* den0 */ L_acc = L_mac(L_acc, ptr_y_up[0], ptr_y_up[0]);#if (WMOPS) move32();#endif *ptr_L_den0 = L_acc; /* den1 */ L_acc = L_mac(L_temp0, ptr_y_up[G729EV_G729_L_SUBFR], ptr_y_up[G729EV_G729_L_SUBFR]);#if (WMOPS) move32();#endif *ptr_L_den1 = L_acc; IF(sub(abs_s(ptr_y_up[0]), abs_s(ptr_y_up[G729EV_G729_L_SUBFR])) > 0) { L_temp = L_sub(*ptr_L_den0, L_den_max); if (L_temp > 0L) {#if (WMOPS) move32();#endif L_den_max = *ptr_L_den0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -