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