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/g_adapt.c 35 Functions: 36 37 Date: 02/04/2002 38 39 ------------------------------------------------------------------------------ 40 REVISION HISTORY 41 42 Description: Updated template used to PV coding template. 43 Changed to accept the pOverflow flag for EPOC compatibility. 44 45 Description: Replaced OSCL mem type functions and eliminated include 46 files that now are chosen by OSCL definitions 47 48 Description: Replaced "int" and/or "char" with OSCL defined types. 49 50 Description: 51 52 ------------------------------------------------------------------------------ 53 MODULE DESCRIPTION 54 55 56 ------------------------------------------------------------------------------ 57 */ 58 59 /*---------------------------------------------------------------------------- 60 ; INCLUDES 61 ----------------------------------------------------------------------------*/ 62 #include <stdlib.h> 63 64 #include "g_adapt.h" 65 #include "typedef.h" 66 #include "basic_op.h" 67 #include "oper_32b.h" 68 #include "cnst.h" 69 #include "gmed_n.h" 70 71 /*---------------------------------------------------------------------------- 72 ; MACROS 73 ; Define module specific macros here 74 ----------------------------------------------------------------------------*/ 75 76 /*---------------------------------------------------------------------------- 77 ; DEFINES 78 ; Include all pre-processor statements here. Include conditional 79 ; compile variables also. 80 ----------------------------------------------------------------------------*/ 81 #define LTP_GAIN_THR1 2721 /* 2721 Q13 = 0.3322 ~= 1.0 / (10*log10(2)) */ 82 #define LTP_GAIN_THR2 5443 /* 5443 Q13 = 0.6644 ~= 2.0 / (10*log10(2)) */ 83 84 /*---------------------------------------------------------------------------- 85 ; LOCAL FUNCTION DEFINITIONS 86 ; Function Prototype declaration 87 ----------------------------------------------------------------------------*/ 88 89 /*---------------------------------------------------------------------------- 90 ; LOCAL VARIABLE DEFINITIONS 91 ; Variable declaration - defined here and used outside this module 92 ----------------------------------------------------------------------------*/ 93 94 95 /* 96 ------------------------------------------------------------------------------ 97 FUNCTION NAME: gain_adapt_init 98 ------------------------------------------------------------------------------ 99 INPUT AND OUTPUT DEFINITIONS 100 101 Inputs: 102 st -- double pointer to GainAdaptState 103 104 Outputs: 105 st -- double ponter to GainAdaptState 106 107 Returns: 108 -1 if an error occurs during memory initialization 109 0 if OK 110 111 Global Variables Used: 112 None 113 114 Local Variables Needed: 115 None 116 117 ------------------------------------------------------------------------------ 118 FUNCTION DESCRIPTION 119 120 Allocates state memory and initializes state memory 121 122 ------------------------------------------------------------------------------ 123 REQUIREMENTS 124 125 None 126 127 ------------------------------------------------------------------------------ 128 REFERENCES 129 130 g_adapt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 131 132 ------------------------------------------------------------------------------ 133 PSEUDO-CODE 134 135 136 ------------------------------------------------------------------------------ 137 RESOURCES USED [optional] 138 139 When the code is written for a specific target processor the 140 the resources used should be documented below. 141 142 HEAP MEMORY USED: x bytes 143 144 STACK MEMORY USED: x bytes 145 146 CLOCK CYCLES: (cycle count equation for this function) + (variable 147 used to represent cycle count for each subroutine 148 called) 149 where: (cycle count variable) = cycle count for [subroutine 150 name] 151 152 ------------------------------------------------------------------------------ 153 CAUTION [optional] 154 [State any special notes, constraints or cautions for users of this function] 155 156 ------------------------------------------------------------------------------ 157 */ 158 159 Word16 gain_adapt_init(GainAdaptState **st) 160 { 161 GainAdaptState* s; 162 163 if (st == (GainAdaptState **) NULL) 164 { 165 /* fprintf(stderr, "gain_adapt_init: invalid parameter\n"); */ 166 return -1; 167 } 168 *st = NULL; 169 170 /* allocate memory */ 171 if ((s = (GainAdaptState *) malloc(sizeof(GainAdaptState))) == NULL) 172 { 173 /* fprintf(stderr, "gain_adapt_init: can't malloc state structure\n"); */ 174 return -1; 175 } 176 gain_adapt_reset(s); 177 *st = s; 178 179 return 0; 180 } 181 182 /* 183 ------------------------------------------------------------------------------ 184 FUNCTION NAME: gain_adapt_reset 185 ------------------------------------------------------------------------------ 186 INPUT AND OUTPUT DEFINITIONS 187 188 Inputs: 189 st -- double pointer to GainAdaptState 190 191 Outputs: 192 st -- double ponter to GainAdaptState 193 194 Returns: 195 -1 if an error occurs 196 0 if OK 197 198 Global Variables Used: 199 None 200 201 Local Variables Needed: 202 None 203 204 ------------------------------------------------------------------------------ 205 FUNCTION DESCRIPTION 206 207 Initializes state memory to zero 208 ------------------------------------------------------------------------------ 209 REQUIREMENTS 210 211 None 212 213 ------------------------------------------------------------------------------ 214 REFERENCES 215 216 g_adapt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 217 218 ------------------------------------------------------------------------------ 219 PSEUDO-CODE 220 221 222 ------------------------------------------------------------------------------ 223 RESOURCES USED [optional] 224 225 When the code is written for a specific target processor the 226 the resources used should be documented below. 227 228 HEAP MEMORY USED: x bytes 229 230 STACK MEMORY USED: x bytes 231 232 CLOCK CYCLES: (cycle count equation for this function) + (variable 233 used to represent cycle count for each subroutine 234 called) 235 where: (cycle count variable) = cycle count for [subroutine 236 name] 237 238 ------------------------------------------------------------------------------ 239 CAUTION [optional] 240 [State any special notes, constraints or cautions for users of this function] 241 242 ------------------------------------------------------------------------------ 243 */ 244 245 Word16 gain_adapt_reset(GainAdaptState *st) 246 { 247 Word16 i; 248 249 if (st == (GainAdaptState *) NULL) 250 { 251 /* fprintf(stderr, "gain_adapt_reset: invalid parameter\n"); */ 252 return -1; 253 } 254 255 st->onset = 0; 256 st->prev_alpha = 0; 257 st->prev_gc = 0; 258 259 for (i = 0; i < LTPG_MEM_SIZE; i++) 260 { 261 st->ltpg_mem[i] = 0; 262 } 263 264 return 0; 265 } 266 267 268 /* 269 ------------------------------------------------------------------------------ 270 FUNCTION NAME: gain_adapt_exit 271 ------------------------------------------------------------------------------ 272 INPUT AND OUTPUT DEFINITIONS 273 274 Inputs: 275 st -- double pointer to GainAdaptState 276 277 Outputs: 278 None 279 280 Returns: 281 None 282 283 Global Variables Used: 284 None 285 286 Local Variables Needed: 287 None 288 289 ------------------------------------------------------------------------------ 290 FUNCTION DESCRIPTION 291 292 The memory used for state memory is freed 293 ------------------------------------------------------------------------------ 294 REQUIREMENTS 295 296 None 297 298 ------------------------------------------------------------------------------ 299 REFERENCES 300 301 g_adapt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 302 303 ------------------------------------------------------------------------------ 304 PSEUDO-CODE 305 306 307 ------------------------------------------------------------------------------ 308 RESOURCES USED [optional] 309 310 When the code is written for a specific target processor the 311 the resources used should be documented below. 312 313 HEAP MEMORY USED: x bytes 314 315 STACK MEMORY USED: x bytes 316 317 CLOCK CYCLES: (cycle count equation for this function) + (variable 318 used to represent cycle count for each subroutine 319 called) 320 where: (cycle count variable) = cycle count for [subroutine 321 name] 322 323 ------------------------------------------------------------------------------ 324 CAUTION [optional] 325 [State any special notes, constraints or cautions for users of this function] 326 327 ------------------------------------------------------------------------------ 328 */ 329 330 void gain_adapt_exit(GainAdaptState **st) 331 { 332 if (st == NULL || *st == NULL) 333 return; 334 335 /* deallocate memory */ 336 free(*st); 337 *st = NULL; 338 339 return; 340 } 341 342 /* 343 ------------------------------------------------------------------------------ 344 FUNCTION NAME: gain_adapt 345 ------------------------------------------------------------------------------ 346 INPUT AND OUTPUT DEFINITIONS 347 348 Inputs: 349 st -- double pointer to GainAdaptState 350 ltpg -- Word16 -- ltp coding gain (log2()), Q13 351 gain_cod -- Word16 -- code gain, Q1 352 353 Outputs: 354 alpha -- Pointer to Word16 -- gain adaptation factor, Q15 355 pOverflow -- Pointer to Flag -- overflow indicator 356 357 Returns: 358 None 359 360 Global Variables Used: 361 None 362 363 Local Variables Needed: 364 None 365 366 ------------------------------------------------------------------------------ 367 FUNCTION DESCRIPTION 368 369 Purpose: calculate pitch/codebook gain adaptation factor alpha 370 (and update the adaptor state) 371 372 ------------------------------------------------------------------------------ 373 REQUIREMENTS 374 375 None 376 377 ------------------------------------------------------------------------------ 378 REFERENCES 379 380 g_adapt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 381 382 ------------------------------------------------------------------------------ 383 PSEUDO-CODE 384 385 386 ------------------------------------------------------------------------------ 387 RESOURCES USED [optional] 388 389 When the code is written for a specific target processor the 390 the resources used should be documented below. 391 392 HEAP MEMORY USED: x bytes 393 394 STACK MEMORY USED: x bytes 395 396 CLOCK CYCLES: (cycle count equation for this function) + (variable 397 used to represent cycle count for each subroutine 398 called) 399 where: (cycle count variable) = cycle count for [subroutine 400 name] 401 402 ------------------------------------------------------------------------------ 403 CAUTION [optional] 404 [State any special notes, constraints or cautions for users of this function] 405 406 ------------------------------------------------------------------------------ 407 */ 408 409 void gain_adapt( 410 GainAdaptState *st, /* i : state struct */ 411 Word16 ltpg, /* i : ltp coding gain (log2()), Q13 */ 412 Word16 gain_cod, /* i : code gain, Q1 */ 413 Word16 *alpha, /* o : gain adaptation factor, Q15 */ 414 Flag *pOverflow 415 ) 416 { 417 Word16 adapt; /* adaptdation status; 0, 1, or 2 */ 418 Word16 result; /* alpha factor, Q13 */ 419 Word16 filt; /* median-filtered LTP coding gain, Q13 */ 420 Word16 tmp; 421 Word16 i; 422 423 /* basic adaptation */ 424 if (ltpg <= LTP_GAIN_THR1) 425 { 426 adapt = 0; 427 } 428 else 429 { 430 if (ltpg <= LTP_GAIN_THR2) 431 { 432 adapt = 1; 433 } 434 else 435 { 436 adapt = 2; 437 } 438 } 439 440 /* 441 * // onset indicator 442 * if ((cbGain > onFact * cbGainMem[0]) && (cbGain > 100.0)) 443 * onset = 8; 444 * else 445 * if (onset) 446 * onset--; 447 */ 448 /* tmp = cbGain / onFact; onFact = 2.0; 200 Q1 = 100.0 */ 449 tmp = shr_r(gain_cod, 1, pOverflow); 450 451 if ((tmp > st->prev_gc) && (gain_cod > 200)) 452 { 453 st->onset = 8; 454 } 455 else 456 { 457 if (st->onset != 0) 458 { 459 st->onset = sub(st->onset, 1, pOverflow); 460 } 461 } 462 463 /* 464 * // if onset, increase adaptor state 465 * if (onset && (gainAdapt < 2)) gainAdapt++; 466 */ 467 if ((st->onset != 0) && (adapt < 2)) 468 { 469 adapt = add(adapt, 1, pOverflow); 470 } 471 472 st->ltpg_mem[0] = ltpg; 473 filt = gmed_n(st->ltpg_mem, 5); /* function result */ 474 475 if (adapt == 0) 476 { 477 if (filt > 5443) /* 5443 Q13 = 0.66443... */ 478 { 479 result = 0; 480 } 481 else 482 { 483 if (filt < 0) 484 { 485 result = 16384; /* 16384 Q15 = 0.5 */ 486 } 487 else 488 { /* result = 0.5 - 0.75257499*filt */ 489 /* result (Q15) = 16384 - 24660 * (filt << 2) */ 490 filt = shl(filt, 2, pOverflow); /* Q15 */ 491 result = mult(24660, filt, pOverflow); 492 result = sub(16384, result, pOverflow); 493 } 494 } 495 } 496 else 497 { 498 result = 0; 499 } 500 /* 501 * if (prevAlpha == 0.0) result = 0.5 * (result + prevAlpha); 502 */ 503 if (st->prev_alpha == 0) 504 { 505 result = shr(result, 1, pOverflow); 506 } 507 508 /* store the result */ 509 *alpha = result; 510 511 /* update adapter state memory */ 512 st->prev_alpha = result; 513 st->prev_gc = gain_cod; 514 515 for (i = LTPG_MEM_SIZE - 1; i > 0; i--) 516 { 517 st->ltpg_mem[i] = st->ltpg_mem[i-1]; 518 } 519 /* mem[0] is just present for convenience in calling the gmed_n[5] 520 * function above. The memory depth is really LTPG_MEM_SIZE-1. 521 */ 522 } 523