• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
code_3i40_14bits(Word16 x[],Word16 h[],Word16 T0,Word16 pitch_sharp,Word16 code[],Word16 y[],Word16 * sign,Flag * pOverflow)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 */
search_3i40(Word16 dn[],Word16 dn2[],Word16 rr[][L_CODE],Word16 codvec[],Flag * pOverflow)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
build_code(Word16 codvec[],Word16 dn_sign[],Word16 cod[],Word16 h[],Word16 y[],Word16 sign[],Flag * pOverflow)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