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/post_pro.c
     35  Functions:
     36            Post_Process_reset
     37            Post_Process
     38 
     39      Date: 04/03/2000
     40 
     41 ------------------------------------------------------------------------------
     42  REVISION HISTORY
     43 
     44  Description: Updated template used to PV coding template. First attempt at
     45           optimizing C code.
     46 
     47  Description: Deleted variables listed in the Local Stores Needed/Modified
     48           sections. Optimized the "else" portion of the first "if"
     49           statement in Post_Process function.
     50 
     51  Description: Made grouping more explicit in the calculation of
     52           signal[i] << 1 in the Post_Process function.
     53 
     54  Description: Added setting of Overflow flag in inlined code.
     55 
     56  Description: Synchronized file with UMTS version 3.2.0. Updated coding
     57               template. Removed unnecessary include files.
     58 
     59  Description: Replaced basic_op.h with the header file of the math functions
     60               used in the file.
     61 
     62  Description: Made the following changes per comments from Phase 2/3 review:
     63               1. Updated copyright year.
     64               2. Fixed typecasting issue with TI C compiler.
     65               3. Used short-hand notation for math operations, e.g., "+=",
     66                  in the code.
     67 
     68  Description: Removed the functions post_pro_init and post_pro_exit.
     69  The post_pro related structure is no longer dynamically allocated.
     70 
     71  Description: Added pOverflow as a passed in variable as per changes needed
     72               for the EPOC release.
     73 
     74  Description: Optimized file to reduce clock cycle usage. Updated copyright
     75               year and removed unused files in Include section.
     76 
     77  Description:  Replaced OSCL mem type functions and eliminated include
     78                files that now are chosen by OSCL definitions
     79 
     80  Description:  Replaced "int" and/or "char" with OSCL defined types.
     81 
     82  Description: Changed round function name to pv_round to avoid conflict with
     83               round function in C standard library.
     84 
     85  Description:
     86 
     87 ------------------------------------------------------------------------------
     88  MODULE DESCRIPTION
     89 
     90  This file contains the function that performs post-processing on the output
     91  speech. Post-processing include filtering the output speech through a second
     92  order high pass filter with cutoff frequency of 60 Hz, and up-scaling the
     93  output speech by a factor of 2. In addition to the post-processing function
     94  itself, a post-processing initialization function, post-processing reset
     95  function, and post-processing exit function are also included in this file.
     96 
     97 ------------------------------------------------------------------------------
     98 */
     99 
    100 
    101 /*----------------------------------------------------------------------------
    102 ; INCLUDES
    103 ----------------------------------------------------------------------------*/
    104 #include "post_pro.h"
    105 #include "typedef.h"
    106 #include "basic_op.h"
    107 
    108 /*----------------------------------------------------------------------------
    109 ; MACROS
    110 ; Define module specific macros here
    111 ----------------------------------------------------------------------------*/
    112 
    113 
    114 /*----------------------------------------------------------------------------
    115 ; DEFINES
    116 ; Include all pre-processor statements here. Include conditional
    117 ; compile variables also.
    118 ----------------------------------------------------------------------------*/
    119 
    120 /*----------------------------------------------------------------------------
    121 ; LOCAL FUNCTION DEFINITIONS
    122 ; Function Prototype declaration
    123 ----------------------------------------------------------------------------*/
    124 
    125 /*----------------------------------------------------------------------------
    126 ; LOCAL VARIABLE DEFINITIONS
    127 ; Variable declaration - defined here and used outside this module
    128 ----------------------------------------------------------------------------*/
    129 
    130 /* filter coefficients (fc = 60 Hz) */
    131 static const Word16 b[3] = {7699, -15398, 7699};
    132 static const Word16 a[3] = {8192, 15836, -7667};
    133 
    134 /*
    135 ------------------------------------------------------------------------------
    136  FUNCTION NAME: Post_Process_reset
    137 ------------------------------------------------------------------------------
    138  INPUT AND OUTPUT DEFINITIONS
    139 
    140  Inputs:
    141     state = pointer to a structure of type Post_ProcessState
    142 
    143  Outputs:
    144     structure pointed to by state will have all its fields initialized
    145       to zero
    146 
    147  Returns:
    148     return_value = 0, if reset was successful; -1, otherwise (int)
    149 
    150  Global Variables Used:
    151     None
    152 
    153  Local Variables Needed:
    154     None
    155 
    156 ------------------------------------------------------------------------------
    157  FUNCTION DESCRIPTION
    158 
    159  This function initializes state memory to zero.
    160 
    161 ------------------------------------------------------------------------------
    162  REQUIREMENTS
    163 
    164  None
    165 
    166 ------------------------------------------------------------------------------
    167  REFERENCES
    168 
    169  post_pro.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    170 
    171 ------------------------------------------------------------------------------
    172  PSEUDO-CODE
    173 
    174 int Post_Process_reset (Post_ProcessState *state)
    175 {
    176   if (state == (Post_ProcessState *) NULL){
    177       fprint(stderr, "Post_Process_reset: invalid parameter\n");
    178       return -1;
    179   }
    180 
    181   state->y2_hi = 0;
    182   state->y2_lo = 0;
    183   state->y1_hi = 0;
    184   state->y1_lo = 0;
    185   state->x0 = 0;
    186   state->x1 = 0;
    187 
    188   return 0;
    189 }
    190 ------------------------------------------------------------------------------
    191  RESOURCES USED [optional]
    192 
    193  When the code is written for a specific target processor the
    194  the resources used should be documented below.
    195 
    196  HEAP MEMORY USED: x bytes
    197 
    198  STACK MEMORY USED: x bytes
    199 
    200  CLOCK CYCLES: (cycle count equation for this function) + (variable
    201                 used to represent cycle count for each subroutine
    202                 called)
    203      where: (cycle count variable) = cycle count for [subroutine
    204                                      name]
    205 
    206 ------------------------------------------------------------------------------
    207  CAUTION [optional]
    208  [State any special notes, constraints or cautions for users of this function]
    209 
    210 ------------------------------------------------------------------------------
    211 */
    212 
    213 Word16 Post_Process_reset(Post_ProcessState *state)
    214 {
    215     if (state == (Post_ProcessState *) NULL)
    216     {
    217         /*  fprint(stderr, "Post_Process_reset: invalid parameter\n");  */
    218         return(-1);
    219     }
    220 
    221     state->y2_hi = 0;
    222     state->y2_lo = 0;
    223     state->y1_hi = 0;
    224     state->y1_lo = 0;
    225     state->x0 = 0;
    226     state->x1 = 0;
    227 
    228     return(0);
    229 }
    230 
    231 /****************************************************************************/
    232 
    233 /*
    234 ------------------------------------------------------------------------------
    235  FUNCTION NAME: Post_Process
    236 ------------------------------------------------------------------------------
    237  INPUT AND OUTPUT DEFINITIONS
    238 
    239  Inputs:
    240     st = pointer to a structure of type Post_ProcessState
    241     signal = buffer containing the input signal (Word16)
    242     lg = length of the input signal (Word16)
    243     pOverflow = pointer to overflow indicator of type Flag
    244 
    245  Outputs:
    246     structure pointed to by st contains new filter input and output values
    247     signal buffer contains the HP filtered and up-scaled input signal
    248     pOverflow points to 1 if overflow occurs in the math functions called
    249               else it points to 0.
    250 
    251  Returns:
    252     return_value = 0 (int)
    253 
    254  Global Variables Used:
    255     a = buffer containing filter coefficients
    256     b = buffer containing filter coefficients
    257 
    258  Local Variables Needed:
    259     None
    260 
    261 ------------------------------------------------------------------------------
    262  FUNCTION DESCRIPTION
    263 
    264  This function performs post-processing on the output speech signal. First,
    265  the output speech goes through a second order high pass filter with a
    266  cutoff frequency of 60 Hz. Then, the filtered output speech is multiplied
    267  by a factor of 2. The algorithm implemented follows the following difference
    268  equation:
    269 
    270  y[i] = b[0]*x[i]*2 + b[1]*x[i-1]*2 + b[2]*x[i-2]*2 + a[1]*y[i-1] + a[2]*y[i-2];
    271 
    272 ------------------------------------------------------------------------------
    273  REQUIREMENTS
    274 
    275  None
    276 
    277 ------------------------------------------------------------------------------
    278  REFERENCES
    279 
    280  post_pro.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    281 
    282 ------------------------------------------------------------------------------
    283  PSEUDO-CODE
    284 
    285 int Post_Process (
    286     Post_ProcessState *st,  //i/o : post process state
    287     Word16 signal[],        //i/o : signal
    288     Word16 lg               //i   : length of signal
    289     )
    290 {
    291     Word16 i, x2;
    292     Word32 L_tmp;
    293 
    294     for (i = 0; i < lg; i++)
    295     {
    296         x2 = st->x1;
    297         st->x1 = st->x0;
    298         st->x0 = signal[i];
    299 
    300         // y[i] = b[0]*x[i]*2 + b[1]*x[i-1]*2 + b140[2]*x[i-2]/2
    301         //                    + a[1]*y[i-1] + a[2] * y[i-2];
    302 
    303         L_tmp = Mpy_32_16 (st->y1_hi, st->y1_lo, a[1]);
    304         L_tmp = L_add (L_tmp, Mpy_32_16 (st->y2_hi, st->y2_lo, a[2]));
    305         L_tmp = L_mac (L_tmp, st->x0, b[0]);
    306         L_tmp = L_mac (L_tmp, st->x1, b[1]);
    307         L_tmp = L_mac (L_tmp, x2, b[2]);
    308         L_tmp = L_shl (L_tmp, 2);
    309 
    310         //Multiplication by two of output speech with saturation.
    311         signal[i] = pv_round(L_shl(L_tmp, 1));
    312 
    313         st->y2_hi = st->y1_hi;
    314         st->y2_lo = st->y1_lo;
    315         L_Extract (L_tmp, &st->y1_hi, &st->y1_lo);
    316     }
    317 
    318     return 0;
    319 }
    320 
    321 ------------------------------------------------------------------------------
    322  RESOURCES USED [optional]
    323 
    324  When the code is written for a specific target processor the
    325  the resources used should be documented below.
    326 
    327  HEAP MEMORY USED: x bytes
    328 
    329  STACK MEMORY USED: x bytes
    330 
    331  CLOCK CYCLES: (cycle count equation for this function) + (variable
    332                 used to represent cycle count for each subroutine
    333                 called)
    334      where: (cycle count variable) = cycle count for [subroutine
    335                                      name]
    336 
    337 ------------------------------------------------------------------------------
    338  CAUTION [optional]
    339  [State any special notes, constraints or cautions for users of this function]
    340 
    341 ------------------------------------------------------------------------------
    342 */
    343 
    344 void Post_Process(
    345     Post_ProcessState *st,  /* i/o : post process state                   */
    346     Word16 signal[],        /* i/o : signal                               */
    347     Word16 lg,              /* i   : length of signal                     */
    348     Flag   *pOverflow
    349 )
    350 {
    351     Word16 i, x2;
    352     Word32 L_tmp;
    353 
    354     Word16 *p_signal;
    355     Word16 c_a1 = a[1];
    356     Word16 c_a2 = a[2];
    357     Word16 c_b0 = b[0];
    358     Word16 c_b1 = b[1];
    359     Word16 c_b2 = b[2];
    360 
    361     p_signal = &signal[0];
    362 
    363     for (i = 0; i < lg; i++)
    364     {
    365         x2 = st->x1;
    366         st->x1 = st->x0;
    367         st->x0 = *(p_signal);
    368 
    369         /*  y[i] = b[0]*x[i]*2 + b[1]*x[i-1]*2 + b140[2]*x[i-2]/2  */
    370         /*                     + a[1]*y[i-1] + a[2] * y[i-2];      */
    371 
    372         L_tmp = ((Word32) st->y1_hi) * c_a1;
    373         L_tmp += (((Word32) st->y1_lo) * c_a1) >> 15;
    374         L_tmp += ((Word32) st->y2_hi) * c_a2;
    375         L_tmp += (((Word32) st->y2_lo) * c_a2) >> 15;
    376         L_tmp += ((Word32) st->x0) * c_b0;
    377         L_tmp += ((Word32) st->x1) * c_b1;
    378         L_tmp += ((Word32) x2) * c_b2;
    379         L_tmp = L_shl(L_tmp, 3, pOverflow);
    380 
    381 
    382         /* Multiplication by two of output speech with saturation. */
    383 
    384         *(p_signal++) = pv_round(L_shl(L_tmp, 1, pOverflow), pOverflow);
    385 
    386         st->y2_hi = st->y1_hi;
    387         st->y2_lo = st->y1_lo;
    388 
    389         st->y1_hi = (Word16)(L_tmp >> 16);
    390         st->y1_lo = (Word16)((L_tmp >> 1) - ((Word32) st->y1_hi << 15));
    391 
    392     }
    393 
    394     return;
    395 }
    396