📄 g729ev_main_filt.c
字号:
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/gamma2) * 1/A(z/gamma1) */ G729EV_G729_Residu(Ap2, &invWz_in[i_subfr], &wsp[i_subfr], G729EV_G729_L_SUBFR); G729EV_G729_Syn_filt(Ap1, &wsp[i_subfr], &wsp[i_subfr], G729EV_G729_L_SUBFR, mem_invwsp, 0); FOR(j = 0; j < G729EV_G729_M; j++) { mem_invwsp[j] = wsp[i_subfr + G729EV_G729_L_SUBFR - G729EV_G729_M + j];#if(WMOPS) move16();#endif } /* 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_q, G729EV_MAIN_L_FRAME2);}/*--------------------------------------------------------------------------* * Function G729EV_MAIN_initQMF_ana() * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Reset the signal memory * *--------------------------------------------------------------------------*/void G729EV_MAIN_initQMF_ana(G729EV_MAIN_QMFCODSTAT * qmf /* (i/o) filter states */ ){ int i; FOR(i = 0; i < (2 * G729EV_MAIN_S_QMF - 1); i++) {#if(WMOPS) move16();#endif qmf->mem[i] = (Word16) 0; }}/*--------------------------------------------------------------------------* * Function G729EV_MAIN_initQMF_ana() * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Reset the sum and difference memory * *--------------------------------------------------------------------------*/void G729EV_MAIN_initQMF_syn(G729EV_MAIN_QMFDECSTAT * qmf /* (i/o) filter states */ ){ int i; FOR(i = 0; i < (2 * G729EV_MAIN_S_QMF_FS - 1); i++) {#if(WMOPS) move16(); move16();#endif qmf->mem_add[i] = (Word16) 0; qmf->mem_sub[i] = (Word16) 0; }}/*--------------------------------------------------------------------------* * Function G729EV_MAIN_QMF_ana() * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Two-channel filter bank analysis * *--------------------------------------------------------------------------*/void G729EV_MAIN_QMF_ana(G729EV_MAIN_QMFCODSTAT * qmf, /* (i/o) filter states */ Word16 * input, /* (i) Q15 input */ Word16 * bf, /* (o) Q14 lower-band */ Word16 * hf, /* (o) Q14 higher-band */ Word16 size /* (i) number of samples */ ){ Word32 a1, b1, a2, b2; Word32 Tempa, Tempb; Word16 signal_buffer[(2 * G729EV_MAIN_S_QMF - 1) + G729EV_MAIN_L_FRAME]; Word16 *signal_ptr; Word16 *x1, *x2; const Word16 *c; Word16 i; signal_ptr = signal_buffer;#if(WMOPS) move16();#endif /* copy memory of signal */ FOR(i = 0; i < (2 * G729EV_MAIN_S_QMF - 1); i++) {#if(WMOPS) move16();#endif *signal_ptr++ = qmf->mem[i]; } /* copy input signal */ FOR(i = 0; i < size; i++) {#if(WMOPS) move16();#endif *signal_ptr++ = *input++; } /* update memory of signal */ FOR(i = 0; i < (2 * G729EV_MAIN_S_QMF - 1); i++) {#if(WMOPS) move16();#endif qmf->mem[i] = signal_buffer[i + size]; } /* efficient QMF implementation with joint computation of (decimated) low-band and high-band signal There are two sums (a & b) that are accumulated using two sets of coeffs (set1 = 0..12 & set2 = 13..End-1). Each set was prescaled with a ratio (32768/31838 or 32768/1378) to make the coeffs more precise (minimized quantification errors) during accumulation. When accumulation is complete, each sum is rescaled to normal. */ signal_ptr = &signal_buffer[G729EV_MAIN_S_QMF - 1];#if(WMOPS) move16();#endif FOR(i = 0; i < size; i += 2) { x1 = signal_ptr++; x2 = signal_ptr++;#if(WMOPS) move16(); move16();#endif /* Use Coeff #1 to Set Sums a1 & b1 */ b1 = L_mult0(G729EV_MAIN_qmf_J64D[0], *x1--); a1 = L_mult0(G729EV_MAIN_qmf_J64D[0], *x2++); /* Use Coeffs #2..13 to Accumulate in Sums a1 & b1 */ FOR(c = &G729EV_MAIN_qmf_J64D[1]; c < &G729EV_MAIN_qmf_J64D[13]; c += 2) { a1 = L_mac0(a1, c[0], *x1--); b1 = L_mac0(b1, c[0], *x2++); b1 = L_mac0(b1, c[1], *x1--); a1 = L_mac0(a1, c[1], *x2++); } /* Use Coeff #14 to Set Sums a2 & b2 */ a2 = L_mult0(G729EV_MAIN_qmf_J64D[13], *x1--); b2 = L_mult0(G729EV_MAIN_qmf_J64D[13], *x2++); /* Use Coeffs 15..End to Accumulate in Sums a2 & b2 */ FOR(c = &G729EV_MAIN_qmf_J64D[14]; c < &G729EV_MAIN_qmf_J64D[G729EV_MAIN_S_QMF]; c += 2) { b2 = L_mac0(b2, c[0], *x1--); a2 = L_mac0(a2, c[0], *x2++); a2 = L_mac0(a2, c[1], *x1--); b2 = L_mac0(b2, c[1], *x2++); } /* Rescale Sums */ a1 = L_mls(a1, 31838 / 2); b1 = L_mls(b1, 31838 / 2); a2 = L_mls(a2, 1378 / 2); b2 = L_mls(b2, 1378 / 2); /* Calculate An + Bn Sum */ Tempa = L_add(L_add(a1, a2), L_add(b1, b2)); /* Calculate An - Bn Difference */ Tempb = L_sub(L_add(a1, a2), L_add(b1, b2)); *bf++ = round(Tempa); *hf++ = round(L_shl(Tempb, 1)); } return;}/*--------------------------------------------------------------------------* * Function G729EV_MAIN_QMF_syn() * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Two-channel filter bank synthesis * *--------------------------------------------------------------------------*/void G729EV_MAIN_QMF_syn(G729EV_MAIN_QMFDECSTAT * qmf, /* (i/o) filter states */ Word16 * inputBF, /* (i) Q14 lower-band */ Word16 * inputHF, /* (i) Q14 higher-band */ Word16 * output, /* (o) Q15 output */ Word16 size, /* (i) number of samples */ Word16 gain_switching /* (i) higher-band attenuation factor for bit-rate switching */ ){ Word32 a1, b1, a2, b2; Word16 add_buffer[(2 * G729EV_MAIN_S_QMF_FS - 1) + G729EV_MAIN_L_FRAME]; Word16 sub_buffer[(2 * G729EV_MAIN_S_QMF_FS - 1) + G729EV_MAIN_L_FRAME]; Word16 *add_ptr; Word16 *sub_ptr; Word16 *x1a, *x2a, *x1b, *x2b; const Word16 *c; Word16 sTemp; Word16 i; /* Joint computation of base-band and high-band now avoids recalculation of the sums and differences for previous input signals. They are stored in the memories. Stack usage was also reduced by eliminating the two buffers. */ add_ptr = add_buffer; sub_ptr = sub_buffer;#if(WMOPS) move16(); move16();#endif /* copy the memories of the sums and differences */ FOR(i = 0; i < (2 * G729EV_MAIN_S_QMF_FS - 1); i++) {#ifdef WMOPS move16(); move16();#endif *add_ptr++ = qmf->mem_add[i]; *sub_ptr++ = qmf->mem_sub[i]; } /* copy the input signals and calculate the sums and differences */ FOR(i = 0; i < size; i++) { /* Scale and Fix for Proper Rounding */ IF(*inputHF < 0) { sTemp = mac_r(-1, *inputHF, gain_switching); } ELSE { sTemp = mult_r(*inputHF, gain_switching); }#if(WMOPS) move16(); move16();#endif *add_ptr++ = add(*inputBF, sTemp); *sub_ptr++ = sub(*inputBF, sTemp); inputBF++; inputHF++; } /* add zeroes (no sum and difference to calculate) */ FOR(i = size; i < G729EV_MAIN_L_FRAME; i++) {#if(WMOPS) move16(); move16();#endif *add_ptr++ = (Word16) 0; *sub_ptr++ = (Word16) 0; } /* update memories of the sums and differences */ FOR(i = 0; i < (2 * G729EV_MAIN_S_QMF_FS - 1); i++) {#if(WMOPS) move16(); move16();#endif qmf->mem_add[i] = add_buffer[i + size]; qmf->mem_sub[i] = sub_buffer[i + size]; } /* Guy Richard 2005/10/26: Pointer logic in the loop was removed. Two iterations to calculate base-band and high-band have been combined into one. */ add_ptr = &add_buffer[G729EV_MAIN_S_QMF_FS - 1]; sub_ptr = &sub_buffer[G729EV_MAIN_S_QMF_FS - 1];#if(WMOPS) move16(); move16();#endif FOR(i = 0; i < size; i++) { x1a = add_ptr++; x2a = x1a; x1b = sub_ptr++; x2b = x1b;#if(WMOPS) move16(); move16(); move16(); move16();#endif /* Use Coeff #1 to Set Sums a1 & b1 */ a1 = L_mult0(G729EV_MAIN_qmf_J64D[0], *x1a--); b1 = L_mult0(G729EV_MAIN_qmf_J64D[0], *++x2b); /* Use Coeffs #2..13 to Accumulate in Sums a1 & b1 */ FOR(c = &G729EV_MAIN_qmf_J64D[1]; c < &G729EV_MAIN_qmf_J64D[13]; c += 2) { a1 = L_mac0(a1, c[0], *++x2a); b1 = L_mac0(b1, c[0], *x1b--); a1 = L_mac0(a1, c[1], *x1a--); b1 = L_mac0(b1, c[1], *++x2b); } /* Use Coeff #14 to Set Sums a2 & b2 */ a2 = L_mult0(G729EV_MAIN_qmf_J64D[13], *++x2a);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -