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: get_prog_config.c 21 22 ------------------------------------------------------------------------------ 23 REVISION HISTORY 24 25 Description: Modified from original shareware code 26 27 Description: Modified to pass variables by reference to eliminate use 28 of global variables. 29 30 Description: Move functionality from get_adif_header for when to change 31 the current program configuration, add a temporary config 32 to read into, clean up code, change function prototype. 33 34 Description: Clean up 35 36 Description: Update per review comments 37 38 Description: Fix double 'could' 39 40 Description: change enter_mc_info to set_mc_info 41 42 Description: update comments 43 44 Description: Replace some instances of getbits to get9_n_lessbits 45 when the number of bits read is 9 or less and get1bits 46 when only 1 bit is read. 47 48 Who: Date: 49 Description: 50 51 ------------------------------------------------------------------------------ 52 INPUT AND OUTPUT DEFINITIONS 53 54 Inputs: 55 pVars = pointer to the structure that holds all information for 56 this instance of the library. pVars->prog_config is directly 57 used, and pVars->mc_info, pVars->prog_config, pVars->winmap, 58 pVars->SFBWidth128 are needed indirectly for calling 59 set_mc_info. Data type pointer to tDec_Int_File structure. 60 61 pScratchPCE = pointer to a temporary ProgConfig structure to be used 62 to read in the program configuration element. 63 64 Local Stores/Buffers/Pointers Needed: None 65 66 Global Stores/Buffers/Pointers Needed: None 67 68 Outputs: 69 status = zero if no error was found, non-zero otherwise. 70 71 Pointers and Buffers Modified: 72 pVars->prog_config contents are updated with the PCE read in. 73 pVars->mc_info contents are updated with channel information. 74 pVars->winmap contents are updated with window information. 75 pVars->SFBWidth128 contents are updated with scale factor band width data. 76 77 Local Stores Modified: None 78 79 Global Stores Modified: None 80 81 ------------------------------------------------------------------------------ 82 FUNCTION DESCRIPTION 83 84 This function reads from the input stream to memory for a temporary 85 program configuration element (PCE). If the PCE read is the first 86 encountered it is saved. Or, if the tag of the PCE read matches the tag of 87 the first PCE encounted, it is saved as well. This is a mechanism for 88 changing the sampling rate. 89 90 ------------------------------------------------------------------------------ 91 REQUIREMENTS 92 93 This function shall not use static or global variables. 94 95 ------------------------------------------------------------------------------ 96 REFERENCES 97 98 (1) ISO/IEC 13818-7:1997 Titled "Information technology - Generic coding 99 of moving pictures and associated audio information - Part 7: Advanced 100 Audio Coding (AAC)", Table 6.21 - Syntax of program_config_element(), 101 page 16, and section 8.5 "Program Config Element (PCE)", page 30. 102 103 (2) MPEG-2 NBC Audio Decoder 104 "This software module was originally developed by AT&T, Dolby 105 Laboratories, Fraunhofer Gesellschaft IIS in the course of development 106 of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and 107 3. This software module is an implementation of a part of one or more 108 MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4 109 Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio 110 standards free license to this software module or modifications thereof 111 for use in hardware or software products claiming conformance to the 112 MPEG-2 NBC/MPEG-4 Audio standards. Those intending to use this software 113 module in hardware or software products are advised that this use may 114 infringe existing patents. The original developer of this software 115 module and his/her company, the subsequent editors and their companies, 116 and ISO/IEC have no liability for use of this software module or 117 modifications thereof in an implementation. Copyright is not released 118 for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original 119 developer retains full right to use the code for his/her own purpose, 120 assign or donate the code to a third party and to inhibit third party 121 from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products. 122 This copyright notice must be included in all copies or derivative 123 works." 124 Copyright(c)1996. 125 126 127 ------------------------------------------------------------------------------ 128 PSEUDO-CODE 129 130 status = SUCCESS; 131 pInputStream = &(pVars->inputStream); 132 133 134 CALL getbits( 135 neededBits = LEN_TAG, 136 pInputStream = pInputStream ) 137 MODIFYING( pInputStream ) 138 RETURNING( tag = returnValue ) 139 140 CALL getbits( 141 neededBits = LEN_PROFILE, 142 pInputStream = pInputStream ) 143 MODIFYING( pInputStream ) 144 RETURNING( pScratchPCE->profile = returnValue ) 145 146 CALL getbits( 147 neededBits = LEN_PROFILE, 148 pInputStream = pInputStream ) 149 MODIFYING( pInputStream ) 150 RETURNING( pScratchPCE->sampling_rate_idx = returnValue ) 151 152 CALL getbits( 153 neededBits = LEN_NUM_ELE, 154 pInputStream = pInputStream ) 155 MODIFYING( pInputStream ) 156 RETURNING( temp = returnValue ) 157 158 pScratchPCE->front.num_ele = temp; 159 160 CALL getbits( 161 neededBits = LEN_NUM_ELE, 162 pInputStream = pInputStream ) 163 MODIFYING( pInputStream ) 164 RETURNING( temp = returnValue ) 165 166 pScratchPCE->side.num_ele = temp; 167 168 CALL getbits( 169 neededBits = LEN_NUM_ELE, 170 pInputStream = pInputStream ) 171 MODIFYING( pInputStream ) 172 RETURNING( temp = returnValue ) 173 174 pScratchPCE->back.num_ele = temp; 175 176 CALL getbits( 177 neededBits = LEN_NUM_LFE, 178 pInputStream = pInputStream ) 179 MODIFYING( pInputStream ) 180 RETURNING( temp = returnValue ) 181 182 pScratchPCE->lfe.num_ele = temp; 183 184 CALL getbits( 185 neededBits = LEN_NUM_DAT, 186 pInputStream = pInputStream ) 187 MODIFYING( pInputStream ) 188 RETURNING( temp = returnValue ) 189 190 pScratchPCE->data.num_ele = temp; 191 192 CALL getbits( 193 neededBits = LEN_NUM_CCE, 194 pInputStream = pInputStream ) 195 MODIFYING( pInputStream ) 196 RETURNING( temp = returnValue ) 197 198 pScratchPCE->coupling.num_ele = temp; 199 200 CALL getbits( 201 neededBits = LEN_MIX_PRES, 202 pInputStream = pInputStream ) 203 MODIFYING( pInputStream ) 204 RETURNING( flag = returnValue ) 205 206 pScratchPCE->mono_mix.present = flag; 207 208 IF (flag != FALSE) 209 THEN 210 CALL getbits( 211 neededBits = LEN_TAG, 212 pInputStream = pInputStream ) 213 MODIFYING( pInputStream ) 214 RETURNING( temp = returnValue ) 215 216 pScratchPCE->mono_mix.ele_tag = temp; 217 218 ENDIF 219 220 CALL getbits( 221 neededBits = LEN_MIX_PRES, 222 pInputStream = pInputStream ) 223 MODIFYING( pInputStream ) 224 RETURNING( flag = returnValue ) 225 226 pScratchPCE->stereo_mix.present = flag; 227 228 IF (flag != FALSE) 229 THEN 230 231 CALL getbits( 232 neededBits = LEN_TAG, 233 pInputStream = pInputStream ) 234 MODIFYING( pInputStream ) 235 RETURNING( temp = returnValue ) 236 237 pScratchPCE->stereo_mix.ele_tag = temp; 238 239 ENDIF 240 241 CALL getbits( 242 neededBits = LEN_MIX_PRES, 243 pInputStream = pInputStream ) 244 MODIFYING( pInputStream ) 245 RETURNING( flag = returnValue ) 246 247 flag = 248 getbits( 249 LEN_MIX_PRES, 250 pInputStream); 251 252 pScratchPCE->matrix_mix.present = flag; 253 254 IF (flag != FALSE) 255 THEN 256 CALL getbits( 257 neededBits = LEN_MMIX_IDX, 258 pInputStream = pInputStream ) 259 MODIFYING( pInputStream ) 260 RETURNING( temp = returnValue ) 261 262 pScratchPCE->matrix_mix.ele_tag = temp; 263 264 CALL getbits( 265 neededBits = LEN_PSUR_ENAB, 266 pInputStream = pInputStream ) 267 MODIFYING( pInputStream ) 268 RETURNING( temp = returnValue ) 269 270 pScratchPCE->matrix_mix.pseudo_enab = temp; 271 272 ENDIF 273 274 275 CALL get_ele_list( 276 pElementList = &pScratchPCE->front, 277 pInputStream = pInputStream, 278 enableCPE = TRUE ) 279 MODIFYING( pInputStream ) 280 MODIFYING( pScratchPCE->front ) 281 RETURNING( nothing ) 282 283 CALL get_ele_list( 284 pElementList = &pScratchPCE->side, 285 pInputStream = pInputStream, 286 enableCPE = TRUE ) 287 MODIFYING( pInputStream ) 288 MODIFYING( pScratchPCE->side ) 289 RETURNING( nothing ) 290 291 CALL get_ele_list( 292 pElementList = &pScratchPCE->back, 293 pInputStream = pInputStream, 294 enableCPE = TRUE ) 295 MODIFYING( pInputStream ) 296 MODIFYING( pScratchPCE->back ) 297 RETURNING( nothing ) 298 299 CALL get_ele_list( 300 pElementList = &pScratchPCE->lfe, 301 pInputStream = pInputStream, 302 enableCPE = FALSE ) 303 MODIFYING( pInputStream ) 304 MODIFYING( pScratchPCE->lfe ) 305 RETURNING( nothing ) 306 307 CALL get_ele_list( 308 pElementList = &pScratchPCE->data, 309 pInputStream = pInputStream, 310 enableCPE = FALSE ) 311 MODIFYING( pInputStream ) 312 MODIFYING( pScratchPCE->data ) 313 RETURNING( nothing ) 314 315 CALL get_ele_list( 316 pElementList = &pScratchPCE->coupling, 317 pInputStream = pInputStream, 318 enableCPE = TRUE ) 319 MODIFYING( pInputStream ) 320 MODIFYING( pScratchPCE->coupling ) 321 RETURNING( nothing ) 322 323 324 CALL byte_align( 325 pInputStream = pInputStream ) 326 MODIFYING( pInputStream ) 327 RETURNING( nothing ) 328 329 CALL getbits( 330 neededBits = LEN_COMMENT_BYTES, 331 pInputStream = pInputStream ) 332 MODIFYING( pInputStream ) 333 RETURNING( numChars = returnValue ) 334 335 FOR (i = numChars; i > 0; i--) 336 337 CALL getbits( 338 neededBits = LEN_COMMENT_BYTES, 339 pInputStream = pInputStream ) 340 MODIFYING( pInputStream ) 341 RETURNING( nothing ) 342 343 ENDFOR 344 345 IF (pVars->current_program < 0) 346 THEN 347 pVars->current_program = tag; 348 ENDIF 349 350 351 IF (tag == pVars->current_program) 352 THEN 353 354 CALL pv_memcpy( 355 to = &pVars->prog_config, 356 from = pScratchPCE, 357 n = sizeof(ProgConfig)) 358 MODIFYING( pVars->prog_config ) 359 RETURNING( nothing ) 360 361 CALL set_mc_info( 362 pMC_Info = &pVars->mc_info, 363 objectType = pVars->prog_config.profile + 1, 364 samplin_rate_idx = pVars->prog_config.sampling_rate_idx, 365 tag = pVars->prog_config.front.ele_tag[0], 366 is_cpe = pVars->prog_config.front.ele_is_cpe[0], 367 pWinSeqInfo = pVars->winmap, 368 pSfbwidth128 = pVars->SFBWidth128) 369 MODIFYING( pVars->mc_info ) 370 MODIFYING( pVars->winmap ) 371 MODIFYING( pVars->SFBWidth128 ) 372 RETURN( status = return_value ) 373 374 ENDIF 375 376 MODIFY( pVars->mc_info ) 377 MODIFY( pVars->winmap ) 378 MODIFY( pVars->SFBWidth128 ) 379 RETURN (status) 380 381 ------------------------------------------------------------------------------ 382 RESOURCES USED 383 When the code is written for a specific target processor the 384 the resources used should be documented below. 385 386 STACK USAGE: [stack count for this module] + [variable to represent 387 stack usage for each subroutine called] 388 389 where: [stack usage variable] = stack usage for [subroutine 390 name] (see [filename].ext) 391 392 DATA MEMORY USED: x words 393 394 PROGRAM MEMORY USED: x words 395 396 CLOCK CYCLES: [cycle count equation for this module] + [variable 397 used to represent cycle count for each subroutine 398 called] 399 400 where: [cycle count variable] = cycle count for [subroutine 401 name] (see [filename].ext) 402 403 ------------------------------------------------------------------------------ 404 */ 405 406 407 /*---------------------------------------------------------------------------- 408 ; INCLUDES 409 ----------------------------------------------------------------------------*/ 410 #include "pv_audio_type_defs.h" 411 #include "s_bits.h" 412 #include "s_elelist.h" 413 #include "s_tdec_int_file.h" 414 #include "s_tdec_int_chan.h" 415 #include "e_progconfigconst.h" 416 #include "ibstream.h" 417 #include "get_ele_list.h" 418 #include "aac_mem_funcs.h" 419 #include "set_mc_info.h" 420 #include "get_prog_config.h" 421 422 /*---------------------------------------------------------------------------- 423 ; MACROS 424 ; Define module specific macros here 425 ----------------------------------------------------------------------------*/ 426 427 /*---------------------------------------------------------------------------- 428 ; DEFINES 429 ; Include all pre-processor statements here. Include conditional 430 ; compile variables also. 431 ----------------------------------------------------------------------------*/ 432 433 /*---------------------------------------------------------------------------- 434 ; LOCAL FUNCTION DEFINITIONS 435 ; Function Prototype declaration 436 ----------------------------------------------------------------------------*/ 437 438 /*---------------------------------------------------------------------------- 439 ; LOCAL VARIABLE DEFINITIONS 440 ; Variable declaration - defined here and used outside this module 441 ----------------------------------------------------------------------------*/ 442 443 /*---------------------------------------------------------------------------- 444 ; EXTERNAL FUNCTION REFERENCES 445 ; Declare functions defined elsewhere and referenced in this module 446 ----------------------------------------------------------------------------*/ 447 448 /*---------------------------------------------------------------------------- 449 ; EXTERNAL VARIABLES REFERENCES 450 ; Declare variables used in this module but defined elsewhere 451 ----------------------------------------------------------------------------*/ 452 453 Int get_prog_config( 454 tDec_Int_File *pVars, 455 ProgConfig *pScratchPCE) 456 { 457 Int i; 458 UInt tag; 459 Int numChars; 460 UInt temp; 461 Bool flag; 462 Int status = SUCCESS; 463 BITS *pInputStream = &(pVars->inputStream); 464 465 466 /* 467 * The tag is used at the very end to see if this PCE is 468 * the one to be used. Otherwise it does not need to be saved for the 469 * the simple configurations to be used in this version of an AAC 470 * decoder. 471 * 472 * All of the bits of this PCE must be read even if this PCE will not 473 * be used. They are read into a temporary PCE, then later it is decided 474 * whether to keep this PCE. 475 * 476 * To allow quick removal of the fields from the ProgConfig structure 477 * that will probably not be used at a later date, 478 * while still advancing the bitstream pointer,the return value of 479 * getbits is saved into a temporary variable, then transfered to 480 * the structure item. 481 */ 482 tag = 483 get9_n_lessbits( 484 LEN_TAG, 485 pInputStream); 486 487 pScratchPCE->profile = 488 get9_n_lessbits( 489 LEN_PROFILE, 490 pInputStream); 491 492 pScratchPCE->sampling_rate_idx = 493 get9_n_lessbits( 494 LEN_SAMP_IDX, 495 pInputStream); 496 497 if (!pVars->adif_test && pScratchPCE->sampling_rate_idx != pVars->prog_config.sampling_rate_idx) 498 { 499 /* rewind the pointer as implicit channel configuration maybe the case */ 500 pInputStream->usedBits -= (LEN_TAG + LEN_PROFILE + LEN_SAMP_IDX); 501 502 return (1); /* mismatch cannot happen */ 503 } 504 505 506 /* 507 * Retrieve the number of element lists for each of 508 * front, side, back, lfe, data, and coupling. 509 * 510 * For two-channel stereo or mono, only the data in the front needs 511 * to be saved. However, ALL fields need to be skipped over in some 512 * fashion. Also, the number of elements needs to be temporarily saved 513 * to call get_ele_list(). If that function was changed to pass in 514 * the number of points to be read, the memory set aside inside the 515 * ProgConfig structure could be removed. 516 */ 517 518 /* 519 * The next six function calls could be combined into one, then use 520 * shifts and masks to retrieve the individual fields. 521 */ 522 temp = 523 get9_n_lessbits( 524 LEN_NUM_ELE, 525 pInputStream); 526 527 pScratchPCE->front.num_ele = temp; 528 529 /* Needed only to read in the element list. */ 530 temp = 531 get9_n_lessbits( 532 LEN_NUM_ELE, 533 pInputStream); 534 535 pScratchPCE->side.num_ele = temp; 536 537 /* Needed only to read in the element list. */ 538 temp = 539 get9_n_lessbits( 540 LEN_NUM_ELE, 541 pInputStream); 542 543 pScratchPCE->back.num_ele = temp; 544 545 /* Needed only to read in the element list. */ 546 temp = 547 get9_n_lessbits( 548 LEN_NUM_LFE, 549 pInputStream); 550 551 pScratchPCE->lfe.num_ele = temp; 552 553 /* Needed only to read in the element list. */ 554 temp = 555 get9_n_lessbits( 556 LEN_NUM_DAT, 557 pInputStream); 558 pScratchPCE->data.num_ele = temp; 559 560 /* Needed only to read in the element list. */ 561 temp = 562 get9_n_lessbits( 563 LEN_NUM_CCE, 564 pInputStream); 565 566 pScratchPCE->coupling.num_ele = temp; 567 568 /* 569 * Read in mix down data. 570 * 571 * Whether these fields can be removed and have proper operation 572 * will be determined at a later date. 573 */ 574 575 /* Read presence of mono_mix */ 576 flag = 577 get1bits(/* LEN_MIX_PRES,*/ 578 pInputStream); 579 580 pScratchPCE->mono_mix.present = flag; 581 582 if (flag != FALSE) 583 { 584 temp = 585 get9_n_lessbits( 586 LEN_TAG, 587 pInputStream); 588 589 pScratchPCE->mono_mix.ele_tag = temp; 590 591 } /* end if (flag != FALSE) */ 592 593 /* Read presence of stereo mix */ 594 flag = 595 get1bits(/* LEN_MIX_PRES,*/ 596 pInputStream); 597 598 pScratchPCE->stereo_mix.present = flag; 599 600 if (flag != FALSE) 601 { 602 temp = 603 get9_n_lessbits( 604 LEN_TAG, 605 pInputStream); 606 607 pScratchPCE->stereo_mix.ele_tag = temp; 608 609 } /* end if (flag != FALSE) */ 610 611 /* Read presence of matrix mix */ 612 flag = 613 get1bits(/* LEN_MIX_PRES,*/ 614 pInputStream); 615 616 pScratchPCE->matrix_mix.present = flag; 617 618 if (flag != FALSE) 619 { 620 temp = 621 get9_n_lessbits( 622 LEN_MMIX_IDX, 623 pInputStream); 624 625 pScratchPCE->matrix_mix.ele_tag = temp; 626 627 temp = 628 get1bits(/* LEN_PSUR_ENAB,*/ 629 pInputStream); 630 631 pScratchPCE->matrix_mix.pseudo_enab = temp; 632 633 } /* end if (flag != FALSE) */ 634 635 /* 636 * Get each of the element lists. Only the front information will be 637 * used for the PV decoder, but the usedBits field of pInputStream must 638 * be advanced appropriately. 639 * 640 * This could be optimized by advancing the bit stream for the 641 * elements that do not need to be read. 642 */ 643 get_ele_list( 644 &pScratchPCE->front, 645 pInputStream, 646 TRUE); 647 648 get_ele_list( 649 &pScratchPCE->side, 650 pInputStream, 651 TRUE); 652 653 get_ele_list( 654 &pScratchPCE->back, 655 pInputStream, 656 TRUE); 657 658 get_ele_list( 659 &pScratchPCE->lfe, 660 pInputStream, 661 FALSE); 662 663 get_ele_list( 664 &pScratchPCE->data, 665 pInputStream, 666 FALSE); 667 668 get_ele_list( 669 &pScratchPCE->coupling, 670 pInputStream, 671 TRUE); 672 673 /* 674 * The standard requests a byte alignment before reading in the 675 * comment. This can be done because LEN_COMMENT_BYTES == 8. 676 */ 677 byte_align(pInputStream); 678 679 numChars = 680 get9_n_lessbits( 681 LEN_COMMENT_BYTES, pInputStream); 682 683 /* 684 * Ignore the comment - it requires 65 bytes to store (or worse on DSP). 685 * If this field is restored, make sure to append a trailing '\0' 686 */ 687 for (i = numChars; i > 0; i--) 688 { 689 pScratchPCE->comments[i] = (Char) get9_n_lessbits(LEN_BYTE, 690 pInputStream); 691 692 } /* end for */ 693 694 if (pVars->current_program < 0) 695 { 696 /* 697 * If this is the first PCE, it becomes the current, regardless of 698 * its tag number. 699 */ 700 pVars->current_program = tag; 701 702 } /* end if (pVars->current_program < 0) */ 703 704 705 if (tag == (UInt)pVars->current_program) 706 { 707 /* 708 * This branch is reached under two conditions: 709 * 1) This is the first PCE found, it was selected in the above if 710 * block. In all encoders found thus far, the tag value has been 711 * zero. 712 * 2) A PCE has been sent by the encoder with a tag that matches the 713 * the first one sent. It will then be re-read. No encoder found 714 * thus far re-sends a PCE, when looking at ADIF files. 715 * 716 * Regardless, the temporary PCE will now be copied into the 717 * the one official program configuration. 718 */ 719 pv_memcpy( 720 &pVars->prog_config, 721 pScratchPCE, 722 sizeof(ProgConfig)); 723 724 /* enter configuration into MC_Info structure */ 725 status = 726 set_mc_info( 727 &pVars->mc_info, 728 (tMP4AudioObjectType)(pVars->prog_config.profile + 1), 729 pVars->prog_config.sampling_rate_idx, 730 pVars->prog_config.front.ele_tag[0], 731 pVars->prog_config.front.ele_is_cpe[0], 732 pVars->winmap, 733 pVars->SFBWidth128); 734 735 } /* end if (tag == pVars->current_program) */ 736 737 return (status); 738 } 739 740