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/b_cn_cod.c
     35  Functions: pseudonoise
     36             build_CN_code
     37             build_CN_param
     38 
     39      Date: 09/28/2000
     40 
     41 ------------------------------------------------------------------------------
     42  REVISION HISTORY
     43 
     44  Description: Updated template. Cleaned up code. Passing in a pointer to
     45               overflow flag for build_CN_code() and build_CN_param() functions.
     46               Removed unnecessary header files.
     47  Description: Make chnages per formal review. Fix error introduced during
     48               optimization in pseudonoise().
     49 
     50  Description:
     51 
     52 ------------------------------------------------------------------------------
     53  MODULE DESCRIPTION
     54 
     55  This module contains functions for comfort noise(CN) generation.
     56 
     57 ------------------------------------------------------------------------------
     58 */
     59 
     60 
     61 /*----------------------------------------------------------------------------
     62 ; INCLUDES
     63 ----------------------------------------------------------------------------*/
     64 #include "b_cn_cod.h"
     65 #include "basic_op.h"
     66 #include "cnst.h"
     67 
     68 /*----------------------------------------------------------------------------
     69 ; MACROS
     70 ; [Define module specific macros here]
     71 ----------------------------------------------------------------------------*/
     72 
     73 
     74 /*----------------------------------------------------------------------------
     75 ; DEFINES
     76 ; [Include all pre-processor statements here. Include conditional
     77 ; compile variables also.]
     78 ----------------------------------------------------------------------------*/
     79 #define  NB_PULSE 10        /* number of random pulses in DTX operation   */
     80 
     81 /*----------------------------------------------------------------------------
     82 ; LOCAL FUNCTION DEFINITIONS
     83 ; [List function prototypes here]
     84 ----------------------------------------------------------------------------*/
     85 
     86 /*----------------------------------------------------------------------------
     87 ; LOCAL VARIABLE DEFINITIONS
     88 ; [Variable declaration - defined here and used outside this module]
     89 ----------------------------------------------------------------------------*/
     90 
     91 /*
     92 ------------------------------------------------------------------------------
     93  FUNCTION NAME: pseudonoise
     94 ------------------------------------------------------------------------------
     95  INPUT AND OUTPUT DEFINITIONS
     96 
     97  Inputs:
     98     pShift_reg = pointer to Old CN generator shift register state (Word32)
     99     no_bits = Number of bits (Word16)
    100 
    101  Outputs:
    102     pShift_reg -> Updated CN generator shift register state
    103 
    104  Returns:
    105     noise_bits = Generated random integer value (Word16)
    106 
    107  Global Variables Used:
    108     None
    109 
    110  Local Variables Needed:
    111     None
    112 
    113 ------------------------------------------------------------------------------
    114  FUNCTION DESCRIPTION
    115 
    116  Generate a random integer value to use in comfort noise generation. The
    117  algorithm uses polynomial x^31 + x^3 + 1. Length of the PN sequence
    118  is 2^31 - 1
    119 
    120 ------------------------------------------------------------------------------
    121  REQUIREMENTS
    122 
    123  None
    124 
    125 ------------------------------------------------------------------------------
    126  REFERENCES
    127 
    128  b_cn_cod.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    129 
    130 ------------------------------------------------------------------------------
    131  PSEUDO-CODE
    132 
    133 Word16 pseudonoise (
    134     Word32 *shift_reg, // i/o : Old CN generator shift register state
    135     Word16 no_bits     // i   : Number of bits
    136 )
    137 {
    138    Word16 noise_bits, Sn, i;
    139 
    140    noise_bits = 0;
    141    for (i = 0; i < no_bits; i++)
    142    {
    143       // State n == 31
    144       if ((*shift_reg & 0x00000001L) != 0)
    145       {
    146          Sn = 1;
    147       }
    148       else
    149       {
    150          Sn = 0;
    151       }
    152 
    153       // State n == 3
    154       if ((*shift_reg & 0x10000000L) != 0)
    155       {
    156          Sn = Sn ^ 1;
    157       }
    158       else
    159       {
    160          Sn = Sn ^ 0;
    161       }
    162 
    163       noise_bits = shl (noise_bits, 1);
    164       noise_bits = noise_bits | (extract_l (*shift_reg) & 1);
    165 
    166       *shift_reg = L_shr (*shift_reg, 1);
    167       if (Sn & 1)
    168       {
    169          *shift_reg = *shift_reg | 0x40000000L;
    170       }
    171    }
    172    return noise_bits;
    173 }
    174 
    175 ------------------------------------------------------------------------------
    176  RESOURCES USED [optional]
    177 
    178  When the code is written for a specific target processor the
    179  the resources used should be documented below.
    180 
    181  HEAP MEMORY USED: x bytes
    182 
    183  STACK MEMORY USED: x bytes
    184 
    185  CLOCK CYCLES: (cycle count equation for this function) + (variable
    186                 used to represent cycle count for each subroutine
    187                 called)
    188      where: (cycle count variable) = cycle count for [subroutine
    189                                      name]
    190 
    191 ------------------------------------------------------------------------------
    192  CAUTION [optional]
    193  [State any special notes, constraints or cautions for users of this function]
    194 
    195 ------------------------------------------------------------------------------
    196 */
    197 
    198 /*----------------------------------------------------------------------------
    199 ; FUNCTION CODE
    200 ----------------------------------------------------------------------------*/
    201 
    202 Word16 pseudonoise(
    203     Word32 *pShift_reg,     /* i/o : Old CN generator shift register state */
    204     Word16 no_bits          /* i   : Number of bits                        */
    205 )
    206 {
    207     Word16 noise_bits;
    208     Word16 Sn;
    209     Word16 i;
    210     Word16 temp;
    211 
    212     noise_bits = 0;
    213 
    214     for (i = 0; i < no_bits; i++)
    215     {
    216         /* State n == 31 */
    217         if ((*pShift_reg & 0x00000001L) != 0)
    218         {
    219             Sn = 1;
    220         }
    221         else
    222         {
    223             Sn = 0;
    224         }
    225 
    226         /* State n == 3 */
    227         if ((*pShift_reg & 0x10000000L) != 0)
    228         {
    229             Sn ^= 1;
    230         }
    231         else
    232         {
    233             Sn ^= 0;
    234         }
    235 
    236         noise_bits <<= 1;
    237 
    238         temp = (Word16)((*pShift_reg) & 1);
    239         noise_bits |= temp;
    240 
    241         *pShift_reg >>= 1;
    242         if (Sn & 1)
    243         {
    244             *pShift_reg |= 0x40000000L;
    245         }
    246     }
    247     return noise_bits;
    248 }
    249 
    250 /*
    251 ------------------------------------------------------------------------------
    252  FUNCTION NAME: build_CN_code
    253 ------------------------------------------------------------------------------
    254  INPUT AND OUTPUT DEFINITIONS
    255 
    256  Inputs:
    257     pSeed = pointer to the Old CN generator shift register state (Word32)
    258     cod[] = array to hold the generated CN fixed code vector (Word16)
    259     pOverflow = pointer to overflow flag (Flag)
    260 
    261  Outputs:
    262     cod[] = generated CN fixed code vector (Word16)
    263     pSeed = Updated CN generator shift register state (Word16)
    264     pOverflow -> 1 if overflow occured
    265 
    266  Returns:
    267     None
    268 
    269  Global Variables Used:
    270     None
    271 
    272  Local Variables Needed:
    273     None
    274 
    275 ------------------------------------------------------------------------------
    276  FUNCTION DESCRIPTION
    277 
    278 This function computes the comfort noise fixed codebook excitation. The gains
    279 of the pulses are always +/-1.
    280 
    281 ------------------------------------------------------------------------------
    282  REQUIREMENTS
    283 
    284  None
    285 
    286 ------------------------------------------------------------------------------
    287  REFERENCES
    288 
    289  b_cn_cod.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    290 
    291 ------------------------------------------------------------------------------
    292  PSEUDO-CODE
    293 
    294 void build_CN_code (
    295     Word32 *seed,         // i/o : Old CN generator shift register state
    296     Word16 cod[]          // o   : Generated CN fixed codebook vector
    297 )
    298 {
    299    Word16 i, j, k;
    300 
    301    for (i = 0; i < L_SUBFR; i++)
    302    {
    303       cod[i] = 0;
    304    }
    305 
    306 // The reference ETSI code uses a global flag for Overflow. However in the
    307 // actual implementation a pointer to the overflow flag is passed into the
    308 // function so that it can be passed into the basic math functions L_mult()
    309 // and add()
    310 
    311    for (k = 0; k < NB_PULSE; k++)
    312    {
    313       i = pseudonoise (seed, 2);      // generate pulse position
    314       i = shr (extract_l (L_mult (i, 10)), 1);
    315       i = add (i, k);
    316 
    317       j = pseudonoise (seed, 1);      // generate sign
    318 
    319       if (j > 0)
    320       {
    321          cod[i] = 4096;
    322       }
    323       else
    324       {
    325          cod[i] = -4096;
    326       }
    327    }
    328 
    329    return;
    330 }
    331 ------------------------------------------------------------------------------
    332  RESOURCES USED [optional]
    333 
    334  When the code is written for a specific target processor the
    335  the resources used should be documented below.
    336 
    337  HEAP MEMORY USED: x bytes
    338 
    339  STACK MEMORY USED: x bytes
    340 
    341  CLOCK CYCLES: (cycle count equation for this function) + (variable
    342                 used to represent cycle count for each subroutine
    343                 called)
    344      where: (cycle count variable) = cycle count for [subroutine
    345                                      name]
    346 
    347 ------------------------------------------------------------------------------
    348  CAUTION [optional]
    349  [State any special notes, constraints or cautions for users of this function]
    350 
    351 ------------------------------------------------------------------------------
    352 */
    353 
    354 /*----------------------------------------------------------------------------
    355 ; FUNCTION CODE
    356 ----------------------------------------------------------------------------*/
    357 void build_CN_code(
    358     Word32 *pSeed,          /* i/o : Old CN generator shift register state  */
    359     Word16 cod[],           /* o   : Generated CN fixed codebook vector     */
    360     Flag   *pOverflow       /* i/o : Overflow flag                          */
    361 )
    362 {
    363     Word16 i, j, k;
    364     Word16 temp;
    365 
    366     for (i = 0; i < L_SUBFR; i++)
    367     {
    368         cod[i] = 0;
    369     }
    370 
    371     for (k = 0; k < NB_PULSE; k++)
    372     {
    373         i = pseudonoise(pSeed, 2);       /* generate pulse position */
    374 
    375         temp = (Word16)(L_mult(i, 10, pOverflow));
    376         i = temp >> 1;
    377         i = add(i, k, pOverflow);
    378 
    379         j = pseudonoise(pSeed, 1);       /* generate sign */
    380 
    381         if (j > 0)
    382         {
    383             cod[i] = 4096;
    384         }
    385         else
    386         {
    387             cod[i] = -4096;
    388         }
    389     }
    390 
    391     return;
    392 }
    393 
    394 /*
    395 ------------------------------------------------------------------------------
    396  FUNCTION NAME: build_CN_param
    397 ------------------------------------------------------------------------------
    398  INPUT AND OUTPUT DEFINITIONS
    399 
    400  Inputs:
    401     pSeed = pointer to the Old CN generator shift register state (Word32)
    402     n_param = Number of parameters to randomize (Word16)
    403     param_size_table = table holding paameter sizes (Word16)
    404     param[] = array to hold CN generated paramters (Word16)
    405     pOverflow = pointer to overflow flag (Flag)
    406 
    407  Outputs:
    408     param[] = CN generated parameters (Word16)
    409     pSeed = Updated CN generator shift register state (Word16)
    410     pOverflow -> 1 if overflow occured
    411 
    412  Returns:
    413     None
    414 
    415  Global Variables Used:
    416     None
    417 
    418  Local Variables Needed:
    419     None
    420 
    421 ------------------------------------------------------------------------------
    422  FUNCTION DESCRIPTION
    423 
    424 This function randomizes the speech parameters, so that they do not produce
    425 tonal artifacts if used by ECU.
    426 
    427 ------------------------------------------------------------------------------
    428  REQUIREMENTS
    429 
    430  None
    431 
    432 ------------------------------------------------------------------------------
    433  REFERENCES
    434 
    435  b_cn_cod.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    436 
    437 ------------------------------------------------------------------------------
    438  PSEUDO-CODE
    439 void build_CN_param (
    440     Word16 *seed,             // i/o : Old CN generator shift register state
    441     const Word16 n_param,           // i  : number of params
    442     const Word16 param_size_table[],// i : size of params
    443     Word16 parm[]                   // o : CN Generated params
    444     )
    445 {
    446    Word16 i;
    447    const Word16 *p;
    448 
    449 // The reference ETSI code uses a global flag for Overflow. However in the
    450 // actual implementation a pointer to the overflow flag is passed into the
    451 // function so that it can be passed into the basic math functions L_add()
    452 // and L_mult()
    453 
    454    *seed = extract_l(L_add(L_shr(L_mult(*seed, 31821), 1), 13849L));
    455 
    456    p = &window_200_40[*seed & 0x7F];
    457    for(i=0; i< n_param;i++){
    458      parm[i] = *p++ & ~(0xFFFF<<param_size_table[i]);
    459    }
    460 }
    461 
    462 
    463 ------------------------------------------------------------------------------
    464  RESOURCES USED [optional]
    465 
    466  When the code is written for a specific target processor the
    467  the resources used should be documented below.
    468 
    469  HEAP MEMORY USED: x bytes
    470 
    471  STACK MEMORY USED: x bytes
    472 
    473  CLOCK CYCLES: (cycle count equation for this function) + (variable
    474                 used to represent cycle count for each subroutine
    475                 called)
    476      where: (cycle count variable) = cycle count for [subroutine
    477                                      name]
    478 
    479 ------------------------------------------------------------------------------
    480  CAUTION [optional]
    481  [State any special notes, constraints or cautions for users of this function]
    482 
    483 ------------------------------------------------------------------------------
    484 */
    485 
    486 /*----------------------------------------------------------------------------
    487 ; FUNCTION CODE
    488 ----------------------------------------------------------------------------*/
    489 void build_CN_param(
    490     Word16 *pSeed,          /* i/o : Old CN generator shift register state  */
    491     const Word16 n_param,           /* i  : number of params                */
    492     const Word16 param_size_table[],/* i : size of params                   */
    493     Word16 parm[],                  /* o : CN Generated params              */
    494     Flag  *pOverflow                /* i/o : Overflow Flag                  */
    495 )
    496 
    497 {
    498     Word16 i;
    499     const Word16 *pTemp;
    500     Word32 L_temp;
    501     Word16 temp;
    502 
    503     L_temp = L_mult(*pSeed, 31821, pOverflow);
    504     L_temp >>= 1;
    505 
    506     *pSeed = (Word16)(L_add(L_temp, 13849L, pOverflow));
    507 
    508     pTemp = &window_200_40[*pSeed & 0x7F];
    509 
    510     for (i = 0; i < n_param; i++)
    511     {
    512         temp = ~(0xFFFF << param_size_table[i]);
    513         parm[i] = *pTemp++ & temp;
    514     }
    515 }
    516 
    517