Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 /****************************************************************************************
     19 Portions of this file are derived from the following 3GPP standard:
     20 
     21     3GPP TS 26.073
     22     ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
     23     Available from http://www.3gpp.org
     24 
     25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
     26 Permission to distribute, modify and use this file under the standard license
     27 terms listed above has been obtained from the copyright holder.
     28 ****************************************************************************************/
     29 /*
     30 ------------------------------------------------------------------------------
     31 
     32 
     33 
     34  Pathname: ./audio/gsm-amr/c/src/c3_14pf.c
     35  Functions:
     36 
     37      Date: 05/26/2000
     38 
     39 ------------------------------------------------------------------------------
     40  REVISION HISTORY
     41 
     42  Description: Modified to pass overflow flag through to basic math function.
     43  The flag is passed back to the calling function by pointer reference.
     44 
     45  Description: Optimized file to reduce clock cycle usage. Updated copyright
     46               year. Removed unneccesary include files and added only the
     47               include files for the math functions used. Removed unused
     48               #defines.
     49 
     50  Description: Changed round function name to pv_round to avoid conflict with
     51               round function in C standard library.
     52 
     53  Description:  Replaced "int" and/or "char" with OSCL defined types.
     54 
     55  Description:
     56 
     57 ------------------------------------------------------------------------------
     58  MODULE DESCRIPTION
     59 
     60 ------------------------------------------------------------------------------
     61 */
     62 
     63 /*----------------------------------------------------------------------------
     64 ; INCLUDES
     65 ----------------------------------------------------------------------------*/
     66 #include "c3_14pf.h"
     67 #include "typedef.h"
     68 #include "inv_sqrt.h"
     69 #include "cnst.h"
     70 #include "cor_h.h"
     71 #include "set_sign.h"
     72 #include "basic_op.h"
     73 
     74 /*----------------------------------------------------------------------------
     75 ; MACROS
     76 ; Define module specific macros here
     77 ----------------------------------------------------------------------------*/
     78 
     79 /*----------------------------------------------------------------------------
     80 ; DEFINES
     81 ; Include all pre-processor statements here. Include conditional
     82 ; compile variables also.
     83 ----------------------------------------------------------------------------*/
     84 
     85 #define NB_PULSE  3
     86 
     87 /*----------------------------------------------------------------------------
     88 ; LOCAL FUNCTION DEFINITIONS
     89 ; Function Prototype declaration
     90 ----------------------------------------------------------------------------*/
     91 static void search_3i40(
     92     Word16 dn[],        /* i : correlation between target and h[]            */
     93     Word16 dn2[],       /* i : maximum of corr. in each track.               */
     94     Word16 rr[][L_CODE],/* i : matrix of autocorrelation                     */
     95     Word16 codvec[],    /* o : algebraic codebook vector                     */
     96     Flag   * pOverflow  /* o : Flag set when overflow occurs                 */
     97 );
     98 
     99 static Word16 build_code(
    100     Word16 codvec[],    /* i : algebraic codebook vector                     */
    101     Word16 dn_sign[],   /* i : sign of dn[]                                  */
    102     Word16 cod[],       /* o : algebraic (fixed) codebook excitation         */
    103     Word16 h[],         /* i : impulse response of weighted synthesis filter */
    104     Word16 y[],         /* o : filtered fixed codebook excitation            */
    105     Word16 sign[],      /* o : sign of 3 pulses                              */
    106     Flag   * pOverflow  /* o : Flag set when overflow occurs                 */
    107 );
    108 
    109 /*----------------------------------------------------------------------------
    110 ; LOCAL VARIABLE DEFINITIONS
    111 ; Variable declaration - defined here and used outside this module
    112 ----------------------------------------------------------------------------*/
    113 
    114 /*----------------------------------------------------------------------------
    115 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
    116 ; Declare variables used in this module but defined elsewhere
    117 ----------------------------------------------------------------------------*/
    118 
    119 /*
    120 ------------------------------------------------------------------------------
    121  FUNCTION NAME: code_3i40_14bits
    122 ------------------------------------------------------------------------------
    123  INPUT AND OUTPUT DEFINITIONS
    124 
    125  Inputs:
    126     x[]   Array of type Word16 -- target vector
    127     h[]   Array of type Word16 -- impulse response of weighted synthesis filter
    128                                   h[-L_subfr..-1] must be set to zero.
    129 
    130     T0           Array of type Word16 -- Pitch lag
    131     pitch_sharp, Array of type Word16 --  Last quantized pitch gain
    132 
    133  Outputs:
    134     code[]  Array of type Word16 -- Innovative codebook
    135     y[]     Array of type Word16 -- filtered fixed codebook excitation
    136     * sign  Pointer of type Word16 -- Pointer to the signs of 3 pulses
    137     pOverflow    Pointer to Flag      -- set when overflow occurs
    138 
    139  Returns:
    140     index
    141 
    142  Global Variables Used:
    143     None
    144 
    145  Local Variables Needed:
    146     None
    147 
    148 ------------------------------------------------------------------------------
    149  FUNCTION DESCRIPTION
    150 
    151  PURPOSE:  Searches a 14 bit algebraic codebook containing 3 pulses
    152            in a frame of 40 samples.
    153 
    154  DESCRIPTION:
    155     The code length is 40, containing 3 nonzero pulses: i0...i2.
    156     All pulses can have two possible amplitudes: +1 or -1.
    157     Pulse i0 can have 8 possible positions, pulses i1 and i2 can have
    158     2x8=16 positions.
    159 
    160         i0 :  0, 5, 10, 15, 20, 25, 30, 35.
    161         i1 :  1, 6, 11, 16, 21, 26, 31, 36.
    162               3, 8, 13, 18, 23, 28, 33, 38.
    163         i2 :  2, 7, 12, 17, 22, 27, 32, 37.
    164               4, 9, 14, 19, 24, 29, 34, 39.
    165 
    166 ------------------------------------------------------------------------------
    167  REQUIREMENTS
    168 
    169  None
    170 
    171 ------------------------------------------------------------------------------
    172  REFERENCES
    173 
    174  [1] c3_14pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    175 
    176 ------------------------------------------------------------------------------
    177  PSEUDO-CODE
    178 
    179 ------------------------------------------------------------------------------
    180  RESOURCES USED [optional]
    181 
    182  When the code is written for a specific target processor the
    183  the resources used should be documented below.
    184 
    185  HEAP MEMORY USED: x bytes
    186 
    187  STACK MEMORY USED: x bytes
    188 
    189  CLOCK CYCLES: (cycle count equation for this function) + (variable
    190                 used to represent cycle count for each subroutine
    191                 called)
    192      where: (cycle count variable) = cycle count for [subroutine
    193                                      name]
    194 
    195 ------------------------------------------------------------------------------
    196  CAUTION [optional]
    197  [State any special notes, constraints or cautions for users of this function]
    198 
    199 ------------------------------------------------------------------------------
    200 */
    201 
    202 Word16 code_3i40_14bits(
    203     Word16 x[],         /* i : target vector                                 */
    204     Word16 h[],         /* i : impulse response of weighted synthesis filter */
    205     /*     h[-L_subfr..-1] must be set to zero.          */
    206     Word16 T0,          /* i : Pitch lag                                     */
    207     Word16 pitch_sharp, /* i : Last quantized pitch gain                     */
    208     Word16 code[],      /* o : Innovative codebook                           */
    209     Word16 y[],         /* o : filtered fixed codebook excitation            */
    210     Word16 * sign,      /* o : Signs of 3 pulses                             */
    211     Flag   * pOverflow  /* o : Flag set when overflow occurs                 */
    212 )
    213 {
    214     Word16 codvec[NB_PULSE];
    215     Word16 dn[L_CODE];
    216     Word16 dn2[L_CODE];
    217     Word16 dn_sign[L_CODE];
    218     Word16 rr[L_CODE][L_CODE];
    219     Word16 i;
    220     Word16 index;
    221     Word16 sharp;
    222     Word16 tempWord;
    223 
    224     /* sharp = shl(pitch_sharp, 1, pOverflow); */
    225     sharp = pitch_sharp << 1;
    226 
    227     if (T0 < L_CODE)
    228     {
    229         for (i = T0; i < L_CODE; i++)
    230         {
    231             tempWord =
    232                 mult(
    233                     h[i - T0],
    234                     sharp,
    235                     pOverflow);
    236 
    237             h[i] =
    238                 add(
    239                     h[i],
    240                     tempWord,
    241                     pOverflow);
    242         }
    243     }
    244 
    245     cor_h_x(
    246         h,
    247         x,
    248         dn,
    249         1,
    250         pOverflow);
    251 
    252     set_sign(
    253         dn,
    254         dn_sign,
    255         dn2,
    256         6);
    257 
    258     cor_h(
    259         h,
    260         dn_sign,
    261         rr,
    262         pOverflow);
    263 
    264     search_3i40(
    265         dn,
    266         dn2,
    267         rr,
    268         codvec,
    269         pOverflow);
    270 
    271     /* function result */
    272     index =
    273         build_code(
    274             codvec,
    275             dn_sign,
    276             code,
    277             h,
    278             y,
    279             sign,
    280             pOverflow);
    281 
    282     /*-----------------------------------------------------------------*
    283     * Compute innovation vector gain.                                 *
    284     * Include fixed-gain pitch contribution into code[].              *
    285     *-----------------------------------------------------------------*/
    286 
    287     if (T0 < L_CODE)
    288     {
    289         for (i = T0; i < L_CODE; i++)
    290         {
    291             tempWord =
    292                 mult(
    293                     code[i - T0],
    294                     sharp,
    295                     pOverflow);
    296 
    297             code[i] =
    298                 add(
    299                     code[i],
    300                     tempWord,
    301                     pOverflow);
    302         }
    303     }
    304     return index;
    305 }
    306 
    307 /****************************************************************************/
    308 
    309 /*
    310 ------------------------------------------------------------------------------
    311  FUNCTION NAME: search_3i40
    312 ------------------------------------------------------------------------------
    313  INPUT AND OUTPUT DEFINITIONS
    314 
    315  Inputs:
    316     dn[]         Array of type Word16 -- correlation between target and h[]
    317     dn2[]        Array of type Word16 -- maximum of corr. in each track.
    318     rr[][L_CODE] Double Array of type Word16 -- autocorrelation matrix
    319 
    320  Outputs:
    321     codvec[]     Array of type Word16 -- algebraic codebook vector
    322     pOverflow    Pointer to Flag      -- set when overflow occurs
    323 
    324  Returns:
    325     None
    326 
    327  Global Variables Used:
    328     None
    329 
    330  Local Variables Needed:
    331     None
    332 
    333 ------------------------------------------------------------------------------
    334  FUNCTION DESCRIPTION
    335 
    336  PURPOSE: Search the best codevector; determine positions of the 3 pulses
    337           in the 40-sample frame.
    338 ------------------------------------------------------------------------------
    339  REQUIREMENTS
    340 
    341  None
    342 
    343 ------------------------------------------------------------------------------
    344  REFERENCES
    345 
    346  [1] c3_14pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    347 
    348 ------------------------------------------------------------------------------
    349  PSEUDO-CODE
    350 
    351 ------------------------------------------------------------------------------
    352  RESOURCES USED [optional]
    353 
    354  When the code is written for a specific target processor the
    355  the resources used should be documented below.
    356 
    357  HEAP MEMORY USED: x bytes
    358 
    359  STACK MEMORY USED: x bytes
    360 
    361  CLOCK CYCLES: (cycle count equation for this function) + (variable
    362                 used to represent cycle count for each subroutine
    363                 called)
    364      where: (cycle count variable) = cycle count for [subroutine
    365                                      name]
    366 
    367 ------------------------------------------------------------------------------
    368  CAUTION [optional]
    369  [State any special notes, constraints or cautions for users of this function]
    370 
    371 ------------------------------------------------------------------------------
    372 */
    373 static void search_3i40(
    374     Word16 dn[],         /* i : correlation between target and h[] */
    375     Word16 dn2[],        /* i : maximum of corr. in each track.    */
    376     Word16 rr[][L_CODE], /* i : matrix of autocorrelation          */
    377     Word16 codvec[],     /* o : algebraic codebook vector          */
    378     Flag   * pOverflow   /* o : Flag set when overflow occurs      */
    379 )
    380 {
    381     Word16 i0;
    382     Word16 i1;
    383     Word16 i2;
    384 
    385     Word16 ix = 0; /* initialization only needed to keep gcc silent */
    386     Word16 ps = 0; /* initialization only needed to keep gcc silent */
    387 
    388     Word16 i;
    389     Word16 pos;
    390     Word16 track1;
    391     Word16 track2;
    392     Word16 ipos[NB_PULSE];
    393 
    394     Word16 psk;
    395     Word16 ps0;
    396     Word16 ps1;
    397     Word16 sq;
    398     Word16 sq1;
    399     Word16 alpk;
    400     Word16 alp;
    401     Word16 alp_16;
    402 
    403     Word16 *p_codvec = &codvec[0];
    404 
    405     Word32 s;
    406     Word32 alp0;
    407     Word32 alp1;
    408 
    409     psk = -1;
    410     alpk = 1;
    411 
    412     for (i = 0; i < NB_PULSE; i++)
    413     {
    414         *(p_codvec++) = i;
    415     }
    416 
    417     for (track1 = 1; track1 < 4; track1 += 2)
    418     {
    419         for (track2 = 2; track2 < 5; track2 += 2)
    420         {
    421             /* fix starting position */
    422 
    423             ipos[0] = 0;
    424             ipos[1] = track1;
    425             ipos[2] = track2;
    426 
    427             /*------------------------------------------------------------------*
    428              * main loop: try 3 tracks.                                         *
    429              *------------------------------------------------------------------*/
    430 
    431             for (i = 0; i < NB_PULSE; i++)
    432             {
    433                 /*----------------------------------------------------------------*
    434                  * i0 loop: try 8 positions.                                      *
    435                  *----------------------------------------------------------------*/
    436 
    437                 /* account for ptr. init. (rr[io]) */
    438                 for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP)
    439                 {
    440                     if (dn2[i0] >= 0)
    441                     {
    442                         ps0 = dn[i0];
    443 
    444                         /* alp0 = L_mult(rr[i0][i0],_1_4, pOverflow); */
    445                         alp0 = (Word32) rr[i0][i0] << 14;
    446 
    447                         /*----------------------------------------------------------------*
    448                          * i1 loop: 8 positions.                                          *
    449                          *----------------------------------------------------------------*/
    450 
    451                         sq = -1;
    452                         alp = 1;
    453                         ps = 0;
    454                         ix = ipos[1];
    455 
    456                         /* initialize 4 index for next loop. */
    457                         /*-------------------------------------------------------------------*
    458                          *  These index have low complexity address computation because      *
    459                          *  they are, in fact, pointers with fixed increment.  For example,  *
    460                          *  "rr[i0][i2]" is a pointer initialized to "&rr[i0][ipos[2]]"      *
    461                          *  and incremented by "STEP".                                       *
    462                          *-------------------------------------------------------------------*/
    463 
    464                         for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP)
    465                         {
    466                             /* idx increment = STEP */
    467                             /* ps1 = add(ps0, dn[i1], pOverflow); */
    468                             ps1 = ps0 + dn[i1];
    469 
    470                             /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */
    471 
    472                             /* idx incr = STEP */
    473                             /* alp1 = L_mac(alp0, rr[i1][i1], _1_4, pOverflow); */
    474                             alp1 = alp0 + ((Word32) rr[i1][i1] << 14);
    475 
    476                             /* idx incr = STEP */
    477                             /* alp1 = L_mac(alp1, rr[i0][i1], _1_2, pOverflow); */
    478                             alp1 += (Word32) rr[i0][i1] << 15;
    479 
    480                             /* sq1 = mult(ps1, ps1, pOverflow); */
    481                             sq1 = (Word16)(((Word32) ps1 * ps1) >> 15);
    482 
    483                             /* alp_16 = pv_round(alp1, pOverflow); */
    484                             alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16);
    485 
    486                             /* s = L_mult(alp, sq1, pOverflow); */
    487                             s = ((Word32) alp * sq1) << 1;
    488 
    489                             /* s = L_msu(s, sq, alp_16, pOverflow); */
    490                             s -= (((Word32) sq * alp_16) << 1);
    491 
    492                             if (s > 0)
    493                             {
    494                                 sq = sq1;
    495                                 ps = ps1;
    496                                 alp = alp_16;
    497                                 ix = i1;
    498                             }
    499                         }
    500                         i1 = ix;
    501 
    502                         /*----------------------------------------------------------------*
    503                          * i2 loop: 8 positions.                                          *
    504                          *----------------------------------------------------------------*/
    505 
    506                         ps0 = ps;
    507 
    508                         /* alp0 = L_mult(alp, _1_4, pOverflow); */
    509                         alp0 = (Word32) alp << 14;
    510 
    511                         sq = -1;
    512                         alp = 1;
    513                         ps = 0;
    514                         ix = ipos[2];
    515 
    516                         /* initialize 4 index for next loop (see i1 loop) */
    517 
    518                         for (i2 = ipos[2]; i2 < L_CODE; i2 += STEP)
    519                         {
    520                             /* index increment = STEP */
    521                             /* ps1 = add(ps0, dn[i2], pOverflow); */
    522                             ps1 = ps0 + dn[i2];
    523 
    524                             /* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */
    525 
    526                             /* idx incr = STEP */
    527                             /* alp1 = L_mac(alp0, rr[i2][i2], _1_16, pOverflow); */
    528                             alp1 = alp0 + ((Word32) rr[i2][i2] << 12);
    529 
    530                             /* idx incr = STEP */
    531                             /* alp1 = L_mac(alp1, rr[i1][i2], _1_8, pOverflow); */
    532                             alp1 += (Word32) rr[i1][i2] << 13;
    533 
    534                             /* idx incr = STEP */
    535                             /* alp1 = L_mac(alp1,rr[i0][i2], _1_8, pOverflow); */
    536                             alp1 += (Word32) rr[i0][i2] << 13;
    537 
    538                             /* sq1 = mult(ps1, ps1, pOverflow); */
    539                             sq1 = (Word16)(((Word32) ps1 * ps1) >> 15);
    540 
    541                             /* alp_16 = pv_round(alp1, pOverflow); */
    542                             alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16);
    543 
    544                             /* s = L_mult(alp, sq1, pOverflow); */
    545                             s = ((Word32) alp * sq1) << 1;
    546 
    547                             /* s = L_msu(s, sq, alp_16, pOverflow); */
    548                             s -= (((Word32) sq * alp_16) << 1);
    549 
    550                             if (s > 0)
    551                             {
    552                                 sq = sq1;
    553                                 ps = ps1;
    554                                 alp = alp_16;
    555                                 ix = i2;
    556                             }
    557                         }
    558                         i2 = ix;
    559 
    560                         /* memorize codevector if this one
    561                          * is better than the last one.
    562                          */
    563 
    564                         s = L_mult(alpk, sq, pOverflow);
    565                         //s = ((Word32) alpk * sq) << 1;
    566 
    567                         s = L_msu(s, psk, alp, pOverflow);
    568                         //s -= (((Word32) psk * alp) << 1);
    569 
    570                         if (s > 0)
    571                         {
    572                             psk = sq;
    573                             alpk = alp;
    574                             p_codvec = &codvec[0];
    575 
    576                             *(p_codvec++) = i0;
    577                             *(p_codvec++) = i1;
    578                             *(p_codvec) = i2;
    579                         }
    580                     }
    581                 }
    582                 /*----------------------------------------------------------------*
    583                  * Cyclic permutation of i0, i1 and i2.                           *
    584                  *----------------------------------------------------------------*/
    585 
    586                 pos = ipos[2];
    587                 ipos[2] = ipos[1];
    588                 ipos[1] = ipos[0];
    589                 ipos[0] = pos;
    590             }
    591         }
    592     }
    593     return;
    594 }
    595 
    596 /****************************************************************************/
    597 
    598 /*
    599 ------------------------------------------------------------------------------
    600  FUNCTION NAME:  build_code()
    601 ------------------------------------------------------------------------------
    602  INPUT AND OUTPUT DEFINITIONS
    603 
    604  Inputs:
    605     codvec[]   Array of type Word16 -- position of pulses
    606     dn_sign[]  Array of type Word16 -- sign of pulses
    607     h[]        Array of type Word16 -- impulse response of
    608                                        weighted synthesis filter
    609 
    610  Outputs:
    611     cod[]  Array of type Word16 -- innovative code vector
    612     y[]    Array of type Word16 -- filtered innovative code
    613     sign[] Array of type Word16 -- sign of 3 pulses
    614     pOverflow  Pointer to Flag  -- set when overflow occurs
    615 
    616  Returns:
    617     indx
    618 
    619  Global Variables Used:
    620     None
    621 
    622  Local Variables Needed:
    623     None
    624 
    625 ------------------------------------------------------------------------------
    626  FUNCTION DESCRIPTION
    627 
    628  PURPOSE: Builds the codeword, the filtered codeword and index of the
    629           codevector, based on the signs and positions of 3 pulses.
    630 
    631 ------------------------------------------------------------------------------
    632  REQUIREMENTS
    633 
    634  None
    635 
    636 ------------------------------------------------------------------------------
    637  REFERENCES
    638 
    639  [1] c3_14pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    640 
    641 ------------------------------------------------------------------------------
    642  PSEUDO-CODE
    643 
    644 ------------------------------------------------------------------------------
    645  RESOURCES USED [optional]
    646 
    647  When the code is written for a specific target processor the
    648  the resources used should be documented below.
    649 
    650  HEAP MEMORY USED: x bytes
    651 
    652  STACK MEMORY USED: x bytes
    653 
    654  CLOCK CYCLES: (cycle count equation for this function) + (variable
    655                 used to represent cycle count for each subroutine
    656                 called)
    657      where: (cycle count variable) = cycle count for [subroutine
    658                                      name]
    659 
    660 ------------------------------------------------------------------------------
    661  CAUTION [optional]
    662  [State any special notes, constraints or cautions for users of this function]
    663 
    664 ------------------------------------------------------------------------------
    665 */
    666 
    667 static Word16
    668 build_code(
    669     Word16 codvec[],  /* i : position of pulses                            */
    670     Word16 dn_sign[], /* i : sign of pulses                                */
    671     Word16 cod[],     /* o : innovative code vector                        */
    672     Word16 h[],       /* i : impulse response of weighted synthesis filter */
    673     Word16 y[],       /* o : filtered innovative code                      */
    674     Word16 sign[],    /* o : sign of 3 pulses                              */
    675     Flag  *pOverflow  /* o : Flag set when overflow occurs                 */
    676 )
    677 {
    678     Word16 i;
    679     Word16 j;
    680     Word16 k;
    681     Word16 track;
    682     Word16 index;
    683     Word16 _sign[NB_PULSE];
    684     Word16 indx;
    685     Word16 rsign;
    686 
    687     Word16 *p0;
    688     Word16 *p1;
    689     Word16 *p2;
    690 
    691     Word32 s;
    692 
    693     for (i = 0; i < L_CODE; i++)
    694     {
    695         cod[i] = 0;
    696     }
    697 
    698     indx = 0;
    699     rsign = 0;
    700 
    701     for (k = 0; k < NB_PULSE; k++)
    702     {
    703         i = codvec[k];  /* read pulse position */
    704         j = dn_sign[i];  /* read sign           */
    705 
    706         /* index = pos/5 */
    707         /* index = mult(i, 6554, pOverflow); */
    708         index = (Word16)(((Word32) i * 6554) >> 15);
    709 
    710         /* track = pos%5 */
    711         /* s = L_mult(index, 5, pOverflow); */
    712         s = ((Word32) index * 5) << 1;
    713 
    714         /* s = L_shr(s, 1, pOverflow); */
    715         s >>= 1;
    716 
    717         /* track = sub(i, (Word16) s, pOverflow); */
    718         track = i - (Word16) s;
    719 
    720         if (track == 1)
    721         {
    722             /* index = shl(index, 4, pOverflow); */
    723             index <<= 4;
    724         }
    725         else if (track == 2)
    726         {
    727             track = 2;
    728 
    729             /* index = shl(index, 8, pOverflow); */
    730             index <<= 8;
    731         }
    732         else if (track == 3)
    733         {
    734             track = 1;
    735 
    736             /* index = shl(index, 4, pOverflow); */
    737             index <<= 4;
    738 
    739             /* index = add(index, 8, pOverflow); */
    740             index += 8;
    741         }
    742         else if (track == 4)
    743         {
    744             track = 2;
    745 
    746             /* index = shl(index, 8, pOverflow); */
    747             index <<= 8;
    748 
    749             /* index = add(index, 128, pOverflow); */
    750             index += 128;
    751         }
    752 
    753         if (j > 0)
    754         {
    755             cod[i] = 8191;
    756             _sign[k] = 32767;
    757 
    758             /* track = shl(1, track, pOverflow); */
    759             track = 1 << track;
    760 
    761             /* rsign = add(rsign, track, pOverflow); */
    762             rsign += track;
    763         }
    764         else
    765         {
    766             cod[i] = -8192;
    767             _sign[k] = (Word16) - 32768L;
    768         }
    769 
    770         /* indx = add(indx, index, pOverflow); */
    771         indx += index;
    772     }
    773     *sign = rsign;
    774 
    775     p0 = h - codvec[0];
    776     p1 = h - codvec[1];
    777     p2 = h - codvec[2];
    778 
    779     for (i = 0; i < L_CODE; i++)
    780     {
    781         s = 0;
    782         s =
    783             L_mac(
    784                 s,
    785                 *p0++,
    786                 _sign[0],
    787                 pOverflow);
    788 
    789         s =
    790             L_mac(
    791                 s,
    792                 *p1++,
    793                 _sign[1],
    794                 pOverflow);
    795 
    796         s =
    797             L_mac(
    798                 s,
    799                 *p2++,
    800                 _sign[2],
    801                 pOverflow);
    802 
    803         y[i] =
    804             pv_round(
    805                 s,
    806                 pOverflow);
    807     }
    808 
    809     return indx;
    810 }
    811 
    812 
    813 
    814 
    815 
    816 
    817 
    818