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/pre_proc.c
     35  Funtions: Pre_Process_init
     36            Pre_Process_reset
     37            Pre_Process_exit
     38            Pre_Process
     39 
     40      Date: 05/17/2000
     41 
     42 ------------------------------------------------------------------------------
     43  REVISION HISTORY
     44 
     45  Description: Put the file into our template structure.
     46 
     47  Description: First pass optimization.
     48 
     49  Description: Made changes based on comments from review meeting.
     50 
     51  Description: Synchronized file with UMTS version 3.2.0. Updated coding
     52               template. Removed unnecessary include files.
     53 
     54  Description: Removed basic_op.h from the Include section. It is not used.
     55 
     56  Description: Made the following changes per comments from Phase 2/3 review:
     57               1. Fixed typecasting issue with TI C compiler.
     58               2. Modified FOR loop to count down.
     59               3. Cosmetic changes to the code to make address post-increment
     60                  clearer.
     61               4. Removed unnecessary typecasting in the multiply-accumulate
     62                  portion of FOR loop body.
     63               5. Removed "static" in table definitions.
     64               6. Updated copyright year.
     65 
     66  Description:  For Pre_Process()
     67               1. Replaced variables (containing filter coefficients) with
     68                  constants, to avoid extra register swaping.
     69               2. Changed to decrement loop
     70 
     71  Description:  Replaced OSCL mem type functions and eliminated include
     72                files that now are chosen by OSCL definitions
     73 
     74  Description:  Replaced "int" and/or "char" with OSCL defined types.
     75 
     76  Description: Changed round function name to pv_round to avoid conflict with
     77               round function in C standard library.
     78 
     79  Description:
     80 
     81 ------------------------------------------------------------------------------
     82  MODULE DESCRIPTION
     83 
     84  These modules handle the preprocessing of input speech.
     85 
     86 ------------------------------------------------------------------------------
     87 */
     88 
     89 
     90 /*----------------------------------------------------------------------------
     91 ; INCLUDES
     92 ----------------------------------------------------------------------------*/
     93 #include <stdlib.h>
     94 
     95 #include "pre_proc.h"
     96 #include "typedef.h"
     97 
     98 /*----------------------------------------------------------------------------
     99 ; MACROS
    100 ; Define module specific macros here
    101 ----------------------------------------------------------------------------*/
    102 
    103 
    104 /*----------------------------------------------------------------------------
    105 ; DEFINES
    106 ; Include all pre-processor statements here. Include conditional
    107 ; compile variables also.
    108 ----------------------------------------------------------------------------*/
    109 
    110 
    111 /*----------------------------------------------------------------------------
    112 ; LOCAL FUNCTION DEFINITIONS
    113 ; Function Prototype declaration
    114 ----------------------------------------------------------------------------*/
    115 
    116 /*----------------------------------------------------------------------------
    117 ; LOCAL VARIABLE DEFINITIONS
    118 ; Variable declaration - defined here and used outside this module
    119 ----------------------------------------------------------------------------*/
    120 
    121 
    122 
    123 
    124 /*
    125 ------------------------------------------------------------------------------
    126  FUNCTION NAME: Pre_Process_init
    127 ------------------------------------------------------------------------------
    128  INPUT AND OUTPUT DEFINITIONS
    129 
    130  Inputs:
    131     state = pointer to an array of pointer to structures of type
    132         Pre_ProcessState
    133 
    134  Outputs:
    135     Structure pointed to by the pointer pointed to by state is
    136       initialized to its reset value
    137     state points to the allocated memory
    138 
    139  Returns:
    140     return_value = 0 if memory was successfully initialized,
    141                    otherwise returns -1.
    142 
    143  Global Variables Used:
    144     None.
    145 
    146  Local Variables Needed:
    147     None.
    148 
    149 ------------------------------------------------------------------------------
    150  FUNCTION DESCRIPTION
    151 
    152  Allocates state memory and initializes state memory.
    153 
    154 ------------------------------------------------------------------------------
    155  REQUIREMENTS
    156 
    157  None.
    158 
    159 ------------------------------------------------------------------------------
    160  REFERENCES
    161 
    162  pre_proc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    163 
    164 ------------------------------------------------------------------------------
    165  PSEUDO-CODE
    166 
    167 int Pre_Process_init (Pre_ProcessState **state)
    168 {
    169   Pre_ProcessState* s;
    170 
    171   if (state == (Pre_ProcessState **) NULL){
    172       fprintf(stderr, "Pre_Process_init: invalid parameter\n");
    173       return -1;
    174   }
    175   *state = NULL;
    176 
    177   // allocate memory
    178   if ((s= (Pre_ProcessState *) malloc(sizeof(Pre_ProcessState))) == NULL){
    179       fprintf(stderr, "Pre_Process_init: can not malloc state structure\n");
    180       return -1;
    181   }
    182 
    183   Pre_Process_reset(s);
    184   *state = s;
    185 
    186   return 0;
    187 }
    188 
    189 ------------------------------------------------------------------------------
    190  RESOURCES USED [optional]
    191 
    192  When the code is written for a specific target processor the
    193  the resources used should be documented below.
    194 
    195  HEAP MEMORY USED: x bytes
    196 
    197  STACK MEMORY USED: x bytes
    198 
    199  CLOCK CYCLES: (cycle count equation for this function) + (variable
    200                 used to represent cycle count for each subroutine
    201                 called)
    202      where: (cycle count variable) = cycle count for [subroutine
    203                                      name]
    204 
    205 ------------------------------------------------------------------------------
    206  CAUTION [optional]
    207  [State any special notes, constraints or cautions for users of this function]
    208 
    209 ------------------------------------------------------------------------------
    210 */
    211 
    212 Word16 Pre_Process_init(Pre_ProcessState **state)
    213 {
    214     Pre_ProcessState* s;
    215 
    216     if (state == (Pre_ProcessState **) NULL)
    217     {
    218         /*  fprintf(stderr, "Pre_Process_init: invalid parameter\n");  */
    219         return(-1);
    220     }
    221     *state = NULL;
    222 
    223     /* allocate memory */
    224     if ((s = (Pre_ProcessState *) malloc(sizeof(Pre_ProcessState))) == NULL)
    225     {
    226         /*  fprintf(stderr, "Pre_Process_init:
    227             can not malloc state structure\n");  */
    228         return(-1);
    229     }
    230 
    231     Pre_Process_reset(s);
    232     *state = s;
    233 
    234     return(0);
    235 }
    236 
    237 /****************************************************************************/
    238 
    239 
    240 /*
    241 ------------------------------------------------------------------------------
    242  FUNCTION NAME: Pre_Process_reset
    243 ------------------------------------------------------------------------------
    244  INPUT AND OUTPUT DEFINITIONS
    245 
    246  Inputs:
    247     state = pointer to structure of type Pre_ProcessState
    248 
    249  Outputs:
    250     Structure pointed to by state is initialized to zero.
    251 
    252  Returns:
    253     return_value = 0 if memory was successfully reset,
    254                    otherwise returns -1.
    255 
    256  Global Variables Used:
    257     None.
    258 
    259  Local Variables Needed:
    260     None.
    261 
    262 ------------------------------------------------------------------------------
    263  FUNCTION DESCRIPTION
    264 
    265  Initializes state memory to zero.
    266 
    267 ------------------------------------------------------------------------------
    268  REQUIREMENTS
    269 
    270  None.
    271 
    272 ------------------------------------------------------------------------------
    273  REFERENCES
    274 
    275  pre_proc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    276 
    277 ------------------------------------------------------------------------------
    278  PSEUDO-CODE
    279 
    280 int Pre_Process_reset (Pre_ProcessState *state)
    281 {
    282   if (state == (Pre_ProcessState *) NULL){
    283       fprintf(stderr, "Pre_Process_reset: invalid parameter\n");
    284       return -1;
    285   }
    286 
    287   state->y2_hi = 0;
    288   state->y2_lo = 0;
    289   state->y1_hi = 0;
    290   state->y1_lo = 0;
    291   state->x0 = 0;
    292   state->x1 = 0;
    293 
    294   return 0;
    295 }
    296 
    297 ------------------------------------------------------------------------------
    298  RESOURCES USED [optional]
    299 
    300  When the code is written for a specific target processor the
    301  the resources used should be documented below.
    302 
    303  HEAP MEMORY USED: x bytes
    304 
    305  STACK MEMORY USED: x bytes
    306 
    307  CLOCK CYCLES: (cycle count equation for this function) + (variable
    308                 used to represent cycle count for each subroutine
    309                 called)
    310      where: (cycle count variable) = cycle count for [subroutine
    311                                      name]
    312 
    313 ------------------------------------------------------------------------------
    314  CAUTION [optional]
    315  [State any special notes, constraints or cautions for users of this function]
    316 
    317 ------------------------------------------------------------------------------
    318 */
    319 
    320 Word16 Pre_Process_reset(Pre_ProcessState *state)
    321 {
    322     if (state == (Pre_ProcessState *) NULL)
    323     {
    324         /*  fprintf(stderr, "Pre_Process_reset: invalid parameter\n");  */
    325         return(-1);
    326     }
    327 
    328     state->y2_hi = 0;
    329     state->y2_lo = 0;
    330     state->y1_hi = 0;
    331     state->y1_lo = 0;
    332     state->x0 = 0;
    333     state->x1 = 0;
    334 
    335     return(0);
    336 }
    337 
    338 /****************************************************************************/
    339 
    340 
    341 /*
    342 ------------------------------------------------------------------------------
    343  FUNCTION NAME: Pre_Process_exit
    344 ------------------------------------------------------------------------------
    345  INPUT AND OUTPUT DEFINITIONS
    346 
    347  Inputs:
    348     state = a pointer to an array of pointers to structures of
    349         type Pre_ProcessState
    350 
    351  Outputs:
    352     state points to a NULL address
    353 
    354  Returns:
    355     None.
    356 
    357  Global Variables Used:
    358     None.
    359 
    360  Local Variables Needed:
    361     None.
    362 
    363 ------------------------------------------------------------------------------
    364  FUNCTION DESCRIPTION
    365 
    366  The memory used for state memory is freed.
    367 
    368 ------------------------------------------------------------------------------
    369  REQUIREMENTS
    370 
    371  None.
    372 
    373 ------------------------------------------------------------------------------
    374  REFERENCES
    375 
    376  pre_proc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    377 
    378 ------------------------------------------------------------------------------
    379  PSEUDO-CODE
    380 
    381 void Pre_Process_exit (Pre_ProcessState **state)
    382 {
    383   if (state == NULL || *state == NULL)
    384       return;
    385 
    386   // deallocate memory
    387   free(*state);
    388   *state = NULL;
    389 
    390   return;
    391 }
    392 
    393 ------------------------------------------------------------------------------
    394  RESOURCES USED [optional]
    395 
    396  When the code is written for a specific target processor the
    397  the resources used should be documented below.
    398 
    399  HEAP MEMORY USED: x bytes
    400 
    401  STACK MEMORY USED: x bytes
    402 
    403  CLOCK CYCLES: (cycle count equation for this function) + (variable
    404                 used to represent cycle count for each subroutine
    405                 called)
    406      where: (cycle count variable) = cycle count for [subroutine
    407                                      name]
    408 
    409 ------------------------------------------------------------------------------
    410  CAUTION [optional]
    411  [State any special notes, constraints or cautions for users of this function]
    412 
    413 ------------------------------------------------------------------------------
    414 */
    415 
    416 void Pre_Process_exit(Pre_ProcessState **state)
    417 {
    418     if (state == NULL || *state == NULL)
    419     {
    420         return;
    421     }
    422 
    423     /* deallocate memory */
    424     free(*state);
    425     *state = NULL;
    426 
    427     return;
    428 }
    429 
    430 /****************************************************************************/
    431 
    432 /*
    433 ------------------------------------------------------------------------------
    434  FUNCTION NAME: Pre_Process
    435 ------------------------------------------------------------------------------
    436  INPUT AND OUTPUT DEFINITIONS
    437 
    438  Inputs:
    439     st = a pointer to a structure of type Pre_ProcessState
    440     signal = input/output signal (Word16)
    441     lg = length of signal (Word16)
    442 
    443  Outputs:
    444     st points to the updated structure
    445 
    446  Returns:
    447     return_value = 0 (int)
    448 
    449  Global Variables Used:
    450     a = points to a buffer of filter coefficients
    451     b = points to a buffer of filter coefficients
    452 
    453  Local Variables Needed:
    454     None.
    455 
    456 ------------------------------------------------------------------------------
    457  FUNCTION DESCRIPTION
    458 
    459  This module performs the preprocessing of the input speech.
    460  The signal is passed through a 2nd order high pass filtering with cut off
    461  frequency at 80 Hz. The input is divided by two in the filtering process.
    462 
    463     y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b[2]*x[i-2]/2
    464                      + a[1]*y[i-1] + a[2]*y[i-2];
    465 
    466 ------------------------------------------------------------------------------
    467  REQUIREMENTS
    468 
    469  None.
    470 
    471 ------------------------------------------------------------------------------
    472  REFERENCES
    473 
    474  pre_proc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    475 
    476 ------------------------------------------------------------------------------
    477  PSEUDO-CODE
    478 
    479 int Pre_Process (
    480     Pre_ProcessState *st,
    481     Word16 signal[], // input/output signal
    482     Word16 lg)       // lenght of signal
    483 {
    484     Word16 i, x2;
    485     Word32 L_tmp;
    486 
    487     for (i = 0; i < lg; i++)
    488     {
    489         x2 = st->x1;
    490         st->x1 = st->x0;
    491         st->x0 = signal[i];
    492 
    493         //  y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b140[2]*x[i-2]/2
    494         //                     + a[1]*y[i-1] + a[2] * y[i-2];
    495 
    496         L_tmp = Mpy_32_16 (st->y1_hi, st->y1_lo, a[1]);
    497         L_tmp = L_add (L_tmp, Mpy_32_16 (st->y2_hi, st->y2_lo, a[2]));
    498         L_tmp = L_mac (L_tmp, st->x0, b[0]);
    499         L_tmp = L_mac (L_tmp, st->x1, b[1]);
    500         L_tmp = L_mac (L_tmp, x2, b[2]);
    501         L_tmp = L_shl (L_tmp, 3);
    502         signal[i] = pv_round (L_tmp);
    503 
    504         st->y2_hi = st->y1_hi;
    505         st->y2_lo = st->y1_lo;
    506         L_Extract (L_tmp, &st->y1_hi, &st->y1_lo);
    507     }
    508     return 0;
    509 }
    510 
    511 ------------------------------------------------------------------------------
    512  RESOURCES USED [optional]
    513 
    514  When the code is written for a specific target processor the
    515  the resources used should be documented below.
    516 
    517  HEAP MEMORY USED: x bytes
    518 
    519  STACK MEMORY USED: x bytes
    520 
    521  CLOCK CYCLES: (cycle count equation for this function) + (variable
    522                 used to represent cycle count for each subroutine
    523                 called)
    524      where: (cycle count variable) = cycle count for [subroutine
    525                                      name]
    526 
    527 ------------------------------------------------------------------------------
    528  CAUTION [optional]
    529  [State any special notes, constraints or cautions for users of this function]
    530 
    531 ------------------------------------------------------------------------------
    532 */
    533 /*
    534     filter coefficients (fc = 80 Hz, coeff. b[] is divided by 2)
    535     const Word16 b[3] = {1899, -3798, 1899};
    536     const Word16 a[3] = {4096, 7807, -3733};
    537 
    538 */
    539 
    540 void Pre_Process(
    541     Pre_ProcessState *st,
    542     Word16 signal[], /* input/output signal */
    543     Word16 lg)       /* length of signal    */
    544 {
    545     Word16 i;
    546     Word16 x_n_2;
    547     Word16 x_n_1;
    548     Word32 L_tmp;
    549     Word16 *p_signal = signal;
    550 
    551     x_n_2 = st->x1;
    552     x_n_1 = st->x0;
    553 
    554     for (i = lg; i != 0; i--)
    555     {
    556 
    557 
    558         /*  y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b140[2]*x[i-2]/2  */
    559         /*                     + a[1]*y[i-1] + a[2] * y[i-2];      */
    560 
    561         L_tmp     = ((Word32) st->y1_hi) * 7807;
    562         L_tmp    += (Word32)(((Word32) st->y1_lo * 7807) >> 15);
    563 
    564         L_tmp    += ((Word32) st->y2_hi) * (-3733);
    565         st->y2_hi =  st->y1_hi;
    566         L_tmp    += (Word32)(((Word32) st->y2_lo * (-3733)) >> 15);
    567         st->y2_lo =  st->y1_lo;
    568 
    569         L_tmp    += ((Word32) x_n_2) * 1899;
    570         x_n_2     =  x_n_1;
    571         L_tmp    += ((Word32) x_n_1) * (-3798);
    572         x_n_1     = *(p_signal);
    573         L_tmp    += ((Word32) x_n_1) * 1899;
    574 
    575 
    576         *(p_signal++) = (Word16)((L_tmp + 0x0000800L) >> 12);
    577 
    578         st->y1_hi = (Word16)(L_tmp >> 12);
    579         st->y1_lo = (Word16)((L_tmp << 3) - ((Word32)(st->y1_hi) << 15));
    580 
    581     }
    582 
    583     st->x1 = x_n_2;
    584     st->x0 = x_n_1;
    585 
    586     return;
    587 }
    588 
    589 
    590