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 <<= 3; 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