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/c_g_aver.c
     35  Functions:
     36             Cb_gain_average_reset
     37             Cb_gain_average
     38 
     39      Date: 03/28/2000
     40 
     41 ------------------------------------------------------------------------------
     42  REVISION HISTORY
     43 
     44  Description: Made some changes to the comments to match the comments from
     45     other modules.
     46 
     47  Description: Made changes based on comments from the review meeting.
     48 
     49  Description: Synchronized file with UMTS version 3.2.0. Updated coding
     50               template.
     51 
     52  Description: Made the following changes per comments from Phase 2/3 review:
     53               1. Defined one local variable per line.
     54 
     55  Description: Removed the functions Cb_gain_average_init and
     56  Cb_gain_average_exit.  The Cb_gain_average related structure is no longer
     57  dynamically allocated.
     58 
     59  Description: Passing in pOverflow to comply with changes needed for EPOC
     60               Updated the include files for the module.
     61 
     62  Description: Changed round function name to pv_round to avoid conflict with
     63               round function in C standard library.
     64 
     65 
     66  Description:  Replaced OSCL mem type functions and eliminated include
     67                files that now are chosen by OSCL definitions
     68 
     69  Description:
     70 ------------------------------------------------------------------------------
     71  MODULE DESCRIPTION
     72 
     73  This file contains functions that reset and perform
     74  codebook gain calculations.
     75 
     76 ------------------------------------------------------------------------------
     77 */
     78 
     79 
     80 /*----------------------------------------------------------------------------
     81 ; INCLUDES
     82 ----------------------------------------------------------------------------*/
     83 #include <string.h>
     84 
     85 #include    "c_g_aver.h"
     86 #include    "typedef.h"
     87 #include    "mode.h"
     88 #include    "cnst.h"
     89 
     90 #include    "basic_op.h"
     91 
     92 /*----------------------------------------------------------------------------
     93 ; MACROS
     94 ; Define module specific macros here
     95 ----------------------------------------------------------------------------*/
     96 
     97 
     98 /*----------------------------------------------------------------------------
     99 ; DEFINES
    100 ; Include all pre-processor statements here. Include conditional
    101 ; compile variables also.
    102 ----------------------------------------------------------------------------*/
    103 
    104 /*----------------------------------------------------------------------------
    105 ; LOCAL FUNCTION DEFINITIONS
    106 ; Function Prototype declaration
    107 ----------------------------------------------------------------------------*/
    108 
    109 /*----------------------------------------------------------------------------
    110 ; LOCAL VARIABLE DEFINITIONS
    111 ; Variable declaration - defined here and used outside this module
    112 ----------------------------------------------------------------------------*/
    113 
    114 /*
    115 ------------------------------------------------------------------------------
    116  FUNCTION NAME: Cb_gain_average_reset
    117 ------------------------------------------------------------------------------
    118  INPUT AND OUTPUT DEFINITIONS
    119 
    120  Inputs:
    121     state = pointer to a structure of type Cb_gain_averageState
    122 
    123  Outputs:
    124     Structure pointed to by state is initialized to zeros
    125 
    126  Returns:
    127     Returns 0 if memory was successfully initialized,
    128         otherwise returns -1.
    129 
    130  Global Variables Used:
    131     None.
    132 
    133  Local Variables Needed:
    134     None.
    135 
    136 ------------------------------------------------------------------------------
    137  FUNCTION DESCRIPTION
    138 
    139  Resets state memory
    140 
    141 ------------------------------------------------------------------------------
    142  REQUIREMENTS
    143 
    144  None.
    145 
    146 ------------------------------------------------------------------------------
    147  REFERENCES
    148 
    149  c_g_aver.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    150 
    151 ------------------------------------------------------------------------------
    152  PSEUDO-CODE
    153 
    154 Word16 Cb_gain_average_reset (Cb_gain_averageState *state)
    155 {
    156    if (state == (Cb_gain_averageState *) NULL){
    157       fprintf(stderr, "Cb_gain_average_reset: invalid parameter\n");
    158       return -1;
    159    }
    160 
    161    // Static vectors to zero
    162    Set_zero (state->cbGainHistory, L_CBGAINHIST);
    163 
    164    // Initialize hangover handling
    165    state->hangVar = 0;
    166    state->hangCount= 0;
    167 
    168    return 0;
    169 }
    170 
    171 ------------------------------------------------------------------------------
    172  RESOURCES USED [optional]
    173 
    174  When the code is written for a specific target processor the
    175  the resources used should be documented below.
    176 
    177  HEAP MEMORY USED: x bytes
    178 
    179  STACK MEMORY USED: x bytes
    180 
    181  CLOCK CYCLES: (cycle count equation for this function) + (variable
    182                 used to represent cycle count for each subroutine
    183                 called)
    184      where: (cycle count variable) = cycle count for [subroutine
    185                                      name]
    186 
    187 ------------------------------------------------------------------------------
    188  CAUTION [optional]
    189  [State any special notes, constraints or cautions for users of this function]
    190 
    191 ------------------------------------------------------------------------------
    192 */
    193 
    194 Word16  Cb_gain_average_reset(Cb_gain_averageState *state)
    195 {
    196     if (state == (Cb_gain_averageState *) NULL)
    197     {
    198         /* fprint(stderr, "Cb_gain_average_reset: invalid parameter\n");  */
    199         return(-1);
    200     }
    201 
    202     /* Static vectors to zero */
    203     memset(state->cbGainHistory, 0, L_CBGAINHIST*sizeof(Word16));
    204 
    205     /* Initialize hangover handling */
    206     state->hangVar = 0;
    207     state->hangCount = 0;
    208 
    209     return(0);
    210 }
    211 
    212 /****************************************************************************/
    213 
    214 /*
    215 ------------------------------------------------------------------------------
    216  FUNCTION NAME: Cb_gain_average
    217 ------------------------------------------------------------------------------
    218  INPUT AND OUTPUT DEFINITIONS
    219 
    220  Inputs:
    221     st = pointer to structure of type Cb_gain_averageState
    222     mode = AMR mode (enum Mode)
    223     gain_code = CB gain (Word16)
    224     lsp = the LSP for the current frame (Word16)
    225     lspAver = the average of LSP for 8 frames (Word16)
    226     bfi = bad frame indication flag (Word16)
    227     prev_bf = previous bad frame indication flag (Word16)
    228     pdfi = potential degraded bad frame ind flag (Word16)
    229     prev_pdf = prev pot. degraded bad frame ind flag (Word16)
    230     inBackgroundNoise = background noise decision (Word16)
    231     voicedHangover = # of frames after last voiced frame (Word16)
    232     pOverflow = address of overflow (Flag)
    233 
    234  Returns:
    235     cbGainMix = codebook gain (Word16)
    236 
    237  Outputs:
    238     None.
    239 
    240  Global Variables Used:
    241     None.
    242 
    243  Local Variables Needed:
    244     None.
    245 
    246 ------------------------------------------------------------------------------
    247  FUNCTION DESCRIPTION
    248 
    249  The mix cb gains for MR475, MR515, MR59, MR67, MR102; gain_code other modes
    250 
    251 ------------------------------------------------------------------------------
    252  REQUIREMENTS
    253 
    254  None.
    255 
    256 ------------------------------------------------------------------------------
    257  REFERENCES
    258 
    259  c_g_aver.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    260 
    261 ------------------------------------------------------------------------------
    262  PSEUDO-CODE
    263 
    264 Word16 Cb_gain_average (
    265    Cb_gain_averageState *st, // i/o : State variables for CB gain avergeing
    266    enum Mode mode,           // i   : AMR mode
    267    Word16 gain_code,         // i   : CB gain                              Q1
    268    Word16 lsp[],             // i   : The LSP for the current frame       Q15
    269    Word16 lspAver[],         // i   : The average of LSP for 8 frames     Q15
    270    Word16 bfi,               // i   : bad frame indication flag
    271    Word16 prev_bf,           // i   : previous bad frame indication flag
    272    Word16 pdfi,              // i   : potential degraded bad frame ind flag
    273    Word16 prev_pdf,          // i   : prev pot. degraded bad frame ind flag
    274    Word16 inBackgroundNoise, // i   : background noise decision
    275    Word16 voicedHangover     // i   : # of frames after last voiced frame
    276    )
    277 {
    278    //---------------------------------------------------------*
    279     * Compute mixed cb gain, used to make cb gain more        *
    280     * smooth in background noise for modes 5.15, 5.9 and 6.7  *
    281     * states that needs to be updated by all                  *
    282     *---------------------------------------------------------
    283    Word16 i;
    284    Word16 cbGainMix, diff, tmp_diff, bgMix, cbGainMean;
    285    Word32 L_sum;
    286    Word16 tmp[M], tmp1, tmp2, shift1, shift2, shift;
    287 
    288    // set correct cbGainMix for MR74, MR795, MR122
    289    cbGainMix = gain_code;
    290 
    291     *-------------------------------------------------------*
    292     *   Store list of CB gain needed in the CB gain         *
    293     *   averaging                                           *
    294     *-------------------------------------------------------*
    295    for (i = 0; i < (L_CBGAINHIST-1); i++)
    296    {
    297       st->cbGainHistory[i] = st->cbGainHistory[i+1];
    298    }
    299    st->cbGainHistory[L_CBGAINHIST-1] = gain_code;
    300 
    301    // compute lsp difference
    302    for (i = 0; i < M; i++) {
    303       tmp1 = abs_s(sub(lspAver[i], lsp[i]));  // Q15
    304       shift1 = sub(norm_s(tmp1), 1);          // Qn
    305       tmp1 = shl(tmp1, shift1);               // Q15+Qn
    306       shift2 = norm_s(lspAver[i]);            // Qm
    307       tmp2 = shl(lspAver[i], shift2);         // Q15+Qm
    308       tmp[i] = div_s(tmp1, tmp2);             // Q15+(Q15+Qn)-(Q15+Qm)
    309       shift = sub(add(2, shift1), shift2);
    310       if (shift >= 0)
    311       {
    312          tmp[i] = shr(tmp[i], shift); // Q15+Qn-Qm-Qx=Q13
    313       }
    314       else
    315       {
    316          tmp[i] = shl(tmp[i], negate(shift)); // Q15+Qn-Qm-Qx=Q13
    317       }
    318    }
    319 
    320    diff = tmp[0];
    321    for (i = 1; i < M; i++) {
    322       diff = add(diff, tmp[i]);       // Q13
    323    }
    324 
    325    // Compute hangover
    326    if (sub(diff, 5325) > 0)  // 0.65 in Q11
    327    {
    328       st->hangVar = add(st->hangVar, 1);
    329    }
    330    else
    331    {
    332       st->hangVar = 0;
    333    }
    334 
    335    if (sub(st->hangVar, 10) > 0)
    336    {
    337       st->hangCount = 0;  // Speech period, reset hangover variable
    338    }
    339 
    340    // Compute mix constant (bgMix)
    341    bgMix = 8192;    // 1 in Q13
    342    if ((sub(mode, MR67) <= 0) || (sub(mode, MR102) == 0))
    343       // MR475, MR515, MR59, MR67, MR102
    344    {
    345       // if errors and presumed noise make smoothing probability stronger
    346       if (((((pdfi != 0) && (prev_pdf != 0)) || (bfi != 0) || (prev_bf != 0)) &&
    347           (sub(voicedHangover, 1) > 0) && (inBackgroundNoise != 0) &&
    348           ((sub(mode, MR475) == 0) ||
    349            (sub(mode, MR515) == 0) ||
    350            (sub(mode, MR59) == 0)) ))
    351       {
    352          // bgMix = min(0.25, max(0.0, diff-0.55)) / 0.25;
    353          tmp_diff = sub(diff, 4506);   // 0.55 in Q13
    354 
    355          // max(0.0, diff-0.55)
    356          if (tmp_diff > 0)
    357          {
    358             tmp1 = tmp_diff;
    359          }
    360          else
    361          {
    362             tmp1 = 0;
    363          }
    364 
    365          // min(0.25, tmp1)
    366          if (sub(2048, tmp1) < 0)
    367          {
    368             bgMix = 8192;
    369          }
    370          else
    371          {
    372             bgMix = shl(tmp1, 2);
    373          }
    374       }
    375       else
    376       {
    377          // bgMix = min(0.25, max(0.0, diff-0.40)) / 0.25;
    378          tmp_diff = sub(diff, 3277); // 0.4 in Q13
    379 
    380          // max(0.0, diff-0.40)
    381          if (tmp_diff > 0)
    382          {
    383             tmp1 = tmp_diff;
    384          }
    385          else
    386          {
    387             tmp1 = 0;
    388          }
    389 
    390          // min(0.25, tmp1)
    391          if (sub(2048, tmp1) < 0)
    392          {
    393             bgMix = 8192;
    394          }
    395          else
    396          {
    397             bgMix = shl(tmp1, 2);
    398          }
    399       }
    400 
    401       if ((sub(st->hangCount, 40) < 0) || (sub(diff, 5325) > 0)) // 0.65 in Q13
    402       {
    403          bgMix = 8192;  // disable mix if too short time since
    404       }
    405 
    406       // Smoothen the cb gain trajectory
    407       // smoothing depends on mix constant bgMix
    408       L_sum = L_mult(6554, st->cbGainHistory[2]); // 0.2 in Q15; L_sum in Q17
    409       for (i = 3; i < L_CBGAINHIST; i++)
    410       {
    411          L_sum = L_mac(L_sum, 6554, st->cbGainHistory[i]);
    412       }
    413       cbGainMean = pv_round(L_sum);                      // Q1
    414 
    415       // more smoothing in error and bg noise (NB no DFI used  here)
    416       if (((bfi != 0) || (prev_bf != 0)) && (inBackgroundNoise != 0) &&
    417           ((sub(mode, MR475) == 0) ||
    418            (sub(mode, MR515) == 0) ||
    419            (sub(mode, MR59) == 0)) )
    420       {
    421          L_sum = L_mult(4681, st->cbGainHistory[0]); // 0.143 in Q15; L_sum in Q17
    422          for (i = 1; i < L_CBGAINHIST; i++)
    423          {
    424             L_sum = L_mac(L_sum, 4681, st->cbGainHistory[i]);
    425          }
    426          cbGainMean = pv_round(L_sum);                   // Q1
    427       }
    428 
    429       // cbGainMix = bgMix*cbGainMix + (1-bgMix)*cbGainMean;
    430       L_sum = L_mult(bgMix, cbGainMix);               // L_sum in Q15
    431       L_sum = L_mac(L_sum, 8192, cbGainMean);
    432       L_sum = L_msu(L_sum, bgMix, cbGainMean);
    433       cbGainMix = pv_round(L_shl(L_sum, 2));             // Q1
    434    }
    435 
    436    st->hangCount = add(st->hangCount, 1);
    437    return cbGainMix;
    438 }
    439 
    440 ------------------------------------------------------------------------------
    441  RESOURCES USED [optional]
    442 
    443  When the code is written for a specific target processor the
    444  the resources used should be documented below.
    445 
    446  HEAP MEMORY USED: x bytes
    447 
    448  STACK MEMORY USED: x bytes
    449 
    450  CLOCK CYCLES: (cycle count equation for this function) + (variable
    451                 used to represent cycle count for each subroutine
    452                 called)
    453      where: (cycle count variable) = cycle count for [subroutine
    454                                      name]
    455 
    456 ------------------------------------------------------------------------------
    457  CAUTION [optional]
    458  [State any special notes, constraints or cautions for users of this function]
    459 
    460 ------------------------------------------------------------------------------
    461 */
    462 
    463 Word16 Cb_gain_average(
    464     Cb_gain_averageState *st, /* i/o : State variables for CB gain averaging */
    465     enum Mode mode,           /* i   : AMR mode                              */
    466     Word16 gain_code,         /* i   : CB gain                            Q1 */
    467     Word16 lsp[],             /* i   : The LSP for the current frame     Q15 */
    468     Word16 lspAver[],         /* i   : The average of LSP for 8 frames   Q15 */
    469     Word16 bfi,               /* i   : bad frame indication flag             */
    470     Word16 prev_bf,           /* i   : previous bad frame indication flag    */
    471     Word16 pdfi,              /* i   : potential degraded bad frame ind flag */
    472     Word16 prev_pdf,          /* i   : prev pot. degraded bad frame ind flag */
    473     Word16 inBackgroundNoise, /* i   : background noise decision             */
    474     Word16 voicedHangover,    /* i   : # of frames after last voiced frame   */
    475     Flag   *pOverflow
    476 )
    477 {
    478     Word16 i;
    479     Word16 cbGainMix;
    480     Word16 diff;
    481     Word16 tmp_diff;
    482     Word16 bgMix;
    483     Word16 cbGainMean;
    484     Word32 L_sum;
    485     Word16 tmp[M];
    486     Word16 tmp1;
    487     Word16 tmp2;
    488     Word16 shift1;
    489     Word16 shift2;
    490     Word16 shift;
    491 
    492     /*---------------------------------------------------------*
    493      * Compute mixed cb gain, used to make cb gain more        *
    494      * smooth in background noise for modes 5.15, 5.9 and 6.7  *
    495      * states that needs to be updated by all                  *
    496      *---------------------------------------------------------*/
    497 
    498     /* set correct cbGainMix for MR74, MR795, MR122 */
    499     cbGainMix = gain_code;
    500 
    501     /*-------------------------------------------------------*
    502      *   Store list of CB gain needed in the CB gain         *
    503      *   averaging                                           *
    504      *-------------------------------------------------------*/
    505     for (i = 0; i < (L_CBGAINHIST - 1); i++)
    506     {
    507         st->cbGainHistory[i] = st->cbGainHistory[i+1];
    508     }
    509     st->cbGainHistory[L_CBGAINHIST-1] = gain_code;
    510 
    511     diff = 0;
    512 
    513     /* compute lsp difference */
    514     for (i = 0; i < M; i++)
    515     {
    516         tmp1 = abs_s(sub(*(lspAver + i), *(lsp + i), pOverflow));
    517         /* Q15      */
    518         shift1 = sub(norm_s(tmp1), 1, pOverflow);       /* Qn       */
    519         tmp1 = shl(tmp1, shift1, pOverflow);            /* Q15+Qn   */
    520         shift2 = norm_s(*(lspAver + i));                /* Qm       */
    521         tmp2 = shl(*(lspAver + i), shift2, pOverflow);  /* Q15+Qm   */
    522         tmp[i] = div_s(tmp1, tmp2);        /* Q15+(Q15+Qn)-(Q15+Qm) */
    523 
    524         shift = 2 + shift1 - shift2;
    525 
    526         if (shift >= 0)
    527         {
    528             *(tmp + i) = shr(*(tmp + i), shift, pOverflow);
    529             /* Q15+Qn-Qm-Qx=Q13 */
    530         }
    531         else
    532         {
    533             *(tmp + i) = shl(*(tmp + i), negate(shift), pOverflow);
    534             /* Q15+Qn-Qm-Qx=Q13 */
    535         }
    536 
    537         diff = add(diff, *(tmp + i), pOverflow);           /* Q13 */
    538     }
    539 
    540     /* Compute hangover */
    541 
    542     if (diff > 5325)                /* 0.65 in Q11 */
    543     {
    544         st->hangVar += 1;
    545     }
    546     else
    547     {
    548         st->hangVar = 0;
    549     }
    550 
    551 
    552     if (st->hangVar > 10)
    553     {
    554         /* Speech period, reset hangover variable */
    555         st->hangCount = 0;
    556     }
    557 
    558     /* Compute mix constant (bgMix) */
    559     bgMix = 8192;    /* 1 in Q13 */
    560 
    561     if ((mode <= MR67) || (mode == MR102))
    562         /* MR475, MR515, MR59, MR67, MR102 */
    563     {
    564         /* if errors and presumed noise make smoothing probability stronger */
    565 
    566         if (((((pdfi != 0) && (prev_pdf != 0)) || (bfi != 0) ||
    567                 (prev_bf != 0))
    568                 && (voicedHangover > 1)
    569                 && (inBackgroundNoise != 0)
    570                 && ((mode == MR475) || (mode == MR515) ||
    571                     (mode == MR59))))
    572         {
    573             /* bgMix = min(0.25, max(0.0, diff-0.55)) / 0.25; */
    574             tmp_diff = sub(diff, 4506, pOverflow);   /* 0.55 in Q13 */
    575         }
    576         else
    577         {
    578             /* bgMix = min(0.25, max(0.0, diff-0.40)) / 0.25; */
    579             tmp_diff = sub(diff, 3277, pOverflow); /* 0.4 in Q13 */
    580         }
    581 
    582         /* max(0.0, diff-0.55)  or  */
    583         /* max(0.0, diff-0.40) */
    584         if (tmp_diff > 0)
    585         {
    586             tmp1 = tmp_diff;
    587         }
    588         else
    589         {
    590             tmp1 = 0;
    591         }
    592 
    593         /* min(0.25, tmp1) */
    594         if (2048 < tmp1)
    595         {
    596             bgMix = 8192;
    597         }
    598         else
    599         {
    600             bgMix = shl(tmp1, 2, pOverflow);
    601         }
    602 
    603         if ((st->hangCount < 40) || (diff > 5325)) /* 0.65 in Q13 */
    604         {
    605             /* disable mix if too short time since */
    606             bgMix = 8192;
    607         }
    608 
    609         /* Smoothen the cb gain trajectory  */
    610         /* smoothing depends on mix constant bgMix */
    611         L_sum = L_mult(6554, st->cbGainHistory[2], pOverflow);
    612         /* 0.2 in Q15; L_sum in Q17 */
    613 
    614         for (i = 3; i < L_CBGAINHIST; i++)
    615         {
    616             L_sum = L_mac(L_sum, 6554, st->cbGainHistory[i], pOverflow);
    617         }
    618         cbGainMean = pv_round(L_sum, pOverflow);               /* Q1 */
    619 
    620         /* more smoothing in error and bg noise (NB no DFI used here) */
    621 
    622         if (((bfi != 0) || (prev_bf != 0)) && (inBackgroundNoise != 0)
    623                 && ((mode == MR475) || (mode == MR515)
    624                     || (mode == MR59)))
    625         {
    626             /* 0.143 in Q15; L_sum in Q17    */
    627             L_sum = L_mult(4681, st->cbGainHistory[0], pOverflow);
    628             for (i = 1; i < L_CBGAINHIST; i++)
    629             {
    630                 L_sum =
    631                     L_mac(L_sum, 4681, st->cbGainHistory[i], pOverflow);
    632             }
    633             cbGainMean = pv_round(L_sum, pOverflow);              /* Q1 */
    634         }
    635 
    636         /* cbGainMix = bgMix*cbGainMix + (1-bgMix)*cbGainMean; */
    637         /* L_sum in Q15 */
    638         L_sum = L_mult(bgMix, cbGainMix, pOverflow);
    639         L_sum = L_mac(L_sum, 8192, cbGainMean, pOverflow);
    640         L_sum = L_msu(L_sum, bgMix, cbGainMean, pOverflow);
    641         cbGainMix = pv_round(L_shl(L_sum, 2, pOverflow), pOverflow);  /* Q1 */
    642     }
    643 
    644     st->hangCount += 1;
    645 
    646     return (cbGainMix);
    647 }
    648 
    649