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 20 Pathname: ./src/unpack_idx.c 21 Function: unpack_idx 22 unpack_idx_sgn 23 unpack_idx_esc 24 25------------------------------------------------------------------------------ 26 REVISION HISTORY 27 28 Description: Modified from original shareware code 29 30 Description: Eliminated 3 divisions and 1 multiplication through a table 31 look-up method for calculating 1/mod and constant allocation of 1/mod^3 32 and 1/mod^2. 33 Eliminated 3 additions through simple optimizations in the code. 34 Changed if/else statement to a switch/case utilizing fall-through. 35 36 Description: Made changes per review comments. Main improvements were 37 in change of switch/case to if statement, and use of temporary variable 38 to hold value of *pQuantSpec. 39 40 Description: (1) Typecast codeword_indx to Int32 before multiplication, this 41 assures the shift operation happens on a 32-bit product on 42 TI-C55x processor. 43 (2) define temp_spec as Int32 to avoid overflow 44 45 Description: Modified per review comments 46 (1) remove the two typecastings of codeword_indx when 47 pHuffCodebook->dim == DIMENSION_4 48 (2) temp_spec is Int because the result never exceeds 16 bits 49 50 Description: Break up and combine unpack index with sign bit reading and for 51 special escape code. Parent function must know which one of the 52 3 functions should be called. 53 54 Description: Put back if-statement to get the max. 55 56 Description: When searching for the max, there was some instances where the 57 max was compared against a negative number, so the max was never 58 updated (defaulted to 0), leading to block processing in other 59 magnitude sensitive stages. 60 61 Who: Date: 62 Description: 63------------------------------------------------------------------------------ 64 INPUT AND OUTPUT DEFINITIONS 65 66 Inputs: 67 Int quant_spec[] = Array for storage of the quantized 68 spectral coefficients. Length is either 2 or 4. 69 See Ref #1, Page 76 for a complete description. 70 71 Int codeword_indx = The index into the Huffman table. 72 Range is [1-288] 73 74 const Hcb *pHuffCodebook = Pointer to HuffmanCodebook information. 75 76 BITS *pInputStream = Pointer to the bitstream buffer. 77 Int *max = Pointer to maximum coefficient value. 78 79 Local Stores/Buffers/Pointers Needed: 80 const UInt div_mod[18] = An array with the values for 1/mod 81 stored in Q-formats 13. 82 83 Global Stores/Buffers/Pointers Needed: 84 None 85 86 Outputs: 87 None 88 89 Pointers and Buffers Modified: 90 Int quant_spec[] = Output (the quantized and signed spectral coefficients) 91 returned via this pointer. 92 93 Local Stores Modified: 94 None 95 96 Global Stores Modified: 97 None 98 99------------------------------------------------------------------------------ 100 FUNCTION DESCRIPTION 101 102 This function decodes quantized spectral coefficients and decode their signs 103 from the input bitstream. Quantized spectral coefficients are transmitted as 104 four-tuples or 2-tuples, and this information is conveyed to the function via 105 the variable HuffCodebook->dim. 106 107 See Reference #1 for a complete description 108------------------------------------------------------------------------------ 109 REQUIREMENTS 110 111 This function shall correctly calculate pQuantSpec[], given the inputs 112 113 codeword_indx = {1-288}; 114 HuffCodebook->off = {0, 1, 4}; 115 HuffCodebook->mod = {3, 8, 9, 13, 17}; 116 117 mod = LAV + 1 if unsigned codebook 118 mod = 2*LAV + 1 if signed codebook 119 120 Range of values for LAV is {2,7,12,16} if unsigned 121 {1,4} if signed 122 123 Additionally, 124 LAV <= 2 if dim == 4 125 126 This restricts mod == 3 if dim == 4 127 and mod == {3, 8, 9, 13, 17} if dim == 2 128 129 This function will NOT function correctly if fed values that do not 130 meet the requirements as stated above. 131 132 This limitation on the range of values was determined by analysis 133 of Reference #1 (see below.) 134 135------------------------------------------------------------------------------ 136 REFERENCES 137 138 (1) ISO/IEC 14496-3:1999(E) 139 Part 3 140 Subpart 4.6.3.3 Decoding Process 141 Subpart 4.6.4 Tables 142 (2) MPEG-2 NBC Audio Decoder 143 "This software module was originally developed by AT&T, Dolby 144 Laboratories, Fraunhofer Gesellschaft IIS in the course of development 145 of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and 146 3. This software module is an implementation of a part of one or more 147 MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4 148 Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio 149 standards free license to this software module or modifications thereof 150 for use in hardware or software products claiming conformance to the 151 MPEG-2 NBC/MPEG-4 Audio standards. Those intending to use this software 152 module in hardware or software products are advised that this use may 153 infringe existing patents. The original developer of this software 154 module and his/her company, the subsequent editors and their companies, 155 and ISO/IEC have no liability for use of this software module or 156 modifications thereof in an implementation. Copyright is not released 157 for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original 158 developer retains full right to use the code for his/her own purpose, 159 assign or donate the code to a third party and to inhibit third party 160 from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products. 161 This copyright notice must be included in all copies or derivative 162 works." 163 Copyright(c)1996. 164 165------------------------------------------------------------------------------ 166 PSEUDO-CODE 167 168 IF (pHuffCodebook->dim == 4) 169 *(pQuantSpec) = codeword_indx/(3^3); 170 codeword_indx = codeword_indx - *(pQuantSpec)*(3^3); 171 *(pQuantSpec) = *(pQuantSpec) - off; 172 173 pQuantSpec = pQuantSpec + 1; 174 175 *(pQuantSpec) = codeword_indx/(3^2); 176 codeword_indx = codeword_indx - *(pQuantSpec)*(3^2); 177 *(pQuantSpec) = *(pQuantSpec) - off; 178 179 pQuantSpec = pQuantSpec + 1; 180 ENDIF 181 182 *(pQuantSpec) = codeword_indx/mod; 183 codeword_indx = codeword_indx - (*pQuantSpec)*mod; 184 *(pQuantSpec) = *(pQuantSpec) - off; 185 186 pQuantSpec = pQuantSpec + 1; 187 188 *(pQuantSpec) = codeword_indx - off; 189 190------------------------------------------------------------------------------ 191 RESOURCES USED 192 When the code is written for a specific target processor the 193 the resources used should be documented below. 194 195 STACK USAGE: [stack count for this module] + [variable to represent 196 stack usage for each subroutine called] 197 198 where: [stack usage variable] = stack usage for [subroutine 199 name] (see [filename].ext) 200 201 DATA MEMORY USED: x words 202 203 PROGRAM MEMORY USED: x words 204 205 CLOCK CYCLES: [cycle count equation for this module] + [variable 206 used to represent cycle count for each subroutine 207 called] 208 209 where: [cycle count variable] = cycle count for [subroutine 210 name] (see [filename].ext) 211 212------------------------------------------------------------------------------ 213*/ 214 215 216/*---------------------------------------------------------------------------- 217; INCLUDES 218----------------------------------------------------------------------------*/ 219#include "pv_audio_type_defs.h" 220#include "s_hcb.h" 221#include "ibstream.h" 222#include "unpack_idx.h" 223 224#include "fxp_mul32.h" 225 226 227/*---------------------------------------------------------------------------- 228; MACROS 229; Define module specific macros here 230----------------------------------------------------------------------------*/ 231 232/*---------------------------------------------------------------------------- 233; DEFINES 234; Include all pre-processor statements here. Include conditional 235; compile variables also. 236----------------------------------------------------------------------------*/ 237#define DIV_3_CUBED 19 /* 19 = 1/27 in Q-9 format */ 238#define THREE_CUBED 27 /* 27 = 3^3 */ 239 240#define DIV_3_SQUARED 57 /* 57 = 1/9 in Q-9 format */ 241#define THREE_SQUARED 9 /* 9 = 3^2 */ 242 243#define Q_FORMAT_MOD 13 /* Q-format for 1/mod table */ 244#define Q_FORMAT_MOD2 9 /* Q-format for DIV_3_SQUARED */ 245#define Q_FORMAT_MOD3 9 /* Q-format for DIV_3_CUBED */ 246 247#define LOWER_5_BITS_MASK 0x1F 248 249 250#if ( defined(PV_ARM_V5) || defined(PV_ARM_V4)) 251 252__inline Int32 abs1(Int32 x) 253{ 254 Int32 z; 255 /* 256 z = x - (x<0); 257 x = z ^ sign(z) 258 */ 259 __asm 260 { 261 sub z, x, x, lsr #31 262 eor x, z, z, asr #31 263 } 264 return (x); 265} 266 267#define pv_abs(x) abs1(x) 268 269 270#else 271 272#define pv_abs(x) ((x) > 0)? (x) : (-x) 273 274#endif 275 276 277 278/*---------------------------------------------------------------------------- 279; LOCAL FUNCTION DEFINITIONS 280; Function Prototype declaration 281----------------------------------------------------------------------------*/ 282 283/*---------------------------------------------------------------------------- 284; LOCAL STORE/BUFFER/POINTER DEFINITIONS 285; Variable declaration - defined here and used outside this module 286----------------------------------------------------------------------------*/ 287/*-------------------------------------------------------------------------- 288 Possible values for mod = {3,8,9,13,17} 289 290 There exists "empty" spaces in the table. These can potentially 291 be utilized by other const tables, if available memory becomes an issue. 292---------------------------------------------------------------------------*/ 293 294const Int div_mod[18] = /* mod index Q-format */ 295{ 296 /* ----------------------- */ 297 0xCC, /* | | 0 | */ 298 0xCC, /* | | 1 | */ 299 0xCC, /* | | 2 | */ 300 2731, /* | 3 | 3 | 13 */ 301 0xCC, /* | | 4 | */ 302 0xCC, /* | | 5 | */ 303 0xCC, /* | | 6 | */ 304 0xCC, /* | | 7 | */ 305 1025, /* | 8 | 8 | 13 */ 306 911, /* | 9 | 9 | 13 */ 307 0xCC, /* | | 10 | */ 308 0xCC, /* | | 11 | */ 309 0xCC, /* | | 12 | */ 310 631, /* | 13 | 13 | 13 */ 311 0xCC, /* | | 14 | */ 312 0xCC, /* | | 15 | */ 313 0xCC, /* | | 16 | */ 314 482, /* | 17 | 17 | 13 */ 315}; 316 317/*---------------------------------------------------------------------------- 318; EXTERNAL FUNCTION REFERENCES 319; Declare functions defined elsewhere and referenced in this module 320----------------------------------------------------------------------------*/ 321 322/*---------------------------------------------------------------------------- 323; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 324; Declare variables used in this module but defined elsewhere 325----------------------------------------------------------------------------*/ 326 327/*---------------------------------------------------------------------------- 328; FUNCTION CODE 329----------------------------------------------------------------------------*/ 330void unpack_idx( 331 Int16 quant_spec[], 332 Int codeword_indx, 333 const Hcb *pHuffCodebook, 334 BITS *pInputStream, 335 Int *max) 336{ 337 Int16 *pQuantSpec = &quant_spec[0]; 338 Int temp_spec; 339 340 const Int mod = pHuffCodebook->mod; 341 const Int off = pHuffCodebook->off; 342 343 OSCL_UNUSED_ARG(pInputStream); 344 345 346 if (pHuffCodebook->dim == DIMENSION_4) 347 { 348 /* Calculate pQuantSpec[0] */ 349 350 temp_spec = (codeword_indx * DIV_3_CUBED) >> Q_FORMAT_MOD3; 351 352 codeword_indx -= temp_spec * THREE_CUBED; 353 354 temp_spec -= off; 355 *pQuantSpec++ = (Int16)temp_spec; 356 357 temp_spec = pv_abs(temp_spec); 358 359 if (temp_spec > *max) 360 { 361 *max = temp_spec; 362 } 363 364 /* Calculate pQuantSpec[1] */ 365 temp_spec = (codeword_indx * DIV_3_SQUARED) >> Q_FORMAT_MOD2; 366 367 codeword_indx -= temp_spec * THREE_SQUARED; 368 369 temp_spec -= off; 370 *pQuantSpec++ = (Int16)temp_spec; 371 372 temp_spec = pv_abs(temp_spec); 373 374 if (temp_spec > *max) 375 { 376 *max = temp_spec; 377 } 378 } 379 380 /* 381 * Calculate pQuantSpec[2] if dim == 4 382 * Calculate pQuantSpec[0] if dim == 2 383 */ 384 385 temp_spec = ((Int32) codeword_indx * div_mod[mod]) >> Q_FORMAT_MOD; 386 387 codeword_indx -= temp_spec * mod; 388 389 temp_spec -= off; 390 *pQuantSpec++ = (Int16)temp_spec; 391 392 temp_spec = pv_abs(temp_spec); 393 394 395 if (temp_spec > *max) 396 { 397 *max = temp_spec; 398 } 399 400 /* 401 * Calculate pQuantSpec[3] if dim == 4 402 * Calculate pQuantSpec[1] if dim == 2 403 */ 404 codeword_indx -= off; 405 *pQuantSpec = (Int16)codeword_indx ; 406 407 408 codeword_indx = pv_abs(codeword_indx); 409 410 if (codeword_indx > *max) 411 { 412 *max = codeword_indx; 413 } 414 415 416 return ; 417} /* unpack_idx */ 418 419 420void unpack_idx_sgn( 421 Int16 quant_spec[], 422 Int codeword_indx, 423 const Hcb *pHuffCodebook, 424 BITS *pInputStream, 425 Int *max) 426{ 427 Int16 *pQuantSpec = &quant_spec[0]; 428 Int temp_spec; 429 Int sgn; 430 431 const Int mod = pHuffCodebook->mod; 432 const Int off = pHuffCodebook->off; 433 434 435 436 if (pHuffCodebook->dim == DIMENSION_4) 437 { 438 /* Calculate pQuantSpec[0] */ 439 preload_cache((Int32 *)pQuantSpec); 440 temp_spec = (codeword_indx * DIV_3_CUBED) >> Q_FORMAT_MOD3; 441 442 codeword_indx -= temp_spec * THREE_CUBED; 443 444 temp_spec -= off; 445 if (temp_spec) 446 { 447 sgn = get1bits(pInputStream); 448 449 450 *pQuantSpec++ = (Int16)((sgn) ? -temp_spec : temp_spec); 451 452 temp_spec = pv_abs(temp_spec); 453 454 if (temp_spec > *max) 455 { 456 *max = temp_spec; 457 } 458 459 } 460 else 461 { 462 *pQuantSpec++ = 0; 463 } 464 465 /* Calculate pQuantSpec[1] */ 466 temp_spec = (codeword_indx * DIV_3_SQUARED) >> Q_FORMAT_MOD2; 467 468 codeword_indx -= temp_spec * THREE_SQUARED; 469 470 temp_spec -= off; 471 if (temp_spec) 472 { 473 474 sgn = get1bits(pInputStream); 475 476 *pQuantSpec++ = (Int16)((sgn) ? -temp_spec : temp_spec); 477 478 temp_spec = pv_abs(temp_spec); 479 480 if (temp_spec > *max) 481 { 482 *max = temp_spec; 483 } 484 } 485 else 486 { 487 *pQuantSpec++ = 0; 488 } 489 } 490 491 /* 492 * Calculate pQuantSpec[2] if dim == 4 493 * Calculate pQuantSpec[0] if dim == 2 494 */ 495 496 temp_spec = ((Int32) codeword_indx * div_mod[mod]) >> Q_FORMAT_MOD; 497 498 codeword_indx -= temp_spec * mod; 499 500 temp_spec -= off; 501 if (temp_spec) 502 { 503 504 sgn = get1bits(pInputStream); 505 506 *pQuantSpec++ = (Int16)((sgn) ? -temp_spec : temp_spec); 507 508 temp_spec = pv_abs(temp_spec); 509 510 if (temp_spec > *max) 511 { 512 *max = temp_spec; 513 } 514 } 515 else 516 { 517 *pQuantSpec++ = 0; 518 } 519 520 /* 521 * Calculate pQuantSpec[3] if dim == 4 522 * Calculate pQuantSpec[1] if dim == 2 523 */ 524 codeword_indx -= off; 525 if (codeword_indx) 526 { 527 528 sgn = get1bits(pInputStream); 529 530 *pQuantSpec = (Int16)((sgn) ? -codeword_indx : codeword_indx); 531 532 codeword_indx = pv_abs(codeword_indx); 533 534 if (codeword_indx > *max) 535 { 536 *max = codeword_indx; 537 } 538 } 539 else 540 { 541 *pQuantSpec = 0; 542 } 543 544 return ; 545} /* unpack_idx_sgn */ 546 547 548void unpack_idx_esc( 549 Int16 quant_spec[], 550 Int codeword_indx, 551 const Hcb *pHuffCodebook, 552 BITS *pInputStream, 553 Int *max) 554{ 555 Int temp_spec; 556 Int sgn1 = 0, sgn2 = 0; 557 Int N; 558 Int32 esc_seq; 559 560 const Int mod = pHuffCodebook->mod; 561 const Int off = pHuffCodebook->off; 562 563 564 temp_spec = ((Int32) codeword_indx * div_mod[mod]) >> Q_FORMAT_MOD; 565 566 codeword_indx -= temp_spec * mod; 567 568 temp_spec -= off; 569 if (temp_spec) 570 { 571 sgn1 = get1bits(pInputStream); 572 } 573 574 codeword_indx -= off; 575 if (codeword_indx) 576 { 577 sgn2 = get1bits(pInputStream); 578 } 579 580 581 if ((temp_spec & LOWER_5_BITS_MASK) == 16) 582 { 583 N = 3; 584 do 585 { 586 N++; 587 588 esc_seq = get1bits(pInputStream); 589 590 } 591 while (esc_seq != 0); 592 593 esc_seq = getbits(N, pInputStream); 594 595 esc_seq += (1 << N); 596 597 598 temp_spec = (Int)((temp_spec * esc_seq) >> 4); 599 600 } 601 602 603 if (sgn1) 604 { 605 quant_spec[0] = (Int16)(-temp_spec); 606 } 607 else 608 { 609 quant_spec[0] = (Int16)temp_spec; 610 } 611 612 temp_spec = pv_abs(temp_spec); 613 614 if (temp_spec > *max) 615 { 616 *max = temp_spec; 617 } 618 619 if ((codeword_indx & LOWER_5_BITS_MASK) == 16) 620 { 621 N = 3; 622 do 623 { 624 N++; 625 626 esc_seq = get1bits(pInputStream); 627 628 } 629 while (esc_seq != 0); 630 631 esc_seq = getbits(N, pInputStream); 632 633 esc_seq += (1 << N); 634 635 codeword_indx = (Int)((codeword_indx * esc_seq) >> 4); 636 } 637 638 639 640 641 if (sgn2) 642 { 643 quant_spec[1] = (Int16)(-codeword_indx); 644 } 645 else 646 { 647 quant_spec[1] = (Int16)codeword_indx; 648 } 649 650 651 codeword_indx = pv_abs(codeword_indx); 652 653 if (codeword_indx > *max) 654 { 655 *max = codeword_indx; 656 } 657 658 659 return ; 660} /* unpack_idx_esc */ 661