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/hufffac.c 21 Funtions: 22 hufffac 23 24------------------------------------------------------------------------------ 25 REVISION HISTORY 26 27 Description: Modified from original shareware code 28 29 Description: Modified to pass variables by reference to eliminate use 30 of global variables. 31 32 Description: (1) Modified with new templates, 33 (2) Modified variable names for clarity 34 (3) adjusted variables of "for loop" 35 (4) eliminated multiple returns, use return valid 36 37 Description: (1) Change return logic: 0 if success, 1 if error 38 (2) Define SectInfo structure to store section codebook index 39 and section boundary 40 (3) Substitute "switch" with "if- else if" 41 (4) move BITS *pInputStream to second pass-in parameter 42 (5) pass in huffBookUsed[] to save stack size 43 44 Description: (1) Remove pass in parameter Hcb pBook 45 46 Description: Use binary tree search in decode_huff_cw_binary 47 48 Description: Use decode_huff_scl function. 49 50 Who: Date: MM/DD/YYYY 51 Description: 52 53------------------------------------------------------------------------------ 54 INPUT AND OUTPUT DEFINITIONS 55 56 Inputs: 57 58 *pFrameInfo = pointer to structure that holds information 59 of each Frame. type FrameInfo 60 61 *pInputStream = pointer to input bitstream. type BITS 62 63 *pGroup = pointer to array that contains the index of the first 64 window in each group, type UChar 65 66 nsect = number of sections to be decoded. type Int 67 68 *pSect = pointer to structure array that contains the huffman 69 codebook index and section boundary for each section, 70 type SectInfo 71 72 global_gain = initial value for "DPCM encoded" scalefactors and noise 73 energy, type Int 74 75 *pFactors = pointer to array that stores the decoded scalefactors, 76 intensity position or noise energy, type Int 77 78 huffBookUsed = array that will hold the huffman codebook index for 79 each sfb, type Int 80 81 *pBook = pointer to structure that contains the huffman codebook 82 information, such as dimension, Largest Absolute Value 83 (LAV) of each huffman codebook, etc. type Hcb 84 85 86 Local Stores/Buffers/Pointers Needed: None 87 88 Global Stores/Buffers/Pointers Needed: None 89 90 Outputs: 91 0 if success 92 1 if error 93 94 Pointers and Buffers Modified: 95 96 Int *pFactors contains the newly decoded scalefactors and/or 97 intensity position and/or noise energy level 98 99 Local Stores Modified: 100 101 Global Stores Modified: 102 103------------------------------------------------------------------------------ 104 FUNCTION DESCRIPTION 105 106 This function first reads the Huffman codebook index of all sections within 107 one Frame. Then, depending on the huffman codebook index of each section, 108 the function decodes the scalefactors, and/or intensity positions 109 (INTENSITY_HCB, INTENSITY_HCB2), and/or noise energy (NOISE_HCB) 110 for every scalefactor band in each section. 111 The function returns 0 upon successful decoding, returns 1 if error. 112 113------------------------------------------------------------------------------ 114 REQUIREMENTS 115 116 This function should replace the content of the array pFactors with the 117 decoded scalefactors and/or intensity positions and/or noise energy 118 119------------------------------------------------------------------------------ 120 REFERENCES 121 122 (1) MPEG-2 NBC Audio Decoder 123 "This software module was originally developed by AT&T, Dolby 124 Laboratories, Fraunhofer Gesellschaft IIS in the course of development 125 of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and 126 3. This software module is an implementation of a part of one or more 127 MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4 128 Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio 129 standards free license to this software module or modifications thereof 130 for use in hardware or software products claiming conformance to the 131 MPEG-2 NBC/MPEG-4 Audio standards. Those intending to use this software 132 module in hardware or software products are advised that this use may 133 infringe existing patents. The original developer of this software 134 module and his/her company, the subsequent editors and their companies, 135 and ISO/IEC have no liability for use of this software module or 136 modifications thereof in an implementation. Copyright is not released 137 for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original 138 developer retains full right to use the code for his/her own purpose, 139 assign or donate the code to a third party and to inhibit third party 140 from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products. 141 This copyright notice must be included in all copies or derivative 142 works." 143 Copyright(c)1996. 144 145 (2) ISO/IEC 14496-3: 1999(E) 146 Subpart 4 p72-73 (scalefactors) 147 p76 (decoding) 148 p78 (Table 4.6.1, Table 4.6.2) 149 p93-94 (INTENSITY_HCB) 150 p123 (NOISE_HCB) 151 152------------------------------------------------------------------------------ 153 PSEUDO-CODE 154 155 status = SUCCESS; 156 157 CALL pv_memset(pHuffBookUsed, ZERO_HCB, MAXBANDS*sizeof(*pHuffBookUsed)); 158 159 CALL pv_memset(pFactors, ZERO_HCB, MAXBANDS*sizeof(*pFactors)); 160 161 sect_start = 0; 162 163 FOR(sect_idx = nsect; sect_idx > 0; sect_idx--) 164 { 165 sect_cb = pSect->sect_cb; 166 sect_end = pSect->sect_end; 167 pSect++; 168 169 CALL pv_memset( 170 &pHuffBookUsed[sect_start], 171 sect_cb, 172 (sect_end - sect_start)); 173 174 } 175 ENDFOR 176 177 fac = global_gain; 178 is_pos = 0; 179 noise_nrg = global_gain - NOISE_OFFSET; 180 181 pTable = pBook[BOOKSCL].pTable; 182 group_win = 0; 183 group_end = 0; 184 185 WHILE((group_end < pFrameInfo->num_win)&&(status == SUCCESS)) 186 { 187 nsfb_win = pFrameInfo->sfb_per_win[group_end]; 188 group_end = *pGroup++; 189 190 FOR(sfb = 0; sfb < nsfb_win; sfb++) 191 { 192 IF ((pHuffBookUsed[sfb] > 0)&&(pHuffBookUsed[sfb] < BOOKSCL)) 193 { 194 cw_index = CALL decode_huff_cw_binary(pTable, pInputStream); 195 196 fac += cw_index - MIDFAC; 197 198 IF((fac >= 2*TEXP) || (fac < 0)) 199 { 200 status = 1; 201 } 202 ELSE 203 { 204 pFactors[sfb] = fac; 205 } 206 ENDIF (fac) 207 208 } 209 ELSE IF (pHuffBookUsed[sfb] == ZERO_HCB) 210 { 211 do nothing; 212 } 213 214 ELSE IF ((pHuffBookUsed[sfb] == INTENSITY_HCB)|| 215 (pHuffBookUsed[sfb] == INTENSITY_HCB2)) 216 { 217 cw_index = CALL decode_huff_cw_binary(pTable, pInputStream); 218 219 is_pos += cw_index - MIDFAC; 220 pFactors[sfb] = is_pos; 221 } 222 223 ELSE IF (pHuffBookUsed[sfb] == NOISE_HCB) 224 { 225 IF (noise_pcm_flag == TRUE) 226 { 227 noise_pcm_flag = FALSE; 228 dpcm_noise_nrg = CALL getbits( 229 NOISE_PCM_BITS, 230 pInputStream); 231 232 dpcm_noise_nrg -= NOISE_PCM_OFFSET; 233 } 234 ELSE 235 { 236 dpcm_noise_nrg = CALL decode_huff_cw_binary( 237 pTable, 238 pInputStream); 239 240 dpcm_noise_nrg -= MIDFAC; 241 } 242 ENDIF (noise_pcm_flag) 243 244 noise_nrg += dpcm_noise_nrg; 245 pFactors[sfb] = noise_nrg; 246 } 247 248 ELSE IF (pHuffBookUsed[sfb] == BOOKSCL) 249 { 250 status = 1; 251 } 252 ENDIF (pHuffBookUsed[sfb]) 253 254 } 255 ENDFOR (sfb) 256 257 IF (pFrameInfo->islong == FALSE) 258 { 259 260 FOR(group_win++; group_win < group_end; group_win++) 261 { 262 FOR (sfb=0; sfb < nsfb_win; sfb++) 263 { 264 pFactors[sfb + nsfb_win] = pFactors[sfb]; 265 } 266 ENDFOR 267 268 pFactors += nsfb_win; 269 } 270 ENDFOR 271 272 } 273 ENDIF (pFrameInfo) 274 275 pHuffBookUsed += nsfb_win; 276 pFactors += nsfb_win; 277 278 } 279 ENDWHILE (group_end) 280 281 return status; 282 283------------------------------------------------------------------------------ 284 RESOURCES USED 285 When the code is written for a specific target processor the 286 the resources used should be documented below. 287 288 STACK USAGE: [stack count for this module] + [variable to represent 289 stack usage for each subroutine called] 290 291 where: [stack usage variable] = stack usage for [subroutine 292 name] (see [filename].ext) 293 294 DATA MEMORY USED: x words 295 296 PROGRAM MEMORY USED: x words 297 298 CLOCK CYCLES: [cycle count equation for this module] + [variable 299 used to represent cycle count for each subroutine 300 called] 301 302 where: [cycle count variable] = cycle count for [subroutine 303 name] (see [filename].ext) 304 305------------------------------------------------------------------------------ 306*/ 307 308 309/*---------------------------------------------------------------------------- 310; INCLUDES 311----------------------------------------------------------------------------*/ 312#include "pv_audio_type_defs.h" 313#include "aac_mem_funcs.h" /* pv_memset */ 314#include "s_frameinfo.h" 315#include "s_bits.h" 316#include "s_sectinfo.h" 317#include "s_huffman.h" 318#include "ibstream.h" 319 320#include "hcbtables.h" 321#include "e_huffmanconst.h" 322#include "e_infoinitconst.h" 323#include "huffman.h" 324 325/*---------------------------------------------------------------------------- 326; MACROS 327; Define module specific macros here 328----------------------------------------------------------------------------*/ 329 330/*---------------------------------------------------------------------------- 331; DEFINES 332; Include all pre-processor statements here. Include conditional 333; compile variables also. 334----------------------------------------------------------------------------*/ 335 336/*---------------------------------------------------------------------------- 337; LOCAL FUNCTION DEFINITIONS 338; Function Prototype declaration 339----------------------------------------------------------------------------*/ 340 341/*---------------------------------------------------------------------------- 342; LOCAL STORE/BUFFER/POINTER DEFINITIONS 343; Variable declaration - defined here and used outside this module 344----------------------------------------------------------------------------*/ 345 346/*---------------------------------------------------------------------------- 347; EXTERNAL FUNCTION REFERENCES 348; Declare functions defined elsewhere and referenced in this module 349----------------------------------------------------------------------------*/ 350 351/*---------------------------------------------------------------------------- 352; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 353; Declare variables used in this module but defined elsewhere 354----------------------------------------------------------------------------*/ 355 356/*---------------------------------------------------------------------------- 357; FUNCTION CODE 358----------------------------------------------------------------------------*/ 359Int hufffac( 360 FrameInfo *pFrameInfo, 361 BITS *pInputStream, 362 Int *pGroup, /* may be changed to Int */ 363 Int nsect, 364 SectInfo *pSect, /* may be changed to Int */ 365 Int global_gain, 366 Int *pFactors, 367 Int huffBookUsed[]) 368{ 369 Int sect_idx; 370 Int group_end; /* index of 1st window in next group */ 371 Int group_win; /* window index within group */ 372 Int cw_index; /* huff codeword index */ 373 Int nsfb_win; /* # of scfbands per window */ 374 Int sfb; /* scalefactor band index */ 375 Int sect_cb; /* huff codebook # for each section */ 376 Int fac; /* decoded scf */ 377 Int is_pos; /* intensity stereo position */ 378 Int noise_pcm_flag = TRUE; /* first PNS sfb */ 379 Int dpcm_noise_nrg; /* dpcm noise energy */ 380 Int noise_nrg; /* noise energy */ 381 Int status = SUCCESS; /* status of decoding */ 382 Int *pHuffBookUsed = &huffBookUsed[0]; 383 384 385 pv_memset(pFactors, 386 ZERO_HCB, 387 MAXBANDS*sizeof(*pFactors)); 388 389 390 if (nsect) 391 { 392 /* read section length and codebook */ 393 394 if (nsect == 1) /* long window */ 395 { 396 sect_cb = pSect->sect_cb; /* codebook for this section */ 397 398 /* all sfbs in one section share the same codebook */ 399 400 for (sfb = pSect->sect_end >> 2; sfb != 0; sfb--) 401 { 402 *(pHuffBookUsed++) = sect_cb; 403 *(pHuffBookUsed++) = sect_cb; 404 *(pHuffBookUsed++) = sect_cb; 405 *(pHuffBookUsed++) = sect_cb; 406 } 407 for (sfb = pSect->sect_end & 3; sfb != 0; sfb--) 408 { 409 *(pHuffBookUsed++) = sect_cb; 410 } 411 412 } 413 else /* short */ 414 { 415 Int sect_start = 0; /* start index of sfb for each section */ 416 for (sect_idx = nsect; sect_idx > 0; sect_idx--) 417 { 418 sect_cb = pSect->sect_cb; /* codebook for this section */ 419 420 /* all sfbs in one section share the same codebook */ 421 for (sfb = sect_start; sfb < pSect->sect_end; sfb++) 422 { 423 pHuffBookUsed[sfb] = sect_cb; 424 } 425 426 pSect++; 427 sect_start = sfb; 428 429 } /* for (sect_idx) */ 430 } 431 } 432 else 433 { 434 /* clear array for the case of max_sfb == 0 */ 435 pv_memset(pHuffBookUsed, 436 ZERO_HCB, 437 MAXBANDS*sizeof(*pHuffBookUsed)); 438 } 439 440 pHuffBookUsed = &huffBookUsed[0]; 441 442 /* scale factors and noise energy are dpcm relative to global gain 443 * intensity positions are dpcm relative to zero 444 */ 445 fac = global_gain; 446 is_pos = 0; 447 noise_nrg = global_gain - NOISE_OFFSET; 448 449 /* get scale factors, 450 * use reserved Table entry = 12, see reference (2) p78 Table 4.6.2 451 */ 452 group_win = 0; 453 group_end = 0; 454 455 456 /* group by group decoding scalefactors and/or noise energy 457 * and/or intensity position 458 */ 459 while ((group_end < pFrameInfo->num_win) && (status == SUCCESS)) 460 { 461 nsfb_win = pFrameInfo->sfb_per_win[group_end]; 462 group_end = *pGroup++; /* index of 1st window in next group */ 463 464 /* decode scf in first window of each group */ 465 466 for (sfb = 0; sfb < nsfb_win; sfb++) 467 { 468 469 switch (pHuffBookUsed[sfb]) 470 { 471 case ZERO_HCB: 472 break; 473 case INTENSITY_HCB: 474 case INTENSITY_HCB2: 475 /* intensity books */ 476 /* decode intensity position */ 477 cw_index = decode_huff_scl(pInputStream); 478 479 is_pos += cw_index - MIDFAC; 480 pFactors[sfb] = is_pos; 481 break; 482 case NOISE_HCB: 483 /* noise books */ 484 /* decode noise energy */ 485 if (noise_pcm_flag == TRUE) 486 { 487 noise_pcm_flag = FALSE; 488 dpcm_noise_nrg = get9_n_lessbits(NOISE_PCM_BITS, 489 pInputStream); 490 491 dpcm_noise_nrg -= NOISE_PCM_OFFSET; 492 } 493 else 494 { 495 dpcm_noise_nrg = decode_huff_scl(pInputStream); 496 497 dpcm_noise_nrg -= MIDFAC; 498 } /* if (noise_pcm_flag) */ 499 500 noise_nrg += dpcm_noise_nrg; 501 pFactors[sfb] = noise_nrg; 502 break; 503 case BOOKSCL: 504 status = 1; /* invalid books */ 505 sfb = nsfb_win; /* force out */ 506 break; 507 default: 508 /* spectral books */ 509 /* decode scale factors */ 510 cw_index = decode_huff_scl(pInputStream); 511 512 fac += cw_index - MIDFAC; /* 1.5 dB */ 513 if ((fac >= 2*TEXP) || (fac < 0)) 514 { 515 status = 1; /* error, MUST 0<=scf<256, Ref. p73 */ 516 } 517 else 518 { 519 pFactors[sfb] = fac; /* store scf */ 520 } /* if (fac) */ 521 } 522 523 } /* for (sfb=0), first window decode ends */ 524 525 /* expand scf to other windows in the same group */ 526 if (pFrameInfo->islong == FALSE) 527 { 528 529 for (group_win++; group_win < group_end; group_win++) 530 { 531 for (sfb = 0; sfb < nsfb_win; sfb++) 532 { 533 pFactors[sfb + nsfb_win] = pFactors[sfb]; 534 } 535 pFactors += nsfb_win; 536 } 537 538 } /* if (pFrameInfo->islong), one group decode ends */ 539 540 541 /* points to next group */ 542 pHuffBookUsed += nsfb_win; 543 pFactors += nsfb_win; 544 545 } /* while (group_end), all groups decode end */ 546 547 return status; 548 549} /* hufffac */ 550 551