xref: /aosp_15_r20/frameworks/av/media/module/codecs/amrnb/enc/src/c3_14pf.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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 mul;
407     Word32 alp0;
408     Word32 alp1;
409 
410     psk = -1;
411     alpk = 1;
412 
413     for (i = 0; i < NB_PULSE; i++)
414     {
415         *(p_codvec++) = i;
416     }
417 
418     for (track1 = 1; track1 < 4; track1 += 2)
419     {
420         for (track2 = 2; track2 < 5; track2 += 2)
421         {
422             /* fix starting position */
423 
424             ipos[0] = 0;
425             ipos[1] = track1;
426             ipos[2] = track2;
427 
428             /*------------------------------------------------------------------*
429              * main loop: try 3 tracks.                                         *
430              *------------------------------------------------------------------*/
431 
432             for (i = 0; i < NB_PULSE; i++)
433             {
434                 /*----------------------------------------------------------------*
435                  * i0 loop: try 8 positions.                                      *
436                  *----------------------------------------------------------------*/
437 
438                 /* account for ptr. init. (rr[io]) */
439                 for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP)
440                 {
441                     if (dn2[i0] >= 0)
442                     {
443                         ps0 = dn[i0];
444 
445                         /* alp0 = L_mult(rr[i0][i0],_1_4, pOverflow); */
446                         alp0 = (Word32) rr[i0][i0] << 14;
447 
448                         /*----------------------------------------------------------------*
449                          * i1 loop: 8 positions.                                          *
450                          *----------------------------------------------------------------*/
451 
452                         sq = -1;
453                         alp = 1;
454                         ps = 0;
455                         ix = ipos[1];
456 
457                         /* initialize 4 index for next loop. */
458                         /*-------------------------------------------------------------------*
459                          *  These index have low complexity address computation because      *
460                          *  they are, in fact, pointers with fixed increment.  For example,  *
461                          *  "rr[i0][i2]" is a pointer initialized to "&rr[i0][ipos[2]]"      *
462                          *  and incremented by "STEP".                                       *
463                          *-------------------------------------------------------------------*/
464 
465                         for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP)
466                         {
467                             /* idx increment = STEP */
468                             /* ps1 = add(ps0, dn[i1], pOverflow); */
469                             ps1 = ps0 + dn[i1];
470 
471                             /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */
472 
473                             /* idx incr = STEP */
474                             /* alp1 = L_mac(alp0, rr[i1][i1], _1_4, pOverflow); */
475                             alp1 = alp0 + ((Word32) rr[i1][i1] << 14);
476 
477                             /* idx incr = STEP */
478                             /* alp1 = L_mac(alp1, rr[i0][i1], _1_2, pOverflow); */
479                             alp1 += (Word32) rr[i0][i1] << 15;
480 
481                             /* sq1 = mult(ps1, ps1, pOverflow); */
482                             sq1 = (Word16)(((Word32) ps1 * ps1) >> 15);
483 
484                             /* alp_16 = pv_round(alp1, pOverflow); */
485                             alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16);
486 
487                             /* s = L_mult(alp, sq1, pOverflow); */
488                             s = ((Word32) alp * sq1) << 1;
489 
490                             /* s = L_msu(s, sq, alp_16, pOverflow); */
491                             __builtin_mul_overflow(sq, alp_16, &mul);
492                             __builtin_sub_overflow(s, (mul << 1), &s);
493 
494                             if (s > 0)
495                             {
496                                 sq = sq1;
497                                 ps = ps1;
498                                 alp = alp_16;
499                                 ix = i1;
500                             }
501                         }
502                         i1 = ix;
503 
504                         /*----------------------------------------------------------------*
505                          * i2 loop: 8 positions.                                          *
506                          *----------------------------------------------------------------*/
507 
508                         ps0 = ps;
509 
510                         /* alp0 = L_mult(alp, _1_4, pOverflow); */
511                         alp0 = (Word32) alp << 14;
512 
513                         sq = -1;
514                         alp = 1;
515                         ps = 0;
516                         ix = ipos[2];
517 
518                         /* initialize 4 index for next loop (see i1 loop) */
519 
520                         for (i2 = ipos[2]; i2 < L_CODE; i2 += STEP)
521                         {
522                             /* index increment = STEP */
523                             /* ps1 = add(ps0, dn[i2], pOverflow); */
524                             ps1 = ps0 + dn[i2];
525 
526                             /* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */
527 
528                             /* idx incr = STEP */
529                             /* alp1 = L_mac(alp0, rr[i2][i2], _1_16, pOverflow); */
530                             alp1 = alp0 + ((Word32) rr[i2][i2] << 12);
531 
532                             /* idx incr = STEP */
533                             /* alp1 = L_mac(alp1, rr[i1][i2], _1_8, pOverflow); */
534                             alp1 += (Word32) rr[i1][i2] << 13;
535 
536                             /* idx incr = STEP */
537                             /* alp1 = L_mac(alp1,rr[i0][i2], _1_8, pOverflow); */
538                             alp1 += (Word32) rr[i0][i2] << 13;
539 
540                             /* sq1 = mult(ps1, ps1, pOverflow); */
541                             sq1 = (Word16)(((Word32) ps1 * ps1) >> 15);
542 
543                             /* alp_16 = pv_round(alp1, pOverflow); */
544                             alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16);
545 
546                             /* s = L_mult(alp, sq1, pOverflow); */
547                             s = ((Word32) alp * sq1) << 1;
548 
549                             /* s = L_msu(s, sq, alp_16, pOverflow); */
550                             s -= (((Word32) sq * alp_16) << 1);
551 
552                             if (s > 0)
553                             {
554                                 sq = sq1;
555                                 ps = ps1;
556                                 alp = alp_16;
557                                 ix = i2;
558                             }
559                         }
560                         i2 = ix;
561 
562                         /* memorize codevector if this one
563                          * is better than the last one.
564                          */
565 
566                         s = L_mult(alpk, sq, pOverflow);
567                         //s = ((Word32) alpk * sq) << 1;
568 
569                         s = L_msu(s, psk, alp, pOverflow);
570                         //s -= (((Word32) psk * alp) << 1);
571 
572                         if (s > 0)
573                         {
574                             psk = sq;
575                             alpk = alp;
576                             p_codvec = &codvec[0];
577 
578                             *(p_codvec++) = i0;
579                             *(p_codvec++) = i1;
580                             *(p_codvec) = i2;
581                         }
582                     }
583                 }
584                 /*----------------------------------------------------------------*
585                  * Cyclic permutation of i0, i1 and i2.                           *
586                  *----------------------------------------------------------------*/
587 
588                 pos = ipos[2];
589                 ipos[2] = ipos[1];
590                 ipos[1] = ipos[0];
591                 ipos[0] = pos;
592             }
593         }
594     }
595     return;
596 }
597 
598 /****************************************************************************/
599 
600 /*
601 ------------------------------------------------------------------------------
602  FUNCTION NAME:  build_code()
603 ------------------------------------------------------------------------------
604  INPUT AND OUTPUT DEFINITIONS
605 
606  Inputs:
607     codvec[]   Array of type Word16 -- position of pulses
608     dn_sign[]  Array of type Word16 -- sign of pulses
609     h[]        Array of type Word16 -- impulse response of
610                                        weighted synthesis filter
611 
612  Outputs:
613     cod[]  Array of type Word16 -- innovative code vector
614     y[]    Array of type Word16 -- filtered innovative code
615     sign[] Array of type Word16 -- sign of 3 pulses
616     pOverflow  Pointer to Flag  -- set when overflow occurs
617 
618  Returns:
619     indx
620 
621  Global Variables Used:
622     None
623 
624  Local Variables Needed:
625     None
626 
627 ------------------------------------------------------------------------------
628  FUNCTION DESCRIPTION
629 
630  PURPOSE: Builds the codeword, the filtered codeword and index of the
631           codevector, based on the signs and positions of 3 pulses.
632 
633 ------------------------------------------------------------------------------
634  REQUIREMENTS
635 
636  None
637 
638 ------------------------------------------------------------------------------
639  REFERENCES
640 
641  [1] c3_14pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
642 
643 ------------------------------------------------------------------------------
644  PSEUDO-CODE
645 
646 ------------------------------------------------------------------------------
647  RESOURCES USED [optional]
648 
649  When the code is written for a specific target processor the
650  the resources used should be documented below.
651 
652  HEAP MEMORY USED: x bytes
653 
654  STACK MEMORY USED: x bytes
655 
656  CLOCK CYCLES: (cycle count equation for this function) + (variable
657                 used to represent cycle count for each subroutine
658                 called)
659      where: (cycle count variable) = cycle count for [subroutine
660                                      name]
661 
662 ------------------------------------------------------------------------------
663  CAUTION [optional]
664  [State any special notes, constraints or cautions for users of this function]
665 
666 ------------------------------------------------------------------------------
667 */
668 
669 static Word16
build_code(Word16 codvec[],Word16 dn_sign[],Word16 cod[],Word16 h[],Word16 y[],Word16 sign[],Flag * pOverflow)670 build_code(
671     Word16 codvec[],  /* i : position of pulses                            */
672     Word16 dn_sign[], /* i : sign of pulses                                */
673     Word16 cod[],     /* o : innovative code vector                        */
674     Word16 h[],       /* i : impulse response of weighted synthesis filter */
675     Word16 y[],       /* o : filtered innovative code                      */
676     Word16 sign[],    /* o : sign of 3 pulses                              */
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 
693     Word32 s;
694 
695     for (i = 0; i < L_CODE; i++)
696     {
697         cod[i] = 0;
698     }
699 
700     indx = 0;
701     rsign = 0;
702 
703     for (k = 0; k < NB_PULSE; k++)
704     {
705         i = codvec[k];  /* read pulse position */
706         j = dn_sign[i];  /* read sign           */
707 
708         /* index = pos/5 */
709         /* index = mult(i, 6554, pOverflow); */
710         index = (Word16)(((Word32) i * 6554) >> 15);
711 
712         /* track = pos%5 */
713         /* s = L_mult(index, 5, pOverflow); */
714         s = ((Word32) index * 5) << 1;
715 
716         /* s = L_shr(s, 1, pOverflow); */
717         s >>= 1;
718 
719         /* track = sub(i, (Word16) s, pOverflow); */
720         track = i - (Word16) s;
721 
722         if (track == 1)
723         {
724             /* index = shl(index, 4, pOverflow); */
725             index <<= 4;
726         }
727         else if (track == 2)
728         {
729             track = 2;
730 
731             /* index = shl(index, 8, pOverflow); */
732             index <<= 8;
733         }
734         else if (track == 3)
735         {
736             track = 1;
737 
738             /* index = shl(index, 4, pOverflow); */
739             index <<= 4;
740 
741             /* index = add(index, 8, pOverflow); */
742             index += 8;
743         }
744         else if (track == 4)
745         {
746             track = 2;
747 
748             /* index = shl(index, 8, pOverflow); */
749             index <<= 8;
750 
751             /* index = add(index, 128, pOverflow); */
752             index += 128;
753         }
754 
755         if (j > 0)
756         {
757             cod[i] = 8191;
758             _sign[k] = 32767;
759 
760             /* track = shl(1, track, pOverflow); */
761             track = 1 << track;
762 
763             /* rsign = add(rsign, track, pOverflow); */
764             rsign += track;
765         }
766         else
767         {
768             cod[i] = -8192;
769             _sign[k] = (Word16) - 32768L;
770         }
771 
772         /* indx = add(indx, index, pOverflow); */
773         indx += index;
774     }
775     *sign = rsign;
776 
777     p0 = h - codvec[0];
778     p1 = h - codvec[1];
779     p2 = h - codvec[2];
780 
781     for (i = 0; i < L_CODE; i++)
782     {
783         s = 0;
784         s =
785             L_mac(
786                 s,
787                 *p0++,
788                 _sign[0],
789                 pOverflow);
790 
791         s =
792             L_mac(
793                 s,
794                 *p1++,
795                 _sign[1],
796                 pOverflow);
797 
798         s =
799             L_mac(
800                 s,
801                 *p2++,
802                 _sign[2],
803                 pOverflow);
804 
805         y[i] =
806             pv_round(
807                 s,
808                 pOverflow);
809     }
810 
811     return indx;
812 }
813 
814 
815 
816 
817 
818 
819 
820