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 register 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