1 2 /* ----------------------------------------------------------------------------------------------------------- 3 Software License for The Fraunhofer FDK AAC Codec Library for Android 4 5 Copyright 1995 - 2012 Fraunhofer-Gesellschaft zur Frderung der angewandten Forschung e.V. 6 All rights reserved. 7 8 1. INTRODUCTION 9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements 10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. 11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices. 12 13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual 14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by 15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part 16 of the MPEG specifications. 17 18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) 19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners 20 individually for the purpose of encoding or decoding bit streams in products that are compliant with 21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license 22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec 23 software may already be covered under those patent licenses when it is used for those licensed purposes only. 24 25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, 26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional 27 applications information and documentation. 28 29 2. COPYRIGHT LICENSE 30 31 Redistribution and use in source and binary forms, with or without modification, are permitted without 32 payment of copyright license fees provided that you satisfy the following conditions: 33 34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or 35 your modifications thereto in source code form. 36 37 You must retain the complete text of this software license in the documentation and/or other materials 38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. 39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your 40 modifications thereto to recipients of copies in binary form. 41 42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without 43 prior written permission. 44 45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec 46 software or your modifications thereto. 47 48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software 49 and the date of any change. For modified versions of the FDK AAC Codec, the term 50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term 51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." 52 53 3. NO PATENT LICENSE 54 55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, 56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with 57 respect to this software. 58 59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized 60 by appropriate patent licenses. 61 62 4. DISCLAIMER 63 64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors 65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties 66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, 68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits, 69 or business interruption, however caused and on any theory of liability, whether in contract, strict 70 liability, or tort (including negligence), arising in any way out of the use of this software, even if 71 advised of the possibility of such damage. 72 73 5. CONTACT INFORMATION 74 75 Fraunhofer Institute for Integrated Circuits IIS 76 Attention: Audio and Multimedia Departments - FDK AAC LL 77 Am Wolfsmantel 33 78 91058 Erlangen, Germany 79 80 www.iis.fraunhofer.de/amm 81 amm-info (at) iis.fraunhofer.de 82 ----------------------------------------------------------------------------------------------------------- */ 83 84 /******************************** MPEG Audio Encoder ************************** 85 86 Initial author: A. Horndasch (code originally from lwr) / Josef Hoepfl (FDK) 87 contents/description: intensity stereo processing 88 89 ******************************************************************************/ 90 91 #include "intensity.h" 92 #include "interface.h" 93 #include "psy_configuration.h" 94 #include "psy_const.h" 95 #include "qc_main.h" 96 #include "bit_cnt.h" 97 98 /* only set an IS seed it left/right channel correlation is above IS_CORR_THRESH */ 99 #define IS_CORR_THRESH FL2FXCONST_DBL(0.95f) 100 101 /* when expanding the IS region to more SFBs only accept an error that is 102 * not more than IS_TOTAL_ERROR_THRESH overall and 103 * not more than IS_LOCAL_ERROR_THRESH for the current SFB */ 104 #define IS_TOTAL_ERROR_THRESH FL2FXCONST_DBL(0.04f) 105 #define IS_LOCAL_ERROR_THRESH FL2FXCONST_DBL(0.01f) 106 107 /* the maximum allowed change of the intensity direction (unit: IS scale) - scaled with factor 0.25 - */ 108 #define IS_DIRECTION_DEVIATION_THRESH_SF 2 109 #define IS_DIRECTION_DEVIATION_THRESH FL2FXCONST_DBL(2.0f/(1<<IS_DIRECTION_DEVIATION_THRESH_SF)) 110 111 /* IS regions need to have a minimal percentage of the overall loudness, e.g. 0.06 == 6% */ 112 #define IS_REGION_MIN_LOUDNESS FL2FXCONST_DBL(0.1f) 113 114 /* only perform IS if IS_MIN_SFBS neighboring SFBs can be processed */ 115 #define IS_MIN_SFBS 6 116 117 /* only do IS if 118 * if IS_LEFT_RIGHT_RATIO_THRESH < sfbEnergyLeft[sfb]/sfbEnergyRight[sfb] < 1 / IS_LEFT_RIGHT_RATIO_THRESH 119 * -> no IS if the panning angle is not far from the middle, MS will do */ 120 /* this is equivalent to a scale of +/-1.02914634566 */ 121 #define IS_LEFT_RIGHT_RATIO_THRESH FL2FXCONST_DBL(0.7f) 122 123 /* scalefactor of realScale */ 124 #define REAL_SCALE_SF 1 125 126 /* scalefactor overallLoudness */ 127 #define OVERALL_LOUDNESS_SF 6 128 129 /* scalefactor for sum over max samples per goup */ 130 #define MAX_SFB_PER_GROUP_SF 6 131 132 /* scalefactor for sum of mdct spectrum */ 133 #define MDCT_SPEC_SF 6 134 135 136 typedef struct 137 { 138 139 FIXP_DBL corr_thresh; /*!< Only set an IS seed it left/right channel correlation is above corr_thresh */ 140 141 FIXP_DBL total_error_thresh; /*!< When expanding the IS region to more SFBs only accept an error that is 142 not more than 'total_error_thresh' overall. */ 143 144 FIXP_DBL local_error_thresh; /*!< When expanding the IS region to more SFBs only accept an error that is 145 not more than 'local_error_thresh' for the current SFB. */ 146 147 FIXP_DBL direction_deviation_thresh; /*!< The maximum allowed change of the intensity direction (unit: IS scale) */ 148 149 FIXP_DBL is_region_min_loudness; /*!< IS regions need to have a minimal percentage of the overall loudness, e.g. 0.06 == 6% */ 150 151 INT min_is_sfbs; /*!< Only perform IS if 'min_is_sfbs' neighboring SFBs can be processed */ 152 153 FIXP_DBL left_right_ratio_threshold; /*!< No IS if the panning angle is not far from the middle, MS will do */ 154 155 } INTENSITY_PARAMETERS; 156 157 158 /***************************************************************************** 159 160 functionname: calcSfbMaxScale 161 162 description: Calc max value in scalefactor band 163 164 input: *mdctSpectrum 165 l1 166 l2 167 168 output: none 169 170 returns: scalefactor 171 172 *****************************************************************************/ 173 static INT 174 calcSfbMaxScale(const FIXP_DBL *mdctSpectrum, 175 const INT l1, 176 const INT l2) 177 { 178 INT i; 179 INT sfbMaxScale; 180 FIXP_DBL maxSpc; 181 182 maxSpc = FL2FXCONST_DBL(0.0); 183 for (i=l1; i<l2; i++) { 184 FIXP_DBL tmp = fixp_abs((FIXP_DBL)mdctSpectrum[i]); 185 maxSpc = fixMax(maxSpc, tmp); 186 } 187 sfbMaxScale = (maxSpc==FL2FXCONST_DBL(0.0)) ? (DFRACT_BITS-2) : CntLeadingZeros(maxSpc)-1; 188 189 return sfbMaxScale; 190 } 191 192 193 /***************************************************************************** 194 195 functionname: FDKaacEnc_initIsParams 196 197 description: Initialization of intensity parameters 198 199 input: isParams 200 201 output: isParams 202 203 returns: none 204 205 *****************************************************************************/ 206 static void 207 FDKaacEnc_initIsParams(INTENSITY_PARAMETERS *isParams) 208 { 209 isParams->corr_thresh = IS_CORR_THRESH; 210 isParams->total_error_thresh = IS_TOTAL_ERROR_THRESH; 211 isParams->local_error_thresh = IS_LOCAL_ERROR_THRESH; 212 isParams->direction_deviation_thresh = IS_DIRECTION_DEVIATION_THRESH; 213 isParams->is_region_min_loudness = IS_REGION_MIN_LOUDNESS; 214 isParams->min_is_sfbs = IS_MIN_SFBS; 215 isParams->left_right_ratio_threshold = IS_LEFT_RIGHT_RATIO_THRESH; 216 } 217 218 219 /***************************************************************************** 220 221 functionname: FDKaacEnc_prepareIntensityDecision 222 223 description: Prepares intensity decision 224 225 input: sfbEnergyLeft 226 sfbEnergyRight 227 sfbEnergyLdDataLeft 228 sfbEnergyLdDataRight 229 mdctSpectrumLeft 230 sfbEnergyLdDataRight 231 isParams 232 233 output: hrrErr scale: none 234 isMask scale: none 235 realScale scale: LD_DATA_SHIFT + REAL_SCALE_SF 236 normSfbLoudness scale: none 237 238 returns: none 239 240 *****************************************************************************/ 241 static void 242 FDKaacEnc_prepareIntensityDecision(const FIXP_DBL *sfbEnergyLeft, 243 const FIXP_DBL *sfbEnergyRight, 244 const FIXP_DBL *sfbEnergyLdDataLeft, 245 const FIXP_DBL *sfbEnergyLdDataRight, 246 const FIXP_DBL *mdctSpectrumLeft, 247 const FIXP_DBL *mdctSpectrumRight, 248 const INTENSITY_PARAMETERS *isParams, 249 FIXP_DBL *hrrErr, 250 INT *isMask, 251 FIXP_DBL *realScale, 252 FIXP_DBL *normSfbLoudness, 253 const INT sfbCnt, 254 const INT sfbPerGroup, 255 const INT maxSfbPerGroup, 256 const INT *sfbOffset) 257 { 258 INT j,sfb,sfboffs; 259 INT grpCounter; 260 261 /* temporary variables to compute loudness */ 262 FIXP_DBL overallLoudness[MAX_NO_OF_GROUPS]; 263 264 /* temporary variables to compute correlation */ 265 FIXP_DBL channelCorr[MAX_GROUPED_SFB]; 266 FIXP_DBL ml, mr; 267 FIXP_DBL prod_lr; 268 FIXP_DBL square_l, square_r; 269 FIXP_DBL tmp_l, tmp_r; 270 FIXP_DBL inv_n; 271 272 FDKmemclear(channelCorr, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); 273 FDKmemclear(normSfbLoudness, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); 274 FDKmemclear(overallLoudness, MAX_NO_OF_GROUPS*sizeof(FIXP_DBL)); 275 FDKmemclear(realScale, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); 276 277 for (grpCounter = 0, sfboffs = 0; sfboffs < sfbCnt; sfboffs += sfbPerGroup, grpCounter++) { 278 overallLoudness[grpCounter] = FL2FXCONST_DBL(0.0f); 279 for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { 280 INT sL,sR,s; 281 FIXP_DBL isValue = sfbEnergyLdDataLeft[sfb+sfboffs]-sfbEnergyLdDataRight[sfb+sfboffs]; 282 283 /* delimitate intensity scale value to representable range */ 284 realScale[sfb + sfboffs] = fixMin(FL2FXCONST_DBL(60.f/(1<<(REAL_SCALE_SF+LD_DATA_SHIFT))), fixMax(FL2FXCONST_DBL(-60.f/(1<<(REAL_SCALE_SF+LD_DATA_SHIFT))), isValue)); 285 286 sL = fixMax(0,(CntLeadingZeros(sfbEnergyLeft[sfb + sfboffs])-1)); 287 sR = fixMax(0,(CntLeadingZeros(sfbEnergyRight[sfb + sfboffs])-1)); 288 s = (fixMin(sL,sR)>>2)<<2; 289 normSfbLoudness[sfb + sfboffs] = sqrtFixp(sqrtFixp(((sfbEnergyLeft[sfb + sfboffs]<<s) >> 1) + ((sfbEnergyRight[sfb + sfboffs]<<s) >> 1))) >> (s>>2); 290 291 overallLoudness[grpCounter] += normSfbLoudness[sfb + sfboffs] >> OVERALL_LOUDNESS_SF; 292 /* don't do intensity if 293 * - panning angle is too close to the middle or 294 * - one channel is non-existent or 295 * - if it is dual mono */ 296 if( (sfbEnergyLeft[sfb + sfboffs] >= fMult(isParams->left_right_ratio_threshold,sfbEnergyRight[sfb + sfboffs])) 297 && (fMult(isParams->left_right_ratio_threshold,sfbEnergyLeft[sfb + sfboffs]) <= sfbEnergyRight[sfb + sfboffs]) ) { 298 299 /* this will prevent post processing from considering this SFB for merging */ 300 hrrErr[sfb + sfboffs] = FL2FXCONST_DBL(1.0/8.0); 301 } 302 } 303 } 304 305 for (grpCounter = 0, sfboffs = 0; sfboffs < sfbCnt; sfboffs += sfbPerGroup, grpCounter++) { 306 INT invOverallLoudnessSF; 307 FIXP_DBL invOverallLoudness; 308 309 if (overallLoudness[grpCounter] == FL2FXCONST_DBL(0.0)) { 310 invOverallLoudness = FL2FXCONST_DBL(0.0); 311 invOverallLoudnessSF = 0; 312 } 313 else { 314 invOverallLoudness = fDivNorm((FIXP_DBL)MAXVAL_DBL, overallLoudness[grpCounter],&invOverallLoudnessSF); 315 invOverallLoudnessSF = invOverallLoudnessSF - OVERALL_LOUDNESS_SF + 1; /* +1: compensate fMultDiv2() in subsequent loop */ 316 } 317 invOverallLoudnessSF = fixMin(fixMax(invOverallLoudnessSF,-(DFRACT_BITS-1)),DFRACT_BITS-1); 318 319 for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { 320 FIXP_DBL tmp; 321 322 tmp = fMultDiv2((normSfbLoudness[sfb + sfboffs]>>OVERALL_LOUDNESS_SF)<<OVERALL_LOUDNESS_SF,invOverallLoudness); 323 324 normSfbLoudness[sfb + sfboffs] = scaleValue(tmp, invOverallLoudnessSF); 325 326 channelCorr[sfb + sfboffs] = FL2FXCONST_DBL(0.0f); 327 328 FDK_ASSERT(50 >= 49); 329 /* max width of scalefactorband is 96; width's are always even */ 330 /* inv_n is scaled with factor 2 to compensate fMultDiv2() in subsequent loops */ 331 inv_n = GetInvInt((sfbOffset[sfb + sfboffs + 1] - sfbOffset[sfb + sfboffs])>>1); 332 333 if (inv_n > FL2FXCONST_DBL(0.0f)) { 334 INT s,sL,sR; 335 336 /* correlation := Pearson's product-moment coefficient */ 337 /* compute correlation between channels and check if it is over threshold */ 338 ml = FL2FXCONST_DBL(0.0f); 339 mr = FL2FXCONST_DBL(0.0f); 340 prod_lr = FL2FXCONST_DBL(0.0f); 341 square_l = FL2FXCONST_DBL(0.0f); 342 square_r = FL2FXCONST_DBL(0.0f); 343 344 sL = calcSfbMaxScale(mdctSpectrumLeft,sfbOffset[sfb+sfboffs],sfbOffset[sfb+sfboffs+1]); 345 sR = calcSfbMaxScale(mdctSpectrumRight,sfbOffset[sfb+sfboffs],sfbOffset[sfb+sfboffs+1]); 346 s = fixMin(sL,sR); 347 348 for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; j++) { 349 ml += fMultDiv2((mdctSpectrumLeft[j] << s),inv_n); // scaled with mdctScale - s + inv_n 350 mr += fMultDiv2((mdctSpectrumRight[j] << s),inv_n); // scaled with mdctScale - s + inv_n 351 } 352 ml = fMultDiv2(ml,inv_n); // scaled with mdctScale - s + inv_n 353 mr = fMultDiv2(mr,inv_n); // scaled with mdctScale - s + inv_n 354 355 for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; j++) { 356 tmp_l = fMultDiv2((mdctSpectrumLeft[j] << s),inv_n) - ml; // scaled with mdctScale - s + inv_n 357 tmp_r = fMultDiv2((mdctSpectrumRight[j] << s),inv_n) - mr; // scaled with mdctScale - s + inv_n 358 359 prod_lr += fMultDiv2(tmp_l,tmp_r); // scaled with 2*(mdctScale - s + inv_n) + 1 360 square_l += fPow2Div2(tmp_l); // scaled with 2*(mdctScale - s + inv_n) + 1 361 square_r += fPow2Div2(tmp_r); // scaled with 2*(mdctScale - s + inv_n) + 1 362 } 363 prod_lr = prod_lr << 1; // scaled with 2*(mdctScale - s + inv_n) 364 square_l = square_l << 1; // scaled with 2*(mdctScale - s + inv_n) 365 square_r = square_r << 1; // scaled with 2*(mdctScale - s + inv_n) 366 367 if (square_l > FL2FXCONST_DBL(0.0f) && square_r > FL2FXCONST_DBL(0.0f)) { 368 INT channelCorrSF = 0; 369 370 /* local scaling of square_l and square_r is compensated after sqrt calculation */ 371 sL = fixMax(0,(CntLeadingZeros(square_l)-1)); 372 sR = fixMax(0,(CntLeadingZeros(square_r)-1)); 373 s = ((sL + sR)>>1)<<1; 374 sL = fixMin(sL,s); 375 sR = s-sL; 376 tmp = fMult(square_l<<sL,square_r<<sR); 377 tmp = sqrtFixp(tmp); 378 379 FDK_ASSERT(tmp > FL2FXCONST_DBL(0.0f)); 380 381 /* numerator and denominator have the same scaling */ 382 if (prod_lr < FL2FXCONST_DBL(0.0f) ) { 383 channelCorr[sfb + sfboffs] = -(fDivNorm(-prod_lr,tmp,&channelCorrSF)); 384 385 } 386 else { 387 channelCorr[sfb + sfboffs] = (fDivNorm( prod_lr,tmp,&channelCorrSF)); 388 } 389 channelCorrSF = fixMin(fixMax(( channelCorrSF + ((sL+sR)>>1)),-(DFRACT_BITS-1)),DFRACT_BITS-1); 390 391 if (channelCorrSF < 0) { 392 channelCorr[sfb + sfboffs] = channelCorr[sfb + sfboffs] >> (-channelCorrSF); 393 } 394 else { 395 /* avoid overflows due to limited computational accuracy */ 396 if ( fAbs(channelCorr[sfb + sfboffs]) > (((FIXP_DBL)MAXVAL_DBL)>>channelCorrSF) ) { 397 if (channelCorr[sfb + sfboffs] < FL2FXCONST_DBL(0.0f)) 398 channelCorr[sfb + sfboffs] = -(FIXP_DBL) MAXVAL_DBL; 399 else 400 channelCorr[sfb + sfboffs] = (FIXP_DBL) MAXVAL_DBL; 401 } 402 else { 403 channelCorr[sfb + sfboffs] = channelCorr[sfb + sfboffs] << channelCorrSF; 404 } 405 } 406 } 407 } 408 409 /* for post processing: hrrErr is the error in terms of (too little) correlation 410 * weighted with the loudness of the SFB; SFBs with small hrrErr can be merged */ 411 if (hrrErr[sfb + sfboffs] == FL2FXCONST_DBL(1.0/8.0)) { 412 continue; 413 } 414 415 hrrErr[sfb + sfboffs] = fMultDiv2((FL2FXCONST_DBL(0.25f)-(channelCorr[sfb + sfboffs]>>2)),normSfbLoudness[sfb + sfboffs]); 416 417 /* set IS mask/vector to 1, if correlation is high enough */ 418 if (fAbs(channelCorr[sfb + sfboffs]) >= isParams->corr_thresh) { 419 isMask[sfb + sfboffs] = 1; 420 } 421 } 422 } 423 } 424 425 426 /***************************************************************************** 427 428 functionname: FDKaacEnc_finalizeIntensityDecision 429 430 description: Finalizes intensity decision 431 432 input: isParams scale: none 433 hrrErr scale: none 434 realIsScale scale: LD_DATA_SHIFT + REAL_SCALE_SF 435 normSfbLoudness scale: none 436 437 output: isMask scale: none 438 439 returns: none 440 441 *****************************************************************************/ 442 static void 443 FDKaacEnc_finalizeIntensityDecision(const FIXP_DBL *hrrErr, 444 INT *isMask, 445 const FIXP_DBL *realIsScale, 446 const FIXP_DBL *normSfbLoudness, 447 const INTENSITY_PARAMETERS *isParams, 448 const INT sfbCnt, 449 const INT sfbPerGroup, 450 const INT maxSfbPerGroup) 451 { 452 INT sfb,sfboffs, j; 453 INT startIsSfb = 0; 454 INT inIsBlock; 455 INT currentIsSfbCount; 456 FIXP_DBL overallHrrError; 457 FIXP_DBL isScaleLast = FL2FXCONST_DBL(0.0f); 458 FIXP_DBL isRegionLoudness; 459 460 for (sfboffs = 0; sfboffs < sfbCnt; sfboffs += sfbPerGroup) { 461 inIsBlock = 0; 462 currentIsSfbCount = 0; 463 overallHrrError = FL2FXCONST_DBL(0.0f); 464 isRegionLoudness = FL2FXCONST_DBL(0.0f); 465 for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { 466 if (isMask[sfboffs + sfb] == 1) { 467 if (currentIsSfbCount == 0) { 468 startIsSfb = sfboffs + sfb; 469 isScaleLast = realIsScale[sfboffs + sfb]; 470 } 471 inIsBlock = 1; 472 currentIsSfbCount++; 473 overallHrrError += hrrErr[sfboffs + sfb] >> (MAX_SFB_PER_GROUP_SF-3); 474 isRegionLoudness += normSfbLoudness[sfboffs + sfb] >> MAX_SFB_PER_GROUP_SF; 475 } 476 else { 477 /* based on correlation, IS should not be used 478 * -> use it anyway, if overall error is below threshold 479 * and if local error does not exceed threshold 480 * otherwise: check if there are enough IS SFBs 481 */ 482 if (inIsBlock) { 483 overallHrrError += hrrErr[sfboffs + sfb] >> (MAX_SFB_PER_GROUP_SF-3); 484 isRegionLoudness += normSfbLoudness[sfboffs + sfb] >> MAX_SFB_PER_GROUP_SF; 485 486 if ( (hrrErr[sfboffs + sfb] < (isParams->local_error_thresh>>3)) && (overallHrrError < (isParams->total_error_thresh>>MAX_SFB_PER_GROUP_SF)) ) { 487 currentIsSfbCount++; 488 /* overwrite correlation based decision */ 489 isMask[sfboffs + sfb] = 1; 490 } else { 491 inIsBlock = 0; 492 } 493 } 494 } 495 /* check for large direction deviation */ 496 if (inIsBlock) { 497 if( fAbs(isScaleLast-realIsScale[sfboffs + sfb]) < (isParams->direction_deviation_thresh>>(REAL_SCALE_SF+LD_DATA_SHIFT-IS_DIRECTION_DEVIATION_THRESH_SF)) ) { 498 isScaleLast = realIsScale[sfboffs + sfb]; 499 } 500 else{ 501 isMask[sfboffs + sfb] = 0; 502 inIsBlock = 0; 503 currentIsSfbCount--; 504 } 505 } 506 507 if (currentIsSfbCount > 0 && (!inIsBlock || sfb == maxSfbPerGroup - 1)) { 508 /* not enough SFBs -> do not use IS */ 509 if (currentIsSfbCount < isParams->min_is_sfbs || (isRegionLoudness < isParams->is_region_min_loudness>>MAX_SFB_PER_GROUP_SF)) { 510 for(j = startIsSfb; j <= sfboffs + sfb; j++) { 511 isMask[j] = 0; 512 } 513 } 514 currentIsSfbCount = 0; 515 overallHrrError = FL2FXCONST_DBL(0.0f); 516 isRegionLoudness = FL2FXCONST_DBL(0.0f); 517 } 518 } 519 } 520 } 521 522 523 /***************************************************************************** 524 525 functionname: FDKaacEnc_IntensityStereoProcessing 526 527 description: Intensity stereo processing tool 528 529 input: sfbEnergyLeft 530 sfbEnergyRight 531 mdctSpectrumLeft 532 mdctSpectrumRight 533 sfbThresholdLeft 534 sfbThresholdRight 535 sfbSpreadEnLeft 536 sfbSpreadEnRight 537 sfbEnergyLdDataLeft 538 sfbEnergyLdDataRight 539 540 output: isBook 541 isScale 542 pnsData->pnsFlag 543 msDigest zeroed from start to sfbCnt 544 msMask zeroed from start to sfbCnt 545 mdctSpectrumRight zeroed where isBook!=0 546 sfbEnergyRight zeroed where isBook!=0 547 sfbSpreadEnRight zeroed where isBook!=0 548 sfbThresholdRight zeroed where isBook!=0 549 sfbEnergyLdDataRight FL2FXCONST_DBL(-1.0) where isBook!=0 550 sfbThresholdLdDataRight FL2FXCONST_DBL(-0.515625f) where isBook!=0 551 552 returns: none 553 554 *****************************************************************************/ 555 void FDKaacEnc_IntensityStereoProcessing( 556 FIXP_DBL *sfbEnergyLeft, 557 FIXP_DBL *sfbEnergyRight, 558 FIXP_DBL *mdctSpectrumLeft, 559 FIXP_DBL *mdctSpectrumRight, 560 FIXP_DBL *sfbThresholdLeft, 561 FIXP_DBL *sfbThresholdRight, 562 FIXP_DBL *sfbThresholdLdDataRight, 563 FIXP_DBL *sfbSpreadEnLeft, 564 FIXP_DBL *sfbSpreadEnRight, 565 FIXP_DBL *sfbEnergyLdDataLeft, 566 FIXP_DBL *sfbEnergyLdDataRight, 567 INT *msDigest, 568 INT *msMask, 569 const INT sfbCnt, 570 const INT sfbPerGroup, 571 const INT maxSfbPerGroup, 572 const INT *sfbOffset, 573 const INT allowIS, 574 INT *isBook, 575 INT *isScale, 576 PNS_DATA *RESTRICT pnsData[2] 577 ) 578 { 579 INT sfb,sfboffs, j; 580 FIXP_DBL scale; 581 FIXP_DBL lr; 582 FIXP_DBL hrrErr[MAX_GROUPED_SFB]; 583 FIXP_DBL normSfbLoudness[MAX_GROUPED_SFB]; 584 FIXP_DBL realIsScale[MAX_GROUPED_SFB]; 585 INTENSITY_PARAMETERS isParams; 586 INT isMask[MAX_GROUPED_SFB]; 587 588 FDKmemclear((void*)isBook,sfbCnt*sizeof(INT)); 589 FDKmemclear((void*)isMask,sfbCnt*sizeof(INT)); 590 FDKmemclear((void*)realIsScale,sfbCnt*sizeof(FIXP_DBL)); 591 FDKmemclear((void*)isScale,sfbCnt*sizeof(INT)); 592 FDKmemclear((void*)hrrErr,sfbCnt*sizeof(FIXP_DBL)); 593 594 if (!allowIS) 595 return; 596 597 FDKaacEnc_initIsParams(&isParams); 598 599 /* compute / set the following values per SFB: 600 * - left/right ratio between channels 601 * - normalized loudness 602 * + loudness == average of energy in channels to 0.25 603 * + normalization: division by sum of all SFB loudnesses 604 * - isMask (is set to 0 if channels are the same or one is 0) 605 */ 606 FDKaacEnc_prepareIntensityDecision(sfbEnergyLeft, 607 sfbEnergyRight, 608 sfbEnergyLdDataLeft, 609 sfbEnergyLdDataRight, 610 mdctSpectrumLeft, 611 mdctSpectrumRight, 612 &isParams, 613 hrrErr, 614 isMask, 615 realIsScale, 616 normSfbLoudness, 617 sfbCnt, 618 sfbPerGroup, 619 maxSfbPerGroup, 620 sfbOffset); 621 622 FDKaacEnc_finalizeIntensityDecision(hrrErr, 623 isMask, 624 realIsScale, 625 normSfbLoudness, 626 &isParams, 627 sfbCnt, 628 sfbPerGroup, 629 maxSfbPerGroup); 630 631 for (sfb=0; sfb<sfbCnt; sfb+=sfbPerGroup) { 632 for (sfboffs=0; sfboffs<maxSfbPerGroup; sfboffs++) { 633 INT sL, sR; 634 FIXP_DBL inv_n; 635 636 msMask[sfb+sfboffs] = 0; 637 if (isMask[sfb+sfboffs] == 0) { 638 continue; 639 } 640 641 if ( (sfbEnergyLeft[sfb+sfboffs] < sfbThresholdLeft[sfb+sfboffs]) 642 &&(fMult(FL2FXCONST_DBL(1.0f/1.5f),sfbEnergyRight[sfb+sfboffs]) > sfbThresholdRight[sfb+sfboffs]) ) { 643 continue; 644 } 645 /* NEW: if there is a big-enough IS region, switch off PNS */ 646 if (pnsData[0]) { 647 if(pnsData[0]->pnsFlag[sfb+sfboffs]) { 648 pnsData[0]->pnsFlag[sfb+sfboffs] = 0; 649 } 650 if(pnsData[1]->pnsFlag[sfb+sfboffs]) { 651 pnsData[1]->pnsFlag[sfb+sfboffs] = 0; 652 } 653 } 654 655 inv_n = GetInvInt((sfbOffset[sfb + sfboffs + 1] - sfbOffset[sfb + sfboffs])>>1); // scaled with 2 to compensate fMultDiv2() in subsequent loop 656 sL = calcSfbMaxScale(mdctSpectrumLeft,sfbOffset[sfb+sfboffs],sfbOffset[sfb+sfboffs+1]); 657 sR = calcSfbMaxScale(mdctSpectrumRight,sfbOffset[sfb+sfboffs],sfbOffset[sfb+sfboffs+1]); 658 659 lr = FL2FXCONST_DBL(0.0f); 660 for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) 661 lr += fMultDiv2(fMultDiv2(mdctSpectrumLeft[j]<<sL,mdctSpectrumRight[j]<<sR),inv_n); 662 lr = lr<<1; 663 664 if (lr < FL2FXCONST_DBL(0.0f)) { 665 /* This means OUT OF phase intensity stereo, cf. standard */ 666 INT s0, s1, s2; 667 FIXP_DBL tmp, d, ed = FL2FXCONST_DBL(0.0f); 668 669 s0 = fixMin(sL,sR); 670 for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) { 671 d = ((mdctSpectrumLeft[j]<<s0)>>1) - ((mdctSpectrumRight[j]<<s0)>>1); 672 ed += fMultDiv2(d,d)>>(MDCT_SPEC_SF-1); 673 } 674 msMask[sfb+sfboffs] = 1; 675 tmp = fDivNorm(sfbEnergyLeft[sfb+sfboffs],ed,&s1); 676 s2 = (s1) + (2*s0) - 2 - MDCT_SPEC_SF; 677 if (s2 & 1) { 678 tmp = tmp>>1; 679 s2 = s2+1; 680 } 681 s2 = (s2>>1) + 1; // +1 compensate fMultDiv2() in subsequent loop 682 s2 = fixMin(fixMax(s2,-(DFRACT_BITS-1)),(DFRACT_BITS-1)); 683 scale = sqrtFixp(tmp); 684 if (s2 < 0) { 685 s2 = -s2; 686 for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) { 687 mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j],scale) - fMultDiv2(mdctSpectrumRight[j],scale)) >> s2; 688 mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f); 689 } 690 } 691 else { 692 for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) { 693 mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j],scale) - fMultDiv2(mdctSpectrumRight[j],scale)) << s2; 694 mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f); 695 } 696 } 697 } 698 else { 699 /* This means IN phase intensity stereo, cf. standard */ 700 INT s0,s1,s2; 701 FIXP_DBL tmp, s, es = FL2FXCONST_DBL(0.0f); 702 703 s0 = fixMin(sL,sR); 704 for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) { 705 s = ((mdctSpectrumLeft[j]<<s0)>>1) + ((mdctSpectrumRight[j]<<s0)>>1); 706 es += fMultDiv2(s,s)>>(MDCT_SPEC_SF-1); // scaled 2*(mdctScale - s0 + 1) + MDCT_SPEC_SF 707 } 708 msMask[sfb+sfboffs] = 0; 709 tmp = fDivNorm(sfbEnergyLeft[sfb+sfboffs],es,&s1); 710 s2 = (s1) + (2*s0) - 2 - MDCT_SPEC_SF; 711 if (s2 & 1) { 712 tmp = tmp>>1; 713 s2 = s2 + 1; 714 } 715 s2 = (s2>>1) + 1; // +1 compensate fMultDiv2() in subsequent loop 716 s2 = fixMin(fixMax(s2,-(DFRACT_BITS-1)),(DFRACT_BITS-1)); 717 scale = sqrtFixp(tmp); 718 if (s2 < 0) { 719 s2 = -s2; 720 for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) { 721 mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j],scale) + fMultDiv2(mdctSpectrumRight[j],scale)) >> s2; 722 mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f); 723 } 724 } 725 else { 726 for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) { 727 mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j],scale) + fMultDiv2(mdctSpectrumRight[j],scale)) << s2; 728 mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f); 729 } 730 } 731 } 732 733 isBook[sfb+sfboffs] = CODE_BOOK_IS_IN_PHASE_NO; 734 735 if ( realIsScale[sfb+sfboffs] < FL2FXCONST_DBL(0.0f) ) { 736 isScale[sfb+sfboffs] = (INT)(((realIsScale[sfb+sfboffs]>>1)-FL2FXCONST_DBL(0.5f/(1<<(REAL_SCALE_SF+LD_DATA_SHIFT+1))))>>(DFRACT_BITS-1-REAL_SCALE_SF-LD_DATA_SHIFT-1)) + 1; 737 } 738 else { 739 isScale[sfb+sfboffs] = (INT)(((realIsScale[sfb+sfboffs]>>1)+FL2FXCONST_DBL(0.5f/(1<<(REAL_SCALE_SF+LD_DATA_SHIFT+1))))>>(DFRACT_BITS-1-REAL_SCALE_SF-LD_DATA_SHIFT-1)); 740 } 741 742 sfbEnergyRight[sfb+sfboffs] = FL2FXCONST_DBL(0.0f); 743 sfbEnergyLdDataRight[sfb+sfboffs] = FL2FXCONST_DBL(-1.0f); 744 sfbThresholdRight[sfb+sfboffs] = FL2FXCONST_DBL(0.0f); 745 sfbThresholdLdDataRight[sfb+sfboffs] = FL2FXCONST_DBL(-0.515625f); 746 sfbSpreadEnRight[sfb+sfboffs] = FL2FXCONST_DBL(0.0f); 747 748 *msDigest = MS_SOME; 749 } 750 } 751 } 752 753