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

语音压缩

开发平台:

C/C++

  1. /*
  2.    ITU-T G.729A Speech Coder    ANSI-C Source Code
  3.    Version 1.1    Last modified: September 1996
  4.    Copyright (c) 1996,
  5.    AT&T, France Telecom, NTT, Universite de Sherbrooke
  6.    All rights reserved.
  7. */
  8. /*---------------------------------------------------------------------------*
  9.  *  Function  ACELP_Code_A()                                                 *
  10.  *  ~~~~~~~~~~~~~~~~~~~~~~~~                                                 *
  11.  *   Find Algebraic codebook for G.729A                                      *
  12.  *--------------------------------------------------------------------------*/
  13. #include "typedef.h"
  14. #include "basic_op.h"
  15. #include "ld8a.h"
  16. /* Constants defined in ld8a.h */
  17. /*  L_SUBFR   -> Lenght of subframe.                                        */
  18. /*  NB_POS    -> Number of positions for each pulse.                        */
  19. /*  STEP      -> Step betweem position of the same pulse.                   */
  20. /*  MSIZE     -> Size of vectors for cross-correlation between two pulses.  */
  21. /* local routines definition */
  22. static void Cor_h(
  23.      Word16 *H,         /* (i) Q12 :Impulse response of filters */
  24.      Word16 *rr         /* (o)     :Correlations of H[]         */
  25. );
  26. static Word16 D4i40_17_fast(/*(o) : Index of pulses positions.               */
  27.   Word16 dn[],          /* (i)    : Correlations between h[] and Xn[].       */
  28.   Word16 *rr,           /* (i)    : Correlations of impulse response h[].    */
  29.   Word16 h[],           /* (i) Q12: Impulse response of filters.             */
  30.   Word16 cod[],         /* (o) Q13: Selected algebraic codeword.             */
  31.   Word16 y[],           /* (o) Q12: Filtered algebraic codeword.             */
  32.   Word16 *sign          /* (o)    : Signs of 4 pulses.                       */
  33. );
  34.  /*-----------------------------------------------------------------*
  35.   * Main ACELP function.                                            *
  36.   *-----------------------------------------------------------------*/
  37. Word16  ACELP_Code_A(    /* (o)     :index of pulses positions    */
  38.   Word16 x[],            /* (i)     :Target vector                */
  39.   Word16 h[],            /* (i) Q12 :Inpulse response of filters  */
  40.   Word16 T0,             /* (i)     :Pitch lag                    */
  41.   Word16 pitch_sharp,    /* (i) Q14 :Last quantized pitch gain    */
  42.   Word16 code[],         /* (o) Q13 :Innovative codebook          */
  43.   Word16 y[],            /* (o) Q12 :Filtered innovative codebook */
  44.   Word16 *sign           /* (o)     :Signs of 4 pulses            */
  45. )
  46. {
  47.   Word16 i, index, sharp;
  48.   Word16 Dn[L_SUBFR];
  49.   Word16 rr[DIM_RR];
  50.  /*-----------------------------------------------------------------*
  51.   * Include fixed-gain pitch contribution into impulse resp. h[]    *
  52.   * Find correlations of h[] needed for the codebook search.        *
  53.   *-----------------------------------------------------------------*/
  54.   sharp = shl(pitch_sharp, 1);          /* From Q14 to Q15 */
  55.   if (T0 < L_SUBFR)
  56.      for (i = T0; i < L_SUBFR; i++)     /* h[i] += pitch_sharp*h[i-T0] */
  57.        h[i] = add(h[i], mult(h[i-T0], sharp));
  58.   Cor_h(h, rr);
  59.  /*-----------------------------------------------------------------*
  60.   * Compute correlation of target vector with impulse response.     *
  61.   *-----------------------------------------------------------------*/
  62.   Cor_h_X(h, x, Dn);
  63.  /*-----------------------------------------------------------------*
  64.   * Find innovative codebook.                                       *
  65.   *-----------------------------------------------------------------*/
  66.   index = D4i40_17_fast(Dn, rr, h, code, y, sign);
  67.  /*-----------------------------------------------------------------*
  68.   * Compute innovation vector gain.                                 *
  69.   * Include fixed-gain pitch contribution into code[].              *
  70.   *-----------------------------------------------------------------*/
  71.   if(T0 < L_SUBFR)
  72.      for (i = T0; i < L_SUBFR; i++)    /* code[i] += pitch_sharp*code[i-T0] */
  73.        code[i] = add(code[i], mult(code[i-T0], sharp));
  74.   return index;
  75. }
  76. /*--------------------------------------------------------------------------*
  77.  *  Function  Cor_h()                                                       *
  78.  *  ~~~~~~~~~~~~~~~~~                                                       *
  79.  * Compute  correlations of h[]  needed for the codebook search.            *
  80.  *--------------------------------------------------------------------------*/
  81. static void Cor_h(
  82.   Word16 *H,     /* (i) Q12 :Impulse response of filters */
  83.   Word16 *rr     /* (o)     :Correlations of H[]         */
  84. )
  85. {
  86.   Word16 *rri0i0, *rri1i1, *rri2i2, *rri3i3, *rri4i4;
  87.   Word16 *rri0i1, *rri0i2, *rri0i3, *rri0i4;
  88.   Word16 *rri1i2, *rri1i3, *rri1i4;
  89.   Word16 *rri2i3, *rri2i4;
  90.   Word16 *p0, *p1, *p2, *p3, *p4;
  91.   Word16 *ptr_hd, *ptr_hf, *ptr_h1, *ptr_h2;
  92.   Word32 cor;
  93.   Word16 i, k, ldec, l_fin_sup, l_fin_inf;
  94.   Word16 h[L_SUBFR];
  95.  /* Scaling h[] for maximum precision */
  96.   cor = 0;
  97.   for(i=0; i<L_SUBFR; i++)
  98.     cor = L_mac(cor, H[i], H[i]);
  99.   if(sub(extract_h(cor),32000) > 0)
  100.   {
  101.     for(i=0; i<L_SUBFR; i++) {
  102.       h[i] = shr(H[i], 1);
  103.     }
  104.   }
  105.   else
  106.   {
  107.     k = norm_l(cor);
  108.     k = shr(k, 1);
  109.     for(i=0; i<L_SUBFR; i++) {
  110.       h[i] = shl(H[i], k);
  111.     }
  112.   }
  113.  /*------------------------------------------------------------*
  114.   * Compute rri0i0[], rri1i1[], rri2i2[], rri3i3 and rri4i4[]  *
  115.   *------------------------------------------------------------*/
  116.   /* Init pointers */
  117.   rri0i0 = rr;
  118.   rri1i1 = rri0i0 + NB_POS;
  119.   rri2i2 = rri1i1 + NB_POS;
  120.   rri3i3 = rri2i2 + NB_POS;
  121.   rri4i4 = rri3i3 + NB_POS;
  122.   rri0i1 = rri4i4 + NB_POS;
  123.   rri0i2 = rri0i1 + MSIZE;
  124.   rri0i3 = rri0i2 + MSIZE;
  125.   rri0i4 = rri0i3 + MSIZE;
  126.   rri1i2 = rri0i4 + MSIZE;
  127.   rri1i3 = rri1i2 + MSIZE;
  128.   rri1i4 = rri1i3 + MSIZE;
  129.   rri2i3 = rri1i4 + MSIZE;
  130.   rri2i4 = rri2i3 + MSIZE;
  131.   p0 = rri0i0 + NB_POS-1;   /* Init pointers to last position of rrixix[] */
  132.   p1 = rri1i1 + NB_POS-1;
  133.   p2 = rri2i2 + NB_POS-1;
  134.   p3 = rri3i3 + NB_POS-1;
  135.   p4 = rri4i4 + NB_POS-1;
  136.   ptr_h1 = h;
  137.   cor    = 0;
  138.   for(i=0;  i<NB_POS; i++)
  139.   {
  140.     cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++;
  141.     *p4-- = extract_h(cor);
  142.     cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++;
  143.     *p3-- = extract_h(cor);
  144.     cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++;
  145.     *p2-- = extract_h(cor);
  146.     cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++;
  147.     *p1-- = extract_h(cor);
  148.     cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++;
  149.     *p0-- = extract_h(cor);
  150.   }
  151.  /*-----------------------------------------------------------------*
  152.   * Compute elements of: rri2i3[], rri1i2[], rri0i1[] and rri0i4[]  *
  153.   *-----------------------------------------------------------------*/
  154.   l_fin_sup = MSIZE-1;
  155.   l_fin_inf = l_fin_sup-(Word16)1;
  156.   ldec = NB_POS+1;
  157.   ptr_hd = h;
  158.   ptr_hf = ptr_hd + 1;
  159.   for(k=0; k<NB_POS; k++) {
  160.           p3 = rri2i3 + l_fin_sup;
  161.           p2 = rri1i2 + l_fin_sup;
  162.           p1 = rri0i1 + l_fin_sup;
  163.           p0 = rri0i4 + l_fin_inf;
  164.           cor = 0;
  165.           ptr_h1 = ptr_hd;
  166.           ptr_h2 =  ptr_hf;
  167.           for(i=k+(Word16)1; i<NB_POS; i++ ) {
  168.                   cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  169.                   cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  170.                   *p3 = extract_h(cor);
  171.                   cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  172.                   *p2 = extract_h(cor);
  173.                   cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  174.                   *p1 = extract_h(cor);
  175.                   cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  176.                   *p0 = extract_h(cor);
  177.                   p3 -= ldec;
  178.                   p2 -= ldec;
  179.                   p1 -= ldec;
  180.                   p0 -= ldec;
  181.           }
  182.           cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  183.           cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  184.           *p3 = extract_h(cor);
  185.           cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  186.           *p2 = extract_h(cor);
  187.           cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  188.           *p1 = extract_h(cor);
  189.           l_fin_sup -= NB_POS;
  190.           l_fin_inf--;
  191.           ptr_hf += STEP;
  192.   }
  193.  /*---------------------------------------------------------------------*
  194.   * Compute elements of: rri2i4[], rri1i3[], rri0i2[], rri1i4[], rri0i3 *
  195.   *---------------------------------------------------------------------*/
  196.   ptr_hd = h;
  197.   ptr_hf = ptr_hd + 2;
  198.   l_fin_sup = MSIZE-1;
  199.   l_fin_inf = l_fin_sup-(Word16)1;
  200.   for(k=0; k<NB_POS; k++) {
  201.           p4 = rri2i4 + l_fin_sup;
  202.           p3 = rri1i3 + l_fin_sup;
  203.           p2 = rri0i2 + l_fin_sup;
  204.           p1 = rri1i4 + l_fin_inf;
  205.           p0 = rri0i3 + l_fin_inf;
  206.           cor = 0;
  207.           ptr_h1 = ptr_hd;
  208.           ptr_h2 =  ptr_hf;
  209.           for(i=k+(Word16)1; i<NB_POS; i++ ) {
  210.                   cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  211.                   *p4 = extract_h(cor);
  212.                   cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  213.                   *p3 = extract_h(cor);
  214.                   cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  215.                   *p2 = extract_h(cor);
  216.                   cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  217.                   *p1 = extract_h(cor);
  218.                   cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  219.                   *p0 = extract_h(cor);
  220.                   p4 -= ldec;
  221.                   p3 -= ldec;
  222.                   p2 -= ldec;
  223.                   p1 -= ldec;
  224.                   p0 -= ldec;
  225.           }
  226.           cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  227.           *p4 = extract_h(cor);
  228.           cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  229.           *p3 = extract_h(cor);
  230.           cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  231.           *p2 = extract_h(cor);
  232.           l_fin_sup -= NB_POS;
  233.           l_fin_inf--;
  234.           ptr_hf += STEP;
  235.   }
  236.  /*----------------------------------------------------------------------*
  237.   * Compute elements of: rri1i4[], rri0i3[], rri2i4[], rri1i3[], rri0i2  *
  238.   *----------------------------------------------------------------------*/
  239.   ptr_hd = h;
  240.   ptr_hf = ptr_hd + 3;
  241.   l_fin_sup = MSIZE-1;
  242.   l_fin_inf = l_fin_sup-(Word16)1;
  243.   for(k=0; k<NB_POS; k++) {
  244.           p4 = rri1i4 + l_fin_sup;
  245.           p3 = rri0i3 + l_fin_sup;
  246.           p2 = rri2i4 + l_fin_inf;
  247.           p1 = rri1i3 + l_fin_inf;
  248.           p0 = rri0i2 + l_fin_inf;
  249.           ptr_h1 = ptr_hd;
  250.           ptr_h2 =  ptr_hf;
  251.           cor = 0;
  252.           for(i=k+(Word16)1; i<NB_POS; i++ ) {
  253.                   cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  254.                   *p4 = extract_h(cor);
  255.                   cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  256.                   *p3 = extract_h(cor);
  257.                   cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  258.                   *p2 = extract_h(cor);
  259.                   cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  260.                   *p1 = extract_h(cor);
  261.                   cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  262.                   *p0 = extract_h(cor);
  263.                   p4 -= ldec;
  264.                   p3 -= ldec;
  265.                   p2 -= ldec;
  266.                   p1 -= ldec;
  267.                   p0 -= ldec;
  268.           }
  269.           cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  270.           *p4 = extract_h(cor);
  271.           cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  272.           *p3 = extract_h(cor);
  273.           l_fin_sup -= NB_POS;
  274.           l_fin_inf--;
  275.           ptr_hf += STEP;
  276.   }
  277.  /*----------------------------------------------------------------------*
  278.   * Compute elements of: rri0i4[], rri2i3[], rri1i2[], rri0i1[]          *
  279.   *----------------------------------------------------------------------*/
  280.   ptr_hd = h;
  281.   ptr_hf = ptr_hd + 4;
  282.   l_fin_sup = MSIZE-1;
  283.   l_fin_inf = l_fin_sup-(Word16)1;
  284.   for(k=0; k<NB_POS; k++) {
  285.           p3 = rri0i4 + l_fin_sup;
  286.           p2 = rri2i3 + l_fin_inf;
  287.           p1 = rri1i2 + l_fin_inf;
  288.           p0 = rri0i1 + l_fin_inf;
  289.           ptr_h1 = ptr_hd;
  290.           ptr_h2 =  ptr_hf;
  291.           cor = 0;
  292.           for(i=k+(Word16)1; i<NB_POS; i++ ) {
  293.                   cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  294.                   *p3 = extract_h(cor);
  295.                   cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  296.                   cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  297.                   *p2 = extract_h(cor);
  298.                   cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  299.                   *p1 = extract_h(cor);
  300.                   cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  301.                   *p0 = extract_h(cor);
  302.                   p3 -= ldec;
  303.                   p2 -= ldec;
  304.                   p1 -= ldec;
  305.                   p0 -= ldec;
  306.           }
  307.           cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  308.           *p3 = extract_h(cor);
  309.           l_fin_sup -= NB_POS;
  310.           l_fin_inf--;
  311.           ptr_hf += STEP;
  312.   }
  313.   return;
  314. }
  315. /*------------------------------------------------------------------------*
  316.  * Function  D4i40_17_fast()                                              *
  317.  *           ~~~~~~~~~                                                    *
  318.  * Algebraic codebook for ITU 8kb/s.                                      *
  319.  *  -> 17 bits; 4 pulses in a frame of 40 samples                         *
  320.  *                                                                        *
  321.  *------------------------------------------------------------------------*
  322.  * The code length is 40, containing 4 nonzero pulses i0, i1, i2, i3.     *
  323.  * Each pulses can have 8 possible positions (positive or negative)       *
  324.  * except i3 that have 16 possible positions.                             *
  325.  *                                                                        *
  326.  * i0 (+-1) : 0, 5, 10, 15, 20, 25, 30, 35                                *
  327.  * i1 (+-1) : 1, 6, 11, 16, 21, 26, 31, 36                                *
  328.  * i2 (+-1) : 2, 7, 12, 17, 22, 27, 32, 37                                *
  329.  * i3 (+-1) : 3, 8, 13, 18, 23, 28, 33, 38                                *
  330.  *            4, 9, 14, 19, 24, 29, 34, 39                                *
  331.  *------------------------------------------------------------------------*/
  332. static Word16 D4i40_17_fast(/*(o) : Index of pulses positions.               */
  333.   Word16 dn[],          /* (i)    : Correlations between h[] and Xn[].       */
  334.   Word16 rr[],          /* (i)    : Correlations of impulse response h[].    */
  335.   Word16 h[],           /* (i) Q12: Impulse response of filters.             */
  336.   Word16 cod[],         /* (o) Q13: Selected algebraic codeword.             */
  337.   Word16 y[],           /* (o) Q12: Filtered algebraic codeword.             */
  338.   Word16 *sign          /* (o)    : Signs of 4 pulses.                       */
  339. )
  340. {
  341.   Word16 i0, i1, i2, i3, ip0, ip1, ip2, ip3;
  342.   Word16 i, j, ix, iy, track, trk, max;
  343.   Word16 prev_i0, i1_offset;
  344.   Word16 psk, ps, ps0, ps1, ps2, sq, sq2;
  345.   Word16 alpk, alp, alp_16;
  346.   Word32 s, alp0, alp1, alp2;
  347.   Word16 *p0, *p1, *p2, *p3, *p4;
  348.   Word16 sign_dn[L_SUBFR], sign_dn_inv[L_SUBFR], *psign;
  349.   Word16 tmp_vect[NB_POS];
  350.   Word16 *rri0i0, *rri1i1, *rri2i2, *rri3i3, *rri4i4;
  351.   Word16 *rri0i1, *rri0i2, *rri0i3, *rri0i4;
  352.   Word16 *rri1i2, *rri1i3, *rri1i4;
  353.   Word16 *rri2i3, *rri2i4;
  354.   Word16  *ptr_rri0i3_i4;
  355.   Word16  *ptr_rri1i3_i4;
  356.   Word16  *ptr_rri2i3_i4;
  357.   Word16  *ptr_rri3i3_i4;
  358.      /* Init pointers */
  359.    rri0i0 = rr;
  360.    rri1i1 = rri0i0 + NB_POS;
  361.    rri2i2 = rri1i1 + NB_POS;
  362.    rri3i3 = rri2i2 + NB_POS;
  363.    rri4i4 = rri3i3 + NB_POS;
  364.    rri0i1 = rri4i4 + NB_POS;
  365.    rri0i2 = rri0i1 + MSIZE;
  366.    rri0i3 = rri0i2 + MSIZE;
  367.    rri0i4 = rri0i3 + MSIZE;
  368.    rri1i2 = rri0i4 + MSIZE;
  369.    rri1i3 = rri1i2 + MSIZE;
  370.    rri1i4 = rri1i3 + MSIZE;
  371.    rri2i3 = rri1i4 + MSIZE;
  372.    rri2i4 = rri2i3 + MSIZE;
  373.  /*-----------------------------------------------------------------------*
  374.   * Chose the sign of the impulse.                                        *
  375.   *-----------------------------------------------------------------------*/
  376.    for (i=0; i<L_SUBFR; i++)
  377.    {
  378.      if (dn[i] >= 0)
  379.      {
  380.        sign_dn[i] = MAX_16;
  381.        sign_dn_inv[i] = MIN_16;
  382.      }
  383.      else
  384.      {
  385.        sign_dn[i] = MIN_16;
  386.        sign_dn_inv[i] = MAX_16;
  387.        dn[i] = negate(dn[i]);
  388.      }
  389.    }
  390.  /*-------------------------------------------------------------------*
  391.   * Modification of rrixiy[] to take signs into account.              *
  392.   *-------------------------------------------------------------------*/
  393.   p0 = rri0i1;
  394.   p1 = rri0i2;
  395.   p2 = rri0i3;
  396.   p3 = rri0i4;
  397.   for(i0=0; i0<L_SUBFR; i0+=STEP)
  398.   {
  399.     psign = sign_dn;
  400.     if (psign[i0] < 0) psign = sign_dn_inv;
  401.     for(i1=1; i1<L_SUBFR; i1+=STEP)
  402.     {
  403.       *p0++ = mult(*p0, psign[i1]);
  404.       *p1++ = mult(*p1, psign[i1+1]);
  405.       *p2++ = mult(*p2, psign[i1+2]);
  406.       *p3++ = mult(*p3, psign[i1+3]);
  407.     }
  408.   }
  409.   p0 = rri1i2;
  410.   p1 = rri1i3;
  411.   p2 = rri1i4;
  412.   for(i1=1; i1<L_SUBFR; i1+=STEP)
  413.   {
  414.     psign = sign_dn;
  415.     if (psign[i1] < 0) psign = sign_dn_inv;
  416.     for(i2=2; i2<L_SUBFR; i2+=STEP)
  417.     {
  418.       *p0++ = mult(*p0, psign[i2]);
  419.       *p1++ = mult(*p1, psign[i2+1]);
  420.       *p2++ = mult(*p2, psign[i2+2]);
  421.     }
  422.   }
  423.   p0 = rri2i3;
  424.   p1 = rri2i4;
  425.   for(i2=2; i2<L_SUBFR; i2+=STEP)
  426.   {
  427.     psign = sign_dn;
  428.     if (psign[i2] < 0) psign = sign_dn_inv;
  429.     for(i3=3; i3<L_SUBFR; i3+=STEP)
  430.     {
  431.       *p0++ = mult(*p0, psign[i3]);
  432.       *p1++ = mult(*p1, psign[i3+1]);
  433.     }
  434.   }
  435.  /*-------------------------------------------------------------------*
  436.   * Search the optimum positions of the four pulses which maximize    *
  437.   *     square(correlation) / energy                                  *
  438.   *-------------------------------------------------------------------*/
  439.   psk = -1;
  440.   alpk = 1;
  441.   ptr_rri0i3_i4 = rri0i3;
  442.   ptr_rri1i3_i4 = rri1i3;
  443.   ptr_rri2i3_i4 = rri2i3;
  444.   ptr_rri3i3_i4 = rri3i3;
  445.   /* Initializations only to remove warning from some compilers */
  446.   ip0=0; ip1=1; ip2=2; ip3=3; ix=0; iy=0; ps=0;
  447.   /* search 2 times: track 3 and 4 */
  448.   for (track=3, trk=0; track<5; track++, trk++)
  449.   {
  450.    /*------------------------------------------------------------------*
  451.     * depth first search 3, phase A: track 2 and 3/4.                  *
  452.     *------------------------------------------------------------------*/
  453.     sq = -1;
  454.     alp = 1;
  455.     /* i0 loop: 2 positions in track 2 */
  456.     prev_i0  = -1;
  457.     for (i=0; i<2; i++)
  458.     {
  459.       max = -1;
  460.       /* search "dn[]" maximum position in track 2 */
  461.       for (j=2; j<L_SUBFR; j+=STEP)
  462.       {
  463.         if ((sub(dn[j], max) > 0) && (sub(prev_i0,j) != 0))
  464.         {
  465.           max = dn[j];
  466.           i0 = j;
  467.         }
  468.       }
  469.       prev_i0 = i0;
  470.       j = mult(i0, 6554);        /* j = i0/5 */
  471.       p0 = rri2i2 + j;
  472.       ps1 = dn[i0];
  473.       alp1 = L_mult(*p0, _1_4);
  474.       /* i1 loop: 8 positions in track 2 */
  475.       p0 = ptr_rri2i3_i4 + shl(j, 3);
  476.       p1 = ptr_rri3i3_i4;
  477.       for (i1=track; i1<L_SUBFR; i1+=STEP)
  478.       {
  479.         ps2 = add(ps1, dn[i1]);       /* index increment = STEP */
  480.         /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */
  481.         alp2 = L_mac(alp1, *p0++, _1_2);
  482.         alp2 = L_mac(alp2, *p1++, _1_4);
  483.         sq2 = mult(ps2, ps2);
  484.         alp_16 = round(alp2);
  485.         s = L_msu(L_mult(alp,sq2),sq,alp_16);
  486.         if (s > 0)
  487.         {
  488.           sq = sq2;
  489.           ps = ps2;
  490.           alp = alp_16;
  491.           ix = i0;
  492.           iy = i1;
  493.         }
  494.       }
  495.     }
  496.     i0 = ix;
  497.     i1 = iy;
  498.     i1_offset = shl(mult(i1, 6554), 3);       /* j = 8*(i1/5) */
  499.    /*------------------------------------------------------------------*
  500.     * depth first search 3, phase B: track 0 and 1.                    *
  501.     *------------------------------------------------------------------*/
  502.     ps0 = ps;
  503.     alp0 = L_mult(alp, _1_4);
  504.     sq = -1;
  505.     alp = 1;
  506.     /* build vector for next loop to decrease complexity */
  507.     p0 = rri1i2 + mult(i0, 6554);
  508.     p1 = ptr_rri1i3_i4 + mult(i1, 6554);
  509.     p2 = rri1i1;
  510.     p3 = tmp_vect;
  511.     for (i3=1; i3<L_SUBFR; i3+=STEP)
  512.     {
  513.       /* rrv[i3] = rr[i3][i3] + rr[i0][i3] + rr[i1][i3]; */
  514.       s = L_mult(*p0, _1_4);        p0 += NB_POS;
  515.       s = L_mac(s, *p1, _1_4);      p1 += NB_POS;
  516.       s = L_mac(s, *p2++, _1_8);
  517.       *p3++ = round(s);
  518.     }
  519.     /* i2 loop: 8 positions in track 0 */
  520.     p0 = rri0i2 + mult(i0, 6554);
  521.     p1 = ptr_rri0i3_i4 + mult(i1, 6554);
  522.     p2 = rri0i0;
  523.     p3 = rri0i1;
  524.     for (i2=0; i2<L_SUBFR; i2+=STEP)
  525.     {
  526.       ps1 = add(ps0, dn[i2]);         /* index increment = STEP */
  527.       /* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */
  528.       alp1 = L_mac(alp0, *p0, _1_8);       p0 += NB_POS;
  529.       alp1 = L_mac(alp1, *p1, _1_8);       p1 += NB_POS;
  530.       alp1 = L_mac(alp1, *p2++, _1_16);
  531.       /* i3 loop: 8 positions in track 1 */
  532.       p4 = tmp_vect;
  533.       for (i3=1; i3<L_SUBFR; i3+=STEP)
  534.       {
  535.         ps2 = add(ps1, dn[i3]);       /* index increment = STEP */
  536.         /* alp1 = alp0 + rr[i0][i3] + rr[i1][i3] + rr[i2][i3] + 1/2*rr[i3][i3]; */
  537.         alp2 = L_mac(alp1, *p3++, _1_8);
  538.         alp2 = L_mac(alp2, *p4++, _1_2);
  539.         sq2 = mult(ps2, ps2);
  540.         alp_16 = round(alp2);
  541.         s = L_msu(L_mult(alp,sq2),sq,alp_16);
  542.         if (s > 0)
  543.         {
  544.           sq = sq2;
  545.           alp = alp_16;
  546.           ix = i2;
  547.           iy = i3;
  548.         }
  549.       }
  550.     }
  551.    /*----------------------------------------------------------------*
  552.     * depth first search 3: compare codevector with the best case.   *
  553.     *----------------------------------------------------------------*/
  554.     s = L_msu(L_mult(alpk,sq),psk,alp);
  555.     if (s > 0)
  556.     {
  557.       psk = sq;
  558.       alpk = alp;
  559.       ip2 = i0;
  560.       ip3 = i1;
  561.       ip0 = ix;
  562.       ip1 = iy;
  563.     }
  564.    /*------------------------------------------------------------------*
  565.     * depth first search 4, phase A: track 3 and 0.                    *
  566.     *------------------------------------------------------------------*/
  567.     sq = -1;
  568.     alp = 1;
  569.     /* i0 loop: 2 positions in track 3/4 */
  570.     prev_i0  = -1;
  571.     for (i=0; i<2; i++)
  572.     {
  573.       max = -1;
  574.       /* search "dn[]" maximum position in track 3/4 */
  575.       for (j=track; j<L_SUBFR; j+=STEP)
  576.       {
  577.         if ((sub(dn[j], max) > 0) && (sub(prev_i0,j) != 0))
  578.         {
  579.           max = dn[j];
  580.           i0 = j;
  581.         }
  582.       }
  583.       prev_i0 = i0;
  584.       j = mult(i0, 6554);        /* j = i0/5 */
  585.       p0 = ptr_rri3i3_i4 + j;
  586.       ps1 = dn[i0];
  587.       alp1 = L_mult(*p0, _1_4);
  588.       /* i1 loop: 8 positions in track 0 */
  589.       p0 = ptr_rri0i3_i4 + j;
  590.       p1 = rri0i0;
  591.       for (i1=0; i1<L_SUBFR; i1+=STEP)
  592.       {
  593.         ps2 = add(ps1, dn[i1]);       /* index increment = STEP */
  594.         /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */
  595.         alp2 = L_mac(alp1, *p0, _1_2);       p0 += NB_POS;
  596.         alp2 = L_mac(alp2, *p1++, _1_4);
  597.         sq2 = mult(ps2, ps2);
  598.         alp_16 = round(alp2);
  599.         s = L_msu(L_mult(alp,sq2),sq,alp_16);
  600.         if (s > 0)
  601.         {
  602.           sq = sq2;
  603.           ps = ps2;
  604.           alp = alp_16;
  605.           ix = i0;
  606.           iy = i1;
  607.         }
  608.       }
  609.     }
  610.     i0 = ix;
  611.     i1 = iy;
  612.     i1_offset = shl(mult(i1, 6554), 3);       /* j = 8*(i1/5) */
  613.    /*------------------------------------------------------------------*
  614.     * depth first search 4, phase B: track 1 and 2.                    *
  615.     *------------------------------------------------------------------*/
  616.     ps0 = ps;
  617.     alp0 = L_mult(alp, _1_4);
  618.     sq = -1;
  619.     alp = 1;
  620.     /* build vector for next loop to decrease complexity */
  621.     p0 = ptr_rri2i3_i4 + mult(i0, 6554);
  622.     p1 = rri0i2 + i1_offset;
  623.     p2 = rri2i2;
  624.     p3 = tmp_vect;
  625.     for (i3=2; i3<L_SUBFR; i3+=STEP)
  626.     {
  627.       /* rrv[i3] = rr[i3][i3] + rr[i0][i3] + rr[i1][i3]; */
  628.       s = L_mult(*p0, _1_4);         p0 += NB_POS;
  629.       s = L_mac(s, *p1++, _1_4);
  630.       s = L_mac(s, *p2++, _1_8);
  631.       *p3++ = round(s);
  632.     }
  633.     /* i2 loop: 8 positions in track 1 */
  634.     p0 = ptr_rri1i3_i4 + mult(i0, 6554);
  635.     p1 = rri0i1 + i1_offset;
  636.     p2 = rri1i1;
  637.     p3 = rri1i2;
  638.     for (i2=1; i2<L_SUBFR; i2+=STEP)
  639.     {
  640.       ps1 = add(ps0, dn[i2]);         /* index increment = STEP */
  641.       /* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */
  642.       alp1 = L_mac(alp0, *p0, _1_8);       p0 += NB_POS;
  643.       alp1 = L_mac(alp1, *p1++, _1_8);
  644.       alp1 = L_mac(alp1, *p2++, _1_16);
  645.       /* i3 loop: 8 positions in track 2 */
  646.       p4 = tmp_vect;
  647.       for (i3=2; i3<L_SUBFR; i3+=STEP)
  648.       {
  649.         ps2 = add(ps1, dn[i3]);       /* index increment = STEP */
  650.         /* alp1 = alp0 + rr[i0][i3] + rr[i1][i3] + rr[i2][i3] + 1/2*rr[i3][i3]; */
  651.         alp2 = L_mac(alp1, *p3++, _1_8);
  652.         alp2 = L_mac(alp2, *p4++, _1_2);
  653.         sq2 = mult(ps2, ps2);
  654.         alp_16 = round(alp2);
  655.         s = L_msu(L_mult(alp,sq2),sq,alp_16);
  656.         if (s > 0)
  657.         {
  658.           sq = sq2;
  659.           alp = alp_16;
  660.           ix = i2;
  661.           iy = i3;
  662.         }
  663.       }
  664.     }
  665.    /*----------------------------------------------------------------*
  666.     * depth first search 1: compare codevector with the best case.   *
  667.     *----------------------------------------------------------------*/
  668.     s = L_msu(L_mult(alpk,sq),psk,alp);
  669.     if (s > 0)
  670.     {
  671.       psk = sq;
  672.       alpk = alp;
  673.       ip3 = i0;
  674.       ip0 = i1;
  675.       ip1 = ix;
  676.       ip2 = iy;
  677.     }
  678.   ptr_rri0i3_i4 = rri0i4;
  679.   ptr_rri1i3_i4 = rri1i4;
  680.   ptr_rri2i3_i4 = rri2i4;
  681.   ptr_rri3i3_i4 = rri4i4;
  682.   }
  683.  /* Set the sign of impulses */
  684.  i0 = sign_dn[ip0];
  685.  i1 = sign_dn[ip1];
  686.  i2 = sign_dn[ip2];
  687.  i3 = sign_dn[ip3];
  688.  /* Find the codeword corresponding to the selected positions */
  689.  for(i=0; i<L_SUBFR; i++) {
  690.    cod[i] = 0;
  691.  }
  692.  cod[ip0] = shr(i0, 2);         /* From Q15 to Q13 */
  693.  cod[ip1] = shr(i1, 2);
  694.  cod[ip2] = shr(i2, 2);
  695.  cod[ip3] = shr(i3, 2);
  696.  /* find the filtered codeword */
  697.  for (i = 0; i < ip0; i++) y[i] = 0;
  698.  if(i0 > 0)
  699.    for(i=ip0, j=0; i<L_SUBFR; i++, j++) y[i] = h[j];
  700.  else
  701.    for(i=ip0, j=0; i<L_SUBFR; i++, j++) y[i] = negate(h[j]);
  702.  if(i1 > 0)
  703.    for(i=ip1, j=0; i<L_SUBFR; i++, j++) y[i] = add(y[i], h[j]);
  704.  else
  705.    for(i=ip1, j=0; i<L_SUBFR; i++, j++) y[i] = sub(y[i], h[j]);
  706.  if(i2 > 0)
  707.    for(i=ip2, j=0; i<L_SUBFR; i++, j++) y[i] = add(y[i], h[j]);
  708.  else
  709.    for(i=ip2, j=0; i<L_SUBFR; i++, j++) y[i] = sub(y[i], h[j]);
  710.  if(i3 > 0)
  711.    for(i=ip3, j=0; i<L_SUBFR; i++, j++) y[i] = add(y[i], h[j]);
  712.  else
  713.    for(i=ip3, j=0; i<L_SUBFR; i++, j++) y[i] = sub(y[i], h[j]);
  714.  /* find codebook index;  17-bit address */
  715.  i = 0;
  716.  if(i0 > 0) i = add(i, 1);
  717.  if(i1 > 0) i = add(i, 2);
  718.  if(i2 > 0) i = add(i, 4);
  719.  if(i3 > 0) i = add(i, 8);
  720.  *sign = i;
  721.  ip0 = mult(ip0, 6554);         /* ip0/5 */
  722.  ip1 = mult(ip1, 6554);         /* ip1/5 */
  723.  ip2 = mult(ip2, 6554);         /* ip2/5 */
  724.  i   = mult(ip3, 6554);         /* ip3/5 */
  725.  j   = add(i, shl(i, 2));       /* j = i*5 */
  726.  j   = sub(ip3, add(j, 3));     /* j= ip3%5 -3 */
  727.  ip3 = add(shl(i, 1), j);
  728.  i = add(ip0, shl(ip1, 3));
  729.  i = add(i  , shl(ip2, 6));
  730.  i = add(i  , shl(ip3, 9));
  731.  return i;
  732. }