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  Filename: /audio/gsm_amr/c/src/g_code.c
     35 
     36      Date: 01/31/2002
     37 
     38 ------------------------------------------------------------------------------
     39  REVISION HISTORY
     40 
     41  Description: The return of L_mult was being stored in a Word16 before it was
     42               being operated on (extract_h). Data loss happened here.
     43 
     44  Description:
     45               1. Eliminated unused include files.
     46               2. Replaced array addressing by pointers
     47               3. Eliminated math operations that unnecessary checked for
     48                  saturation, in some cases this by shifting before adding and
     49                  in other cases by evaluating the operands
     50               4. Unrolled loops to speed up processing
     51               5. Eliminated calls to shifts left and right functions by adding
     52                  if-else statements that do the same faster.
     53 
     54  Description:  Added casting to eliminate warnings
     55 
     56  Description:  Replaced "int" and/or "char" with OSCL defined types.
     57 
     58  Description: 1. Using inlines from fxp_arithmetic.h
     59               2. Removing a compiler warning.
     60 
     61  Description: Replacing fxp_arithmetic.h with basic_op.h.
     62 
     63  Description:
     64 
     65 ------------------------------------------------------------------------------
     66 */
     67 
     68 /*----------------------------------------------------------------------------
     69 ; INCLUDES
     70 ----------------------------------------------------------------------------*/
     71 #include    "g_code.h"
     72 #include    "cnst.h"
     73 #include    "basic_op.h"
     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 /*----------------------------------------------------------------------------
     86 ; LOCAL FUNCTION DEFINITIONS
     87 ; [List function prototypes here]
     88 ----------------------------------------------------------------------------*/
     89 
     90 /*----------------------------------------------------------------------------
     91 ; LOCAL VARIABLE DEFINITIONS
     92 ; [Variable declaration - defined here and used outside this module]
     93 ----------------------------------------------------------------------------*/
     94 
     95 /*
     96 ------------------------------------------------------------------------------
     97  FUNCTION NAME: G_code
     98 ------------------------------------------------------------------------------
     99  INPUT AND OUTPUT DEFINITIONS
    100 
    101  Inputs:
    102     xn2[] = target vector (Word16)
    103     y2[] = filtered innovation vector
    104     pOverflow = pointer to overflow (Flag)
    105 
    106  Outputs:
    107     pOverflow -> 1 if the innovative gain calculation resulted in overflow
    108 
    109  Returns:
    110     gain = Gain of Innovation code (Word16)
    111 
    112  Global Variables Used:
    113     None
    114 
    115  Local Variables Needed:
    116     None
    117 
    118 ------------------------------------------------------------------------------
    119  FUNCTION DESCRIPTION
    120 
    121  This function computes the innovative codebook gain.
    122 
    123  The innovative codebook gain is given by
    124     g = <x[], y[]> / <y[], y[]>
    125 
    126  where x[] is the target vector, y[] is the filtered innovative codevector,
    127  and <> denotes dot product.
    128 
    129 ------------------------------------------------------------------------------
    130  REQUIREMENTS
    131 
    132  None
    133 
    134 ------------------------------------------------------------------------------
    135  REFERENCES
    136 
    137  [1] g_code.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    138 
    139 ------------------------------------------------------------------------------
    140  PSEUDO-CODE
    141 
    142 Word16 G_code (         // out   : Gain of innovation code
    143     Word16 xn2[],       // in    : target vector
    144     Word16 y2[]         // in    : filtered innovation vector
    145 )
    146 {
    147     Word16 i;
    148     Word16 xy, yy, exp_xy, exp_yy, gain;
    149     Word16 scal_y2[L_SUBFR];
    150     Word32 s;
    151 
    152 // The original ETSI implementation uses a global overflow flag. However in
    153 // actual implementation a pointer to Overflow flag is passed into the
    154 // function for access by the low level math functions.
    155 
    156     // Scale down Y[] by 2 to avoid overflow
    157 
    158     for (i = 0; i < L_SUBFR; i++)
    159     {
    160         scal_y2[i] = shr (y2[i], 1);
    161     }
    162 
    163     // Compute scalar product <X[],Y[]>
    164 
    165     s = 1L; // Avoid case of all zeros
    166     for (i = 0; i < L_SUBFR; i++)
    167     {
    168         s = L_mac (s, xn2[i], scal_y2[i]);
    169     }
    170     exp_xy = norm_l (s);
    171     xy = extract_h (L_shl (s, exp_xy));
    172 
    173     // If (xy < 0) gain = 0
    174 
    175     if (xy <= 0)
    176         return ((Word16) 0);
    177 
    178     // Compute scalar product <Y[],Y[]>
    179 
    180     s = 0L;
    181     for (i = 0; i < L_SUBFR; i++)
    182     {
    183         s = L_mac (s, scal_y2[i], scal_y2[i]);
    184     }
    185     exp_yy = norm_l (s);
    186     yy = extract_h (L_shl (s, exp_yy));
    187 
    188     // compute gain = xy/yy
    189 
    190     xy = shr (xy, 1);                 // Be sure xy < yy
    191     gain = div_s (xy, yy);
    192 
    193     // Denormalization of division
    194     i = add (exp_xy, 5);              // 15-1+9-18 = 5
    195     i = sub (i, exp_yy);
    196 
    197     gain = shl (shr (gain, i), 1);    // Q0 -> Q1/
    198 
    199     return (gain);
    200 }
    201 
    202 
    203 ------------------------------------------------------------------------------
    204  RESOURCES USED [optional]
    205 
    206  When the code is written for a specific target processor the
    207  the resources used should be documented below.
    208 
    209  HEAP MEMORY USED: x bytes
    210 
    211  STACK MEMORY USED: x bytes
    212 
    213  CLOCK CYCLES: (cycle count equation for this function) + (variable
    214                 used to represent cycle count for each subroutine
    215                 called)
    216      where: (cycle count variable) = cycle count for [subroutine
    217                                      name]
    218 
    219 ------------------------------------------------------------------------------
    220  CAUTION [optional]
    221  [State any special notes, constraints or cautions for users of this function]
    222 
    223 ------------------------------------------------------------------------------
    224 */
    225 
    226 /*----------------------------------------------------------------------------
    227 ; FUNCTION CODE
    228 ----------------------------------------------------------------------------*/
    229 Word16 G_code(          /* o     : Gain of innovation code         */
    230     Word16 xn2[],       /* i     : target vector                   */
    231     Word16 y2[],        /* i     : filtered innovation vector      */
    232     Flag   *pOverflow   /* i/o   : overflow flag                   */
    233 )
    234 {
    235     Word16 i;
    236     Word16 xy, yy, exp_xy, exp_yy, gain;
    237     Word32 s;
    238 
    239     Word16 *p_xn2 = xn2;
    240     Word16 *p_y2  = y2;
    241     Word16 temp;
    242     Word32 temp2;
    243 
    244     OSCL_UNUSED_ARG(pOverflow);
    245 
    246     /* Compute scalar product <X[],Y[]> */
    247     s = 0;
    248 
    249     for (i = (L_SUBFR >> 2); i != 0 ; i--)
    250     {
    251         temp2 = (Word32)(*(p_y2++) >> 1);
    252         s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_xn2++), temp2, s);
    253         temp2 = (Word32)(*(p_y2++) >> 1);
    254         s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_xn2++), temp2, s);
    255         temp2 = (Word32)(*(p_y2++) >> 1);
    256         s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_xn2++), temp2, s);
    257         temp2 = (Word32)(*(p_y2++) >> 1);
    258         s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_xn2++), temp2, s);
    259     }
    260     s <<= 1;
    261     exp_xy = norm_l(s + 1); /* Avoid case of all zeros, add 1 */
    262 
    263     if (exp_xy < 17)        /* extra right shift to be sure xy < yy */
    264     {
    265         xy = (Word16)(s >> (17 - exp_xy));
    266     }
    267     else
    268     {
    269         xy = (Word16)(s << (exp_xy - 17));
    270     }
    271 
    272     /* If (xy < 0) gain = 0  */
    273 
    274     if (xy <= 0)
    275     {
    276         return ((Word16) 0);
    277     }
    278 
    279     /* Compute scalar product <Y[],Y[]> */
    280 
    281     s = 0L;
    282     p_y2  = y2;
    283 
    284     for (i = (L_SUBFR >> 1); i != 0 ; i--)
    285     {
    286         temp = *(p_y2++) >> 1;
    287         s += ((Word32) temp * temp) >> 2;
    288         temp = *(p_y2++) >> 1;
    289         s += ((Word32) temp * temp) >> 2;
    290     }
    291     s <<= 3;
    292     exp_yy = norm_l(s);
    293 
    294     if (exp_yy < 16)
    295     {
    296         yy = (Word16)(s >> (16 - exp_yy));
    297     }
    298     else
    299     {
    300         yy = (Word16)(s << (exp_yy - 16));
    301     }
    302 
    303     gain = div_s(xy, yy);
    304 
    305     /* Denormalization of division */
    306     i  = exp_xy + 5;                                /* 15-1+9-18 = 5 */
    307     i -= exp_yy;
    308 
    309     // gain = shl (shr (gain, i), 1);    /* Q0 -> Q1 */
    310 
    311     if (i > 1)
    312     {
    313         gain >>= i - 1;
    314     }
    315     else
    316     {
    317         gain <<= 1 - i;
    318     }
    319 
    320 
    321     return (gain);
    322 }
    323