📄 g729ev_main_filt.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 <stdlib.h>#include "stl.h"#include "G729EV_G729_defines.h"#include "G729EV_G729_ld8k.h"#include "G729EV_MAIN_defines.h"#include "G729EV_MAIN_filt.h"#include "G729EV_MAIN_decod.h"#include "G729EV_MAIN_OPER_32B.h"/*--------------------------------------------------------------------------* * Function G729EV_MAIN_set_gamma() * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Set adaptive gamma parameters of lower-band postfilter * *--------------------------------------------------------------------------*/void G729EV_MAIN_set_gamma(Word16 * output_lo, /* (i) lower-band synthesis prior to postfiltering */ Word16 * tab_Th, /* (i/o) median filter memory */ Word16 rate, /* (i) decoder bit rate */ Word16 * ga1_post, /* (o) gamma parameter */ Word16 * ga2_post /* (o) gamma parameter */ ){ /* Variables declarations */ Word32 L_temp; Word16 i, j; Word16 Th; /* set gammas */ IF(sub(rate, 14000) >= 0) /* >= 14 kbit/s */ { *ga1_post = G729EV_G729_GAMMA1_PST12K; *ga2_post = G729EV_G729_GAMMA2_PST12K;#if(WMOPS) move16(); move16();#endif } ELSE { IF(sub(rate, 12000) == 0) /* == 12 kbit/s */ { /* compute frame energy */ L_temp = (Word32) 0;#if(WMOPS) move32();#endif FOR(i = 0; i < G729EV_MAIN_L_FRAME2; i++) { L_temp = L_mac(L_temp, output_lo[i], output_lo[i]); } /* compute Th */ L_temp = L_shl(L_temp, 16); Th = extract_h(L_temp); /* smooth Th */ j = sub(G729EV_MAIN_NMAX, 1); FOR(i = 0; i < j; i++) { tab_Th[i] = tab_Th[i + 1];#if(WMOPS) move16();#endif } tab_Th[j] = Th;#if(WMOPS) move16();#endif Th = G729EV_MAIN_gmed_n(tab_Th, G729EV_MAIN_NMAX); /* set gamma = Th * gamma_12k + (1-Th)*gamma_8k */ L_temp = L_mult(Th, G729EV_G729_GAMMA1_PST12K); L_temp = L_mac(L_temp, sub(MAX_16, Th), G729EV_G729_GAMMA1_PST); *ga1_post = round(L_temp); L_temp = L_mult(Th, G729EV_G729_GAMMA2_PST12K); L_temp = L_mac(L_temp, sub(MAX_16, Th), G729EV_G729_GAMMA2_PST); *ga2_post = round(L_temp); } ELSE /* == 8 kbit/s */ { /* at 8 kbit/s use gammas from G729 */ *ga1_post = G729EV_G729_GAMMA1_PST; *ga2_post = G729EV_G729_GAMMA2_PST;#if(WMOPS) move16(); move16();#endif } }}/*--------------------------------------------------------------------------* * Function G729EV_MAIN_gmed_n() * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Median filter for sequence of odd length * *--------------------------------------------------------------------------*//* */Word16 G729EV_MAIN_gmed_n( /* (o) median value */ Word16 ind[], /* (i) Current and past values */ Word16 n /* (i) number of values (valid for an odd number of gains <= G729EV_MAIN_NMAX) */ ){ Word16 tmp[G729EV_MAIN_NMAX]; Word16 tmp2[G729EV_MAIN_NMAX]; Word16 i, j, ix; Word16 max; Word16 medianIndex; ix = (Word16) 0;#if(WMOPS) move16();#endif FOR(i = 0; i < n; i++) { tmp2[i] = ind[i];#if(WMOPS) move16();#endif } FOR(i = 0; i < n; i++) { max = (Word16) - 1;#if(WMOPS) move16();#endif FOR(j = 0; j < n; j++) { if (sub(tmp2[j], max) >= 0) { max = tmp2[j]; ix = j;#if(WMOPS) move16(); move16();#endif } } tmp2[ix] = (Word16) - 1; tmp[i] = ix;#if(WMOPS) move16(); move16();#endif } medianIndex = tmp[shr(n, 1)]; /* account for complex addressing */#if(WMOPS) move16();#endif return (ind[medianIndex]);}/*--------------------------------------------------------------------------* * Function G729EV_MAIN_weighting_filter() * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Weighting filter of lower-band difference signal including an adaptive * * gain compensation * *--------------------------------------------------------------------------*/void G729EV_MAIN_weighting_filter(Word16 * Az, /* (i) LPC coefficients from CELP local decoder */ Word16 * mem_Wz_in, /* (i) memory of input */ Word16 * mem_wsp, /* (i) memory of output */ Word16 * diff /* (i/o) difference signal before and after weighting */ ){ Word32 L_temp, L_num, L_den; Word16 wsp[G729EV_MAIN_L_FRAME2]; Word16 Ap1[G729EV_G729_MP1]; Word16 Ap2[G729EV_G729_MP1]; Word16 Wz_in_buffer[G729EV_MAIN_L_FRAME2 + G729EV_G729_M]; Word16 *Wz_in; Word16 *ptr_Az; Word16 i_subfr, i, j, end_loop; Word16 fac; Word16 e_den, frac_den, e_num, frac_num, e_fac; /* set buffer for W(z) */ Wz_in = Wz_in_buffer + G729EV_G729_M;#if(WMOPS) move16();#endif G729EV_G729_Copy(mem_Wz_in, &Wz_in[-G729EV_G729_M], G729EV_G729_M); G729EV_G729_Copy(diff, Wz_in, G729EV_MAIN_L_FRAME2); G729EV_G729_Copy(&diff[(G729EV_MAIN_L_FRAME2) - G729EV_G729_M], mem_Wz_in, G729EV_G729_M); /* apply W(z)= fac*A(z/gamma1)/A(z/gamma2) */ ptr_Az = Az; i_subfr = (Word16) 0;#if(WMOPS) move16(); move16();#endif FOR(i = 0; i < 4; i++) { /* weight A(z) */ G729EV_G729_Weight_Az(ptr_Az, G729EV_MAIN_GAMMA1, G729EV_G729_M, Ap1); G729EV_G729_Weight_Az(ptr_Az, G729EV_MAIN_GAMMA2, G729EV_G729_M, Ap2); /* compute gain */ L_den = L_deposit_h(shr(Ap1[0], 1)); /* (Word32)Q12>>1 -> Q27 = 1^27 */ L_num = L_deposit_h(shr(Ap2[0], 1)); /* (Word32)Q12>>1 -> Q27 = 1^27 */ fac = (Word16) - 16384; /* Q13 */#if(WMOPS) move16();#endif FOR(j = 1; j <= G729EV_G729_M; j++) { /* Q12 x Q13<<1 -> Q26 */ L_den = L_mac(L_den, Ap1[j], fac); /* den += Ap1[j] << 14 */ L_num = L_mac(L_num, Ap2[j], fac); /* num += Ap2[j] << 14 */ fac = negate(fac); } /* decompose L_den into exponent (e_den) and fraction (frac_den) */ if (L_den < 0) { L_den = L_negate(L_den); /* force den > 0 (needed by div_s) */ } if (L_den == 0) { L_den = (Word32) 1;#if(WMOPS) move32();#endif } e_den = norm_l(L_den); frac_den = extract_h(L_shl(L_den, e_den)); /* decompose L_num into exponent (e_den) and fraction (frac_den) */ if (L_num < 0) { L_num = L_negate(L_num); } if (L_num == 0) { L_num = (Word32) 1;#if(WMOPS) move32();#endif } e_num = norm_l(L_num); frac_num = extract_h(L_shl(L_num, e_num)); /* compute fac = div_s(frac_num, frac_den) * exponent */ IF(sub(frac_num, frac_den) > 0) { frac_num = shr(frac_num, 1); e_num = sub(e_num, 1); } fac = div_s(frac_num, frac_den); e_fac = sub(e_num, e_den); e_fac = add(e_fac, 2); /* shift by 2 ---> Q13 */ fac = shr(fac, e_fac); /* Q13 */ /* filter by A(z/gamma) * 1/A(z/gamma2) */ G729EV_G729_Residu(Ap1, &Wz_in[i_subfr], &wsp[i_subfr], G729EV_G729_L_SUBFR); G729EV_G729_Syn_filt(Ap2, &wsp[i_subfr], &wsp[i_subfr], G729EV_G729_L_SUBFR, mem_wsp, 0); FOR(j = 0; j < G729EV_G729_M; j++) {#if(WMOPS) move16();#endif mem_wsp[j] = wsp[i_subfr + G729EV_G729_L_SUBFR - G729EV_G729_M + j]; } /* scale */ end_loop = add(i_subfr, G729EV_G729_L_SUBFR); FOR(j = i_subfr; j < end_loop; j++) { /* wsp[j] *= fac; */ L_temp = L_mult(wsp[j], fac); /* Q14 x Q13 <<1 = Q28 */ L_temp = L_shl(L_temp, 2); /* Q30 */ wsp[j] = round(L_temp); /* Q14 */#if(WMOPS) move16();#endif } ptr_Az += G729EV_G729_MP1; i_subfr += G729EV_G729_L_SUBFR; } G729EV_G729_Copy(wsp, diff, G729EV_MAIN_L_FRAME2);}/*--------------------------------------------------------------------------* * Function G729EV_MAIN_inverse_weighting_filter() * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Inverse weighting filter of lower-band difference signal including * * an adaptive gain compensation * *--------------------------------------------------------------------------*/void G729EV_MAIN_inverse_weighting_filter(Word16 * Az, /* (i) LPC coefficients from CELP local decoder */ Word16 * mem_invWz_in, /* (i) memory of input */ Word16 * mem_invwsp, /* (i) memory of output */ Word16 * diff_q /* (i/o) difference signal before and after weighting */ ){ Word32 L_temp, L_num, L_den; Word16 invWz_in_buffer[G729EV_MAIN_L_FRAME2 + G729EV_G729_M]; Word16 wsp[G729EV_MAIN_L_FRAME2]; Word16 Ap1[G729EV_G729_MP1]; Word16 Ap2[G729EV_G729_MP1]; Word16 *invWz_in, *ptr_Az; Word16 i_subfr, i, j, end_loop; Word16 fac; Word16 e_den, frac_den, e_num, frac_num, e_fac; /* set buffer for W(z) */ invWz_in = invWz_in_buffer + G729EV_G729_M;#if(WMOPS) move16();#endif G729EV_G729_Copy(mem_invWz_in, &invWz_in[-G729EV_G729_M], G729EV_G729_M); G729EV_G729_Copy(diff_q, invWz_in, G729EV_MAIN_L_FRAME2); G729EV_G729_Copy(&diff_q[(G729EV_MAIN_L_FRAME2) - G729EV_G729_M], mem_invWz_in, G729EV_G729_M); /* apply W(z)= fac*A(z/gamma2)/A(z/gamma1) */ ptr_Az = Az; i_subfr = (Word16) 0;#if(WMOPS) move16(); move16();#endif FOR(i = 0; i < 4; i++) { /* weight A(z) */ G729EV_G729_Weight_Az(ptr_Az, G729EV_MAIN_GAMMA1, G729EV_G729_M, Ap1); G729EV_G729_Weight_Az(ptr_Az, G729EV_MAIN_GAMMA2, G729EV_G729_M, Ap2); /* compute gain */ L_den = L_deposit_h(shr(Ap2[0], 1)); /* (Word32)Q12>>1 -> Q27 */ L_num = L_deposit_h(shr(Ap1[0], 1)); /* (Word32)Q12>>1 -> Q27 */ fac = (Word16) - 16384; /* Q13 */#if(WMOPS) move16();#endif FOR(j = 1; j <= G729EV_G729_M; j++) { /* Q12 x Q13<<1 -> Q26 */ L_den = L_mac(L_den, Ap2[j], fac); /* den += Ap1[j] << 14 */ L_num = L_mac(L_num, Ap1[j], fac); /* num += Ap2[j] << 14 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -