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/b_cn_cod.c 35 Functions: pseudonoise 36 build_CN_code 37 build_CN_param 38 39 Date: 09/28/2000 40 41 ------------------------------------------------------------------------------ 42 REVISION HISTORY 43 44 Description: Updated template. Cleaned up code. Passing in a pointer to 45 overflow flag for build_CN_code() and build_CN_param() functions. 46 Removed unnecessary header files. 47 Description: Make chnages per formal review. Fix error introduced during 48 optimization in pseudonoise(). 49 50 Description: 51 52 ------------------------------------------------------------------------------ 53 MODULE DESCRIPTION 54 55 This module contains functions for comfort noise(CN) generation. 56 57 ------------------------------------------------------------------------------ 58 */ 59 60 61 /*---------------------------------------------------------------------------- 62 ; INCLUDES 63 ----------------------------------------------------------------------------*/ 64 #include "b_cn_cod.h" 65 #include "basic_op.h" 66 #include "cnst.h" 67 68 /*---------------------------------------------------------------------------- 69 ; MACROS 70 ; [Define module specific macros here] 71 ----------------------------------------------------------------------------*/ 72 73 74 /*---------------------------------------------------------------------------- 75 ; DEFINES 76 ; [Include all pre-processor statements here. Include conditional 77 ; compile variables also.] 78 ----------------------------------------------------------------------------*/ 79 #define NB_PULSE 10 /* number of random pulses in DTX operation */ 80 81 /*---------------------------------------------------------------------------- 82 ; LOCAL FUNCTION DEFINITIONS 83 ; [List function prototypes here] 84 ----------------------------------------------------------------------------*/ 85 86 /*---------------------------------------------------------------------------- 87 ; LOCAL VARIABLE DEFINITIONS 88 ; [Variable declaration - defined here and used outside this module] 89 ----------------------------------------------------------------------------*/ 90 91 /* 92 ------------------------------------------------------------------------------ 93 FUNCTION NAME: pseudonoise 94 ------------------------------------------------------------------------------ 95 INPUT AND OUTPUT DEFINITIONS 96 97 Inputs: 98 pShift_reg = pointer to Old CN generator shift register state (Word32) 99 no_bits = Number of bits (Word16) 100 101 Outputs: 102 pShift_reg -> Updated CN generator shift register state 103 104 Returns: 105 noise_bits = Generated random integer value (Word16) 106 107 Global Variables Used: 108 None 109 110 Local Variables Needed: 111 None 112 113 ------------------------------------------------------------------------------ 114 FUNCTION DESCRIPTION 115 116 Generate a random integer value to use in comfort noise generation. The 117 algorithm uses polynomial x^31 + x^3 + 1. Length of the PN sequence 118 is 2^31 - 1 119 120 ------------------------------------------------------------------------------ 121 REQUIREMENTS 122 123 None 124 125 ------------------------------------------------------------------------------ 126 REFERENCES 127 128 b_cn_cod.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 129 130 ------------------------------------------------------------------------------ 131 PSEUDO-CODE 132 133 Word16 pseudonoise ( 134 Word32 *shift_reg, // i/o : Old CN generator shift register state 135 Word16 no_bits // i : Number of bits 136 ) 137 { 138 Word16 noise_bits, Sn, i; 139 140 noise_bits = 0; 141 for (i = 0; i < no_bits; i++) 142 { 143 // State n == 31 144 if ((*shift_reg & 0x00000001L) != 0) 145 { 146 Sn = 1; 147 } 148 else 149 { 150 Sn = 0; 151 } 152 153 // State n == 3 154 if ((*shift_reg & 0x10000000L) != 0) 155 { 156 Sn = Sn ^ 1; 157 } 158 else 159 { 160 Sn = Sn ^ 0; 161 } 162 163 noise_bits = shl (noise_bits, 1); 164 noise_bits = noise_bits | (extract_l (*shift_reg) & 1); 165 166 *shift_reg = L_shr (*shift_reg, 1); 167 if (Sn & 1) 168 { 169 *shift_reg = *shift_reg | 0x40000000L; 170 } 171 } 172 return noise_bits; 173 } 174 175 ------------------------------------------------------------------------------ 176 RESOURCES USED [optional] 177 178 When the code is written for a specific target processor the 179 the resources used should be documented below. 180 181 HEAP MEMORY USED: x bytes 182 183 STACK MEMORY USED: x bytes 184 185 CLOCK CYCLES: (cycle count equation for this function) + (variable 186 used to represent cycle count for each subroutine 187 called) 188 where: (cycle count variable) = cycle count for [subroutine 189 name] 190 191 ------------------------------------------------------------------------------ 192 CAUTION [optional] 193 [State any special notes, constraints or cautions for users of this function] 194 195 ------------------------------------------------------------------------------ 196 */ 197 198 /*---------------------------------------------------------------------------- 199 ; FUNCTION CODE 200 ----------------------------------------------------------------------------*/ 201 202 Word16 pseudonoise( 203 Word32 *pShift_reg, /* i/o : Old CN generator shift register state */ 204 Word16 no_bits /* i : Number of bits */ 205 ) 206 { 207 Word16 noise_bits; 208 Word16 Sn; 209 Word16 i; 210 Word16 temp; 211 212 noise_bits = 0; 213 214 for (i = 0; i < no_bits; i++) 215 { 216 /* State n == 31 */ 217 if ((*pShift_reg & 0x00000001L) != 0) 218 { 219 Sn = 1; 220 } 221 else 222 { 223 Sn = 0; 224 } 225 226 /* State n == 3 */ 227 if ((*pShift_reg & 0x10000000L) != 0) 228 { 229 Sn ^= 1; 230 } 231 else 232 { 233 Sn ^= 0; 234 } 235 236 noise_bits <<= 1; 237 238 temp = (Word16)((*pShift_reg) & 1); 239 noise_bits |= temp; 240 241 *pShift_reg >>= 1; 242 if (Sn & 1) 243 { 244 *pShift_reg |= 0x40000000L; 245 } 246 } 247 return noise_bits; 248 } 249 250 /* 251 ------------------------------------------------------------------------------ 252 FUNCTION NAME: build_CN_code 253 ------------------------------------------------------------------------------ 254 INPUT AND OUTPUT DEFINITIONS 255 256 Inputs: 257 pSeed = pointer to the Old CN generator shift register state (Word32) 258 cod[] = array to hold the generated CN fixed code vector (Word16) 259 pOverflow = pointer to overflow flag (Flag) 260 261 Outputs: 262 cod[] = generated CN fixed code vector (Word16) 263 pSeed = Updated CN generator shift register state (Word16) 264 pOverflow -> 1 if overflow occured 265 266 Returns: 267 None 268 269 Global Variables Used: 270 None 271 272 Local Variables Needed: 273 None 274 275 ------------------------------------------------------------------------------ 276 FUNCTION DESCRIPTION 277 278 This function computes the comfort noise fixed codebook excitation. The gains 279 of the pulses are always +/-1. 280 281 ------------------------------------------------------------------------------ 282 REQUIREMENTS 283 284 None 285 286 ------------------------------------------------------------------------------ 287 REFERENCES 288 289 b_cn_cod.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 290 291 ------------------------------------------------------------------------------ 292 PSEUDO-CODE 293 294 void build_CN_code ( 295 Word32 *seed, // i/o : Old CN generator shift register state 296 Word16 cod[] // o : Generated CN fixed codebook vector 297 ) 298 { 299 Word16 i, j, k; 300 301 for (i = 0; i < L_SUBFR; i++) 302 { 303 cod[i] = 0; 304 } 305 306 // The reference ETSI code uses a global flag for Overflow. However in the 307 // actual implementation a pointer to the overflow flag is passed into the 308 // function so that it can be passed into the basic math functions L_mult() 309 // and add() 310 311 for (k = 0; k < NB_PULSE; k++) 312 { 313 i = pseudonoise (seed, 2); // generate pulse position 314 i = shr (extract_l (L_mult (i, 10)), 1); 315 i = add (i, k); 316 317 j = pseudonoise (seed, 1); // generate sign 318 319 if (j > 0) 320 { 321 cod[i] = 4096; 322 } 323 else 324 { 325 cod[i] = -4096; 326 } 327 } 328 329 return; 330 } 331 ------------------------------------------------------------------------------ 332 RESOURCES USED [optional] 333 334 When the code is written for a specific target processor the 335 the resources used should be documented below. 336 337 HEAP MEMORY USED: x bytes 338 339 STACK MEMORY USED: x bytes 340 341 CLOCK CYCLES: (cycle count equation for this function) + (variable 342 used to represent cycle count for each subroutine 343 called) 344 where: (cycle count variable) = cycle count for [subroutine 345 name] 346 347 ------------------------------------------------------------------------------ 348 CAUTION [optional] 349 [State any special notes, constraints or cautions for users of this function] 350 351 ------------------------------------------------------------------------------ 352 */ 353 354 /*---------------------------------------------------------------------------- 355 ; FUNCTION CODE 356 ----------------------------------------------------------------------------*/ 357 void build_CN_code( 358 Word32 *pSeed, /* i/o : Old CN generator shift register state */ 359 Word16 cod[], /* o : Generated CN fixed codebook vector */ 360 Flag *pOverflow /* i/o : Overflow flag */ 361 ) 362 { 363 Word16 i, j, k; 364 Word16 temp; 365 366 for (i = 0; i < L_SUBFR; i++) 367 { 368 cod[i] = 0; 369 } 370 371 for (k = 0; k < NB_PULSE; k++) 372 { 373 i = pseudonoise(pSeed, 2); /* generate pulse position */ 374 375 temp = (Word16)(L_mult(i, 10, pOverflow)); 376 i = temp >> 1; 377 i = add(i, k, pOverflow); 378 379 j = pseudonoise(pSeed, 1); /* generate sign */ 380 381 if (j > 0) 382 { 383 cod[i] = 4096; 384 } 385 else 386 { 387 cod[i] = -4096; 388 } 389 } 390 391 return; 392 } 393 394 /* 395 ------------------------------------------------------------------------------ 396 FUNCTION NAME: build_CN_param 397 ------------------------------------------------------------------------------ 398 INPUT AND OUTPUT DEFINITIONS 399 400 Inputs: 401 pSeed = pointer to the Old CN generator shift register state (Word32) 402 n_param = Number of parameters to randomize (Word16) 403 param_size_table = table holding paameter sizes (Word16) 404 param[] = array to hold CN generated paramters (Word16) 405 pOverflow = pointer to overflow flag (Flag) 406 407 Outputs: 408 param[] = CN generated parameters (Word16) 409 pSeed = Updated CN generator shift register state (Word16) 410 pOverflow -> 1 if overflow occured 411 412 Returns: 413 None 414 415 Global Variables Used: 416 None 417 418 Local Variables Needed: 419 None 420 421 ------------------------------------------------------------------------------ 422 FUNCTION DESCRIPTION 423 424 This function randomizes the speech parameters, so that they do not produce 425 tonal artifacts if used by ECU. 426 427 ------------------------------------------------------------------------------ 428 REQUIREMENTS 429 430 None 431 432 ------------------------------------------------------------------------------ 433 REFERENCES 434 435 b_cn_cod.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 436 437 ------------------------------------------------------------------------------ 438 PSEUDO-CODE 439 void build_CN_param ( 440 Word16 *seed, // i/o : Old CN generator shift register state 441 const Word16 n_param, // i : number of params 442 const Word16 param_size_table[],// i : size of params 443 Word16 parm[] // o : CN Generated params 444 ) 445 { 446 Word16 i; 447 const Word16 *p; 448 449 // The reference ETSI code uses a global flag for Overflow. However in the 450 // actual implementation a pointer to the overflow flag is passed into the 451 // function so that it can be passed into the basic math functions L_add() 452 // and L_mult() 453 454 *seed = extract_l(L_add(L_shr(L_mult(*seed, 31821), 1), 13849L)); 455 456 p = &window_200_40[*seed & 0x7F]; 457 for(i=0; i< n_param;i++){ 458 parm[i] = *p++ & ~(0xFFFF<<param_size_table[i]); 459 } 460 } 461 462 463 ------------------------------------------------------------------------------ 464 RESOURCES USED [optional] 465 466 When the code is written for a specific target processor the 467 the resources used should be documented below. 468 469 HEAP MEMORY USED: x bytes 470 471 STACK MEMORY USED: x bytes 472 473 CLOCK CYCLES: (cycle count equation for this function) + (variable 474 used to represent cycle count for each subroutine 475 called) 476 where: (cycle count variable) = cycle count for [subroutine 477 name] 478 479 ------------------------------------------------------------------------------ 480 CAUTION [optional] 481 [State any special notes, constraints or cautions for users of this function] 482 483 ------------------------------------------------------------------------------ 484 */ 485 486 /*---------------------------------------------------------------------------- 487 ; FUNCTION CODE 488 ----------------------------------------------------------------------------*/ 489 void build_CN_param( 490 Word16 *pSeed, /* i/o : Old CN generator shift register state */ 491 const Word16 n_param, /* i : number of params */ 492 const Word16 param_size_table[],/* i : size of params */ 493 Word16 parm[], /* o : CN Generated params */ 494 Flag *pOverflow /* i/o : Overflow Flag */ 495 ) 496 497 { 498 Word16 i; 499 const Word16 *pTemp; 500 Word32 L_temp; 501 Word16 temp; 502 503 L_temp = L_mult(*pSeed, 31821, pOverflow); 504 L_temp >>= 1; 505 506 *pSeed = (Word16)(L_add(L_temp, 13849L, pOverflow)); 507 508 pTemp = &window_200_40[*pSeed & 0x7F]; 509 510 for (i = 0; i < n_param; i++) 511 { 512 temp = ~(0xFFFF << param_size_table[i]); 513 parm[i] = *pTemp++ & temp; 514 } 515 } 516 517