PST.C
上传用户:meifeng08
上传日期:2013-06-18
资源大小:5304k
文件大小:32k
源码类别:

语音压缩

开发平台:

C/C++

  1. /* Version 3.3    Last modified: December 26, 1995 */
  2. /************************************************************************/
  3. /*      Post - filtering : short term + long term                       */
  4. /************************************************************************/
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. /**** Prototypes                                                        */
  8. #include "typedef.h"
  9. #include "ld8k.h"
  10. #include "basic_op.h"
  11. #include "oper_32b.h"
  12. /* Prototypes for local functions */
  13. /**********************************/
  14. static void pst_ltp(Word16 t0, Word16 *ptr_sig_in,
  15.     Word16 *ptr_sig_pst0, Word16 *vo);
  16. static void search_del(Word16 t0, Word16 *ptr_sig_in, Word16 *ltpdel,
  17.     Word16 *phase, Word16 *num_gltp, Word16 *den_gltp, Word16 *sh_num_gltp,
  18.     Word16 *sh_den_gltp, Word16 *y_up, Word16 *off_yup);
  19. static void filt_plt( Word16 *s_in, Word16 *s_ltp,
  20.     Word16 *s_out, Word16 gain_plt);
  21. static void compute_ltp_l(Word16 *s_in, Word16 ltpdel, Word16 phase,
  22.     Word16 *y_up, Word16 *num, Word16 *den, Word16 *sh_num, Word16 *sh_den);
  23. static Word16 select_ltp(Word16 num1, Word16 den1, Word16 sh_num1,
  24.     Word16 sh_den1, Word16 num2, Word16 den2, Word16 sh_num2, Word16 sh_den2);
  25. static void calc_st_filt(Word16 *apond2, Word16 *apond1, Word16 *parcor0,
  26.     Word16 *signal_ltp0_ptr);
  27. static void filt_mu(Word16 *sig_in, Word16 *sig_out, Word16 parcor0);
  28. static void calc_rc0_h(Word16 *h, Word16 *rc0);
  29. static void scale_st(Word16 *sig_in, Word16 *sig_out, Word16 *gain_prec);
  30. /* Static arrays and variables */
  31. /*******************************/
  32. /* Arrays */
  33. static Word16 apond2[LONG_H_ST];    /* s.t. numerator coeff.        */
  34. static Word16 mem_stp[M];           /* s.t. postfilter memory       */
  35. static Word16 mem_zero[M];          /* null memory to compute h_st  */
  36. static Word16 res2[SIZ_RES2];       /* A(gamma2) residual           */
  37. /* pointers */
  38. Word16 *res2_ptr;
  39. Word16 *ptr_mem_stp;
  40. /* Variables */
  41. Word16 gain_prec;
  42. /************************************************************************/
  43. /****   Short term postfilter :                                     *****/
  44. /*      Hst(z) = Hst0(z) Hst1(z)                                        */
  45. /*      Hst0(z) = 1/g0 A(gamma2)(z) / A(gamma1)(z)                      */
  46. /*      if {hi} = i.r. filter A(gamma2)/A(gamma1) (truncated)           */
  47. /*      g0 = SUM(|hi|) if > 1                                           */
  48. /*      g0 = 1. else                                                    */
  49. /*      Hst1(z) = 1/(1 - |mu|) (1 + mu z-1)                             */
  50. /*      with mu = k1 * gamma3                                           */
  51. /*      k1 = 1st parcor calculated on {hi}                              */
  52. /*      gamma3 = gamma3_minus if k1<0, gamma3_plus if k1>0              */
  53. /****   Long term postfilter :                                      *****/
  54. /*      harmonic postfilter :   H0(z) = gl * (1 + b * z-p)              */
  55. /*      b = gamma_g * gain_ltp                                          */
  56. /*      gl = 1 / 1 + b                                                  */
  57. /*      computation of delay p on A(gamma2)(z) s(z)                     */
  58. /*      sub optimal search                                              */
  59. /*      1. search around 1st subframe delay (3 integer values)          */
  60. /*      2. search around best integer with fract. delays (1/8)          */
  61. /************************************************************************/
  62. /*----------------------------------------------------------------------------
  63.  * Init_Post_Filter -  Initialize postfilter functions
  64.  *----------------------------------------------------------------------------
  65.  */
  66. void Init_Post_Filter(
  67.     void
  68. )
  69. {
  70.     int i;
  71.     /* Initialize arrays and pointers */
  72.     /* res2 =  A(gamma2) residual */
  73.     for(i=0; i<MEM_RES2; i++) res2[i] = 0;
  74.     res2_ptr = res2 + MEM_RES2;
  75.     /* 1/A(gamma1) memory */
  76.     for(i=0; i<M; i++) mem_stp[i] = 0;
  77.     ptr_mem_stp = mem_stp + M - 1;
  78.     /* fill apond2[M+1->LONG_H_ST-1] with zeroes */
  79.     for(i=MP1; i<LONG_H_ST; i++) apond2[i] = 0;
  80.     /* null memory to compute i.r. of A(gamma2)/A(gamma1) */
  81.     for(i=0; i<M; i++) mem_zero[i] = 0;
  82.     /* for gain adjustment */
  83.     gain_prec = 16384;
  84.     return;
  85. }
  86. /*----------------------------------------------------------------------------
  87.  * Post - adaptive postfilter main function
  88.  *----------------------------------------------------------------------------
  89.  */
  90. void Post(
  91.  Word16 t0,             /* input : pitch delay given by coder */
  92.  Word16 *signal_ptr,    /* input : input signal (pointer to current subframe */
  93.  Word16 *coeff,         /* input : LPC coefficients for current subframe */
  94.  Word16 *sig_out,       /* output: postfiltered output */
  95.  Word16 *vo             /* output: voicing decision 0 = uv,  > 0 delay */
  96. )
  97. {
  98.     /* Local variables and arrays */
  99.     Word16 apond1[MP1];             /* s.t. denominator coeff.      */
  100.     Word16 sig_ltp[L_SUBFRP1];      /* H0 output signal             */
  101.     Word16 *sig_ltp_ptr;
  102.     Word16 parcor0;
  103.     /* Compute weighted LPC coefficients */
  104.     Weight_Az(coeff, GAMMA1_PST, M, apond1);
  105.     Weight_Az(coeff, GAMMA2_PST, M, apond2);
  106.     /* Compute A(gamma2) residual */
  107.     Residu(apond2, signal_ptr, res2_ptr, L_SUBFR);
  108.     /* Harmonic filtering */
  109.     sig_ltp_ptr = sig_ltp + 1;
  110.     pst_ltp(t0, res2_ptr, sig_ltp_ptr, vo);
  111.     /* Save last output of 1/A(gamma1)  */
  112.     /* (from preceding subframe)        */
  113.     sig_ltp[0] = *ptr_mem_stp;
  114.     /* Controls short term pst filter gain and compute parcor0   */
  115.     calc_st_filt(apond2, apond1, &parcor0, sig_ltp_ptr);
  116.     /* 1/A(gamma1) filtering, mem_stp is updated */
  117.     Syn_filt(apond1, sig_ltp_ptr, sig_ltp_ptr, L_SUBFR, mem_stp, 1);
  118.     /* Tilt filtering */
  119.     filt_mu(sig_ltp, sig_out, parcor0);
  120.     /* Gain control */
  121.     scale_st(signal_ptr, sig_out, &gain_prec);
  122.     /**** Update for next subframe */
  123.     Copy(&res2[L_SUBFR], &res2[0], MEM_RES2);
  124.     return;
  125. }
  126. /*----------------------------------------------------------------------------
  127.  *  pst_ltp - harmonic postfilter
  128.  *----------------------------------------------------------------------------
  129.  */
  130. static void pst_ltp(
  131.  Word16 t0,             /* input : pitch delay given by coder */
  132.  Word16 *ptr_sig_in,    /* input : postfilter input filter (residu2) */
  133.  Word16 *ptr_sig_pst0,  /* output: harmonic postfilter output */
  134.  Word16 *vo             /* output: voicing decision 0 = uv,  > 0 delay */
  135. )
  136. {
  137. /**** Declare variables                                 */
  138.     int i;
  139.     Word16 temp;
  140.     Word16 ltpdel, phase;
  141.     Word16 num_gltp, den_gltp;
  142.     Word16 num2_gltp, den2_gltp;
  143.     Word16 sh_num, sh_den;
  144.     Word16 sh_num2, sh_den2;
  145.     Word16 gain_plt;
  146.     Word16 y_up[SIZ_Y_UP];
  147.     Word16 *ptr_y_up;
  148.     Word16 off_yup;
  149.     Word16 *ptr_sig;
  150.     Word16 sig_cadr[SIZ_RES2], *ptr_sig_cadr;
  151.     Word16 nb_sh_sig;
  152.     Word32 L_temp;
  153.     /* input signal justified on 13 bits */
  154.     ptr_sig = ptr_sig_in - MEM_RES2;
  155.     temp = 0;
  156.     for(i=0; i<SIZ_RES2; i++) {
  157.         temp |= abs_s(ptr_sig[i]);
  158.     }
  159.     nb_sh_sig = sub(3, norm_s(temp));
  160.     for(i=0; i<SIZ_RES2; i++) {   /* nb_sh_sig may be >0, <0 or =0 */
  161.         sig_cadr[i] = shr( ptr_sig[i], nb_sh_sig);
  162.     }
  163.     ptr_sig_cadr = sig_cadr + MEM_RES2;
  164.     /* Sub optimal delay search */
  165.     search_del(t0, ptr_sig_cadr, &ltpdel, &phase, &num_gltp, &den_gltp,
  166.                             &sh_num, &sh_den, y_up, &off_yup);
  167.     *vo = ltpdel;
  168.     if(num_gltp == 0)   {
  169.         Copy(ptr_sig_in, ptr_sig_pst0, L_SUBFR);
  170.     }
  171.     else {
  172.         if(phase == 0) {
  173.             ptr_y_up = ptr_sig_in - ltpdel;
  174.         }
  175.         else {
  176.             /* Filtering with long filter */
  177.             compute_ltp_l(ptr_sig_cadr, ltpdel, phase, ptr_sig_pst0,
  178.                 &num2_gltp, &den2_gltp, &sh_num2, &sh_den2);
  179.             if(select_ltp(num_gltp, den_gltp, sh_num, sh_den,
  180.                 num2_gltp, den2_gltp, sh_num2, sh_den2) == 1) {
  181.                 /* select short filter */
  182.                 temp   = sub(phase, 1);
  183.                 L_temp = L_mult(temp, L_SUBFRP1);
  184.                 L_temp = L_shr(L_temp, 1);
  185.                 temp   = extract_l(L_temp);
  186.                 temp   = add(temp, off_yup);
  187.                 /* ptr_y_up = y_up + (phase-1) * L_SUBFRP1 + off_yup */
  188.                 ptr_y_up = y_up + temp;
  189.             }
  190.             else {
  191.                 /* select long filter */
  192.                 num_gltp = num2_gltp;
  193.                 den_gltp = den2_gltp;
  194.                 sh_num   = sh_num2;
  195.                 sh_den   = sh_den2;
  196.                 ptr_y_up = ptr_sig_pst0;
  197.             }
  198.             /* rescale y_up */
  199.             for(i=0; i<L_SUBFR; i++) {  /* nb_sh_sig may be >0, <0 or =0 */
  200.                 ptr_y_up[i] = shl(ptr_y_up[i], nb_sh_sig);
  201.             }
  202.         }
  203.         temp = sub(sh_num,sh_den);
  204.         if(temp >= 0) den_gltp = shr(den_gltp, temp);
  205.         else {
  206.             num_gltp = shl(num_gltp, temp); /*  >> (-temp) */
  207.         }
  208.         if(sub(num_gltp ,den_gltp)>=0) {
  209.             /* beta bounded to 1 */
  210.             gain_plt = MIN_GPLT;
  211.         }
  212.         else {
  213.             /* GAMMA_G = 0.5                                            */
  214.             /* gain_plt = den_gltp x 2**15 / (den_gltp + 0.5 num_gltp)  */
  215.             /* shift 1 bit to avoid overflows in add                    */
  216.             num_gltp = shr(num_gltp, 2);
  217.             den_gltp = shr(den_gltp, 1);
  218.             temp     = add(den_gltp, num_gltp);
  219.             gain_plt = div_s(den_gltp, temp);   /* Q15 */
  220.         }
  221.         /** filtering by H0(z) = harmonic filter **/
  222.         filt_plt(ptr_sig_in, ptr_y_up, ptr_sig_pst0, gain_plt);
  223.     }
  224.     return;
  225. }
  226. /*----------------------------------------------------------------------------
  227.  *  search_del: computes best (shortest) integer LTP delay + fine search
  228.  *----------------------------------------------------------------------------
  229.  */
  230. static void search_del(
  231.  Word16 t0,                /* input : pitch delay given by coder */
  232.  Word16 *ptr_sig_in,       /* input : input signal (with delay line) */
  233.  Word16 *ltpdel,           /* output: delay = *ltpdel - *phase / f_up */
  234.  Word16 *phase,            /* output: phase */
  235.  Word16 *num_gltp,         /* output: 16 bits numerator of LTP gain */
  236.  Word16 *den_gltp,         /* output: 16 bits denominator of LTP gain */
  237.  Word16 *sh_num_gltp,      /* output: justification for num_gltp */
  238.  Word16 *sh_den_gltp,      /* output: justification for den_gltp */
  239.  Word16 *y_up,             /* output: LT delayed signal if fract. delay */
  240.  Word16 *off_yup           /* output: offset in y_up */
  241. )
  242. {
  243.     /* Tables of constants */
  244.     extern Word16 tab_hup_s[SIZ_TAB_HUP_S];
  245.     Word32 L_den0[F_UP_PST-1];
  246.     Word32 L_den1[F_UP_PST-1];
  247.     Word32 *ptr_L_den0, *ptr_L_den1;
  248.     int i, n;
  249.     Word16 *ptr_h;
  250.     Word16 *ptr_sig_past, *ptr_sig_past0;
  251.     Word16 *ptr1, *ptr_y_up;
  252.     Word16 num, den0, den1;
  253.     Word16 den_max, num_max;
  254.     Word32 L_num_int, L_den_int, L_den_max;
  255.     Word16 hi_numsq, hi_numsq_max;
  256.     Word16 lo_numsq, lo_numsq_max;
  257.     Word16 ener;
  258.     Word16 sh_num, sh_den, sh_ener;
  259.     Word16 i_max, lambda, phi, phi_max, ioff;
  260.     Word16 temp;
  261.     Word32 L_temp0, L_temp1;
  262.     Word32 L_acc;
  263.     Word32 L_temp;
  264.     /* Computes energy of current signal */
  265.     /*************************************/
  266.     L_acc = 0L;
  267.     for(i=0; i<L_SUBFR; i++) {
  268.         L_acc = L_mac( L_acc, ptr_sig_in[i] , ptr_sig_in[i]);
  269.     }
  270.     if(L_acc == 0) {
  271.         *num_gltp = 0;
  272.         *den_gltp = 1;
  273.         *ltpdel = 0;
  274.         *phase = 0;
  275.         return;
  276.     }
  277.     sh_ener = sub(16, norm_l(L_acc));
  278.     /* save energy for final decision */
  279.     if(sh_ener > 0) {
  280.         ener = extract_l(L_shr(L_acc, sh_ener));
  281.     }
  282.     else {
  283.         sh_ener = 0;
  284.         ener = extract_l(L_acc);
  285.     }
  286.     /*************************************/
  287.     /* Selects best of 3 integer delays  */
  288.     /* Maximum of 3 numerators around t0 */
  289.     /*************************************/
  290.     lambda = sub(t0,1);
  291.     ptr_sig_past = ptr_sig_in - lambda;
  292.     L_num_int = -1L;
  293.    /* initialization used only to suppress Microsoft Visual C++ warnings */
  294.     i_max = (Word16)0;
  295.     for(i=0; i<3; i++) {
  296.         L_acc = 0L;
  297.         for(n=0; n<L_SUBFR; n++) {
  298.             L_acc = L_mac( L_acc, ptr_sig_in[n] , ptr_sig_past[n]);
  299.         }
  300.         if(L_acc < 0) {
  301.             L_acc = 0L;
  302.         }
  303.         L_temp =L_sub(L_acc ,L_num_int);
  304.         if(L_temp > 0L) {
  305.             L_num_int = L_acc;
  306.             i_max = (Word16)i;
  307.         }
  308.         ptr_sig_past--;
  309.     }
  310.     if(L_num_int == 0) {
  311.         *num_gltp = 0;
  312.         *den_gltp = 1;
  313.         *ltpdel = 0;
  314.         *phase = 0;
  315.         return;
  316.     }
  317.     /* Compute den for i_max */
  318.     lambda = add(lambda, (Word16)i_max);
  319.     ptr_sig_past = ptr_sig_in - lambda;
  320.     L_acc = 0L;
  321.     for(i=0; i<L_SUBFR; i++) {
  322.         temp = *ptr_sig_past++;
  323.         L_acc = L_mac( L_acc, temp, temp);
  324.     }
  325.     if(L_acc == 0L) {
  326.         *num_gltp = 0;
  327.         *den_gltp = 1;
  328.         *ltpdel = 0;
  329.         *phase = 0;
  330.         return;
  331.     }
  332.     L_den_int = L_acc;
  333.     /***********************************/
  334.     /* Select best phase around lambda */
  335.     /***********************************/
  336.     /* Compute y_up & denominators */
  337.     /*******************************/
  338.     ptr_y_up = y_up;
  339.     L_den_max = L_den_int;
  340.     ptr_L_den0 = L_den0;
  341.     ptr_L_den1 = L_den1;
  342.     ptr_h = tab_hup_s;
  343.     temp = sub(lambda, LH_UP_SM1);
  344.     ptr_sig_past0 = ptr_sig_in - temp;
  345.     /* Loop on phase */
  346.     for(phi=1; phi<F_UP_PST; phi++) {
  347.         /* Compute y_up for lambda+1 - phi/F_UP_PST */
  348.         /* and lambda - phi/F_UP_PST                */
  349.         ptr_sig_past = ptr_sig_past0;
  350.         for(n = 0; n<=L_SUBFR; n++) {
  351.             ptr1 = ptr_sig_past++;
  352.             L_acc = 0L;
  353.             for(i=0; i<LH2_S; i++) {
  354.                 L_acc = L_mac(L_acc, ptr_h[i], ptr1[-i]);
  355.             }
  356.             ptr_y_up[n] = round(L_acc);
  357.         }
  358.         /* compute den0 (lambda+1) and den1 (lambda) */
  359.         /* part common to den0 and den1 */
  360.         L_acc = 0L;
  361.         for(n=1; n<L_SUBFR; n++) {
  362.             L_acc = L_mac(L_acc, ptr_y_up[n] ,ptr_y_up[n]);
  363.         }
  364.         L_temp0 = L_acc;        /* saved for den1 */
  365.         /* den0 */
  366.         L_acc = L_mac(L_acc, ptr_y_up[0] ,ptr_y_up[0]);
  367.         *ptr_L_den0 = L_acc;
  368.         /* den1 */
  369.         L_acc = L_mac(L_temp0, ptr_y_up[L_SUBFR] ,ptr_y_up[L_SUBFR]);
  370.         *ptr_L_den1 = L_acc;
  371.         if(sub(abs_s(ptr_y_up[0]),abs_s(ptr_y_up[L_SUBFR])) >0) {
  372.             L_temp =L_sub(*ptr_L_den0 ,L_den_max );
  373.             if(L_temp> 0L) {
  374.                 L_den_max = *ptr_L_den0;
  375.             }
  376.         }
  377.         else {
  378.             L_temp =L_sub(*ptr_L_den1 ,L_den_max );
  379.             if(L_temp> 0L) {
  380.                 L_den_max = *ptr_L_den1;
  381.             }
  382.         }
  383.         ptr_L_den0++;
  384.         ptr_L_den1++;
  385.         ptr_y_up += L_SUBFRP1;
  386.         ptr_h += LH2_S;
  387.     }
  388.     if(L_den_max == 0) {
  389.         *num_gltp = 0;
  390.         *den_gltp = 1;
  391.         *ltpdel = 0;
  392.         *phase = 0;
  393.         return;
  394.     }
  395.     sh_den = sub(16, norm_l(L_den_max));
  396.     /* if sh_den <= 0 :  dynamic between current frame */
  397.     /* and delay line too high                         */
  398.     if(sh_den <= 0) {
  399.         *num_gltp = 0;
  400.         *den_gltp = 1;
  401.         *ltpdel = 0;
  402.         *phase = 0;
  403.         return;
  404.     }
  405.     /* search sh_num to justify correlations   */
  406.     /* sh_num = Max(sh_den, sh_ener)           */
  407.     sh_num = (sub( sh_den , sh_ener)>=0) ? sh_den : sh_ener;
  408.     /* Computation of the numerators                */
  409.     /* and selection of best num*num/den            */
  410.     /* for non null phases                          */
  411.     /* Initialize with null phase */
  412.     L_acc        = L_shr(L_den_int, sh_den);   /* sh_den > 0 */
  413.     den_max      = extract_l(L_acc);
  414.     L_acc        = L_shr(L_num_int, sh_num);   /* sh_num > 0 */
  415.     num_max      = extract_l(L_acc);
  416.     L_acc        = L_mult(num_max, num_max);
  417.     L_Extract(L_acc, &hi_numsq_max, &lo_numsq_max);
  418.     phi_max      = 0;
  419.     ioff         = 1;
  420.     ptr_L_den0   = L_den0;
  421.     ptr_L_den1   = L_den1;
  422.     ptr_y_up     = y_up;
  423.     /* if den_max = 0 : will be selected and declared unvoiced */
  424.     /* if num!=0 & den=0 : will be selected and declared unvoiced */
  425.     /* degenerated seldom cases, switch off LT is OK */
  426.     /* Loop on phase */
  427.     for(phi=1; phi<F_UP_PST; phi++) {
  428.         /* compute num for lambda+1 - phi/F_UP_PST */
  429.         L_acc = 0L;
  430.         for(n = 0; n<L_SUBFR; n++) {
  431.             L_acc = L_mac(L_acc, ptr_sig_in[n] ,ptr_y_up[n]);
  432.         }
  433.         L_acc = L_shr(L_acc, sh_num);       /* sh_num > 0 */
  434.         if(L_acc < 0L) {
  435.             num = 0;
  436.         }
  437.         else {
  438.             num  = extract_l(L_acc);
  439.         }
  440.         /* selection if num**2/den0 max */
  441.         L_acc    = L_mult(num, num);
  442.         L_Extract(L_acc, &hi_numsq, &lo_numsq);
  443.         L_temp0  = Mpy_32_16(hi_numsq, lo_numsq, den_max);
  444.         L_acc    = *ptr_L_den0++;
  445.         L_acc    = L_shr(L_acc, sh_den);        /* sh_den > 0 */
  446.         den0     = extract_l(L_acc);
  447.         L_temp1  = Mpy_32_16(hi_numsq_max, lo_numsq_max, den0);
  448.         L_temp = L_sub(L_temp0, L_temp1);
  449.         if(L_temp>0L) {
  450.             num_max      = num;
  451.             hi_numsq_max = hi_numsq;
  452.             lo_numsq_max = lo_numsq;
  453.             den_max      = den0;
  454.             ioff         = 0;
  455.             phi_max      = phi;
  456.         }
  457.         /* compute num for lambda - phi/F_UP_PST */
  458.         ptr_y_up++;
  459.         L_acc = 0L;
  460.         for(n = 0; n<L_SUBFR; n++) {
  461.             L_acc = L_mac(L_acc, ptr_sig_in[n] ,ptr_y_up[n]);
  462.         }
  463.         L_acc = L_shr(L_acc, sh_num);   /* sh_num > 0 */
  464.         if(L_acc < 0L) {
  465.             num = 0;
  466.         }
  467.         else {
  468.             num  = extract_l(L_acc);
  469.         }
  470.         /* selection if num**2/den1 max */
  471.         L_acc    = L_mult(num, num);
  472.         L_Extract(L_acc, &hi_numsq, &lo_numsq);
  473.         L_temp0  = Mpy_32_16(hi_numsq, lo_numsq, den_max);
  474.         L_acc    = *ptr_L_den1++;
  475.         L_acc    = L_shr(L_acc, sh_den);        /* sh_den > 0 */
  476.         den1     = extract_l(L_acc);
  477.         L_temp1  = Mpy_32_16(hi_numsq_max, lo_numsq_max, den1);
  478.         L_temp = L_sub(L_temp0,L_temp1);
  479.         if(L_temp> 0L) {
  480.             num_max      = num;
  481.             hi_numsq_max = hi_numsq;
  482.             lo_numsq_max = lo_numsq;
  483.             den_max     = den1;
  484.             ioff        = 1;
  485.             phi_max     = phi;
  486.         }
  487.         ptr_y_up += L_SUBFR;
  488.     }
  489.     /***************************************************/
  490.     /*** test if normalized crit0[iopt] > THRESHCRIT ***/
  491.     /***************************************************/
  492.     if((num_max == 0) || (sub(den_max,1) <= 0)) {
  493.         *num_gltp = 0;
  494.         *den_gltp = 1;
  495.         *ltpdel = 0;
  496.         *phase = 0;
  497.         return;
  498.     }
  499.     /* compare num**2               */
  500.     /* to ener * den * 0.5          */
  501.     /* (THRESHCRIT = 0.5)           */
  502.     L_temp1 = L_mult(den_max, ener);
  503.     L_temp0 = L_Comp(hi_numsq_max, lo_numsq_max);
  504.     /* temp = 2 * sh_num - sh_den - sh_ener + 1 */
  505.     /* 16 bits with no overflows  */
  506.     temp = shl(sh_num,1);
  507.     temp = sub(temp, sh_den);
  508.     temp = sub(temp, sh_ener);
  509.     temp = add(temp, 1);
  510.     if(temp < 0) {
  511.         temp    = negate(temp);             /* no overflow */
  512.         L_temp0 = L_shr(L_temp0, temp);
  513.     }
  514.     else {
  515.         if(temp > 0) L_temp1 = L_shr(L_temp1, temp);
  516.     }
  517.     L_temp = L_sub(L_temp0 ,L_temp1);
  518.     if(L_temp >= 0L) {
  519.         temp         = add(lambda, 1);
  520.         *ltpdel      = sub(temp, ioff);
  521.         *off_yup     = ioff;
  522.         *phase       = phi_max;
  523.         *num_gltp    = num_max;
  524.         *den_gltp    = den_max;
  525.         *sh_den_gltp = sh_den;
  526.         *sh_num_gltp = sh_num;
  527.     }
  528.     else {
  529.         *num_gltp = 0;
  530.         *den_gltp = 1;
  531.         *ltpdel = 0;
  532.         *phase = 0;
  533.     }
  534.     return;
  535. }
  536. /*----------------------------------------------------------------------------
  537.  *  filt_plt -  ltp  postfilter
  538.  *----------------------------------------------------------------------------
  539.  */
  540. static void filt_plt(
  541.  Word16 *s_in,       /* input : input signal with past*/
  542.  Word16 *s_ltp,      /* input : filtered signal with gain 1 */
  543.  Word16 *s_out,      /* output: output signal */
  544.  Word16 gain_plt     /* input : filter gain  */
  545. )
  546. {
  547.     /* Local variables */
  548.     int n;
  549.     Word32 L_acc;
  550.     Word16 gain_plt_1;
  551.     gain_plt_1 = sub(32767, gain_plt);
  552.     gain_plt_1 = add(gain_plt_1, 1);        /* 2**15 (1 - g) */
  553.     for(n=0;  n<L_SUBFR; n++) {
  554.         /* s_out(n) = gain_plt x s_in(n) + gain_plt_1 x s_ltp(n)        */
  555.         L_acc    = L_mult(gain_plt, s_in[n]);
  556.         L_acc    = L_mac(L_acc, gain_plt_1, s_ltp[n]);  /* no overflow      */
  557.         s_out[n] = round(L_acc);
  558.     }
  559.     return;
  560. }
  561. /*----------------------------------------------------------------------------
  562.  *  compute_ltp_l : compute delayed signal,
  563.                     num & den of gain for fractional delay
  564.  *                  with long interpolation filter
  565.  *----------------------------------------------------------------------------
  566.  */
  567. static void compute_ltp_l(
  568.  Word16 *s_in,       /* input signal with past*/
  569.  Word16 ltpdel,      /* delay factor */
  570.  Word16 phase,       /* phase factor */
  571.  Word16 *y_up,       /* delayed signal */
  572.  Word16 *num,        /* numerator of LTP gain */
  573.  Word16 *den,        /* denominator of LTP gain */
  574.  Word16 *sh_num,     /* justification factor of num */
  575.  Word16 *sh_den      /* justification factor of den */
  576. )
  577. {
  578. /**** Table of constants declared externally            */
  579.     extern Word16 tab_hup_l[SIZ_TAB_HUP_L];
  580.     /* Pointer on table of constants */
  581.     Word16 *ptr_h;
  582.     /* Local variables */
  583.     int n, i;
  584.     Word16 *ptr2;
  585.     Word16 temp;
  586.     Word32 L_acc;
  587.     temp  = sub(phase, 1);
  588.     temp  = shl(temp, L2_LH2_L);
  589.     ptr_h = tab_hup_l + temp;   /* tab_hup_l + LH2_L * (phase-1) */
  590.     temp  = sub(LH_UP_L, ltpdel);
  591.     ptr2  = s_in + temp; ;
  592.     /* Compute y_up */
  593.     for(n = 0; n<L_SUBFR; n++) {
  594.         L_acc = 0L;
  595.         for(i=0; i<LH2_L; i++) {
  596.             L_acc = L_mac(L_acc, ptr_h[i], (*ptr2--));
  597.         }
  598.         y_up[n] = round(L_acc);
  599.         ptr2 += LH2_L_P1;
  600.     }
  601.     /* Compute num */
  602.     L_acc = 0L;
  603.     for(n=0; n<L_SUBFR; n++)    {
  604.         L_acc = L_mac(L_acc, y_up[n], s_in[n]);
  605.     }
  606.     if(L_acc < 0L) {
  607.         *num = 0;
  608.         *sh_num = 0;
  609.     }
  610.     else {
  611.         temp = sub(16, norm_l(L_acc));
  612.         if(temp < 0) {
  613.             temp = 0;
  614.         }
  615.         L_acc = L_shr(L_acc, temp);   /* with temp >= 0 */
  616.         *num = extract_l(L_acc);
  617.         *sh_num = temp;
  618.     }
  619.     /* Compute den */
  620.     L_acc = 0L;
  621.     for(n=0; n<L_SUBFR; n++)    {
  622.         L_acc = L_mac(L_acc, y_up[n], y_up[n]);
  623.     }
  624.     temp = sub(16, norm_l(L_acc));
  625.     if(temp < 0) {
  626.         temp = 0;
  627.     }
  628.     L_acc = L_shr(L_acc, temp);     /* with temp >= 0 */
  629.     *den = extract_l(L_acc);
  630.     *sh_den = temp;
  631.     return;
  632. }
  633. /*----------------------------------------------------------------------------
  634.  *  select_ltp : selects best of (gain1, gain2)
  635.  *  with gain1 = num1 * 2** sh_num1 / den1 * 2** sh_den1
  636.  *  and  gain2 = num2 * 2** sh_num2 / den2 * 2** sh_den2
  637.  *----------------------------------------------------------------------------
  638.  */
  639. static Word16 select_ltp(  /* output : 1 = 1st gain, 2 = 2nd gain */
  640.  Word16 num1,       /* input : numerator of gain1 */
  641.  Word16 den1,       /* input : denominator of gain1 */
  642.  Word16 sh_num1,    /* input : just. factor for num1 */
  643.  Word16 sh_den1,    /* input : just. factor for den1 */
  644.  Word16 num2,       /* input : numerator of gain2 */
  645.  Word16 den2,       /* input : denominator of gain2 */
  646.  Word16 sh_num2,    /* input : just. factor for num2 */
  647.  Word16 sh_den2)    /* input : just. factor for den2 */
  648. {
  649.     Word32 L_temp1, L_temp2;
  650.     Word16 temp1, temp2;
  651.     Word16 hi, lo;
  652.     Word32 L_temp;
  653.     if(den2 == 0) {
  654.         return(1);
  655.     }
  656.     /* compares criteria = num**2/den */
  657.     L_temp1 = L_mult(num1, num1);
  658.     L_Extract(L_temp1, &hi, &lo);
  659.     L_temp1 = Mpy_32_16(hi, lo, den2);
  660.     L_temp2 = L_mult(num2, num2);
  661.     L_Extract(L_temp2, &hi, &lo);
  662.     L_temp2 = Mpy_32_16(hi, lo, den1);
  663.     /* temp1 = sh_den2 + 2 * sh_num1 */
  664.     temp1 = shl(sh_num1, 1);
  665.     temp1 = add(temp1, sh_den2);
  666.     /* temp2 = sh_den1 + 2 * sh_num2; */
  667.     temp2 = shl(sh_num2, 1);
  668.     temp2 = add(temp2, sh_den1);
  669.     if(sub(temp2 ,temp1)>0) {
  670.         temp2 = sub(temp2, temp1);
  671.         L_temp1 = L_shr(L_temp1, temp2);    /* temp2 > 0 */
  672.     }
  673.     else {
  674.         if(sub(temp1 ,temp2) >0){
  675.             temp1 = sub(temp1, temp2);
  676.             L_temp2 = L_shr(L_temp2, temp1);    /* temp1 > 0 */
  677.         }
  678.     }
  679.     L_temp = L_sub(L_temp2,L_temp1);
  680.     if(L_temp>0L) {
  681.         return(2);
  682.     }
  683.     else {
  684.         return(1);
  685.     }
  686. }
  687. /*----------------------------------------------------------------------------
  688.  *   calc_st_filt -  computes impulse response of A(gamma2) / A(gamma1)
  689.  *   controls gain : computation of energy impulse response as
  690.  *                    SUMn  (abs (h[n])) and computes parcor0
  691.  *----------------------------------------------------------------------------
  692.  */
  693. static void calc_st_filt(
  694.  Word16 *apond2,     /* input : coefficients of numerator */
  695.  Word16 *apond1,     /* input : coefficients of denominator */
  696.  Word16 *parcor0,    /* output: 1st parcor calcul. on composed filter */
  697.  Word16 *sig_ltp_ptr    /* in/out: input of 1/A(gamma1) : scaled by 1/g0 */
  698. )
  699. {
  700.     Word16 h[LONG_H_ST];
  701.     Word32 L_temp, L_g0;
  702.     Word16 g0, temp;
  703.     int i;
  704.     /* compute i.r. of composed filter apond2 / apond1 */
  705.     Syn_filt(apond1, apond2, h, LONG_H_ST, mem_zero, 0);
  706.     /* compute 1st parcor */
  707.     calc_rc0_h(h, parcor0);
  708.     /* compute g0 */
  709.     L_g0 = 0L;
  710.     for(i=0; i<LONG_H_ST; i++) {
  711.         L_temp = L_deposit_l(abs_s(h[i]));
  712.         L_g0   = L_add(L_g0, L_temp);
  713.     }
  714.     g0 = extract_h(L_shl(L_g0, 14));
  715.     /* Scale signal input of 1/A(gamma1) */
  716.     if(sub(g0, 1024)>0) {
  717.         temp = div_s(1024, g0);     /* temp = 2**15 / gain0 */
  718.         for(i=0; i<L_SUBFR; i++) {
  719.             sig_ltp_ptr[i] = mult_r(sig_ltp_ptr[i], temp);
  720.         }
  721.     }
  722.     return;
  723. }
  724. /*----------------------------------------------------------------------------
  725.  * calc_rc0_h - computes 1st parcor from composed filter impulse response
  726.  *----------------------------------------------------------------------------
  727.  */
  728. static void calc_rc0_h(
  729.  Word16 *h,      /* input : impulse response of composed filter */
  730.  Word16 *rc0     /* output: 1st parcor */
  731. )
  732. {
  733.     Word16 acf0, acf1;
  734.     Word32 L_acc;
  735.     Word16 temp, sh_acf;
  736.     Word16 *ptrs;
  737.     int i;
  738.     /* computation of the autocorrelation function acf */
  739.     L_acc  = 0L;
  740.     for(i=0; i<LONG_H_ST; i++) L_acc = L_mac(L_acc, h[i], h[i]);
  741.     sh_acf = norm_l(L_acc);
  742.     L_acc  = L_shl(L_acc, sh_acf);
  743.     acf0   = extract_h(L_acc);
  744.     L_acc  = 0L;
  745.     ptrs   = h;
  746.     for(i=0; i<LONG_H_ST-1; i++){
  747.         temp = *ptrs++;
  748.         L_acc = L_mac(L_acc, temp, *ptrs);
  749.     }
  750.     L_acc = L_shl(L_acc, sh_acf);
  751.     acf1  = extract_h(L_acc);
  752.     /* Compute 1st parcor */
  753.     /**********************/
  754.     if( sub(acf0, abs_s(acf1))<0) {
  755.         *rc0 = 0;
  756.         return;
  757.     }
  758.     *rc0 = div_s(abs_s(acf1), acf0);
  759.     if(acf1 > 0) {
  760.         *rc0 = negate(*rc0);
  761.     }
  762.     return;
  763. }
  764. /*----------------------------------------------------------------------------
  765.  * filt_mu - tilt filtering with : (1 + mu z-1) * (1/1-|mu|)
  766.  *   computes y[n] = (1/1-|mu|) (x[n]+mu*x[n-1])
  767.  *----------------------------------------------------------------------------
  768.  */
  769. static void filt_mu(
  770.  Word16 *sig_in,     /* input : input signal (beginning at sample -1) */
  771.  Word16 *sig_out,    /* output: output signal */
  772.  Word16 parcor0      /* input : parcor0 (mu = parcor0 * gamma3) */
  773. )
  774. {
  775.     int n;
  776.     Word16 mu, mu2, ga, temp;
  777.     Word32 L_acc, L_temp, L_fact;
  778.     Word16 fact, sh_fact1;
  779.     Word16 *ptrs;
  780.     if(parcor0 > 0) {
  781.         mu      = mult_r(parcor0, GAMMA3_PLUS);
  782.         /* GAMMA3_PLUS < 0.5 */
  783.         sh_fact1 = 15;                   /* sh_fact + 1 */
  784.         fact     = (Word16)0x4000;       /* 2**sh_fact */
  785.         L_fact   = (Word32)0x00004000L;
  786.     }
  787.     else {
  788.         mu       = mult_r(parcor0, GAMMA3_MINUS);
  789.         /* GAMMA3_MINUS < 0.9375 */
  790.         sh_fact1 = 12;                   /* sh_fact + 1 */
  791.         fact     = (Word16)0x0800;       /* 2**sh_fact */
  792.         L_fact   = (Word32)0x00000800L;
  793.     }
  794.     temp = sub(1, abs_s(mu));
  795.     mu2  = add(32767, temp);    /* 2**15 (1 - |mu|) */
  796.     ga   = div_s(fact, mu2);    /* 2**sh_fact / (1 - |mu|) */
  797.     ptrs = sig_in;     /* points on sig_in(-1) */
  798.     mu   = shr(mu, 1);          /* to avoid overflows   */
  799.     for(n=0; n<L_SUBFR; n++) {
  800.         temp   = *ptrs++;
  801.         L_temp = L_deposit_l(*ptrs);
  802.         L_acc  = L_shl(L_temp, 15);         /* sig_in(n) * 2**15 */
  803.         L_temp = L_mac(L_acc, mu, temp);
  804.         L_temp = L_add(L_temp, 0x00004000L);
  805.         temp   = extract_l(L_shr(L_temp,15));
  806.         /* ga x temp x 2 with rounding */
  807.         L_temp = L_add(L_mult(temp, ga),L_fact);
  808.         L_temp = L_shr(L_temp, sh_fact1); /* mult. temp x ga */
  809.         sig_out[n] = sature(L_temp);
  810.     }
  811.     return;
  812. }
  813. /*----------------------------------------------------------------------------
  814.  *   scale_st  - control of the subframe gain
  815.  *   gain[n] = AGC_FAC * gain[n-1] + (1 - AGC_FAC) g_in/g_out
  816.  *----------------------------------------------------------------------------
  817.  */
  818. static void scale_st(
  819.  Word16 *sig_in,     /* input : postfilter input signal */
  820.  Word16 *sig_out,    /* in/out: postfilter output signal */
  821.  Word16 *gain_prec   /* in/out: last value of gain for subframe */
  822. )
  823. {
  824.     int i;
  825.     Word16 scal_in, scal_out;
  826.     Word32 L_acc, L_temp;
  827.     Word16 s_g_in, s_g_out, temp, sh_g0, g0;
  828.     Word16 gain;
  829.     /* compute input gain */
  830.     L_acc = 0L;
  831.     for(i=0; i<L_SUBFR; i++) {
  832.         L_temp  = L_abs(L_deposit_l(sig_in[i]));
  833.         L_acc   = L_add(L_acc, L_temp);
  834.     }
  835.     if(L_acc == 0L) {
  836.         g0 = 0;
  837.     }
  838.     else {
  839.         scal_in = norm_l(L_acc);
  840.         L_acc   = L_shl(L_acc, scal_in);
  841.         s_g_in  = extract_h(L_acc);    /* normalized */
  842.         /* Compute output gain */
  843.         L_acc = 0L;
  844.         for(i=0; i<L_SUBFR; i++) {
  845.             L_temp  = L_abs(L_deposit_l(sig_out[i]));
  846.             L_acc   = L_add(L_acc, L_temp);
  847.         }
  848.         if(L_acc == 0L) {
  849.             *gain_prec = 0;
  850.             return;
  851.         }
  852.         scal_out = norm_l(L_acc);
  853.         L_acc    = L_shl(L_acc, scal_out);
  854.         s_g_out  = extract_h(L_acc);  /* normalized */
  855.         sh_g0    = add(scal_in, 1);
  856.         sh_g0    = sub(sh_g0, scal_out);    /* scal_in - scal_out + 1 */
  857.         if(sub(s_g_in ,s_g_out)<0) {
  858.             g0 = div_s(s_g_in, s_g_out);    /* s_g_in/s_g_out in Q15 */
  859.         }
  860.         else {
  861.             temp  = sub(s_g_in, s_g_out);   /* sufficient since normalized */
  862.             g0    = shr(div_s(temp, s_g_out), 1);
  863.             g0    = add(g0, (Word16)0x4000);/* s_g_in/s_g_out in Q14 */
  864.             sh_g0 = sub(sh_g0, 1);
  865.         }
  866.         /* L_gain_in/L_gain_out in Q14              */
  867.         /* overflows if L_gain_in > 2 * L_gain_out  */
  868.         g0 = shr(g0, sh_g0);        /* sh_g0 may be >0, <0, or =0 */
  869.         g0 = mult_r(g0, AGC_FAC1);  /* L_gain_in/L_gain_out * AGC_FAC1      */
  870.     }
  871.     /* gain(n) = AGC_FAC gain(n-1) + AGC_FAC1 gain_in/gain_out          */
  872.     /* sig_out(n) = gain(n) sig_out(n)                                  */
  873.     gain = *gain_prec;
  874.     for(i=0; i<L_SUBFR; i++) {
  875.         temp = mult_r(AGC_FAC, gain);
  876.         gain = add(temp, g0);            /* in Q14 */
  877.         L_temp = L_mult(gain, sig_out[i]);
  878.         L_temp = L_shl(L_temp, 1);
  879.         sig_out[i] = round(L_temp);
  880.     }
  881.     *gain_prec = gain;
  882.     return;
  883. }