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/c1035pf.c 35 Functions: q_p 36 build_code 37 code_10i40_35bits 38 39 40 Date: 09/28/2000 41 42 ------------------------------------------------------------------------------ 43 REVISION HISTORY 44 45 Description: Updated template. Cleaned up code. Passing in a pointer to 46 overflow flag for build_code() and code_10i40_35bits() functions. 47 Removed unnecessary header files. 48 49 Description: 50 1. Eliminated unused include files. 51 2. Replaced array addressing by pointers 52 3. Eliminated math operations that unnecessary checked for 53 saturation 54 4. Replaced for-loops with memset() 55 56 Description: Changed function name to pv_round to avoid conflict with 57 round function in C standard library. 58 59 Description: Replaced OSCL mem type functions and eliminated include 60 files that now are chosen by OSCL definitions 61 62 Description: Replaced "int" and/or "char" with OSCL defined types. 63 64 Description: 65 66 ------------------------------------------------------------------------------ 67 MODULE DESCRIPTION 68 69 This file contains the function that searches a 35 bit algebraic codebook 70 containing 10 pulses in a frame of 40 samples. 71 72 ------------------------------------------------------------------------------ 73 */ 74 75 /*---------------------------------------------------------------------------- 76 ; INCLUDES 77 ----------------------------------------------------------------------------*/ 78 #include <string.h> 79 80 #include "c1035pf.h" 81 #include "cnst.h" 82 #include "basic_op.h" 83 #include "inv_sqrt.h" 84 #include "set_sign.h" 85 #include "cor_h.h" 86 #include "cor_h_x.h" 87 #include "s10_8pf.h" 88 89 /*---------------------------------------------------------------------------- 90 ; MACROS 91 ; [Define module specific macros here] 92 ----------------------------------------------------------------------------*/ 93 94 95 /*---------------------------------------------------------------------------- 96 ; DEFINES 97 ; [Include all pre-processor statements here. Include conditional 98 ; compile variables also.] 99 ----------------------------------------------------------------------------*/ 100 #define NB_PULSE 10 101 102 /*---------------------------------------------------------------------------- 103 ; LOCAL FUNCTION DEFINITIONS 104 ; [List function prototypes here] 105 ----------------------------------------------------------------------------*/ 106 107 /*---------------------------------------------------------------------------- 108 ; LOCAL VARIABLE DEFINITIONS 109 ; [Variable declaration - defined here and used outside this module] 110 ----------------------------------------------------------------------------*/ 111 112 /* 113 ------------------------------------------------------------------------------ 114 FUNCTION NAME: q_p 115 ------------------------------------------------------------------------------ 116 INPUT AND OUTPUT DEFINITIONS 117 118 Inputs: 119 pShift_reg = pointer to Old CN generator shift register state (Word32) 120 no_bits = Number of bits (Word16) 121 122 Outputs: 123 pShift_reg -> Updated CN generator shift register state 124 125 Returns: 126 noise_bits = Generated random integer value (Word16) 127 128 Global Variables Used: 129 None 130 131 Local Variables Needed: 132 None 133 134 ------------------------------------------------------------------------------ 135 FUNCTION DESCRIPTION 136 137 This is a local function that determnes the index of the pulses by looking up 138 the gray encoder table 139 140 ------------------------------------------------------------------------------ 141 REQUIREMENTS 142 143 None 144 145 ------------------------------------------------------------------------------ 146 REFERENCES 147 148 c1035pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 149 150 ------------------------------------------------------------------------------ 151 PSEUDO-CODE 152 153 void q_p ( 154 Word16 *ind, // Pulse position 155 Word16 n // Pulse number 156 ) 157 { 158 Word16 tmp; 159 160 tmp = *ind; 161 162 if (sub (n, 5) < 0) 163 { 164 *ind = (tmp & 0x8) | gray[tmp & 0x7]; 165 } 166 else 167 { 168 *ind = gray[tmp & 0x7]; 169 } 170 } 171 172 ------------------------------------------------------------------------------ 173 RESOURCES USED [optional] 174 175 When the code is written for a specific target processor the 176 the resources used should be documented below. 177 178 HEAP MEMORY USED: x bytes 179 180 STACK MEMORY USED: x bytes 181 182 CLOCK CYCLES: (cycle count equation for this function) + (variable 183 used to represent cycle count for each subroutine 184 called) 185 where: (cycle count variable) = cycle count for [subroutine 186 name] 187 188 ------------------------------------------------------------------------------ 189 CAUTION [optional] 190 [State any special notes, constraints or cautions for users of this function] 191 192 ------------------------------------------------------------------------------ 193 */ 194 195 /*---------------------------------------------------------------------------- 196 ; FUNCTION CODE 197 ----------------------------------------------------------------------------*/ 198 199 void q_p( 200 Word16 *pInd, /* Pulse position */ 201 Word16 n /* Pulse number */ 202 ) 203 { 204 Word16 tmp; 205 206 tmp = *pInd; 207 208 if (n < 5) 209 { 210 *pInd = (tmp & 0x8) | gray[tmp & 0x7]; 211 } 212 else 213 { 214 *pInd = gray[tmp & 0x7]; 215 } 216 } 217 218 /* 219 ------------------------------------------------------------------------------ 220 FUNCTION NAME: build_code 221 ------------------------------------------------------------------------------ 222 INPUT AND OUTPUT DEFINITIONS 223 224 Inputs: 225 pSeed = pointer to the Old CN generator shift register state (Word32) 226 n_param = Number of parameters to randomize (Word16) 227 param_size_table = table holding paameter sizes (Word16) 228 param[] = array to hold CN generated paramters (Word16) 229 pOverflow = pointer to overflow flag (Flag) 230 231 Outputs: 232 param[] = CN generated parameters (Word16) 233 pSeed = Updated CN generator shift register state (Word16) 234 pOverflow -> 1 if overflow occured 235 236 Returns: 237 None 238 239 Global Variables Used: 240 None 241 242 Local Variables Needed: 243 None 244 245 ------------------------------------------------------------------------------ 246 FUNCTION DESCRIPTION 247 248 This function builds the codeword, the filtered codeword and index of the 249 codevector, based on the signs and positions of 10 pulses. 250 ------------------------------------------------------------------------------ 251 REQUIREMENTS 252 253 None 254 255 ------------------------------------------------------------------------------ 256 REFERENCES 257 258 c1035pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 259 260 ------------------------------------------------------------------------------ 261 PSEUDO-CODE 262 static void build_code ( 263 Word16 codvec[], // (i) : position of pulses 264 Word16 sign[], // (i) : sign of d[n] 265 Word16 cod[], // (o) : innovative code vector 266 Word16 h[], // (i) : impulse response of weighted synthesis filter 267 Word16 y[], // (o) : filtered innovative code 268 Word16 indx[] // (o) : index of 10 pulses (sign+position) 269 ) 270 { 271 Word16 i, j, k, track, index, _sign[NB_PULSE]; 272 Word16 *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9; 273 Word32 s; 274 275 for (i = 0; i < L_CODE; i++) 276 { 277 cod[i] = 0; 278 } 279 for (i = 0; i < NB_TRACK; i++) 280 { 281 indx[i] = -1; 282 } 283 284 for (k = 0; k < NB_PULSE; k++) 285 { 286 // read pulse position 287 i = codvec[k]; 288 // read sign 289 j = sign[i]; 290 291 index = mult (i, 6554); // index = pos/5 292 // track = pos%5 293 track = sub (i, extract_l (L_shr (L_mult (index, 5), 1))); 294 295 if (j > 0) 296 { 297 cod[i] = add (cod[i], 4096); 298 _sign[k] = 8192; 299 300 } 301 else 302 { 303 cod[i] = sub (cod[i], 4096); 304 _sign[k] = -8192; 305 index = add (index, 8); 306 } 307 308 if (indx[track] < 0) 309 { 310 indx[track] = index; 311 } 312 else 313 { 314 if (((index ^ indx[track]) & 8) == 0) 315 { 316 // sign of 1st pulse == sign of 2nd pulse 317 318 if (sub (indx[track], index) <= 0) 319 { 320 indx[track + 5] = index; 321 } 322 else 323 { 324 indx[track + 5] = indx[track]; 325 indx[track] = index; 326 } 327 } 328 else 329 { 330 // sign of 1st pulse != sign of 2nd pulse 331 332 if (sub ((Word16)(indx[track] & 7), (Word16)(index & 7)) <= 0) 333 { 334 indx[track + 5] = indx[track]; 335 indx[track] = index; 336 } 337 else 338 { 339 indx[track + 5] = index; 340 } 341 } 342 } 343 } 344 345 p0 = h - codvec[0]; 346 p1 = h - codvec[1]; 347 p2 = h - codvec[2]; 348 p3 = h - codvec[3]; 349 p4 = h - codvec[4]; 350 p5 = h - codvec[5]; 351 p6 = h - codvec[6]; 352 p7 = h - codvec[7]; 353 p8 = h - codvec[8]; 354 p9 = h - codvec[9]; 355 356 for (i = 0; i < L_CODE; i++) 357 { 358 s = 0; 359 s = L_mac (s, *p0++, _sign[0]); 360 s = L_mac (s, *p1++, _sign[1]); 361 s = L_mac (s, *p2++, _sign[2]); 362 s = L_mac (s, *p3++, _sign[3]); 363 s = L_mac (s, *p4++, _sign[4]); 364 s = L_mac (s, *p5++, _sign[5]); 365 s = L_mac (s, *p6++, _sign[6]); 366 s = L_mac (s, *p7++, _sign[7]); 367 s = L_mac (s, *p8++, _sign[8]); 368 s = L_mac (s, *p9++, _sign[9]); 369 y[i] = pv_round (s); 370 } 371 } 372 373 ------------------------------------------------------------------------------ 374 RESOURCES USED [optional] 375 376 When the code is written for a specific target processor the 377 the resources used should be documented below. 378 379 HEAP MEMORY USED: x bytes 380 381 STACK MEMORY USED: x bytes 382 383 CLOCK CYCLES: (cycle count equation for this function) + (variable 384 used to represent cycle count for each subroutine 385 called) 386 where: (cycle count variable) = cycle count for [subroutine 387 name] 388 389 ------------------------------------------------------------------------------ 390 CAUTION [optional] 391 [State any special notes, constraints or cautions for users of this function] 392 393 ------------------------------------------------------------------------------ 394 */ 395 396 /*---------------------------------------------------------------------------- 397 ; FUNCTION CODE 398 ----------------------------------------------------------------------------*/ 399 static void build_code( 400 Word16 codvec[], /* (i) : position of pulses */ 401 Word16 sign[], /* (i) : sign of d[n] */ 402 Word16 cod[], /* (o) : innovative code vector */ 403 Word16 h[], /* (i) : impulse response of weighted synthesis filter*/ 404 Word16 y[], /* (o) : filtered innovative code */ 405 Word16 indx[], /* (o) : index of 10 pulses (sign+position) */ 406 Flag *pOverflow /* i/o : overflow Flag */ 407 ) 408 { 409 Word16 i, k, track, index, _sign[NB_PULSE]; 410 Word16 *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9; 411 Word32 s; 412 Word16 temp; 413 Word16 *p__sign; 414 Word16 *p_y; 415 Word16 *p_codvec; 416 417 OSCL_UNUSED_ARG(pOverflow); 418 419 memset(cod, 0, L_CODE*sizeof(*cod)); 420 memset(indx, 0xFF, NB_TRACK*sizeof(*indx)); 421 422 p__sign = _sign; 423 424 p0 = &codvec[0]; 425 426 for (k = 0; k < NB_PULSE; k++) 427 { 428 /* read pulse position */ 429 i = *(p0++); 430 /* read sign */ 431 432 index = ((Word32)i * 6554) >> 15; /* index = pos/5 */ 433 434 /* track = pos%5 */ 435 /* track = sub (i, extract_l (L_shr (L_mult (index, 5), 1))); */ 436 track = i - (index * 5); 437 438 if (sign[i] > 0) 439 { 440 cod[i] += 4096; 441 *(p__sign++) = 8192; 442 443 } 444 else 445 { 446 cod[i] -= 4096; 447 *(p__sign++) = -8192; 448 /* index = add (index, 8); */ 449 index += 8; 450 } 451 452 p1 = &indx[track]; 453 454 temp = *p1; 455 456 if (temp < 0) 457 { 458 *p1 = index; 459 } 460 else 461 { 462 if (((index ^ temp) & 8) == 0) 463 { 464 /* sign of 1st pulse == sign of 2nd pulse */ 465 466 /* if (sub (indx[track], index) <= 0) */ 467 if (temp <= index) 468 { 469 *(p1 + 5) = index; 470 } 471 else 472 { 473 *(p1 + 5) = temp; 474 *p1 = index; 475 } 476 } 477 else 478 { 479 /* sign of 1st pulse != sign of 2nd pulse */ 480 481 /* if (sub ((Word16)(indx[track] & 7), (Word16)(index & 7)) <= 0) */ 482 if ((temp & 7) <= (index & 7)) 483 { 484 *(p1 + 5) = temp; 485 *p1 = index; 486 } 487 else 488 { 489 *(p1 + 5) = index; 490 } 491 } 492 } 493 } 494 495 p_codvec = &codvec[0]; 496 497 p0 = h - *(p_codvec++); 498 p1 = h - *(p_codvec++); 499 p2 = h - *(p_codvec++); 500 p3 = h - *(p_codvec++); 501 p4 = h - *(p_codvec++); 502 p5 = h - *(p_codvec++); 503 p6 = h - *(p_codvec++); 504 p7 = h - *(p_codvec++); 505 p8 = h - *(p_codvec++); 506 p9 = h - *(p_codvec++); 507 508 p_y = y; 509 510 for (i = L_CODE; i != 0; i--) 511 { 512 p__sign = _sign; 513 514 s = (*p0++ * *(p__sign++)) >> 7; 515 s += (*p1++ * *(p__sign++)) >> 7; 516 s += (*p2++ * *(p__sign++)) >> 7; 517 s += (*p3++ * *(p__sign++)) >> 7; 518 s += (*p4++ * *(p__sign++)) >> 7; 519 s += (*p5++ * *(p__sign++)) >> 7; 520 s += (*p6++ * *(p__sign++)) >> 7; 521 s += (*p7++ * *(p__sign++)) >> 7; 522 s += (*p8++ * *(p__sign++)) >> 7; 523 s += (*p9++ * *(p__sign++)) >> 7; 524 525 *(p_y++) = (s + 0x080) >> 8; 526 } 527 528 } 529 530 /* 531 ------------------------------------------------------------------------------ 532 FUNCTION NAME: code_10i40_35bits 533 ------------------------------------------------------------------------------ 534 INPUT AND OUTPUT DEFINITIONS 535 536 Inputs: 537 pSeed = pointer to the Old CN generator shift register state (Word32) 538 n_param = Number of parameters to randomize (Word16) 539 param_size_table = table holding paameter sizes (Word16) 540 param[] = array to hold CN generated paramters (Word16) 541 pOverflow = pointer to overflow flag (Flag) 542 543 Outputs: 544 param[] = CN generated parameters (Word16) 545 pSeed = Updated CN generator shift register state (Word16) 546 pOverflow -> 1 if overflow occured 547 548 Returns: 549 None 550 551 Global Variables Used: 552 None 553 554 Local Variables Needed: 555 None 556 557 ------------------------------------------------------------------------------ 558 FUNCTION DESCRIPTION 559 560 This function searches a 35 bit algebraic codebook containing 10 pulses in a 561 frame of 40 samples. 562 563 The code contains 10 nonzero pulses: i0...i9. 564 All pulses can have two possible amplitudes: +1 or -1. 565 The 40 positions in a subframe are divided into 5 tracks of 566 interleaved positions. Each track contains two pulses. 567 The pulses can have the following possible positions: 568 569 i0, i5 : 0, 5, 10, 15, 20, 25, 30, 35. 570 i1, i6 : 1, 6, 11, 16, 21, 26, 31, 36. 571 i2, i7 : 2, 7, 12, 17, 22, 27, 32, 37. 572 i3, i8 : 3, 8, 13, 18, 23, 28, 33, 38. 573 i4, i9 : 4, 9, 14, 19, 24, 29, 34, 39. 574 575 Each pair of pulses require 1 bit for their signs and 6 bits for their 576 positions (3 bits + 3 bits). This results in a 35 bit codebook. 577 The function determines the optimal pulse signs and positions, builds 578 the codevector, and computes the filtered codevector. 579 580 ------------------------------------------------------------------------------ 581 REQUIREMENTS 582 583 None 584 585 ------------------------------------------------------------------------------ 586 REFERENCES 587 588 c1035pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 589 590 ------------------------------------------------------------------------------ 591 PSEUDO-CODE 592 void code_10i40_35bits ( 593 Word16 x[], // (i) : target vector 594 Word16 cn[], // (i) : residual after long term prediction 595 Word16 h[], // (i) : impulse response of weighted synthesis filter 596 // h[-L_subfr..-1] must be set to zero 597 Word16 cod[], // (o) : algebraic (fixed) codebook excitation 598 Word16 y[], // (o) : filtered fixed codebook excitation 599 Word16 indx[] // (o) : index of 10 pulses (sign + position) 600 ) 601 { 602 Word16 ipos[NB_PULSE], pos_max[NB_TRACK], codvec[NB_PULSE]; 603 Word16 dn[L_CODE], sign[L_CODE]; 604 Word16 rr[L_CODE][L_CODE], i; 605 606 cor_h_x (h, x, dn, 2); 607 set_sign12k2 (dn, cn, sign, pos_max, NB_TRACK, ipos, STEP); 608 cor_h (h, sign, rr); 609 610 search_10and8i40 (NB_PULSE, STEP, NB_TRACK, 611 dn, rr, ipos, pos_max, codvec); 612 613 build_code (codvec, sign, cod, h, y, indx); 614 for (i = 0; i < 10; i++) 615 { 616 q_p (&indx[i], i); 617 } 618 return; 619 } 620 621 ------------------------------------------------------------------------------ 622 RESOURCES USED [optional] 623 624 When the code is written for a specific target processor the 625 the resources used should be documented below. 626 627 HEAP MEMORY USED: x bytes 628 629 STACK MEMORY USED: x bytes 630 631 CLOCK CYCLES: (cycle count equation for this function) + (variable 632 used to represent cycle count for each subroutine 633 called) 634 where: (cycle count variable) = cycle count for [subroutine 635 name] 636 637 ------------------------------------------------------------------------------ 638 CAUTION [optional] 639 [State any special notes, constraints or cautions for users of this function] 640 641 ------------------------------------------------------------------------------ 642 */ 643 644 /*---------------------------------------------------------------------------- 645 ; FUNCTION CODE 646 ----------------------------------------------------------------------------*/ 647 void code_10i40_35bits( 648 Word16 x[], /* (i) : target vector */ 649 Word16 cn[], /* (i) : residual after long term prediction */ 650 Word16 h[], /* (i) : impulse response of weighted synthesis filter 651 h[-L_subfr..-1] must be set to zero */ 652 Word16 cod[], /* (o) : algebraic (fixed) codebook excitation */ 653 Word16 y[], /* (o) : filtered fixed codebook excitation */ 654 Word16 indx[], /* (o) : index of 10 pulses (sign + position) */ 655 Flag *pOverflow /* (i/o) : overflow Flag */ 656 ) 657 { 658 Word16 ipos[NB_PULSE], pos_max[NB_TRACK], codvec[NB_PULSE]; 659 Word16 dn[L_CODE], sign[L_CODE]; 660 Word16 rr[L_CODE][L_CODE], i; 661 662 cor_h_x(h, x, dn, 2, pOverflow); 663 set_sign12k2(dn, cn, sign, pos_max, NB_TRACK, ipos, STEP, pOverflow); 664 cor_h(h, sign, rr, pOverflow); 665 666 search_10and8i40(NB_PULSE, STEP, NB_TRACK, 667 dn, rr, ipos, pos_max, codvec, pOverflow); 668 669 build_code(codvec, sign, cod, h, y, indx, pOverflow); 670 for (i = 0; i < 10; i++) 671 { 672 q_p(&indx[i], i); 673 } 674 return; 675 } 676 677