acelp_ca.c
上传用户:zhouyunkk
上传日期:2013-01-10
资源大小:59k
文件大小:26k
源码类别:

语音压缩

开发平台:

C/C++

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