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.173
     22     ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec
     23     Available from http://www.3gpp.org
     24 
     25 (C) 2007, 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: lagconceal.cpp
     35 
     36      Date: 05/08/2007
     37 
     38 ------------------------------------------------------------------------------
     39  REVISION HISTORY
     40 
     41 
     42  Description:
     43 
     44 ------------------------------------------------------------------------------
     45  INPUT AND OUTPUT DEFINITIONS
     46 
     47      int16 gain_hist[],                     (i)  : Gain history
     48      int16 lag_hist[],                      (i)  : Subframe size
     49      int16 * T0,                            (i/o): current lag
     50      int16 * old_T0,                        (i/o): previous lag
     51      int16 * seed,
     52      int16 unusable_frame
     53 
     54 ------------------------------------------------------------------------------
     55  FUNCTION DESCRIPTION
     56 
     57     Concealment of LTP lags during bad frames
     58 
     59 ------------------------------------------------------------------------------
     60  REQUIREMENTS
     61 
     62 
     63 ------------------------------------------------------------------------------
     64  REFERENCES
     65 
     66 ------------------------------------------------------------------------------
     67  PSEUDO-CODE
     68 
     69 ------------------------------------------------------------------------------
     70 */
     71 
     72 
     73 /*----------------------------------------------------------------------------
     74 ; INCLUDES
     75 ----------------------------------------------------------------------------*/
     76 
     77 #include "pv_amr_wb_type_defs.h"
     78 #include "pvamrwbdecoder_basic_op.h"
     79 #include "pvamrwbdecoder_cnst.h"
     80 #include "pvamrwbdecoder_acelp.h"
     81 
     82 /*----------------------------------------------------------------------------
     83 ; MACROS
     84 ; Define module specific macros here
     85 ----------------------------------------------------------------------------*/
     86 
     87 
     88 /*----------------------------------------------------------------------------
     89 ; DEFINES
     90 ; Include all pre-processor statements here. Include conditional
     91 ; compile variables also.
     92 ----------------------------------------------------------------------------*/
     93 #define L_LTPHIST 5
     94 #define ONE_PER_3 10923
     95 #define ONE_PER_LTPHIST 6554
     96 
     97 /*----------------------------------------------------------------------------
     98 ; LOCAL FUNCTION DEFINITIONS
     99 ; Function Prototype declaration
    100 ----------------------------------------------------------------------------*/
    101 void insertion_sort(int16 array[], int16 n);
    102 void insert(int16 array[], int16 num, int16 x);
    103 
    104 /*----------------------------------------------------------------------------
    105 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
    106 ; Variable declaration - defined here and used outside this module
    107 ----------------------------------------------------------------------------*/
    108 
    109 /*----------------------------------------------------------------------------
    110 ; EXTERNAL FUNCTION REFERENCES
    111 ; Declare functions defined elsewhere and referenced in this module
    112 ----------------------------------------------------------------------------*/
    113 
    114 /*----------------------------------------------------------------------------
    115 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
    116 ; Declare variables used in this module but defined elsewhere
    117 ----------------------------------------------------------------------------*/
    118 
    119 /*----------------------------------------------------------------------------
    120 ; FUNCTION CODE
    121 ----------------------------------------------------------------------------*/
    122 
    123 
    124 void Init_Lagconc(int16 lag_hist[])
    125 {
    126     int16 i;
    127 
    128     for (i = 0; i < L_LTPHIST; i++)
    129     {
    130         lag_hist[i] = 64;
    131     }
    132 }
    133 
    134 /*----------------------------------------------------------------------------
    135 ; FUNCTION CODE
    136 ----------------------------------------------------------------------------*/
    137 
    138 void lagconceal(
    139     int16 gain_hist[],                   /* (i) : Gain history     */
    140     int16 lag_hist[],                    /* (i) : Subframe size    */
    141     int16 * T0,
    142     int16 * old_T0,
    143     int16 * seed,
    144     int16 unusable_frame
    145 )
    146 {
    147     int16 maxLag, minLag, lastLag, lagDif, meanLag = 0;
    148     int16 lag_hist2[L_LTPHIST] = {0};
    149     int16 i, tmp, tmp2;
    150     int16 minGain, lastGain, secLastGain;
    151     int16 D, D2;
    152 
    153     /* Is lag index such that it can be aplied directly or does it has to be subtituted */
    154 
    155     lastGain = gain_hist[4];
    156     secLastGain = gain_hist[3];
    157 
    158     lastLag = lag_hist[0];
    159 
    160     /******* SMALLEST history lag *******/
    161     minLag = lag_hist[0];
    162     /*******  BIGGEST history lag *******/
    163     maxLag = lag_hist[0];
    164     for (i = 1; i < L_LTPHIST; i++)
    165     {
    166         if (lag_hist[i] < minLag)
    167         {
    168             minLag = lag_hist[i];
    169         }
    170         if (lag_hist[i] > maxLag)
    171         {
    172             maxLag = lag_hist[i];
    173         }
    174     }
    175     /***********SMALLEST history gain***********/
    176     minGain = gain_hist[0];
    177     for (i = 1; i < L_LTPHIST; i++)
    178     {
    179 
    180         if (gain_hist[i] < minGain)
    181         {
    182             minGain = gain_hist[i];
    183         }
    184     }
    185     /***Difference between MAX and MIN lag**/
    186     lagDif = sub_int16(maxLag, minLag);
    187 
    188 
    189     if (unusable_frame != 0)
    190     {
    191         /* LTP-lag for RX_SPEECH_LOST */
    192         /**********Recognition of the LTP-history*********/
    193 
    194         if ((minGain > 8192) && (lagDif < 10))
    195         {
    196             *T0 = *old_T0;
    197         }
    198         else if (lastGain > 8192 && secLastGain > 8192)
    199         {
    200             *T0 = lag_hist[0];
    201         }
    202         else
    203         {
    204             /********SORT************/
    205             /* The sorting of the lag history */
    206             for (i = 0; i < L_LTPHIST; i++)
    207             {
    208                 lag_hist2[i] = lag_hist[i];
    209             }
    210             insertion_sort(lag_hist2, 5);
    211 
    212             /* Lag is weighted towards bigger lags */
    213             /* and random variation is added */
    214             lagDif = sub_int16(lag_hist2[4], lag_hist2[2]);
    215 
    216 
    217             if (lagDif > 40)
    218             {
    219                 lagDif = 40;
    220             }
    221 
    222             D = noise_gen_amrwb(seed);              /* D={-1, ...,1} */
    223             /* D2={-lagDif/2..lagDif/2} */
    224             tmp = lagDif >> 1;
    225             D2 = mult_int16(tmp, D);
    226             tmp = add_int16(add_int16(lag_hist2[2], lag_hist2[3]), lag_hist2[4]);
    227             *T0 = add_int16(mult_int16(tmp, ONE_PER_3), D2);
    228         }
    229         /* New lag is not allowed to be bigger or smaller than last lag values */
    230 
    231         if (*T0 > maxLag)
    232         {
    233             *T0 = maxLag;
    234         }
    235 
    236         if (*T0 < minLag)
    237         {
    238             *T0 = minLag;
    239         }
    240     }
    241     else
    242     {
    243         /* LTP-lag for RX_BAD_FRAME */
    244 
    245         /***********MEAN lag**************/
    246         meanLag = 0;
    247         for (i = 0; i < L_LTPHIST; i++)
    248         {
    249             meanLag = add_int16(meanLag, lag_hist[i]);
    250         }
    251         meanLag = mult_int16(meanLag, ONE_PER_LTPHIST);
    252 
    253         tmp  = *T0 - maxLag;
    254         tmp2 = *T0 - lastLag;
    255 
    256         if ((lagDif < 10) && (*T0 > (minLag - 5)) && (tmp < 5))
    257         {
    258             *T0 = *T0;
    259         }
    260         else if ((lastGain > 8192) && (secLastGain > 8192) && ((tmp2 + 10) > 0 && tmp2 < 10))
    261         {
    262             *T0 = *T0;
    263         }
    264         else if ((minGain < 6554) && (lastGain == minGain) && (*T0 > minLag && *T0 < maxLag))
    265         {
    266             *T0 = *T0;
    267         }
    268         else if ((lagDif < 70) && (*T0 > minLag) && (*T0 < maxLag))
    269         {
    270             *T0 = *T0;
    271         }
    272         else if ((*T0 > meanLag) && (*T0 < maxLag))
    273         {
    274             *T0 = *T0;
    275         }
    276         else
    277         {
    278 
    279 
    280             if ((minGain > 8192) & (lagDif < 10))
    281             {
    282                 *T0 = lag_hist[0];
    283             }
    284             else if ((lastGain > 8192) && (secLastGain > 8192))
    285             {
    286                 *T0 = lag_hist[0];
    287             }
    288             else
    289             {
    290                 /********SORT************/
    291                 /* The sorting of the lag history */
    292                 for (i = 0; i < L_LTPHIST; i++)
    293                 {
    294                     lag_hist2[i] = lag_hist[i];
    295                 }
    296                 insertion_sort(lag_hist2, 5);
    297 
    298                 /* Lag is weighted towards bigger lags */
    299                 /* and random variation is added */
    300                 lagDif = sub_int16(lag_hist2[4], lag_hist2[2]);
    301 
    302                 if (lagDif > 40)
    303                 {
    304                     lagDif = 40;
    305                 }
    306 
    307                 D = noise_gen_amrwb(seed);          /* D={-1,.., 1} */
    308                 /* D2={-lagDif/2..lagDif/2} */
    309                 tmp = lagDif >> 1;
    310                 D2 = mult_int16(tmp, D);
    311                 tmp = add_int16(add_int16(lag_hist2[2], lag_hist2[3]), lag_hist2[4]);
    312                 *T0 = add_int16(mult_int16(tmp, ONE_PER_3), D2);
    313             }
    314             /* New lag is not allowed to be bigger or smaller than last lag values */
    315 
    316             if (*T0 > maxLag)
    317             {
    318                 *T0 = maxLag;
    319             }
    320 
    321             if (*T0 < minLag)
    322             {
    323                 *T0 = minLag;
    324             }
    325         }
    326     }
    327 }
    328 
    329 /*----------------------------------------------------------------------------
    330 ; FUNCTION CODE
    331 ----------------------------------------------------------------------------*/
    332 
    333 void insertion_sort(int16 array[], int16 n)
    334 {
    335     int16 i;
    336 
    337     for (i = 0; i < n; i++)
    338     {
    339         insert(array, i, array[i]);
    340     }
    341 }
    342 
    343 /*----------------------------------------------------------------------------
    344 ; FUNCTION CODE
    345 ----------------------------------------------------------------------------*/
    346 
    347 void insert(int16 array[], int16 n, int16 x)
    348 {
    349     int16 i;
    350 
    351     for (i = (n - 1); i >= 0; i--)
    352     {
    353 
    354         if (x < array[i])
    355         {
    356             array[i + 1] = array[i];
    357         }
    358         else
    359         {
    360             break;
    361         }
    362     }
    363     array[i + 1] = x;
    364 }
    365