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