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: pns_intensity_right.c 21 22 ------------------------------------------------------------------------------ 23 INPUT AND OUTPUT DEFINITIONS 24 25 Inputs: 26 27 hasmask = mask status for the frame. Enumerated. 28 29 pFrameInfo = Pointer to structure that holds information about each group. 30 (long block flag, number of windows, scalefactor bands 31 per group, etc.) 32 [const pFrameInfo * const] 33 34 group = Array that contains indexes of the 35 first window in the next group. 36 [const Int *, length num_win] 37 38 mask_map = Array that denotes whether M/S stereo is turned on for 39 each grouped scalefactor band. 40 [const Int *, length MAX_SFB] 41 42 codebook_map = Array that denotes which Huffman codebook was used for 43 the encoding of each grouped scalefactor band. 44 [const Int *, length MAX_SFB] 45 46 factorsL = Array of grouped scalefactors for left chan. 47 [const Int *, length MAX_SFB] 48 49 factorsR = Array of scalefactors for right chan. 50 [const Int *, length MAX_SFB] 51 52 sfb_prediction_used = Flag that denotes the activation of long term prediction 53 on a per-scalefactor band, non-grouped basis. 54 [const Int *, length MAX_SFB] 55 56 ltp_data_present = Flag that indicates whether LTP is enbaled for this frame. 57 [const Bool] 58 59 coefLeft = Array containing the fixed-point spectral coefficients 60 for the left channel. 61 [Int32 *, length 1024] 62 63 coefRight = Array containing the fixed-point spectral coefficients 64 for the right channel. 65 [Int32 *, length 1024] 66 67 q_formatLeft = The Q-format for the left channel's fixed-point spectral 68 coefficients, on a per-scalefactor band, non-grouped basis. 69 [Int *, length MAX_SFB] 70 71 q_formatRight = The Q-format for the right channel's fixed-point spectral 72 coefficients, on a per-scalefactor band, non-grouped basis. 73 [Int *, length MAX_SFB] 74 75 pCurrentSeed = Pointer to the current seed for the random number 76 generator in the function gen_rand_vector(). 77 [Int32 * const] 78 79 Local Stores/Buffers/Pointers Needed: 80 None 81 82 Global Stores/Buffers/Pointers Needed: 83 None 84 85 Outputs: 86 None 87 88 Pointers and Buffers Modified: 89 coefLeft = Contains the new spectral information. 90 91 coefRight = Contains the new spectral information. 92 93 q_formatLeft = Q-format may be updated with changed to fixed-point 94 data in coefLeft. 95 96 q_formatRight = Q-format may be updated with changed to fixed-point 97 data in coefRight. 98 99 pCurrentSeed = Value pointed to by pCurrentSeed updated by calls 100 to gen_rand_vector(). 101 102 Local Stores Modified: 103 None 104 105 Global Stores Modified: 106 None 107 108 ------------------------------------------------------------------------------ 109 FUNCTION DESCRIPTION 110 111 This function steps through all of the scalefactor bands, looking for 112 either PNS or IS to be enabled on the right channel. 113 114 If the codebook used is >= NOISE_HCB, the code then checks for the use 115 of Huffman codebooks NOISE_HCB, INTENSITY_HCB, or INTENSITY_HCB2. 116 117 When a SFB utilizing the codebook NOISE_HCB is detected, a check is made to 118 see if M/S has also been enabled for that SFB. 119 120 If M/S is not enabled, the band's spectral information is filled with 121 scaled random data. The scaled random data is generated by the function 122 gen_rand_vector. This is done across all windows in the group. 123 124 If M/S is enabled, the band's spectral information is derived from the data 125 residing in the same band on the left channel. The information on the right 126 channel has independent scaling, so this is a bit more involved than a 127 direct copy of the information on the left channel. This is done by calling 128 the inline function pns_corr(). 129 130 When a SFB utilizing an intensity codebook is detected, the band's spectral 131 information is generated from the information on the left channel. 132 This is done across all windows in the group. M/S being enabled has the 133 effect of reversing the sign of the data on the right channel. This code 134 resides in the inline function intensity_right(). 135 136 ------------------------------------------------------------------------------ 137 REQUIREMENTS 138 139 140 ------------------------------------------------------------------------------ 141 REFERENCES 142 143 (1) ISO/IEC 14496-3:1999(E) 144 Part 3 145 Subpart 4.6.7.1 M/S stereo 146 Subpart 4.6.7.2.3 Decoding Process (Intensity Stereo) 147 Subpart 4.6.12.3 Decoding Process (PNS) 148 Subpart 4.6.2 ScaleFactors 149 150 (2) MPEG-2 NBC Audio Decoder 151 "This software module was originally developed by AT&T, Dolby 152 Laboratories, Fraunhofer Gesellschaft IIS in the course of development 153 of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and 154 3. This software module is an implementation of a part of one or more 155 MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4 156 Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio 157 standards free license to this software module or modifications thereof 158 for use in hardware or software products claiming conformance to the 159 MPEG-2 NBC/MPEG-4 Audio standards. Those intending to use this software 160 module in hardware or software products are advised that this use may 161 infringe existing patents. The original developer of this software 162 module and his/her company, the subsequent editors and their companies, 163 and ISO/IEC have no liability for use of this software module or 164 modifications thereof in an implementation. Copyright is not released 165 for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original 166 developer retains full right to use the code for his/her own purpose, 167 assign or donate the code to a third party and to inhibit third party 168 from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products. 169 This copyright notice must be included in all copies or derivative 170 works." 171 Copyright(c)1996. 172 173 ------------------------------------------------------------------------------ 174 PSEUDO-CODE 175 pCoefRight = coefRight; 176 pCoefLeft = coefLeft; 177 178 window_start = 0; 179 tot_sfb = 0; 180 start_indx = 0; 181 182 coef_per_win = pFrameInfo->coef_per_win[0]; 183 184 sfb_per_win = pFrameInfo->sfb_per_win[0]; 185 186 DO 187 pBand = pFrameInfo->win_sfb_top[window_start]; 188 189 partition = *pGroup; 190 pGroup = pGroup + 1; 191 192 band_start = 0; 193 194 wins_in_group = (partition - window_start); 195 196 FOR (sfb = sfb_per_win; sfb > 0; sfb--) 197 198 band_stop = *(pBand); 199 pBand = pBand + 1; 200 201 codebook = *(pCodebookMap); 202 pCodebookMap = pCodebookMap + 1; 203 204 mask_enabled = *(pMaskMap); 205 pMaskMap = pMaskMap + 1; 206 207 band_length = band_stop - band_start; 208 209 IF (codebook == NOISE_HCB) 210 211 sfb_prediction_used[tot_sfb] &= ltp_data_present; 212 213 IF (sfb_prediction_used[tot_sfb] == FALSE) 214 215 mask_enabled = mask_enabled AND hasmask; 216 217 IF (mask_enabled == FALSE) 218 219 pWindow_CoefR = &(pCoefRight[band_start]); 220 221 start_indx = tot_sfb; 222 223 FOR (win_indx = wins_in_group; 224 win_indx > 0; 225 win_indx--) 226 227 CALL 228 q_formatRight[start_indx] = 229 gen_rand_vector( 230 pWindow_CoefR, 231 band_length, 232 pCurrentSeed, 233 *(pFactorsRight)); 234 MODIFYING 235 pCoefRight[band_start] 236 RETURNING 237 q_formatRight[start_indx] 238 239 pWindow_CoefR += coef_per_win; 240 241 start_indx = start_indx + sfb_per_win; 242 243 ENDFOR 244 245 ELSE 246 CALL 247 pns_corr( 248 (*(pFactorsRight) - 249 *(pFactorsLeft) ), 250 coef_per_win, 251 sfb_per_win, 252 wins_in_group, 253 band_length, 254 q_formatLeft[tot_sfb], 255 &(q_formatRight[tot_sfb]), 256 &(pCoefLeft[band_start]), 257 &(pCoefRight[band_start])); 258 259 MODIFYING 260 pCoefRightt[band_start] 261 q_formatRight[tot_sfb] 262 RETURNING 263 NONE 264 ENDIF 265 266 ENDIF 267 268 ELSE IF (codebook >= INTENSITY_HCB2) 269 270 mask_enabled = mask_enabled AND hasmask; 271 272 CALL 273 intensity_right( 274 *(pFactorsRight), 275 coef_per_win, 276 sfb_per_win, 277 wins_in_group, 278 band_length, 279 codebook, 280 mask_enabled, 281 &(q_formatLeft[tot_sfb]), 282 &(q_formatRight[tot_sfb]), 283 &(pCoefLeft[band_start]), 284 &(pCoefRight[band_start])); 285 286 MODIFYING 287 pCoefRightt[band_start] 288 q_formatRight[tot_sfb] 289 RETURNING 290 NONE 291 292 ENDIF 293 294 band_start = band_stop; 295 296 tot_sfb = tot_sfb + 1; 297 298 ENDFOR 299 300 coef_per_win = coef_per_win * (wins_in_group); 301 302 wins_in_group = wins_in_group - 1; 303 304 tot_sfb = tot_sfb + sfb_per_win * wins_in_group; 305 pFactorsRight = pFactorsRight + sfb_per_win * wins_in_group; 306 pFactorsLeft = pFactorsLeft + sfb_per_win * wins_in_group; 307 308 pCoefRight = pCoefRight + coef_per_win; 309 pCoefLeft = pCoefLeft + coef_per_win; 310 311 window_start = partition; 312 313 WHILE (partition < pFrameInfo->num_win); 314 315 return; 316 317 ------------------------------------------------------------------------------ 318 RESOURCES USED 319 When the code is written for a specific target processor the 320 resources used should be documented below. 321 322 STACK USAGE: [stack count for this module] + [variable to represent 323 stack usage for each subroutine called] 324 325 where: [stack usage variable] = stack usage for [subroutine 326 name] (see [filename].ext) 327 328 DATA MEMORY USED: x words 329 330 PROGRAM MEMORY USED: x words 331 332 CLOCK CYCLES: [cycle count equation for this module] + [variable 333 used to represent cycle count for each subroutine 334 called] 335 336 where: [cycle count variable] = cycle count for [subroutine 337 name] (see [filename].ext) 338 339 ------------------------------------------------------------------------------ 340 */ 341 342 343 /*---------------------------------------------------------------------------- 344 ; INCLUDES 345 ----------------------------------------------------------------------------*/ 346 #include "pv_audio_type_defs.h" 347 #include "pns_intensity_right.h" 348 #include "e_huffmanconst.h" 349 #include "gen_rand_vector.h" 350 #include "intensity_right.h" 351 #include "pns_corr.h" 352 353 /*---------------------------------------------------------------------------- 354 ; MACROS 355 ; Define module specific macros here 356 ----------------------------------------------------------------------------*/ 357 358 /*---------------------------------------------------------------------------- 359 ; DEFINES 360 ; Include all pre-processor statements here. Include conditional 361 ; compile variables also. 362 ----------------------------------------------------------------------------*/ 363 364 /*---------------------------------------------------------------------------- 365 ; LOCAL FUNCTION DEFINITIONS 366 ; Function Prototype declaration 367 ----------------------------------------------------------------------------*/ 368 369 /*---------------------------------------------------------------------------- 370 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS 371 ; Variable declaration - defined here and used outside this module 372 ----------------------------------------------------------------------------*/ 373 374 /*---------------------------------------------------------------------------- 375 ; EXTERNAL FUNCTION REFERENCES 376 ; Declare functions defined elsewhere and referenced in this module 377 ----------------------------------------------------------------------------*/ 378 379 380 /*---------------------------------------------------------------------------- 381 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 382 ; Declare variables used in this module but defined elsewhere 383 ----------------------------------------------------------------------------*/ 384 385 /*---------------------------------------------------------------------------- 386 ; FUNCTION CODE 387 ----------------------------------------------------------------------------*/ 388 389 void pns_intensity_right( 390 const Int hasmask, 391 const FrameInfo * const pFrameInfo, 392 const Int group[], 393 const Bool mask_map[], 394 const Int codebook_map[], 395 const Int factorsL[], 396 const Int factorsR[], 397 Int sfb_prediction_used[], 398 const Bool ltp_data_present, 399 Int32 coefLeft[], 400 Int32 coefRight[], 401 Int q_formatLeft[MAXBANDS], 402 Int q_formatRight[MAXBANDS], 403 Int32 * const pCurrentSeed) 404 { 405 406 Int32 *pCoefRight; 407 Int32 *pWindow_CoefR; 408 409 Int32 *pCoefLeft; 410 411 Int tot_sfb; 412 Int start_indx; 413 Int sfb; 414 415 Int band_length; 416 Int band_start; 417 Int band_stop; 418 Int coef_per_win; 419 420 Int codebook; 421 Int partition; 422 Int window_start; 423 424 Int sfb_per_win; 425 Int wins_in_group; 426 Int win_indx; 427 428 const Int16 *pBand; 429 const Int *pFactorsLeft = factorsL; 430 const Int *pFactorsRight = factorsR; 431 const Int *pCodebookMap = codebook_map; 432 const Int *pGroup = group; 433 const Bool *pMaskMap = mask_map; 434 435 Bool mask_enabled; 436 437 pCoefRight = coefRight; 438 pCoefLeft = coefLeft; 439 440 window_start = 0; 441 tot_sfb = 0; 442 start_indx = 0; 443 444 /* 445 * Each window in the frame should have the same number of coef's, 446 * so coef_per_win is constant in all the loops 447 */ 448 coef_per_win = pFrameInfo->coef_per_win[0]; 449 450 /* 451 * Because the number of scalefactor bands per window should be 452 * constant for each frame, sfb_per_win can be determined outside 453 * of the loop. 454 * 455 * For 44.1 kHz sampling rate sfb_per_win = 14 for short windows 456 * sfb_per_win = 49 for long windows 457 */ 458 459 sfb_per_win = pFrameInfo->sfb_per_win[0]; 460 461 do 462 { 463 pBand = pFrameInfo->win_sfb_top[window_start]; 464 465 /*---------------------------------------------------------- 466 Partition is equal to the first window in the next group 467 468 { Group 0 }{ Group 1 }{ Group 2 }{Group 3} 469 [win 0][win 1][win 2][win 3][win 4][win 5][win 6][win 7] 470 471 pGroup[0] = 2 472 pGroup[1] = 5 473 pGroup[2] = 7 474 pGroup[3] = 8 475 -----------------------------------------------------------*/ 476 partition = *(pGroup++); 477 478 band_start = 0; 479 480 wins_in_group = (partition - window_start); 481 482 for (sfb = sfb_per_win; sfb > 0; sfb--) 483 { 484 /* band is offset table, band_stop is last coef in band */ 485 band_stop = *(pBand++); 486 487 codebook = *(pCodebookMap++); 488 489 mask_enabled = *(pMaskMap++); 490 491 /* 492 * When a tool utilizing sfb is found, apply the correct tool 493 * to that sfb in each window in the group 494 * 495 * Example... sfb[3] == NOISE_HCB 496 * 497 * [ Group 1 ] 498 * [win 0 ][win 1 ] 499 * [0][1][2][X][4][5][6][7][0][1][2][X][4][5][6][7] 500 * 501 * The for(sfb) steps through the sfb's 0-7 in win 0. 502 * 503 * Finding sfb[3]'s codebook == NOISE_HCB, the code 504 * steps through all the windows in the group (they share 505 * the same scalefactors) and replaces that sfb with noise. 506 */ 507 508 /* 509 * Experimental results suggest that ms_synt is the most 510 * commonly used tool, so check for it first. 511 * 512 */ 513 514 band_length = band_stop - band_start; 515 516 if (codebook == NOISE_HCB) 517 { 518 sfb_prediction_used[tot_sfb] &= ltp_data_present; 519 520 if (sfb_prediction_used[tot_sfb] == FALSE) 521 { 522 /* 523 * The branch and the logical AND interact in the 524 * following manner... 525 * 526 * mask_enabled == 0 hasmask == X -- gen_rand_vector 527 * mask_enabled == 1 hasmask == 1 -- pns_corr 528 * mask_enabled == 0 hasmask == 1 -- gen_rand_vector 529 * mask_enabled == 1 hasmask == 2 -- gen_rand_vector 530 * mask_enabled == 0 hasmask == 2 -- gen_rand_vector 531 */ 532 533 mask_enabled &= hasmask; 534 535 if (mask_enabled == FALSE) 536 { 537 pWindow_CoefR = &(pCoefRight[band_start]); 538 539 /* 540 * Step through all the windows in this group, 541 * replacing this band in each window's 542 * spectrum with random noise 543 */ 544 start_indx = tot_sfb; 545 546 for (win_indx = wins_in_group; 547 win_indx > 0; 548 win_indx--) 549 { 550 551 /* generate random noise */ 552 q_formatRight[start_indx] = 553 gen_rand_vector( 554 pWindow_CoefR, 555 band_length, 556 pCurrentSeed, 557 *(pFactorsRight)); 558 559 pWindow_CoefR += coef_per_win; 560 561 start_indx += sfb_per_win; 562 } 563 564 } 565 else 566 { 567 pns_corr( 568 (*(pFactorsRight) - 569 *(pFactorsLeft)), 570 coef_per_win, 571 sfb_per_win, 572 wins_in_group, 573 band_length, 574 q_formatLeft[tot_sfb], 575 &(q_formatRight[tot_sfb]), 576 &(pCoefLeft[band_start]), 577 &(pCoefRight[band_start])); 578 579 } /* if (mask_map == FALSE) */ 580 581 } /* if (sfb_prediction_used[tot_sfb] == FALSE) */ 582 583 } /* if (codebook == 0) */ 584 else if (codebook >= INTENSITY_HCB2) 585 { 586 /* 587 * The logical AND flags the inversion of intensity 588 * in the following manner. 589 * 590 * mask_enabled == X hasmask == 0 -- DO NOT INVERT 591 * mask_enabled == 0 hasmask == X -- DO NOT INVERT 592 * mask_enabled == 1 hasmask == 1 -- DO INVERT 593 * mask_enabled == 0 hasmask == 1 -- DO NOT INVERT 594 * mask_enabled == 1 hasmask == 2 -- DO NOT INVERT 595 * mask_enabled == 0 hasmask == 2 -- DO NOT INVERT 596 */ 597 598 mask_enabled &= hasmask; 599 600 intensity_right( 601 *(pFactorsRight), 602 coef_per_win, 603 sfb_per_win, 604 wins_in_group, 605 band_length, 606 codebook, 607 mask_enabled, 608 &(q_formatLeft[tot_sfb]), 609 &(q_formatRight[tot_sfb]), 610 &(pCoefLeft[band_start]), 611 &(pCoefRight[band_start])); 612 613 } /* END else codebook must be INTENSITY_HCB or ... */ 614 615 band_start = band_stop; 616 617 tot_sfb++; 618 619 pFactorsLeft++; 620 pFactorsRight++; 621 622 } /* for (sfb) */ 623 624 /* 625 * Increment pCoefRight and pCoefLeft by 626 * coef_per_win * the number of windows 627 */ 628 629 pCoefRight += coef_per_win * wins_in_group; 630 pCoefLeft += coef_per_win * wins_in_group--; 631 632 /* 633 * Increase tot_sfb by sfb_per_win times the number of windows minus 1. 634 * The minus 1 comes from the fact that tot_sfb is already pointing 635 * to the first sfb in the 2nd window of the group. 636 */ 637 tot_sfb += sfb_per_win * wins_in_group; 638 639 pFactorsRight += sfb_per_win * wins_in_group; 640 pFactorsLeft += sfb_per_win * wins_in_group; 641 642 window_start = partition; 643 644 } 645 while (partition < pFrameInfo->num_win); 646 647 /* pFrameInfo->num_win = 1 for long windows, 8 for short_windows */ 648 649 return; 650 651 } /* pns_intensity_right() */ 652 653 654