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/****************************************************************************************
19Portions 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)
26Permission to distribute, modify and use this file under the standard license
27terms listed above has been obtained from the copyright holder.
28****************************************************************************************/
29/*
30------------------------------------------------------------------------------
31
32
33
34 Pathname: ./audio/gsm-amr/c/src/c8_31pf.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 unnecessary include files and unused #defines.
47
48 Description: Changed round function name to pv_round to avoid conflict with
49              round function in C standard library.
50
51 Description:  Replaced "int" and/or "char" with OSCL defined types.
52
53 Description:
54
55------------------------------------------------------------------------------
56 MODULE DESCRIPTION
57
58 Purpose          : Searches a 31 bit algebraic codebook containing
59                  : 8 pulses in a frame of 40 samples.
60                  : in the same manner as GSM-EFR
61------------------------------------------------------------------------------
62*/
63
64/*----------------------------------------------------------------------------
65; INCLUDES
66----------------------------------------------------------------------------*/
67#include "c8_31pf.h"
68#include "typedef.h"
69#include "cnst.h"
70#include "inv_sqrt.h"
71#include "cor_h.h"
72#include "cor_h_x2.h"
73#include "set_sign.h"
74#include "s10_8pf.h"
75#include "basic_op.h"
76
77/*----------------------------------------------------------------------------
78; MACROS
79; Define module specific macros here
80----------------------------------------------------------------------------*/
81
82/*----------------------------------------------------------------------------
83; DEFINES
84; Include all pre-processor statements here. Include conditional
85; compile variables also.
86----------------------------------------------------------------------------*/
87#define NB_PULSE 8
88
89/* define values/representation for output codevector and sign */
90#define POS_CODE  8191
91#define NEG_CODE  8191
92#define POS_SIGN  32767
93#define NEG_SIGN  (Word16) (-32768L)
94
95/*----------------------------------------------------------------------------
96; LOCAL FUNCTION DEFINITIONS
97; Function Prototype declaration
98----------------------------------------------------------------------------*/
99
100/*----------------------------------------------------------------------------
101; LOCAL VARIABLE DEFINITIONS
102; Variable declaration - defined here and used outside this module
103----------------------------------------------------------------------------*/
104
105/*----------------------------------------------------------------------------
106; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
107; Declare variables used in this module but defined elsewhere
108----------------------------------------------------------------------------*/
109
110/*
111------------------------------------------------------------------------------
112 FUNCTION NAME:
113------------------------------------------------------------------------------
114 INPUT AND OUTPUT DEFINITIONS
115
116 Inputs:
117    codvec[]   Array of type Word16 -- position of pulses
118    sign[]     Array of type Word16 -- sign of pulses
119    h[]        Array of type Word16 -- impulse response of
120                                       weighted synthesis filter
121 Outputs:
122    cod[]       Array of type Word16 -- innovative code vector
123    y[]         Array of type Word16 -- filtered innovative code
124    sign_indx[] Array of type Word16 -- signs of 4 pulses (signs only)
125    pos_indx[]  Array of type Word16 --
126                             position index of 8 pulses(position only)
127
128    pOverflow  Pointer to Flag  -- set when overflow occurs
129
130 Returns:
131    indx
132
133 Global Variables Used:
134    None
135
136 Local Variables Needed:
137
138------------------------------------------------------------------------------
139 FUNCTION DESCRIPTION
140
141
142------------------------------------------------------------------------------
143 REQUIREMENTS
144
145 None
146
147------------------------------------------------------------------------------
148 REFERENCES
149
150 [1] c8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
151
152------------------------------------------------------------------------------
153 PSEUDO-CODE
154
155------------------------------------------------------------------------------
156 RESOURCES USED [optional]
157
158 When the code is written for a specific target processor the
159 the resources used should be documented below.
160
161 HEAP MEMORY USED: x bytes
162
163 STACK MEMORY USED: x bytes
164
165 CLOCK CYCLES: (cycle count equation for this function) + (variable
166                used to represent cycle count for each subroutine
167                called)
168     where: (cycle count variable) = cycle count for [subroutine
169                                     name]
170
171------------------------------------------------------------------------------
172 CAUTION [optional]
173 [State any special notes, constraints or cautions for users of this function]
174
175------------------------------------------------------------------------------
176*/
177
178/*************************************************************************
179 *
180 *  FUNCTION:  build_code()
181 *
182 *  PURPOSE: Builds the codeword, the filtered codeword and a
183 *   linear uncombined version of  the index of the
184 *           codevector, based on the signs and positions of 8  pulses.
185 *
186 *************************************************************************/
187
188static void build_code(
189    Word16 codvec[],    /* i : position of pulses                           */
190    Word16 sign[],      /* i : sign of d[n]                                 */
191    Word16 cod[],       /* o : innovative code vector                       */
192    Word16 h[],         /* i : impulse response of weighted synthesis filter*/
193    Word16 y[],         /* o : filtered innovative code                     */
194    Word16 sign_indx[], /* o : signs of 4  pulses (signs only)              */
195    Word16 pos_indx[],  /* o : position index of 8 pulses(position only)    */
196    Flag   * pOverflow  /* o : Flag set when overflow occurs                */
197)
198{
199    Word16 i;
200    Word16 j;
201    Word16 k;
202    Word16 track;
203    Word16 sign_index;
204    Word16 pos_index;
205    Word16 _sign[NB_PULSE];
206
207    Word16 *p0;
208    Word16 *p1;
209    Word16 *p2;
210    Word16 *p3;
211    Word16 *p4;
212    Word16 *p5;
213    Word16 *p6;
214    Word16 *p7;
215
216    Word16 *p_cod = &cod[0];
217    Word16 *p_codvec = &codvec[0];
218
219    Word32 s;
220
221    for (i = 0; i < L_CODE; i++)
222    {
223        *(p_cod++) = 0;
224    }
225
226    for (i = 0; i < NB_TRACK_MR102; i++)
227    {
228        pos_indx[i] = -1;
229        sign_indx[i] = -1;
230    }
231
232    for (k = 0; k < NB_PULSE; k++)
233    {
234        /* read pulse position */
235        i = codvec[k];
236        /* read sign           */
237        j = sign[i];
238
239        pos_index = i >> 2; /* index = pos/4 */
240
241        track = i & 3;     /* track = pos%4 */
242
243        if (j > 0)
244        {
245            cod[i] = (Word16)((Word32) cod[i] + POS_CODE);
246
247            _sign[k] = POS_SIGN;
248            sign_index = 0;  /* bit=0 -> positive pulse */
249        }
250        else
251        {
252            cod[i] = (Word16)((Word32) cod[i] - NEG_CODE);
253
254            _sign[k] = NEG_SIGN;
255            sign_index = 1; /* bit=1 => negative pulse */
256            /* index = add (index, 8); 1 = negative  old code */
257        }
258
259        if (pos_indx[track] < 0)
260        {   /* first set first NB_TRACK pulses  */
261            pos_indx[track] = pos_index;
262            sign_indx[track] = sign_index;
263        }
264        else
265        {   /* 2nd row of pulses , test if positions needs to be switched */
266            if (((sign_index ^ sign_indx[track]) & 1) == 0)
267            {
268                /* sign of 1st pulse == sign of 2nd pulse */
269
270                if (pos_indx[track] <= pos_index)
271                {   /* no swap */
272                    pos_indx[track + NB_TRACK_MR102] = pos_index;
273                }
274                else
275                {   /* swap*/
276                    pos_indx[track + NB_TRACK_MR102] = pos_indx[track];
277
278                    pos_indx[track] = pos_index;
279                    sign_indx[track] = sign_index;
280                }
281            }
282            else
283            {
284                /* sign of 1st pulse != sign of 2nd pulse */
285
286                if (pos_indx[track] <= pos_index)
287                {  /*swap*/
288                    pos_indx[track + NB_TRACK_MR102] = pos_indx[track];
289
290                    pos_indx[track] = pos_index;
291                    sign_indx[track] = sign_index;
292                }
293                else
294                {   /*no swap */
295                    pos_indx[track + NB_TRACK_MR102] = pos_index;
296                }
297            }
298        }
299    }
300
301    p0 = h - *(p_codvec++);
302    p1 = h - *(p_codvec++);
303    p2 = h - *(p_codvec++);
304    p3 = h - *(p_codvec++);
305    p4 = h - *(p_codvec++);
306    p5 = h - *(p_codvec++);
307    p6 = h - *(p_codvec++);
308    p7 = h - *(p_codvec);
309
310    for (i = 0; i < L_CODE; i++)
311    {
312        s = 0;
313
314        s =
315            L_mac(
316                s,
317                *p0++,
318                _sign[0],
319                pOverflow);
320        s =
321            L_mac(
322                s,
323                *p1++,
324                _sign[1],
325                pOverflow);
326        s =
327            L_mac(
328                s,
329                *p2++,
330                _sign[2],
331                pOverflow);
332        s =
333            L_mac(
334                s,
335                *p3++,
336                _sign[3],
337                pOverflow);
338        s =
339            L_mac(
340                s,
341                *p4++,
342                _sign[4],
343                pOverflow);
344        s =
345            L_mac(
346                s,
347                *p5++,
348                _sign[5],
349                pOverflow);
350        s =
351            L_mac(
352                s,
353                *p6++,
354                _sign[6],
355                pOverflow);
356        s =
357            L_mac(
358                s,
359                *p7++,
360                _sign[7],
361                pOverflow);
362
363        y[i] =
364            pv_round(
365                s,
366                pOverflow);
367
368    } /* for (i = 0; i < L_CODE; i++) */
369
370} /* build_code */
371
372/****************************************************************************/
373
374/*
375------------------------------------------------------------------------------
376 FUNCTION NAME: compress_code()
377------------------------------------------------------------------------------
378 INPUT AND OUTPUT DEFINITIONS
379
380 Inputs:
381
382 Outputs:
383
384 Returns:
385    None
386
387 Global Variables Used:
388    None
389
390 Local Variables Needed:
391
392------------------------------------------------------------------------------
393 FUNCTION DESCRIPTION
394
395 FUNCTION:
396
397 PURPOSE: compression of three indeces [0..9] to one 10 bit index
398          minimizing the phase shift of a bit error.
399
400------------------------------------------------------------------------------
401 REQUIREMENTS
402
403 None
404
405------------------------------------------------------------------------------
406 REFERENCES
407
408 [1] c8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
409
410------------------------------------------------------------------------------
411 PSEUDO-CODE
412
413------------------------------------------------------------------------------
414 RESOURCES USED [optional]
415
416 When the code is written for a specific target processor the
417 the resources used should be documented below.
418
419 HEAP MEMORY USED: x bytes
420
421 STACK MEMORY USED: x bytes
422
423 CLOCK CYCLES: (cycle count equation for this function) + (variable
424                used to represent cycle count for each subroutine
425                called)
426     where: (cycle count variable) = cycle count for [subroutine
427                                     name]
428
429------------------------------------------------------------------------------
430 CAUTION [optional]
431 [State any special notes, constraints or cautions for users of this function]
432
433------------------------------------------------------------------------------
434*/
435
436static Word16 compress10(
437    Word16 pos_indxA,  /* i : signs of 4 pulses (signs only)             */
438    Word16 pos_indxB,  /* i : position index of 8 pulses (pos only)      */
439    Word16 pos_indxC,  /* i : position and sign of 8 pulses (compressed) */
440    Flag  *pOverflow)  /* o : Flag set when overflow occurs              */
441{
442    Word16 indx;
443    Word16 ia;
444    Word16 ib;
445    Word16 ic;
446
447    Word32 tempWord32;
448
449    OSCL_UNUSED_ARG(pOverflow);
450
451    ia = pos_indxA >> 1;
452
453    ib = pos_indxB >> 1;
454
455    tempWord32 = ((Word32) ib * 5) << 1;
456
457    tempWord32 = tempWord32 >> 1;
458
459    ib = (Word16) tempWord32;
460
461    ic = pos_indxC >> 1;
462
463    tempWord32 = ((Word32) ic * 25) << 1;
464
465    tempWord32 = tempWord32 >> 1;
466
467    ic = (Word16) tempWord32;
468
469    ib += ic;
470
471    ib += ia;
472
473    indx = ib << 3;
474
475    ia = pos_indxA & 1;
476
477    ib = ((Word16)(pos_indxB & 1)) << 1;
478
479    ic = ((Word16)(pos_indxC & 1)) << 2;
480
481    ib += ic;
482
483    ib += ia;
484
485    indx += ib;
486
487    return indx;
488
489}
490
491/****************************************************************************/
492
493/*
494------------------------------------------------------------------------------
495 FUNCTION NAME: compress_code()
496------------------------------------------------------------------------------
497 INPUT AND OUTPUT DEFINITIONS
498
499 Inputs:
500    sign_indx   Array of type Word16 -- signs of 4 pulses (signs only)
501    pos_indx    Array of type Word16 -- position index of 8 pulses
502                                            (position only)
503
504 Outputs:
505    indx         Array of type Word16 -- position and sign of 8 pulses
506                                            (compressed)
507    pOverflow    Pointer to Flag      -- set when overflow occurs
508
509 Returns:
510    None
511
512 Global Variables Used:
513    None
514
515 Local Variables Needed:
516    None
517
518------------------------------------------------------------------------------
519 FUNCTION DESCRIPTION
520
521 PURPOSE: compression of the linear codewords to 4+three indeces
522          one bit from each pulse is made robust to errors by
523          minimizing the phase shift of a bit error.
524          4 signs (one for each track)
525          i0,i4,i1 => one index (7+3) bits, 3   LSBs more robust
526          i2,i6,i5 => one index (7+3) bits, 3   LSBs more robust
527          i3,i7    => one index (5+2) bits, 2-3 LSbs more robust
528
529------------------------------------------------------------------------------
530 REQUIREMENTS
531
532 None
533
534------------------------------------------------------------------------------
535 REFERENCES
536
537 [1] c3_14pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
538
539------------------------------------------------------------------------------
540 PSEUDO-CODE
541
542------------------------------------------------------------------------------
543 RESOURCES USED [optional]
544
545 When the code is written for a specific target processor the
546 the resources used should be documented below.
547
548 HEAP MEMORY USED: x bytes
549
550 STACK MEMORY USED: x bytes
551
552 CLOCK CYCLES: (cycle count equation for this function) + (variable
553                used to represent cycle count for each subroutine
554                called)
555     where: (cycle count variable) = cycle count for [subroutine
556                                     name]
557
558------------------------------------------------------------------------------
559 CAUTION [optional]
560 [State any special notes, constraints or cautions for users of this function]
561
562------------------------------------------------------------------------------
563*/
564
565static void compress_code(
566    Word16 sign_indx[], /* i : signs of 4 pulses (signs only)             */
567    Word16 pos_indx[],  /* i : position index of 8 pulses (position only) */
568    Word16 indx[],      /* o : position and sign of 8 pulses (compressed) */
569    Flag  *pOverflow)   /* o : Flag set when overflow occurs              */
570{
571    Word16 i;
572    Word16 ia;
573    Word16 ib;
574    Word16 ic;
575
576    Word16 *p_indx = &indx[0];
577    Word16 *p_sign_indx = &sign_indx[0];
578
579    Word32 tempWord32;
580
581    for (i = 0; i < NB_TRACK_MR102; i++)
582    {
583        *(p_indx++) = *(p_sign_indx++);
584    }
585
586    /* First index
587      indx[NB_TRACK] = (ia/2+(ib/2)*5 +(ic/2)*25)*8 + ia%2 + (ib%2)*2 + (ic%2)*4; */
588
589    indx[NB_TRACK_MR102] =
590        compress10(
591            pos_indx[0],
592            pos_indx[4],
593            pos_indx[1],
594            pOverflow);
595
596    /* Second index
597      indx[NB_TRACK+1] = (ia/2+(ib/2)*5 +(ic/2)*25)*8 + ia%2 + (ib%2)*2 + (ic%2)*4; */
598
599    indx[NB_TRACK_MR102+1] =
600        compress10(
601            pos_indx[2],
602            pos_indx[6],
603            pos_indx[5],
604            pOverflow);
605
606    /*
607      Third index
608      if ((ib/2)%2 == 1)
609        indx[NB_TRACK+2] = ((((4-ia/2) + (ib/2)*5)*32+12)/25)*4 + ia%2 + (ib%2)*2;
610      else
611        indx[NB_TRACK+2] = ((((ia/2) +   (ib/2)*5)*32+12)/25)*4 + ia%2 + (ib%2)*2;
612        */
613
614    ib = pos_indx[7] >> 1;
615
616    ib &= 1;
617
618    ia = pos_indx[3] >> 1;
619
620    if (ib == 1)
621    {
622        ia = 4 - ia;
623    }
624
625    ib = pos_indx[7] >> 1;
626
627    tempWord32 = ((Word32) ib * 5) << 1;
628
629    tempWord32 = tempWord32 >> 1;
630
631    ib = (Word16) tempWord32;
632
633    ib += ia;
634
635    ib <<= 5;
636
637    ib += 12;
638
639    ic = (Word16)(((Word32) ib * 1311) >> 15);
640
641    ic <<= 2;
642
643    ia = pos_indx[3] & 1;
644
645    ib = ((Word16)(pos_indx[7] & 1)) << 1;
646
647    ib += ic;
648
649    ib += ia;
650
651    indx[NB_TRACK_MR102+2] = ib;
652
653} /* compress_code */
654
655
656/****************************************************************************/
657
658/*
659------------------------------------------------------------------------------
660 FUNCTION NAME: code_8i40_31bits()
661------------------------------------------------------------------------------
662 INPUT AND OUTPUT DEFINITIONS
663
664 Inputs:
665    x   Array of type Word16 -- target vector
666    cn  Array of type Word16 -- residual after long term prediction
667    h   Array of type Word16 -- impulse response of weighted synthesis filter
668
669
670 Outputs:
671    cod Array of type Word16 -- algebraic (fixed) codebook excitation
672    y   Array of type Word16 -- filtered fixed codebook excitation
673    indx Array of type Word16 -- index of 8 pulses (signs+positions)
674    pOverflow    Pointer to Flag      -- set when overflow occurs
675
676 Returns:
677    None
678
679 Global Variables Used:
680    None
681
682 Local Variables Needed:
683    None
684
685------------------------------------------------------------------------------
686 FUNCTION DESCRIPTION
687
688 FUNCTION:
689
690 PURPOSE:  Searches a 31 bit algebraic codebook containing 8 pulses
691           in a frame of 40 samples.
692
693 DESCRIPTION:
694   The code contains 8 nonzero pulses: i0...i7.
695   All pulses can have two possible amplitudes: +1 or -1.
696   The 40 positions in a subframe are divided into 4 tracks of
697   interleaved positions. Each track contains two pulses.
698   The pulses can have the following possible positions:
699
700      i0, i4 :  0, 4, 8,  12, 16, 20, 24, 28, 32, 36
701      i1, i5 :  1, 5, 9,  13, 17, 21, 25, 29, 33, 37
702      i2, i6 :  2, 6, 10, 14, 18, 22, 26, 30, 34, 38
703      i3, i7 :  3, 7, 11, 15, 19, 23, 27, 31, 35, 39
704
705   Each pair of pulses require 1 bit for their signs. The positions
706   are encoded together 3,3 and 2 resulting in
707   (7+3) + (7+3) + (5+2) bits for their
708   positions. This results in a 31 (4 sign and 27 pos) bit codebook.
709   The function determines the optimal pulse signs and positions, builds
710   the codevector, and computes the filtered codevector.
711
712------------------------------------------------------------------------------
713 REQUIREMENTS
714
715 None
716
717------------------------------------------------------------------------------
718 REFERENCES
719
720 [1] c8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
721
722------------------------------------------------------------------------------
723 PSEUDO-CODE
724
725------------------------------------------------------------------------------
726 RESOURCES USED [optional]
727
728 When the code is written for a specific target processor the
729 the resources used should be documented below.
730
731 HEAP MEMORY USED: x bytes
732
733 STACK MEMORY USED: x bytes
734
735 CLOCK CYCLES: (cycle count equation for this function) + (variable
736                used to represent cycle count for each subroutine
737                called)
738     where: (cycle count variable) = cycle count for [subroutine
739                                     name]
740
741------------------------------------------------------------------------------
742 CAUTION [optional]
743 [State any special notes, constraints or cautions for users of this function]
744
745------------------------------------------------------------------------------
746*/
747void code_8i40_31bits(
748    Word16 x[],        /* i : target vector                                  */
749    Word16 cn[],       /* i : residual after long term prediction            */
750    Word16 h[],        /* i : impulse response of weighted synthesis
751                             filter                                         */
752    Word16 cod[],      /* o : algebraic (fixed) codebook excitation          */
753    Word16 y[],        /* o : filtered fixed codebook excitation             */
754    Word16 indx[],     /* o : 7 Word16, index of 8 pulses (signs+positions)  */
755    Flag  *pOverflow   /* o : Flag set when overflow occurs                  */
756)
757{
758    Word16 ipos[NB_PULSE];
759    Word16 pos_max[NB_TRACK_MR102];
760    Word16 codvec[NB_PULSE];
761
762    Word16 dn[L_CODE];
763    Word16 sign[L_CODE];
764
765    Word16 rr[L_CODE][L_CODE];
766    Word16 linear_signs[NB_TRACK_MR102];
767    Word16 linear_codewords[NB_PULSE];
768
769    cor_h_x2(
770        h,
771        x,
772        dn,
773        2,
774        NB_TRACK_MR102,
775        STEP_MR102,
776        pOverflow);
777
778    /* 2 = use GSMEFR scaling */
779
780    set_sign12k2(
781        dn,
782        cn,
783        sign,
784        pos_max,
785        NB_TRACK_MR102,
786        ipos,
787        STEP_MR102,
788        pOverflow);
789
790    /* same setsign alg as GSM-EFR new constants though*/
791
792    cor_h(
793        h,
794        sign,
795        rr,
796        pOverflow);
797
798    search_10and8i40(
799        NB_PULSE,
800        STEP_MR102,
801        NB_TRACK_MR102,
802        dn,
803        rr,
804        ipos,
805        pos_max,
806        codvec,
807        pOverflow);
808
809    build_code(
810        codvec,
811        sign,
812        cod,
813        h,
814        y,
815        linear_signs,
816        linear_codewords,
817        pOverflow);
818
819    compress_code(
820        linear_signs,
821        linear_codewords,
822        indx,
823        pOverflow);
824
825} /* code_8i40_31bits */
826
827
828
829