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/g_adapt.c
     35  Functions:
     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 OSCL mem type functions and eliminated include
     46                files that now are chosen by OSCL definitions
     47 
     48  Description:  Replaced "int" and/or "char" with OSCL defined types.
     49 
     50  Description:
     51 
     52 ------------------------------------------------------------------------------
     53  MODULE DESCRIPTION
     54 
     55 
     56 ------------------------------------------------------------------------------
     57 */
     58 
     59 /*----------------------------------------------------------------------------
     60 ; INCLUDES
     61 ----------------------------------------------------------------------------*/
     62 #include <stdlib.h>
     63 
     64 #include "g_adapt.h"
     65 #include "typedef.h"
     66 #include "basic_op.h"
     67 #include "oper_32b.h"
     68 #include "cnst.h"
     69 #include "gmed_n.h"
     70 
     71 /*----------------------------------------------------------------------------
     72 ; MACROS
     73 ; Define module specific macros here
     74 ----------------------------------------------------------------------------*/
     75 
     76 /*----------------------------------------------------------------------------
     77 ; DEFINES
     78 ; Include all pre-processor statements here. Include conditional
     79 ; compile variables also.
     80 ----------------------------------------------------------------------------*/
     81 #define LTP_GAIN_THR1 2721 /* 2721 Q13 = 0.3322 ~= 1.0 / (10*log10(2)) */
     82 #define LTP_GAIN_THR2 5443 /* 5443 Q13 = 0.6644 ~= 2.0 / (10*log10(2)) */
     83 
     84 /*----------------------------------------------------------------------------
     85 ; LOCAL FUNCTION DEFINITIONS
     86 ; Function Prototype declaration
     87 ----------------------------------------------------------------------------*/
     88 
     89 /*----------------------------------------------------------------------------
     90 ; LOCAL VARIABLE DEFINITIONS
     91 ; Variable declaration - defined here and used outside this module
     92 ----------------------------------------------------------------------------*/
     93 
     94 
     95 /*
     96 ------------------------------------------------------------------------------
     97  FUNCTION NAME: gain_adapt_init
     98 ------------------------------------------------------------------------------
     99  INPUT AND OUTPUT DEFINITIONS
    100 
    101  Inputs:
    102     st -- double pointer to GainAdaptState
    103 
    104  Outputs:
    105     st -- double ponter to GainAdaptState
    106 
    107  Returns:
    108     -1 if an error occurs during memory initialization
    109      0 if OK
    110 
    111  Global Variables Used:
    112     None
    113 
    114  Local Variables Needed:
    115     None
    116 
    117 ------------------------------------------------------------------------------
    118  FUNCTION DESCRIPTION
    119 
    120     Allocates state memory and initializes state memory
    121 
    122 ------------------------------------------------------------------------------
    123  REQUIREMENTS
    124 
    125  None
    126 
    127 ------------------------------------------------------------------------------
    128  REFERENCES
    129 
    130  g_adapt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    131 
    132 ------------------------------------------------------------------------------
    133  PSEUDO-CODE
    134 
    135 
    136 ------------------------------------------------------------------------------
    137  RESOURCES USED [optional]
    138 
    139  When the code is written for a specific target processor the
    140  the resources used should be documented below.
    141 
    142  HEAP MEMORY USED: x bytes
    143 
    144  STACK MEMORY USED: x bytes
    145 
    146  CLOCK CYCLES: (cycle count equation for this function) + (variable
    147                 used to represent cycle count for each subroutine
    148                 called)
    149      where: (cycle count variable) = cycle count for [subroutine
    150                                      name]
    151 
    152 ------------------------------------------------------------------------------
    153  CAUTION [optional]
    154  [State any special notes, constraints or cautions for users of this function]
    155 
    156 ------------------------------------------------------------------------------
    157 */
    158 
    159 Word16 gain_adapt_init(GainAdaptState **st)
    160 {
    161     GainAdaptState* s;
    162 
    163     if (st == (GainAdaptState **) NULL)
    164     {
    165         /* fprintf(stderr, "gain_adapt_init: invalid parameter\n"); */
    166         return -1;
    167     }
    168     *st = NULL;
    169 
    170     /* allocate memory */
    171     if ((s = (GainAdaptState *) malloc(sizeof(GainAdaptState))) == NULL)
    172     {
    173         /* fprintf(stderr, "gain_adapt_init: can't malloc state structure\n"); */
    174         return -1;
    175     }
    176     gain_adapt_reset(s);
    177     *st = s;
    178 
    179     return 0;
    180 }
    181 
    182 /*
    183 ------------------------------------------------------------------------------
    184  FUNCTION NAME: gain_adapt_reset
    185 ------------------------------------------------------------------------------
    186  INPUT AND OUTPUT DEFINITIONS
    187 
    188  Inputs:
    189     st -- double pointer to GainAdaptState
    190 
    191  Outputs:
    192     st -- double ponter to GainAdaptState
    193 
    194  Returns:
    195     -1 if an error occurs
    196      0 if OK
    197 
    198  Global Variables Used:
    199     None
    200 
    201  Local Variables Needed:
    202     None
    203 
    204 ------------------------------------------------------------------------------
    205  FUNCTION DESCRIPTION
    206 
    207     Initializes state memory to zero
    208 ------------------------------------------------------------------------------
    209  REQUIREMENTS
    210 
    211  None
    212 
    213 ------------------------------------------------------------------------------
    214  REFERENCES
    215 
    216  g_adapt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    217 
    218 ------------------------------------------------------------------------------
    219  PSEUDO-CODE
    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 Word16 gain_adapt_reset(GainAdaptState *st)
    246 {
    247     Word16 i;
    248 
    249     if (st == (GainAdaptState *) NULL)
    250     {
    251         /* fprintf(stderr, "gain_adapt_reset: invalid parameter\n"); */
    252         return -1;
    253     }
    254 
    255     st->onset = 0;
    256     st->prev_alpha = 0;
    257     st->prev_gc = 0;
    258 
    259     for (i = 0; i < LTPG_MEM_SIZE; i++)
    260     {
    261         st->ltpg_mem[i] = 0;
    262     }
    263 
    264     return 0;
    265 }
    266 
    267 
    268 /*
    269 ------------------------------------------------------------------------------
    270  FUNCTION NAME: gain_adapt_exit
    271 ------------------------------------------------------------------------------
    272  INPUT AND OUTPUT DEFINITIONS
    273 
    274  Inputs:
    275     st -- double pointer to GainAdaptState
    276 
    277  Outputs:
    278     None
    279 
    280  Returns:
    281     None
    282 
    283  Global Variables Used:
    284     None
    285 
    286  Local Variables Needed:
    287     None
    288 
    289 ------------------------------------------------------------------------------
    290  FUNCTION DESCRIPTION
    291 
    292     The memory used for state memory is freed
    293 ------------------------------------------------------------------------------
    294  REQUIREMENTS
    295 
    296  None
    297 
    298 ------------------------------------------------------------------------------
    299  REFERENCES
    300 
    301  g_adapt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    302 
    303 ------------------------------------------------------------------------------
    304  PSEUDO-CODE
    305 
    306 
    307 ------------------------------------------------------------------------------
    308  RESOURCES USED [optional]
    309 
    310  When the code is written for a specific target processor the
    311  the resources used should be documented below.
    312 
    313  HEAP MEMORY USED: x bytes
    314 
    315  STACK MEMORY USED: x bytes
    316 
    317  CLOCK CYCLES: (cycle count equation for this function) + (variable
    318                 used to represent cycle count for each subroutine
    319                 called)
    320      where: (cycle count variable) = cycle count for [subroutine
    321                                      name]
    322 
    323 ------------------------------------------------------------------------------
    324  CAUTION [optional]
    325  [State any special notes, constraints or cautions for users of this function]
    326 
    327 ------------------------------------------------------------------------------
    328 */
    329 
    330 void gain_adapt_exit(GainAdaptState **st)
    331 {
    332     if (st == NULL || *st == NULL)
    333         return;
    334 
    335     /* deallocate memory */
    336     free(*st);
    337     *st = NULL;
    338 
    339     return;
    340 }
    341 
    342 /*
    343 ------------------------------------------------------------------------------
    344  FUNCTION NAME: gain_adapt
    345 ------------------------------------------------------------------------------
    346  INPUT AND OUTPUT DEFINITIONS
    347 
    348  Inputs:
    349     st -- double pointer to GainAdaptState
    350     ltpg -- Word16 -- ltp coding gain (log2()), Q13
    351     gain_cod -- Word16 -- code gain, Q1
    352 
    353  Outputs:
    354     alpha -- Pointer to Word16 --  gain adaptation factor,   Q15
    355     pOverflow -- Pointer to Flag -- overflow indicator
    356 
    357  Returns:
    358     None
    359 
    360  Global Variables Used:
    361     None
    362 
    363  Local Variables Needed:
    364     None
    365 
    366 ------------------------------------------------------------------------------
    367  FUNCTION DESCRIPTION
    368 
    369  Purpose:    calculate pitch/codebook gain adaptation factor alpha
    370              (and update the adaptor state)
    371 
    372 ------------------------------------------------------------------------------
    373  REQUIREMENTS
    374 
    375  None
    376 
    377 ------------------------------------------------------------------------------
    378  REFERENCES
    379 
    380  g_adapt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    381 
    382 ------------------------------------------------------------------------------
    383  PSEUDO-CODE
    384 
    385 
    386 ------------------------------------------------------------------------------
    387  RESOURCES USED [optional]
    388 
    389  When the code is written for a specific target processor the
    390  the resources used should be documented below.
    391 
    392  HEAP MEMORY USED: x bytes
    393 
    394  STACK MEMORY USED: x bytes
    395 
    396  CLOCK CYCLES: (cycle count equation for this function) + (variable
    397                 used to represent cycle count for each subroutine
    398                 called)
    399      where: (cycle count variable) = cycle count for [subroutine
    400                                      name]
    401 
    402 ------------------------------------------------------------------------------
    403  CAUTION [optional]
    404  [State any special notes, constraints or cautions for users of this function]
    405 
    406 ------------------------------------------------------------------------------
    407 */
    408 
    409 void gain_adapt(
    410     GainAdaptState *st,  /* i  : state struct                  */
    411     Word16 ltpg,         /* i  : ltp coding gain (log2()), Q13 */
    412     Word16 gain_cod,     /* i  : code gain,                Q1  */
    413     Word16 *alpha,       /* o  : gain adaptation factor,   Q15 */
    414     Flag   *pOverflow
    415 )
    416 {
    417     Word16 adapt;      /* adaptdation status; 0, 1, or 2       */
    418     Word16 result;     /* alpha factor, Q13                    */
    419     Word16 filt;       /* median-filtered LTP coding gain, Q13 */
    420     Word16 tmp;
    421     Word16 i;
    422 
    423     /* basic adaptation */
    424     if (ltpg <= LTP_GAIN_THR1)
    425     {
    426         adapt = 0;
    427     }
    428     else
    429     {
    430         if (ltpg <= LTP_GAIN_THR2)
    431         {
    432             adapt = 1;
    433         }
    434         else
    435         {
    436             adapt = 2;
    437         }
    438     }
    439 
    440     /*
    441      * // onset indicator
    442      * if ((cbGain > onFact * cbGainMem[0]) && (cbGain > 100.0))
    443      *     onset = 8;
    444      * else
    445      *     if (onset)
    446      *         onset--;
    447      */
    448     /* tmp = cbGain / onFact; onFact = 2.0; 200 Q1 = 100.0 */
    449     tmp = shr_r(gain_cod, 1, pOverflow);
    450 
    451     if ((tmp > st->prev_gc) && (gain_cod > 200))
    452     {
    453         st->onset = 8;
    454     }
    455     else
    456     {
    457         if (st->onset != 0)
    458         {
    459             st->onset = sub(st->onset, 1, pOverflow);
    460         }
    461     }
    462 
    463     /*
    464      *  // if onset, increase adaptor state
    465      *  if (onset && (gainAdapt < 2)) gainAdapt++;
    466      */
    467     if ((st->onset != 0) && (adapt < 2))
    468     {
    469         adapt = add(adapt, 1, pOverflow);
    470     }
    471 
    472     st->ltpg_mem[0] = ltpg;
    473     filt = gmed_n(st->ltpg_mem, 5);  /* function result */
    474 
    475     if (adapt == 0)
    476     {
    477         if (filt > 5443) /* 5443 Q13 = 0.66443... */
    478         {
    479             result = 0;
    480         }
    481         else
    482         {
    483             if (filt < 0)
    484             {
    485                 result = 16384;  /* 16384 Q15 = 0.5 */
    486             }
    487             else
    488             {   /* result       =   0.5 - 0.75257499*filt     */
    489                 /* result (Q15) = 16384 - 24660 * (filt << 2) */
    490                 filt = shl(filt, 2, pOverflow);  /* Q15 */
    491                 result = mult(24660, filt, pOverflow);
    492                 result = sub(16384, result, pOverflow);
    493             }
    494         }
    495     }
    496     else
    497     {
    498         result = 0;
    499     }
    500     /*
    501      *  if (prevAlpha == 0.0) result = 0.5 * (result + prevAlpha);
    502      */
    503     if (st->prev_alpha == 0)
    504     {
    505         result = shr(result, 1, pOverflow);
    506     }
    507 
    508     /* store the result */
    509     *alpha = result;
    510 
    511     /* update adapter state memory */
    512     st->prev_alpha = result;
    513     st->prev_gc = gain_cod;
    514 
    515     for (i = LTPG_MEM_SIZE - 1; i > 0; i--)
    516     {
    517         st->ltpg_mem[i] = st->ltpg_mem[i-1];
    518     }
    519     /* mem[0] is just present for convenience in calling the gmed_n[5]
    520      * function above. The memory depth is really LTPG_MEM_SIZE-1.
    521      */
    522 }
    523