Home | History | Annotate | Download | only in src
      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/set_sign.c
     35  Funtions: set_sign
     36            set_sign12k2
     37 
     38      Date: 05/26/2000
     39 
     40 ------------------------------------------------------------------------------
     41  REVISION HISTORY
     42 
     43  Description:  Placed into PV template and optimized.
     44 
     45  Description: Synchronized file with UMTS version 3.2.0. Updated coding
     46               template. Removed unnecessary include files.
     47 
     48  Description: Replaced basic_op.h with the header files of the math functions
     49               used in the file.
     50 
     51  Description: Made the following changes per comments from Phase 2/3 review:
     52               1. Modified certain FOR loops to count down.
     53               2. Modified code for further optimization.
     54 
     55  Description: Modified FOR loops in set_sign12k2 to count up. The FOR loops
     56               affected are the loop that calculates the starting position of
     57               each incoming pulse, and the loop that calculates the position
     58               of the max correlation. Updated copyright year.
     59 
     60  Description: Passing in pointer to overflow flag for EPOC compatibility.
     61 
     62  Description:  For set_sign12k2()
     63               1. Eliminated unused include files.
     64               2. Replaced array addressing by pointers
     65               3. Eliminated math operations that unnecessary checked for
     66                  saturation, this by evaluating the operands
     67               4. Replaced loop counter with decrement loops
     68 
     69  Description:  Replaced "int" and/or "char" with OSCL defined types.
     70 
     71  Description: Changed round function name to pv_round to avoid conflict with
     72               round function in C standard library.
     73 
     74  Description:
     75 
     76 ------------------------------------------------------------------------------
     77  MODULE DESCRIPTION
     78 
     79  This module contains the functions set_sign and set_sign12k2.
     80  These functions are used to build a sign vector according
     81  to the values in the input arrays.  These functions also
     82  find the position in the input codes of the maximum correlation
     83  and the starting position for each pulse.
     84 
     85 ------------------------------------------------------------------------------
     86 */
     87 
     88 
     89 /*----------------------------------------------------------------------------
     90 ; INCLUDES
     91 ----------------------------------------------------------------------------*/
     92 #include "set_sign.h"
     93 #include "basic_op.h"
     94 #include "inv_sqrt.h"
     95 #include "cnst.h"
     96 
     97 
     98 /*----------------------------------------------------------------------------
     99 ; MACROS
    100 ; Define module specific macros here
    101 ----------------------------------------------------------------------------*/
    102 
    103 
    104 /*----------------------------------------------------------------------------
    105 ; DEFINES
    106 ; Include all pre-processor statements here. Include conditional
    107 ; compile variables also.
    108 ----------------------------------------------------------------------------*/
    109 
    110 /*----------------------------------------------------------------------------
    111 ; LOCAL FUNCTION DEFINITIONS
    112 ; Function Prototype declaration
    113 ----------------------------------------------------------------------------*/
    114 
    115 /*----------------------------------------------------------------------------
    116 ; LOCAL VARIABLE DEFINITIONS
    117 ; Variable declaration - defined here and used outside this module
    118 ----------------------------------------------------------------------------*/
    119 
    120 
    121 /*
    122 ------------------------------------------------------------------------------
    123  FUNCTION NAME: set_sign
    124 ------------------------------------------------------------------------------
    125  INPUT AND OUTPUT DEFINITIONS
    126 
    127  Inputs:
    128     dn = buffer of correlation values (Word16)
    129     sign = buffer containing sign of dn elements (Word16)
    130     dn2 = buffer containing the maximum of correlation in each track.(Word16)
    131     n = number of maximum correlations in dn2 (Word16)
    132 
    133  Returns:
    134     None
    135 
    136  Outputs:
    137     dn buffer is modified to contain the absolute value of its input
    138     sign buffer is modified to contain the sign information for the
    139       values in dn buffer
    140     dn2 buffer is modified to denote the location of the maximum
    141       correlation for each track.
    142 
    143  Global Variables Used:
    144     None
    145 
    146  Local Variables Needed:
    147     None
    148 
    149 ------------------------------------------------------------------------------
    150  FUNCTION DESCRIPTION
    151 
    152 
    153  This function builds sign vector according to dn buffer It also finds
    154  the position of maximum of correlation in each track and the starting
    155  position for each pulse.
    156 
    157 ------------------------------------------------------------------------------
    158  REQUIREMENTS
    159 
    160  None.
    161 
    162 ------------------------------------------------------------------------------
    163  REFERENCES
    164 
    165  set_sign.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    166 
    167 ------------------------------------------------------------------------------
    168  PSEUDO-CODE
    169 
    170 void set_sign(Word16 dn[],    i/o : correlation between target and h[]
    171               Word16 sign[],  o   : sign of dn[]
    172               Word16 dn2[],   o   : maximum of correlation in each track.
    173               Word16 n        i   : # of maximum correlations in dn2[]
    174 )
    175 {
    176    Word16 i, j, k;
    177    Word16 val, min;
    178    Word16 pos = 0;    //initialization only needed to keep gcc silent
    179 
    180    // set sign according to dn[]
    181 
    182    for (i = 0; i < L_CODE; i++) {
    183       val = dn[i];
    184 
    185       if (val >= 0) {
    186          sign[i] = 32767;
    187       } else {
    188          sign[i] = -32767;
    189          val = negate(val);
    190       }
    191       dn[i] = val;     // modify dn[] according to the fixed sign
    192       dn2[i] = val;
    193    }
    194 
    195    // keep 8-n maximum positions/8 of each track and store it in dn2[]
    196 
    197    for (i = 0; i < NB_TRACK; i++)
    198    {
    199       for (k = 0; k < (8-n); k++)
    200       {
    201          min = 0x7fff;
    202          for (j = i; j < L_CODE; j += STEP)
    203          {
    204             if (dn2[j] >= 0)
    205             {
    206                val = sub(dn2[j], min);
    207 
    208                if (val < 0)
    209                {
    210                   min = dn2[j];
    211                   pos = j;
    212                }
    213             }
    214          }
    215          dn2[pos] = -1;
    216       }
    217    }
    218 
    219    return;
    220 }
    221 
    222 ------------------------------------------------------------------------------
    223  RESOURCES USED [optional]
    224 
    225  When the code is written for a specific target processor the
    226  the resources used should be documented below.
    227 
    228  HEAP MEMORY USED: x bytes
    229 
    230  STACK MEMORY USED: x bytes
    231 
    232  CLOCK CYCLES: (cycle count equation for this function) + (variable
    233                 used to represent cycle count for each subroutine
    234                 called)
    235      where: (cycle count variable) = cycle count for [subroutine
    236                                      name]
    237 
    238 ------------------------------------------------------------------------------
    239  CAUTION [optional]
    240  [State any special notes, constraints or cautions for users of this function]
    241 
    242 ------------------------------------------------------------------------------
    243 */
    244 
    245 void set_sign(Word16 dn[],   /* i/o : correlation between target and h[]    */
    246               Word16 sign[], /* o   : sign of dn[]                          */
    247               Word16 dn2[],  /* o   : maximum of correlation in each track. */
    248               Word16 n       /* i   : # of maximum correlations in dn2[]    */
    249              )
    250 {
    251     register Word16 i, j, k;
    252     Word16 val, min;
    253     Word16 pos = 0; /* initialization only needed to keep gcc silent */
    254 
    255     /* set sign according to dn[] */
    256     for (i = L_CODE - 1; i >= 0; i--)
    257     {
    258         val = dn[i];
    259 
    260         if (val >= 0)
    261         {
    262             sign[i] = 32767;
    263         }
    264         else
    265         {
    266             sign[i] = -32767;
    267             val = negate(val);
    268             dn[i] = val;     /* modify dn[] according to the fixed sign */
    269         }
    270 
    271         dn2[i] = val;
    272     }
    273 
    274     /* keep 8-n maximum positions/8 of each track and store it in dn2[] */
    275 
    276     for (i = 0; i < NB_TRACK; i++)
    277     {
    278         for (k = 0; k < (8 - n); k++)
    279         {
    280             min = 0x7fff;
    281             for (j = i; j < L_CODE; j += STEP)
    282             {
    283                 if (dn2[j] >= 0)
    284                 {
    285                     if (dn2[j] < min)
    286                     {
    287                         min = dn2[j];
    288                         pos = j;
    289                     }
    290                 }
    291             }
    292             dn2[pos] = -1;
    293         }
    294     }
    295 
    296     return;
    297 }
    298 
    299 /****************************************************************************/
    300 
    301 
    302 /*
    303 ------------------------------------------------------------------------------
    304  FUNCTION NAME: set_sign12k2()
    305 ------------------------------------------------------------------------------
    306  INPUT AND OUTPUT DEFINITIONS
    307 
    308  Inputs:
    309     dn = buffer of correlation values (Word16)
    310     cn = buffer of residual after long term prediction (Word16)
    311     sign = sign of correlation buffer elements (Word16)
    312     pos_max = buffer containing position of maximum correlation (Word16)
    313     nb_track = number of tracks (Word16)
    314     ipos = buffer containing the starting position for each pulse (Word16)
    315     step = step size in the tracks (Word16)
    316     pOverflow = pointer to Overflow flag (Flag)
    317 
    318  Outputs:
    319     sign buffer contains the sign of correlation values
    320     dn buffer contains the sign-adjusted correlation values
    321     pos_max buffer contains the maximum correlation position
    322     ipos buffer contains the starting position of each pulse
    323     pOverflow -> 1 if the math operations called by this function result in
    324     saturation
    325 
    326 
    327  Returns:
    328     None
    329 
    330  Global Variables Used:
    331     None
    332 
    333  Local Variables Needed:
    334     None
    335 
    336 ------------------------------------------------------------------------------
    337  FUNCTION DESCRIPTION
    338 
    339  This function builds the sign vector according to dn and cn, and modifies
    340  dn to include the sign information (dn[i]=sign[i]*dn[i]). It also finds
    341  the position of maximum of correlation in each track and the starting
    342  position for each pulse.
    343 
    344 ------------------------------------------------------------------------------
    345  REQUIREMENTS
    346 
    347  None
    348 
    349 ------------------------------------------------------------------------------
    350  REFERENCES
    351 
    352  set_sign.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    353 
    354 ------------------------------------------------------------------------------
    355  PSEUDO-CODE
    356 
    357 void set_sign12k2 (
    358     Word16 dn[],       //i/o : correlation between target and h[]
    359     Word16 cn[],       //i   : residual after long term prediction
    360     Word16 sign[],     //o   : sign of d[n]
    361     Word16 pos_max[],  //o   : position of maximum correlation
    362     Word16 nb_track,   //i   : number of tracks tracks
    363     Word16 ipos[],     //o   : starting position for each pulse
    364     Word16 step        //i   : the step size in the tracks
    365 )
    366 {
    367     Word16 i, j;
    368     Word16 val, cor, k_cn, k_dn, max, max_of_all;
    369     Word16 pos = 0;      // initialization only needed to keep gcc silent
    370     Word16 en[L_CODE];                  // correlation vector
    371     Word32 s;
    372 
    373     // The reference ETSI code uses a global flag for Overflow. However in the
    374     // actual implementation a pointer to the overflow flag is passed in. This
    375     // pointer is passed into the basic math functions called by this routine.
    376 
    377     // calculate energy for normalization of cn[] and dn[]
    378 
    379     s = 256;
    380     for (i = 0; i < L_CODE; i++)
    381     {
    382         s = L_mac (s, cn[i], cn[i]);
    383     }
    384     s = Inv_sqrt (s);
    385     k_cn = extract_h (L_shl (s, 5));
    386 
    387     s = 256;
    388     for (i = 0; i < L_CODE; i++)
    389     {
    390         s = L_mac (s, dn[i], dn[i]);
    391     }
    392     s = Inv_sqrt (s);
    393     k_dn = extract_h (L_shl (s, 5));
    394 
    395     for (i = 0; i < L_CODE; i++)
    396     {
    397         val = dn[i];
    398         cor = pv_round (L_shl (L_mac (L_mult (k_cn, cn[i]), k_dn, val), 10));
    399 
    400         if (cor >= 0)
    401         {
    402             sign[i] = 32767;                      // sign = +1
    403         }
    404         else
    405         {
    406             sign[i] = -32767;                     // sign = -1
    407             cor = negate (cor);
    408             val = negate (val);
    409         }
    410         // modify dn[] according to the fixed sign
    411         dn[i] = val;
    412         en[i] = cor;
    413     }
    414 
    415     max_of_all = -1;
    416     for (i = 0; i < nb_track; i++)
    417     {
    418         max = -1;
    419 
    420         for (j = i; j < L_CODE; j += step)
    421         {
    422             cor = en[j];
    423             val = sub (cor, max);
    424 
    425             if (val > 0)
    426             {
    427                 max = cor;
    428                 pos = j;
    429             }
    430         }
    431         // store maximum correlation position
    432         pos_max[i] = pos;
    433         val = sub (max, max_of_all);
    434 
    435         if (val > 0)
    436         {
    437             max_of_all = max;
    438             // starting position for i0
    439             ipos[0] = i;
    440         }
    441     }
    442 
    443     //
    444     //     Set starting position of each pulse.
    445     //
    446 
    447     pos = ipos[0];
    448     ipos[nb_track] = pos;
    449 
    450     for (i = 1; i < nb_track; i++)
    451     {
    452         pos = add (pos, 1);
    453 
    454         if (sub (pos, nb_track) >= 0)
    455         {
    456            pos = 0;
    457         }
    458         ipos[i] = pos;
    459         ipos[add(i, nb_track)] = pos;
    460     }
    461 }
    462 
    463 ------------------------------------------------------------------------------
    464  RESOURCES USED [optional]
    465 
    466  When the code is written for a specific target processor the
    467  the resources used should be documented below.
    468 
    469  HEAP MEMORY USED: x bytes
    470 
    471  STACK MEMORY USED: x bytes
    472 
    473  CLOCK CYCLES: (cycle count equation for this function) + (variable
    474                 used to represent cycle count for each subroutine
    475                 called)
    476      where: (cycle count variable) = cycle count for [subroutine
    477                                      name]
    478 
    479 ------------------------------------------------------------------------------
    480  CAUTION [optional]
    481  [State any special notes, constraints or cautions for users of this function]
    482 
    483 ------------------------------------------------------------------------------
    484 */
    485 
    486 void set_sign12k2(
    487     Word16 dn[],        /* i/o : correlation between target and h[]         */
    488     Word16 cn[],        /* i   : residual after long term prediction        */
    489     Word16 sign[],      /* o   : sign of d[n]                               */
    490     Word16 pos_max[],   /* o   : position of maximum correlation            */
    491     Word16 nb_track,    /* i   : number of tracks tracks                    */
    492     Word16 ipos[],      /* o   : starting position for each pulse           */
    493     Word16 step,        /* i   : the step size in the tracks                */
    494     Flag   *pOverflow   /* i/o: overflow flag                               */
    495 )
    496 {
    497     Word16 i, j;
    498     Word16 val;
    499     Word16 cor;
    500     Word16 k_cn;
    501     Word16 k_dn;
    502     Word16 max;
    503     Word16 max_of_all;
    504     Word16 pos = 0; /* initialization only needed to keep gcc silent */
    505     Word16 en[L_CODE];                  /* correlation vector */
    506     Word32 s;
    507     Word32 t;
    508     Word32 L_temp;
    509     Word16 *p_cn;
    510     Word16 *p_dn;
    511     Word16 *p_sign;
    512     Word16 *p_en;
    513 
    514     /* calculate energy for normalization of cn[] and dn[] */
    515 
    516     s = 256;
    517     t = 256;
    518     p_cn = cn;
    519     p_dn = dn;      /* crosscorrelation values do not have strong peaks, so
    520                        scaling applied in cor_h_x (sf=2) guaranteed that the
    521                        mac of the energy for this vector will not overflow */
    522 
    523     for (i = L_CODE; i != 0; i--)
    524     {
    525         val = *(p_cn++);
    526         s = L_mac(s, val, val, pOverflow);
    527         val = *(p_dn++);
    528         t += ((Word32) val * val) << 1;
    529     }
    530     s = Inv_sqrt(s, pOverflow);
    531     k_cn = (Word16)((L_shl(s, 5, pOverflow)) >> 16);
    532 
    533     t = Inv_sqrt(t, pOverflow);
    534     k_dn = (Word16)(t >> 11);
    535 
    536     p_cn   = &cn[L_CODE-1];
    537     p_sign = &sign[L_CODE-1];
    538     p_en   = &en[L_CODE-1];
    539 
    540     for (i = L_CODE - 1; i >= 0; i--)
    541     {
    542         L_temp = ((Word32)k_cn * *(p_cn--)) << 1;
    543         val = dn[i];
    544         s = L_mac(L_temp, k_dn, val, pOverflow);
    545         L_temp = L_shl(s, 10, pOverflow);
    546         cor = pv_round(L_temp, pOverflow);
    547 
    548         if (cor >= 0)
    549         {
    550             *(p_sign--) = 32767;                      /* sign = +1 */
    551         }
    552         else
    553         {
    554             *(p_sign--) = -32767;                     /* sign = -1 */
    555             cor = negate(cor);
    556 
    557             /* modify dn[] according to the fixed sign */
    558             dn[i] = negate(val);
    559         }
    560 
    561         *(p_en--) = cor;
    562     }
    563 
    564     max_of_all = -1;
    565     for (i = 0; i < nb_track; i++)
    566     {
    567         max = -1;
    568 
    569         for (j = i; j < L_CODE; j += step)
    570         {
    571             cor = en[j];
    572             if (cor > max)
    573             {
    574                 max = cor;
    575                 pos = j;
    576             }
    577         }
    578         /* store maximum correlation position */
    579         pos_max[i] = pos;
    580         if (max > max_of_all)
    581         {
    582             max_of_all = max;
    583             /* starting position for i0 */
    584             ipos[0] = i;
    585         }
    586     }
    587 
    588     /*----------------------------------------------------------------*
    589      *     Set starting position of each pulse.                       *
    590      *----------------------------------------------------------------*/
    591 
    592     pos = ipos[0];
    593     ipos[nb_track] = pos;
    594 
    595     for (i = 1; i < nb_track; i++)
    596     {
    597         pos++;
    598 
    599         if (pos >= nb_track)
    600         {
    601             pos = 0;
    602         }
    603         ipos[ i] = pos;
    604         ipos[ i + nb_track] = pos;
    605     }
    606 
    607     return;
    608 }
    609 
    610