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/q_gain_p.c
     35  Functions: q_gain_pitch
     36 
     37      Date: 02/04/2002
     38 
     39 ------------------------------------------------------------------------------
     40  REVISION HISTORY
     41 
     42  Description: Updated template used to PV coding template.
     43  Changed to accept the pOverflow flag for EPOC compatibility.
     44 
     45  Description:  Replaced "int" and/or "char" with OSCL defined types.
     46 
     47  Description: Added #ifdef __cplusplus around extern'ed table.
     48 
     49  Description:
     50 
     51 ------------------------------------------------------------------------------
     52  MODULE DESCRIPTION
     53 
     54 
     55 ------------------------------------------------------------------------------
     56 */
     57 
     58 /*----------------------------------------------------------------------------
     59 ; INCLUDES
     60 ----------------------------------------------------------------------------*/
     61 #include "q_gain_p.h"
     62 #include "typedef.h"
     63 #include "oper_32b.h"
     64 #include "cnst.h"
     65 #include "basic_op.h"
     66 
     67 
     68 /*--------------------------------------------------------------------------*/
     69 #ifdef __cplusplus
     70 extern "C"
     71 {
     72 #endif
     73 
     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 #define NB_QUA_PITCH 16
     85 
     86     /*----------------------------------------------------------------------------
     87     ; LOCAL FUNCTION DEFINITIONS
     88     ; Function Prototype declaration
     89     ----------------------------------------------------------------------------*/
     90 
     91     /*----------------------------------------------------------------------------
     92     ; LOCAL VARIABLE DEFINITIONS
     93     ; Variable declaration - defined here and used outside this module
     94     ----------------------------------------------------------------------------*/
     95 
     96     /*----------------------------------------------------------------------------
     97     ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
     98     ; Declare variables used in this module but defined elsewhere
     99     ----------------------------------------------------------------------------*/
    100     extern const Word16 qua_gain_pitch[NB_QUA_PITCH];
    101 
    102     /*--------------------------------------------------------------------------*/
    103 #ifdef __cplusplus
    104 }
    105 #endif
    106 
    107 /*
    108 ------------------------------------------------------------------------------
    109  FUNCTION NAME: q_gain_pitch
    110 ------------------------------------------------------------------------------
    111  INPUT AND OUTPUT DEFINITIONS
    112 
    113  Inputs:
    114     mode -- enum Mode -- AMR mode
    115     gp_limit -- Word16 -- pitch gain limit
    116     gain -- Pointer to Word16 -- Pitch gain (unquant/quant),              Q14
    117 
    118  Outputs:
    119     gain -- Pointer to Word16 -- Pitch gain (unquant/quant),              Q14
    120 
    121     gain_cand -- Array of type Word16 -- pitch gain candidates (3),
    122                                          MR795 only, Q14
    123 
    124     gain_cind -- Array of type Word16 -- pitch gain cand. indices (3),
    125                                          MR795 only, Q0
    126 
    127     pOverflow -- Pointer to Flag -- overflow indicator
    128 
    129  Returns:
    130     Word16 -- index of quantization
    131 
    132  Global Variables Used:
    133     qua_gain_pitch
    134 
    135  Local Variables Needed:
    136     None
    137 
    138 ------------------------------------------------------------------------------
    139  FUNCTION DESCRIPTION
    140 
    141 
    142 ------------------------------------------------------------------------------
    143  REQUIREMENTS
    144 
    145  None
    146 
    147 ------------------------------------------------------------------------------
    148  REFERENCES
    149 
    150  q_gain_p.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    151 
    152 ------------------------------------------------------------------------------
    153  PSEUDO-CODE
    154 
    155 
    156 ------------------------------------------------------------------------------
    157  RESOURCES USED [optional]
    158 
    159  When the code is written for a specific target processor the
    160  the resources used should be documented below.
    161 
    162  HEAP MEMORY USED: x bytes
    163 
    164  STACK MEMORY USED: x bytes
    165 
    166  CLOCK CYCLES: (cycle count equation for this function) + (variable
    167                 used to represent cycle count for each subroutine
    168                 called)
    169      where: (cycle count variable) = cycle count for [subroutine
    170                                      name]
    171 
    172 ------------------------------------------------------------------------------
    173  CAUTION [optional]
    174  [State any special notes, constraints or cautions for users of this function]
    175 
    176 ------------------------------------------------------------------------------
    177 */
    178 
    179 Word16 q_gain_pitch(    /* Return index of quantization                      */
    180     enum Mode mode,     /* i  : AMR mode                                     */
    181     Word16 gp_limit,    /* i  : pitch gain limit                             */
    182     Word16 *gain,       /* i/o: Pitch gain (unquant/quant),              Q14 */
    183     Word16 gain_cand[], /* o  : pitch gain candidates (3),   MR795 only, Q14 */
    184     Word16 gain_cind[], /* o  : pitch gain cand. indices (3),MR795 only, Q0  */
    185     Flag   *pOverflow
    186 )
    187 {
    188     Word16 i;
    189     Word16 index;
    190     Word16 err;
    191     Word16 err_min;
    192 
    193     err_min = sub(*gain, qua_gain_pitch[0], pOverflow);
    194     err_min = abs_s(err_min);
    195 
    196     index = 0;
    197 
    198     for (i = 1; i < NB_QUA_PITCH; i++)
    199     {
    200         if (qua_gain_pitch[i] <= gp_limit)
    201         {
    202             err = sub(*gain, qua_gain_pitch[i], pOverflow);
    203             err = abs_s(err);
    204 
    205             if (err < err_min)
    206             {
    207                 err_min = err;
    208                 index = i;
    209             }
    210         }
    211     }
    212 
    213     if (mode == MR795)
    214     {
    215         /* in MR795 mode, compute three gain_pit candidates around the index
    216          * found in the quantization loop: the index found and the two direct
    217          * neighbours, except for the extreme cases (i=0 or i=NB_QUA_PITCH-1),
    218          * where the direct neighbour and the neighbour to that is used.
    219          */
    220         Word16 ii;
    221 
    222         if (index == 0)
    223         {
    224             ii = index;
    225         }
    226         else
    227         {
    228             if (index == (NB_QUA_PITCH - 1) ||
    229                     (qua_gain_pitch[index+1] > gp_limit))
    230             {
    231                 ii = index - 2;
    232             }
    233             else
    234             {
    235                 ii = index - 1;
    236             }
    237         }
    238 
    239         /* store candidate indices and values */
    240         for (i = 0; i < 3; i++)
    241         {
    242             gain_cind[i] = ii;
    243             gain_cand[i] = qua_gain_pitch[ii];
    244 
    245             ii = add(ii, 1, pOverflow);
    246         }
    247 
    248         *gain = qua_gain_pitch[index];
    249     }
    250     else
    251     {
    252         /* in MR122 mode, just return the index and gain pitch found.
    253          * If bitexactness is required, mask away the two LSBs (because
    254          * in the original EFR, gain_pit was scaled Q12)
    255          */
    256         if (mode == MR122)
    257         {
    258             /* clear 2 LSBits */
    259             *gain = qua_gain_pitch[index] & 0xFFFC;
    260         }
    261         else
    262         {
    263             *gain = qua_gain_pitch[index];
    264         }
    265     }
    266     return index;
    267 }
    268