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/cor_h_x.c
     35 
     36      Date: 09/07/2000
     37 
     38 ------------------------------------------------------------------------------
     39  REVISION HISTORY
     40 
     41  Description: Created a separate file for cor_h_x function.
     42 
     43  Description: Synchronized file with UMTS versin 3.2.0. Updated coding
     44               template.
     45 
     46  Description: Made the following changes per comments from Phase 2/3 review:
     47               1. Modified FOR loop in the code to count down.
     48               2. Fixed typecasting issue with TI C compiler.
     49 
     50  Description: Added call to round() and L_shl() functions in the last FOR
     51               loop to make code bit-exact. Updated copyright year.
     52 
     53  Description: Modified to pass pOverflow in via a pointer, rather than
     54  invoking it as a global variable.
     55 
     56  Description: Made the following changes
     57               1. Unrolled the correlation loop and add mechanism control
     58                  to compute odd or even number of computations.
     59               2. Use pointer to avoid continuos addresses calculation
     60               2. Eliminated math operations that check for saturation.
     61 
     62  Description: Changed round function name to pv_round to avoid conflict with
     63               round function in C standard library.
     64 
     65  Description:
     66 
     67 ------------------------------------------------------------------------------
     68 */
     69 
     70 /*----------------------------------------------------------------------------
     71 ; INCLUDES
     72 ----------------------------------------------------------------------------*/
     73 #include "typedef.h"
     74 #include "cnst.h"
     75 #include "cor_h_x.h"
     76 #include "basic_op.h"
     77 
     78 /*----------------------------------------------------------------------------
     79 ; MACROS
     80 ; Define module specific macros here
     81 ----------------------------------------------------------------------------*/
     82 
     83 
     84 /*----------------------------------------------------------------------------
     85 ; DEFINES
     86 ; Include all pre-processor statements here. Include conditional
     87 ; compile variables also.
     88 ----------------------------------------------------------------------------*/
     89 
     90 /*----------------------------------------------------------------------------
     91 ; LOCAL FUNCTION DEFINITIONS
     92 ; Function Prototype declaration
     93 ----------------------------------------------------------------------------*/
     94 
     95 /*----------------------------------------------------------------------------
     96 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
     97 ; Variable declaration - defined here and used outside this module
     98 ----------------------------------------------------------------------------*/
     99 
    100 /*----------------------------------------------------------------------------
    101 ; EXTERNAL FUNCTION REFERENCES
    102 ; Declare functions defined elsewhere and referenced in 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: cor_h_x
    113 ------------------------------------------------------------------------------
    114  INPUT AND OUTPUT DEFINITIONS
    115 
    116  Inputs:
    117     h = vector containing the impulse response of the weighted synthesis
    118         filter; vector contents are of type Word16; vector length is
    119         2 * L_SUBFR
    120     x = target signal vector; vector contents are of type Word16; vector
    121         length is L_SUBFR
    122     dn = vector containing the correlation between the target and the
    123          impulse response; vector contents are of type Word16; vector
    124          length is L_CODE
    125     sf = scaling factor of type Word16 ; 2 when mode is MR122, 1 for all
    126          other modes
    127 
    128  Outputs:
    129     dn contents are the newly calculated correlation values
    130 
    131     pOverflow = pointer of type Flag * to overflow indicator.
    132 
    133  Returns:
    134     None
    135 
    136  Global Variables Used:
    137     None
    138 
    139  Local Variables Needed:
    140     None
    141 
    142 ------------------------------------------------------------------------------
    143  FUNCTION DESCRIPTION
    144 
    145  This function computes the correlation between the target signal (x) and the
    146  impulse response (h).
    147 
    148  The correlation is given by: d[n] = sum_{i=n}^{L-1} x[i] h[i-n],
    149  where: n=0,...,L-1
    150 
    151  d[n] is normalized such that the sum of 5 maxima of d[n] corresponding to
    152  each position track does not saturate.
    153 
    154 ------------------------------------------------------------------------------
    155  REQUIREMENTS
    156 
    157  None
    158 
    159 ------------------------------------------------------------------------------
    160  REFERENCES
    161 
    162  cor_h.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    163 
    164 ------------------------------------------------------------------------------
    165  PSEUDO-CODE
    166 
    167 void cor_h_x (
    168     Word16 h[],    // (i): impulse response of weighted synthesis filter
    169     Word16 x[],    // (i): target
    170     Word16 dn[],   // (o): correlation between target and h[]
    171     Word16 sf      // (i): scaling factor: 2 for 12.2, 1 for others
    172 )
    173 {
    174     cor_h_x2(h, x, dn, sf, NB_TRACK, STEP);
    175 }
    176 
    177 
    178 void cor_h_x2 (
    179     Word16 h[],    // (i): impulse response of weighted synthesis filter
    180     Word16 x[],    // (i): target
    181     Word16 dn[],   // (o): correlation between target and h[]
    182     Word16 sf,     // (i): scaling factor: 2 for 12.2, 1 for others
    183     Word16 nb_track,// (i): the number of ACB tracks
    184     Word16 step    // (i): step size from one pulse position to the next
    185                            in one track
    186 )
    187 {
    188     Word16 i, j, k;
    189     Word32 s, y32[L_CODE], max, tot;
    190 
    191     // first keep the result on 32 bits and find absolute maximum
    192 
    193     tot = 5;
    194 
    195     for (k = 0; k < nb_track; k++)
    196     {
    197         max = 0;
    198         for (i = k; i < L_CODE; i += step)
    199         {
    200             s = 0;
    201             for (j = i; j < L_CODE; j++)
    202                 s = L_mac (s, x[j], h[j - i]);
    203 
    204             y32[i] = s;
    205 
    206             s = L_abs (s);
    207             if (L_sub (s, max) > (Word32) 0L)
    208                 max = s;
    209         }
    210         tot = L_add (tot, L_shr (max, 1));
    211     }
    212 
    213     j = sub (norm_l (tot), sf);
    214 
    215     for (i = 0; i < L_CODE; i++)
    216     {
    217         dn[i] = pv_round (L_shl (y32[i], j));
    218     }
    219 }
    220 
    221 ------------------------------------------------------------------------------
    222  RESOURCES USED [optional]
    223 
    224  When the code is written for a specific target processor the
    225  the resources used should be documented below.
    226 
    227  HEAP MEMORY USED: x bytes
    228 
    229  STACK MEMORY USED: x bytes
    230 
    231  CLOCK CYCLES: (cycle count equation for this function) + (variable
    232                 used to represent cycle count for each subroutine
    233                 called)
    234      where: (cycle count variable) = cycle count for [subroutine
    235                                      name]
    236 
    237 ------------------------------------------------------------------------------
    238  CAUTION [optional]
    239  [State any special notes, constraints or cautions for users of this function]
    240 
    241 ------------------------------------------------------------------------------
    242 */
    243 
    244 void cor_h_x(
    245     Word16 h[],       /* (i): impulse response of weighted synthesis filter */
    246     Word16 x[],       /* (i): target                                        */
    247     Word16 dn[],      /* (o): correlation between target and h[]            */
    248     Word16 sf,        /* (i): scaling factor: 2 for 12.2, 1 for others      */
    249     Flag   *pOverflow /* (o): pointer to overflow flag                      */
    250 )
    251 {
    252     register Word16 i;
    253     register Word16 j;
    254     register Word16 k;
    255 
    256     Word32 s;
    257     Word32 y32[L_CODE];
    258     Word32 max;
    259     Word32 tot;
    260 
    261     Word16 *p_x;
    262     Word16 *p_ptr;
    263     Word32 *p_y32;
    264 
    265 
    266     tot = 5;
    267     for (k = 0; k < NB_TRACK; k++)              /* NB_TRACK = 5 */
    268     {
    269         max = 0;
    270         for (i = k; i < L_CODE; i += STEP)      /* L_CODE = 40; STEP = 5 */
    271         {
    272             s = 0;
    273             p_x = &x[i];
    274             p_ptr = h;
    275 
    276             for (j = (L_CODE - i - 1) >> 1; j != 0; j--)
    277             {
    278                 s += ((Word32) * (p_x++) * *(p_ptr++)) << 1;
    279                 s += ((Word32) * (p_x++) * *(p_ptr++)) << 1;
    280             }
    281 
    282             s += ((Word32) * (p_x++) * *(p_ptr++)) << 1;
    283 
    284             if (!((L_CODE - i) & 1))    /* if even number of iterations */
    285             {
    286                 s += ((Word32) * (p_x++) * *(p_ptr++)) << 1;
    287             }
    288 
    289             y32[i] = s;
    290 
    291             if (s < 0)
    292             {
    293                 s = -s;
    294             }
    295 
    296             if (s > max)
    297             {
    298                 max = s;
    299             }
    300         }
    301 
    302         tot += (max >> 1);
    303     }
    304 
    305 
    306     j = norm_l(tot) - sf;
    307 
    308     p_ptr = dn;
    309     p_y32 = y32;;
    310 
    311     for (i = L_CODE >> 1; i != 0; i--)
    312     {
    313         s = L_shl(*(p_y32++), j, pOverflow);
    314         *(p_ptr++) = (s + 0x00008000) >> 16;
    315         s = L_shl(*(p_y32++), j, pOverflow);
    316         *(p_ptr++) = (s + 0x00008000) >> 16;
    317     }
    318 
    319     return;
    320 }
    321