1 /* ----------------------------------------------------------------------------- 2 Software License for The Fraunhofer FDK AAC Codec Library for Android 3 4 Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Frderung der angewandten 5 Forschung e.V. All rights reserved. 6 7 1. INTRODUCTION 8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software 9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding 10 scheme for digital audio. This FDK AAC Codec software is intended to be used on 11 a wide variety of Android devices. 12 13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient 14 general perceptual audio codecs. AAC-ELD is considered the best-performing 15 full-bandwidth communications codec by independent studies and is widely 16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG 17 specifications. 18 19 Patent licenses for necessary patent claims for the FDK AAC Codec (including 20 those of Fraunhofer) may be obtained through Via Licensing 21 (www.vialicensing.com) or through the respective patent owners individually for 22 the purpose of encoding or decoding bit streams in products that are compliant 23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of 24 Android devices already license these patent claims through Via Licensing or 25 directly from the patent owners, and therefore FDK AAC Codec software may 26 already be covered under those patent licenses when it is used for those 27 licensed purposes only. 28 29 Commercially-licensed AAC software libraries, including floating-point versions 30 with enhanced sound quality, are also available from Fraunhofer. Users are 31 encouraged to check the Fraunhofer website for additional applications 32 information and documentation. 33 34 2. COPYRIGHT LICENSE 35 36 Redistribution and use in source and binary forms, with or without modification, 37 are permitted without payment of copyright license fees provided that you 38 satisfy the following conditions: 39 40 You must retain the complete text of this software license in redistributions of 41 the FDK AAC Codec or your modifications thereto in source code form. 42 43 You must retain the complete text of this software license in the documentation 44 and/or other materials provided with redistributions of the FDK AAC Codec or 45 your modifications thereto in binary form. You must make available free of 46 charge copies of the complete source code of the FDK AAC Codec and your 47 modifications thereto to recipients of copies in binary form. 48 49 The name of Fraunhofer may not be used to endorse or promote products derived 50 from this library without prior written permission. 51 52 You may not charge copyright license fees for anyone to use, copy or distribute 53 the FDK AAC Codec software or your modifications thereto. 54 55 Your modified versions of the FDK AAC Codec must carry prominent notices stating 56 that you changed the software and the date of any change. For modified versions 57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" 58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK 59 AAC Codec Library for Android." 60 61 3. NO PATENT LICENSE 62 63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without 64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. 65 Fraunhofer provides no warranty of patent non-infringement with respect to this 66 software. 67 68 You may use this FDK AAC Codec software or modifications thereto only for 69 purposes that are authorized by appropriate patent licenses. 70 71 4. DISCLAIMER 72 73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright 74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, 75 including but not limited to the implied warranties of merchantability and 76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, 78 or consequential damages, including but not limited to procurement of substitute 79 goods or services; loss of use, data, or profits, or business interruption, 80 however caused and on any theory of liability, whether in contract, strict 81 liability, or tort (including negligence), arising in any way out of the use of 82 this software, even if advised of the possibility of such damage. 83 84 5. CONTACT INFORMATION 85 86 Fraunhofer Institute for Integrated Circuits IIS 87 Attention: Audio and Multimedia Departments - FDK AAC LL 88 Am Wolfsmantel 33 89 91058 Erlangen, Germany 90 91 www.iis.fraunhofer.de/amm 92 amm-info (at) iis.fraunhofer.de 93 ----------------------------------------------------------------------------- */ 94 95 /**************************** AAC encoder library ****************************** 96 97 Author(s): M. Werner 98 99 Description: Scale factor estimation 100 101 *******************************************************************************/ 102 103 #include "sf_estim.h" 104 #include "aacEnc_rom.h" 105 #include "quantize.h" 106 #include "bit_cnt.h" 107 108 #ifdef __arm__ 109 #endif 110 111 #define UPCOUNT_LIMIT 1 112 #define AS_PE_FAC_SHIFT 7 113 #define DIST_FAC_SHIFT 3 114 #define AS_PE_FAC_FLOAT (float)(1 << AS_PE_FAC_SHIFT) 115 static const INT MAX_SCF_DELTA = 60; 116 117 static const FIXP_DBL PE_C1 = FL2FXCONST_DBL( 118 3.0f / AS_PE_FAC_FLOAT); /* (log(8.0)/log(2)) >> AS_PE_FAC_SHIFT */ 119 static const FIXP_DBL PE_C2 = FL2FXCONST_DBL( 120 1.3219281f / AS_PE_FAC_FLOAT); /* (log(2.5)/log(2)) >> AS_PE_FAC_SHIFT */ 121 static const FIXP_DBL PE_C3 = FL2FXCONST_DBL(0.5593573f); /* 1-C2/C1 */ 122 123 /* 124 Function; FDKaacEnc_FDKaacEnc_CalcFormFactorChannel 125 126 Description: Calculates the formfactor 127 128 sf: scale factor of the mdct spectrum 129 sfbFormFactorLdData is scaled with the factor 1/(((2^sf)^0.5) * 130 (2^FORM_FAC_SHIFT)) 131 */ 132 static void FDKaacEnc_FDKaacEnc_CalcFormFactorChannel( 133 FIXP_DBL *RESTRICT sfbFormFactorLdData, 134 PSY_OUT_CHANNEL *RESTRICT psyOutChan) { 135 INT j, sfb, sfbGrp; 136 FIXP_DBL formFactor; 137 138 int tmp0 = psyOutChan->sfbCnt; 139 int tmp1 = psyOutChan->maxSfbPerGroup; 140 int step = psyOutChan->sfbPerGroup; 141 for (sfbGrp = 0; sfbGrp < tmp0; sfbGrp += step) { 142 for (sfb = 0; sfb < tmp1; sfb++) { 143 formFactor = FL2FXCONST_DBL(0.0f); 144 /* calc sum of sqrt(spec) */ 145 for (j = psyOutChan->sfbOffsets[sfbGrp + sfb]; 146 j < psyOutChan->sfbOffsets[sfbGrp + sfb + 1]; j++) { 147 formFactor += 148 sqrtFixp(fixp_abs(psyOutChan->mdctSpectrum[j])) >> FORM_FAC_SHIFT; 149 } 150 sfbFormFactorLdData[sfbGrp + sfb] = CalcLdData(formFactor); 151 } 152 /* set sfbFormFactor for sfbs with zero spec to zero. Just for debugging. */ 153 for (; sfb < psyOutChan->sfbPerGroup; sfb++) { 154 sfbFormFactorLdData[sfbGrp + sfb] = FL2FXCONST_DBL(-1.0f); 155 } 156 } 157 } 158 159 /* 160 Function: FDKaacEnc_CalcFormFactor 161 162 Description: Calls FDKaacEnc_FDKaacEnc_CalcFormFactorChannel() for each 163 channel 164 */ 165 166 void FDKaacEnc_CalcFormFactor(QC_OUT_CHANNEL *qcOutChannel[(2)], 167 PSY_OUT_CHANNEL *psyOutChannel[(2)], 168 const INT nChannels) { 169 INT j; 170 for (j = 0; j < nChannels; j++) { 171 FDKaacEnc_FDKaacEnc_CalcFormFactorChannel( 172 qcOutChannel[j]->sfbFormFactorLdData, psyOutChannel[j]); 173 } 174 } 175 176 /* 177 Function: FDKaacEnc_calcSfbRelevantLines 178 179 Description: Calculates sfbNRelevantLines 180 181 sfbNRelevantLines is scaled with the factor 1/((2^FORM_FAC_SHIFT) * 2.0) 182 */ 183 static void FDKaacEnc_calcSfbRelevantLines( 184 const FIXP_DBL *const sfbFormFactorLdData, 185 const FIXP_DBL *const sfbEnergyLdData, 186 const FIXP_DBL *const sfbThresholdLdData, const INT *const sfbOffsets, 187 const INT sfbCnt, const INT sfbPerGroup, const INT maxSfbPerGroup, 188 FIXP_DBL *sfbNRelevantLines) { 189 INT sfbOffs, sfb; 190 FIXP_DBL sfbWidthLdData; 191 FIXP_DBL asPeFacLdData = 192 FL2FXCONST_DBL(0.109375); /* AS_PE_FAC_SHIFT*ld64(2) */ 193 FIXP_DBL accu; 194 195 /* sfbNRelevantLines[i] = 2^( (sfbFormFactorLdData[i] - 0.25 * 196 * (sfbEnergyLdData[i] - ld64(sfbWidth[i]/(2^7)) - AS_PE_FAC_SHIFT*ld64(2)) * 197 * 64); */ 198 199 FDKmemclear(sfbNRelevantLines, sfbCnt * sizeof(FIXP_DBL)); 200 201 for (sfbOffs = 0; sfbOffs < sfbCnt; sfbOffs += sfbPerGroup) { 202 for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { 203 /* calc sum of sqrt(spec) */ 204 if ((FIXP_DBL)sfbEnergyLdData[sfbOffs + sfb] > 205 (FIXP_DBL)sfbThresholdLdData[sfbOffs + sfb]) { 206 INT sfbWidth = 207 sfbOffsets[sfbOffs + sfb + 1] - sfbOffsets[sfbOffs + sfb]; 208 209 /* avgFormFactorLdData = 210 * sqrtFixp(sqrtFixp(sfbEnergyLdData[sfbOffs+sfb]/sfbWidth)); */ 211 /* sfbNRelevantLines[sfbOffs+sfb] = sfbFormFactor[sfbOffs+sfb] / 212 * avgFormFactorLdData; */ 213 sfbWidthLdData = 214 (FIXP_DBL)(sfbWidth << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT)); 215 sfbWidthLdData = CalcLdData(sfbWidthLdData); 216 217 accu = sfbEnergyLdData[sfbOffs + sfb] - sfbWidthLdData - asPeFacLdData; 218 accu = sfbFormFactorLdData[sfbOffs + sfb] - (accu >> 2); 219 220 sfbNRelevantLines[sfbOffs + sfb] = CalcInvLdData(accu) >> 1; 221 } 222 } 223 } 224 } 225 226 /* 227 Function: FDKaacEnc_countSingleScfBits 228 229 Description: 230 231 scfBitsFract is scaled by 1/(2^(2*AS_PE_FAC_SHIFT)) 232 */ 233 static FIXP_DBL FDKaacEnc_countSingleScfBits(INT scf, INT scfLeft, 234 INT scfRight) { 235 FIXP_DBL scfBitsFract; 236 237 scfBitsFract = (FIXP_DBL)(FDKaacEnc_bitCountScalefactorDelta(scfLeft - scf) + 238 FDKaacEnc_bitCountScalefactorDelta(scf - scfRight)); 239 240 scfBitsFract = scfBitsFract << (DFRACT_BITS - 1 - (2 * AS_PE_FAC_SHIFT)); 241 242 return scfBitsFract; /* output scaled by 1/(2^(2*AS_PE_FAC)) */ 243 } 244 245 /* 246 Function: FDKaacEnc_calcSingleSpecPe 247 248 specPe is scaled by 1/(2^(2*AS_PE_FAC_SHIFT)) 249 */ 250 static FIXP_DBL FDKaacEnc_calcSingleSpecPe(INT scf, FIXP_DBL sfbConstPePart, 251 FIXP_DBL nLines) { 252 FIXP_DBL specPe = FL2FXCONST_DBL(0.0f); 253 FIXP_DBL ldRatio; 254 FIXP_DBL scfFract; 255 256 scfFract = (FIXP_DBL)(scf << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT)); 257 258 ldRatio = sfbConstPePart - fMult(FL2FXCONST_DBL(0.375f), scfFract); 259 260 if (ldRatio >= PE_C1) { 261 specPe = fMult(FL2FXCONST_DBL(0.7f), fMult(nLines, ldRatio)); 262 } else { 263 specPe = fMult(FL2FXCONST_DBL(0.7f), 264 fMult(nLines, (PE_C2 + fMult(PE_C3, ldRatio)))); 265 } 266 267 return specPe; /* output scaled by 1/(2^(2*AS_PE_FAC)) */ 268 } 269 270 /* 271 Function: FDKaacEnc_countScfBitsDiff 272 273 scfBitsDiff is scaled by 1/(2^(2*AS_PE_FAC_SHIFT)) 274 */ 275 static FIXP_DBL FDKaacEnc_countScfBitsDiff(INT *scfOld, INT *scfNew, INT sfbCnt, 276 INT startSfb, INT stopSfb) { 277 FIXP_DBL scfBitsFract; 278 INT scfBitsDiff = 0; 279 INT sfb = 0, sfbLast; 280 INT sfbPrev, sfbNext; 281 282 /* search for first relevant sfb */ 283 sfbLast = startSfb; 284 while ((sfbLast < stopSfb) && (scfOld[sfbLast] == FDK_INT_MIN)) sfbLast++; 285 /* search for previous relevant sfb and count diff */ 286 sfbPrev = startSfb - 1; 287 while ((sfbPrev >= 0) && (scfOld[sfbPrev] == FDK_INT_MIN)) sfbPrev--; 288 if (sfbPrev >= 0) 289 scfBitsDiff += 290 FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbPrev] - scfNew[sfbLast]) - 291 FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbPrev] - scfOld[sfbLast]); 292 /* now loop through all sfbs and count diffs of relevant sfbs */ 293 for (sfb = sfbLast + 1; sfb < stopSfb; sfb++) { 294 if (scfOld[sfb] != FDK_INT_MIN) { 295 scfBitsDiff += 296 FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfb]) - 297 FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfb]); 298 sfbLast = sfb; 299 } 300 } 301 /* search for next relevant sfb and count diff */ 302 sfbNext = stopSfb; 303 while ((sfbNext < sfbCnt) && (scfOld[sfbNext] == FDK_INT_MIN)) sfbNext++; 304 if (sfbNext < sfbCnt) 305 scfBitsDiff += 306 FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfbNext]) - 307 FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfbNext]); 308 309 scfBitsFract = 310 (FIXP_DBL)(scfBitsDiff << (DFRACT_BITS - 1 - (2 * AS_PE_FAC_SHIFT))); 311 312 return scfBitsFract; 313 } 314 315 /* 316 Function: FDKaacEnc_calcSpecPeDiff 317 318 specPeDiff is scaled by 1/(2^(2*AS_PE_FAC_SHIFT)) 319 */ 320 static FIXP_DBL FDKaacEnc_calcSpecPeDiff( 321 PSY_OUT_CHANNEL *psyOutChan, QC_OUT_CHANNEL *qcOutChannel, INT *scfOld, 322 INT *scfNew, FIXP_DBL *sfbConstPePart, FIXP_DBL *sfbFormFactorLdData, 323 FIXP_DBL *sfbNRelevantLines, INT startSfb, INT stopSfb) { 324 FIXP_DBL specPeDiff = FL2FXCONST_DBL(0.0f); 325 FIXP_DBL scfFract = FL2FXCONST_DBL(0.0f); 326 INT sfb; 327 328 /* loop through all sfbs and count pe difference */ 329 for (sfb = startSfb; sfb < stopSfb; sfb++) { 330 if (scfOld[sfb] != FDK_INT_MIN) { 331 FIXP_DBL ldRatioOld, ldRatioNew, pOld, pNew; 332 333 /* sfbConstPePart[sfb] = (float)log(psyOutChan->sfbEnergy[sfb] * 6.75f / 334 * sfbFormFactor[sfb]) * LOG2_1; */ 335 /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for 336 * log2 */ 337 /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */ 338 if (sfbConstPePart[sfb] == (FIXP_DBL)FDK_INT_MIN) 339 sfbConstPePart[sfb] = 340 ((psyOutChan->sfbEnergyLdData[sfb] - sfbFormFactorLdData[sfb] - 341 FL2FXCONST_DBL(0.09375f)) >> 342 1) + 343 FL2FXCONST_DBL(0.02152255861f); 344 345 scfFract = (FIXP_DBL)(scfOld[sfb] << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT)); 346 ldRatioOld = 347 sfbConstPePart[sfb] - fMult(FL2FXCONST_DBL(0.375f), scfFract); 348 349 scfFract = (FIXP_DBL)(scfNew[sfb] << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT)); 350 ldRatioNew = 351 sfbConstPePart[sfb] - fMult(FL2FXCONST_DBL(0.375f), scfFract); 352 353 if (ldRatioOld >= PE_C1) 354 pOld = ldRatioOld; 355 else 356 pOld = PE_C2 + fMult(PE_C3, ldRatioOld); 357 358 if (ldRatioNew >= PE_C1) 359 pNew = ldRatioNew; 360 else 361 pNew = PE_C2 + fMult(PE_C3, ldRatioNew); 362 363 specPeDiff += fMult(FL2FXCONST_DBL(0.7f), 364 fMult(sfbNRelevantLines[sfb], (pNew - pOld))); 365 } 366 } 367 368 return specPeDiff; 369 } 370 371 /* 372 Function: FDKaacEnc_improveScf 373 374 Description: Calculate the distortion by quantization and inverse quantization 375 of the spectrum with various scalefactors. The scalefactor which provides the 376 best results will be used. 377 */ 378 static INT FDKaacEnc_improveScf(const FIXP_DBL *spec, SHORT *quantSpec, 379 SHORT *quantSpecTmp, INT sfbWidth, 380 FIXP_DBL threshLdData, INT scf, INT minScf, 381 FIXP_DBL *distLdData, INT *minScfCalculated, 382 INT dZoneQuantEnable) { 383 FIXP_DBL sfbDistLdData; 384 INT scfBest = scf; 385 INT k; 386 FIXP_DBL distFactorLdData = FL2FXCONST_DBL(-0.0050301265); /* ld64(1/1.25) */ 387 388 /* calc real distortion */ 389 sfbDistLdData = 390 FDKaacEnc_calcSfbDist(spec, quantSpec, sfbWidth, scf, dZoneQuantEnable); 391 *minScfCalculated = scf; 392 /* nmr > 1.25 -> try to improve nmr */ 393 if (sfbDistLdData > (threshLdData - distFactorLdData)) { 394 INT scfEstimated = scf; 395 FIXP_DBL sfbDistBestLdData = sfbDistLdData; 396 INT cnt; 397 /* improve by bigger scf ? */ 398 cnt = 0; 399 400 while ((sfbDistLdData > (threshLdData - distFactorLdData)) && 401 (cnt++ < UPCOUNT_LIMIT)) { 402 scf++; 403 sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf, 404 dZoneQuantEnable); 405 406 if (sfbDistLdData < sfbDistBestLdData) { 407 scfBest = scf; 408 sfbDistBestLdData = sfbDistLdData; 409 for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k]; 410 } 411 } 412 /* improve by smaller scf ? */ 413 cnt = 0; 414 scf = scfEstimated; 415 sfbDistLdData = sfbDistBestLdData; 416 while ((sfbDistLdData > (threshLdData - distFactorLdData)) && (cnt++ < 1) && 417 (scf > minScf)) { 418 scf--; 419 sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf, 420 dZoneQuantEnable); 421 422 if (sfbDistLdData < sfbDistBestLdData) { 423 scfBest = scf; 424 sfbDistBestLdData = sfbDistLdData; 425 for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k]; 426 } 427 *minScfCalculated = scf; 428 } 429 *distLdData = sfbDistBestLdData; 430 } else { /* nmr <= 1.25 -> try to find bigger scf to use less bits */ 431 FIXP_DBL sfbDistBestLdData = sfbDistLdData; 432 FIXP_DBL sfbDistAllowedLdData = 433 fixMin(sfbDistLdData - distFactorLdData, threshLdData); 434 int cnt; 435 for (cnt = 0; cnt < UPCOUNT_LIMIT; cnt++) { 436 scf++; 437 sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf, 438 dZoneQuantEnable); 439 440 if (sfbDistLdData < sfbDistAllowedLdData) { 441 *minScfCalculated = scfBest + 1; 442 scfBest = scf; 443 sfbDistBestLdData = sfbDistLdData; 444 for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k]; 445 } 446 } 447 *distLdData = sfbDistBestLdData; 448 } 449 450 /* return best scalefactor */ 451 return scfBest; 452 } 453 454 /* 455 Function: FDKaacEnc_assimilateSingleScf 456 457 */ 458 static void FDKaacEnc_assimilateSingleScf( 459 const PSY_OUT_CHANNEL *psyOutChan, const QC_OUT_CHANNEL *qcOutChannel, 460 SHORT *quantSpec, SHORT *quantSpecTmp, INT dZoneQuantEnable, INT *scf, 461 const INT *minScf, FIXP_DBL *sfbDist, FIXP_DBL *sfbConstPePart, 462 const FIXP_DBL *sfbFormFactorLdData, const FIXP_DBL *sfbNRelevantLines, 463 INT *minScfCalculated, INT restartOnSuccess) { 464 INT sfbLast, sfbAct, sfbNext; 465 INT scfAct, *scfLast, *scfNext, scfMin, scfMax; 466 INT sfbWidth, sfbOffs; 467 FIXP_DBL enLdData; 468 FIXP_DBL sfbPeOld, sfbPeNew; 469 FIXP_DBL sfbDistNew; 470 INT i, k; 471 INT success = 0; 472 FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f); 473 FIXP_DBL deltaPeNew, deltaPeTmp; 474 INT prevScfLast[MAX_GROUPED_SFB], prevScfNext[MAX_GROUPED_SFB]; 475 FIXP_DBL deltaPeLast[MAX_GROUPED_SFB]; 476 INT updateMinScfCalculated; 477 478 for (i = 0; i < psyOutChan->sfbCnt; i++) { 479 prevScfLast[i] = FDK_INT_MAX; 480 prevScfNext[i] = FDK_INT_MAX; 481 deltaPeLast[i] = (FIXP_DBL)FDK_INT_MAX; 482 } 483 484 sfbLast = -1; 485 sfbAct = -1; 486 sfbNext = -1; 487 scfLast = 0; 488 scfNext = 0; 489 scfMin = FDK_INT_MAX; 490 scfMax = FDK_INT_MAX; 491 do { 492 /* search for new relevant sfb */ 493 sfbNext++; 494 while ((sfbNext < psyOutChan->sfbCnt) && (scf[sfbNext] == FDK_INT_MIN)) 495 sfbNext++; 496 if ((sfbLast >= 0) && (sfbAct >= 0) && (sfbNext < psyOutChan->sfbCnt)) { 497 /* relevant scfs to the left and to the right */ 498 scfAct = scf[sfbAct]; 499 scfLast = scf + sfbLast; 500 scfNext = scf + sfbNext; 501 scfMin = fixMin(*scfLast, *scfNext); 502 scfMax = fixMax(*scfLast, *scfNext); 503 } else if ((sfbLast == -1) && (sfbAct >= 0) && 504 (sfbNext < psyOutChan->sfbCnt)) { 505 /* first relevant scf */ 506 scfAct = scf[sfbAct]; 507 scfLast = &scfAct; 508 scfNext = scf + sfbNext; 509 scfMin = *scfNext; 510 scfMax = *scfNext; 511 } else if ((sfbLast >= 0) && (sfbAct >= 0) && 512 (sfbNext == psyOutChan->sfbCnt)) { 513 /* last relevant scf */ 514 scfAct = scf[sfbAct]; 515 scfLast = scf + sfbLast; 516 scfNext = &scfAct; 517 scfMin = *scfLast; 518 scfMax = *scfLast; 519 } 520 if (sfbAct >= 0) scfMin = fixMax(scfMin, minScf[sfbAct]); 521 522 if ((sfbAct >= 0) && (sfbLast >= 0 || sfbNext < psyOutChan->sfbCnt) && 523 (scfAct > scfMin) && (scfAct <= scfMin + MAX_SCF_DELTA) && 524 (scfAct >= scfMax - MAX_SCF_DELTA) && 525 (scfAct <= 526 fixMin(scfMin, fixMin(*scfLast, *scfNext)) + MAX_SCF_DELTA) && 527 (*scfLast != prevScfLast[sfbAct] || *scfNext != prevScfNext[sfbAct] || 528 deltaPe < deltaPeLast[sfbAct])) { 529 /* bigger than neighbouring scf found, try to use smaller scf */ 530 success = 0; 531 532 sfbWidth = 533 psyOutChan->sfbOffsets[sfbAct + 1] - psyOutChan->sfbOffsets[sfbAct]; 534 sfbOffs = psyOutChan->sfbOffsets[sfbAct]; 535 536 /* estimate required bits for actual scf */ 537 enLdData = qcOutChannel->sfbEnergyLdData[sfbAct]; 538 539 /* sfbConstPePart[sfbAct] = (float)log(6.75f*en/sfbFormFactor[sfbAct]) * 540 * LOG2_1; */ 541 /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for 542 * log2 */ 543 /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */ 544 if (sfbConstPePart[sfbAct] == (FIXP_DBL)FDK_INT_MIN) { 545 sfbConstPePart[sfbAct] = ((enLdData - sfbFormFactorLdData[sfbAct] - 546 FL2FXCONST_DBL(0.09375f)) >> 547 1) + 548 FL2FXCONST_DBL(0.02152255861f); 549 } 550 551 sfbPeOld = FDKaacEnc_calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct], 552 sfbNRelevantLines[sfbAct]) + 553 FDKaacEnc_countSingleScfBits(scfAct, *scfLast, *scfNext); 554 555 deltaPeNew = deltaPe; 556 updateMinScfCalculated = 1; 557 558 do { 559 /* estimate required bits for smaller scf */ 560 scfAct--; 561 /* check only if the same check was not done before */ 562 if (scfAct < minScfCalculated[sfbAct] && 563 scfAct >= scfMax - MAX_SCF_DELTA) { 564 /* estimate required bits for new scf */ 565 sfbPeNew = FDKaacEnc_calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct], 566 sfbNRelevantLines[sfbAct]) + 567 FDKaacEnc_countSingleScfBits(scfAct, *scfLast, *scfNext); 568 569 /* use new scf if no increase in pe and 570 quantization error is smaller */ 571 deltaPeTmp = deltaPe + sfbPeNew - sfbPeOld; 572 /* 0.0006103515625f = 10.0f/(2^(2*AS_PE_FAC_SHIFT)) */ 573 if (deltaPeTmp < FL2FXCONST_DBL(0.0006103515625f)) { 574 /* distortion of new scf */ 575 sfbDistNew = FDKaacEnc_calcSfbDist( 576 qcOutChannel->mdctSpectrum + sfbOffs, quantSpecTmp + sfbOffs, 577 sfbWidth, scfAct, dZoneQuantEnable); 578 579 if (sfbDistNew < sfbDist[sfbAct]) { 580 /* success, replace scf by new one */ 581 scf[sfbAct] = scfAct; 582 sfbDist[sfbAct] = sfbDistNew; 583 584 for (k = 0; k < sfbWidth; k++) 585 quantSpec[sfbOffs + k] = quantSpecTmp[sfbOffs + k]; 586 587 deltaPeNew = deltaPeTmp; 588 success = 1; 589 } 590 /* mark as already checked */ 591 if (updateMinScfCalculated) minScfCalculated[sfbAct] = scfAct; 592 } else { 593 /* from this scf value on not all new values have been checked */ 594 updateMinScfCalculated = 0; 595 } 596 } 597 } while (scfAct > scfMin); 598 599 deltaPe = deltaPeNew; 600 601 /* save parameters to avoid multiple computations of the same sfb */ 602 prevScfLast[sfbAct] = *scfLast; 603 prevScfNext[sfbAct] = *scfNext; 604 deltaPeLast[sfbAct] = deltaPe; 605 } 606 607 if (success && restartOnSuccess) { 608 /* start again at first sfb */ 609 sfbLast = -1; 610 sfbAct = -1; 611 sfbNext = -1; 612 scfLast = 0; 613 scfNext = 0; 614 scfMin = FDK_INT_MAX; 615 scfMax = FDK_INT_MAX; 616 success = 0; 617 } else { 618 /* shift sfbs for next band */ 619 sfbLast = sfbAct; 620 sfbAct = sfbNext; 621 } 622 } while (sfbNext < psyOutChan->sfbCnt); 623 } 624 625 /* 626 Function: FDKaacEnc_assimilateMultipleScf 627 628 */ 629 static void FDKaacEnc_assimilateMultipleScf( 630 PSY_OUT_CHANNEL *psyOutChan, QC_OUT_CHANNEL *qcOutChannel, SHORT *quantSpec, 631 SHORT *quantSpecTmp, INT dZoneQuantEnable, INT *scf, const INT *minScf, 632 FIXP_DBL *sfbDist, FIXP_DBL *sfbConstPePart, FIXP_DBL *sfbFormFactorLdData, 633 FIXP_DBL *sfbNRelevantLines) { 634 INT sfb, startSfb, stopSfb; 635 INT scfTmp[MAX_GROUPED_SFB], scfMin, scfMax, scfAct; 636 INT possibleRegionFound; 637 INT sfbWidth, sfbOffs, i, k; 638 FIXP_DBL sfbDistNew[MAX_GROUPED_SFB], distOldSum, distNewSum; 639 INT deltaScfBits; 640 FIXP_DBL deltaSpecPe; 641 FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f); 642 FIXP_DBL deltaPeNew; 643 INT sfbCnt = psyOutChan->sfbCnt; 644 645 /* calc min and max scalfactors */ 646 scfMin = FDK_INT_MAX; 647 scfMax = FDK_INT_MIN; 648 for (sfb = 0; sfb < sfbCnt; sfb++) { 649 if (scf[sfb] != FDK_INT_MIN) { 650 scfMin = fixMin(scfMin, scf[sfb]); 651 scfMax = fixMax(scfMax, scf[sfb]); 652 } 653 } 654 655 if (scfMax != FDK_INT_MIN && scfMax <= scfMin + MAX_SCF_DELTA) { 656 scfAct = scfMax; 657 658 do { 659 /* try smaller scf */ 660 scfAct--; 661 for (i = 0; i < MAX_GROUPED_SFB; i++) scfTmp[i] = scf[i]; 662 stopSfb = 0; 663 do { 664 /* search for region where all scfs are bigger than scfAct */ 665 sfb = stopSfb; 666 while (sfb < sfbCnt && (scf[sfb] == FDK_INT_MIN || scf[sfb] <= scfAct)) 667 sfb++; 668 startSfb = sfb; 669 sfb++; 670 while (sfb < sfbCnt && (scf[sfb] == FDK_INT_MIN || scf[sfb] > scfAct)) 671 sfb++; 672 stopSfb = sfb; 673 674 /* check if in all sfb of a valid region scfAct >= minScf[sfb] */ 675 possibleRegionFound = 0; 676 if (startSfb < sfbCnt) { 677 possibleRegionFound = 1; 678 for (sfb = startSfb; sfb < stopSfb; sfb++) { 679 if (scf[sfb] != FDK_INT_MIN) 680 if (scfAct < minScf[sfb]) { 681 possibleRegionFound = 0; 682 break; 683 } 684 } 685 } 686 687 if (possibleRegionFound) { /* region found */ 688 689 /* replace scfs in region by scfAct */ 690 for (sfb = startSfb; sfb < stopSfb; sfb++) { 691 if (scfTmp[sfb] != FDK_INT_MIN) scfTmp[sfb] = scfAct; 692 } 693 694 /* estimate change in bit demand for new scfs */ 695 deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt, 696 startSfb, stopSfb); 697 698 deltaSpecPe = FDKaacEnc_calcSpecPeDiff( 699 psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart, 700 sfbFormFactorLdData, sfbNRelevantLines, startSfb, stopSfb); 701 702 deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe; 703 704 /* new bit demand small enough ? */ 705 /* 0.0006103515625f = 10.0f/(2^(2*AS_PE_FAC_SHIFT)) */ 706 if (deltaPeNew < FL2FXCONST_DBL(0.0006103515625f)) { 707 /* quantize and calc sum of new distortion */ 708 distOldSum = distNewSum = FL2FXCONST_DBL(0.0f); 709 for (sfb = startSfb; sfb < stopSfb; sfb++) { 710 if (scfTmp[sfb] != FDK_INT_MIN) { 711 distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT; 712 713 sfbWidth = psyOutChan->sfbOffsets[sfb + 1] - 714 psyOutChan->sfbOffsets[sfb]; 715 sfbOffs = psyOutChan->sfbOffsets[sfb]; 716 717 sfbDistNew[sfb] = FDKaacEnc_calcSfbDist( 718 qcOutChannel->mdctSpectrum + sfbOffs, 719 quantSpecTmp + sfbOffs, sfbWidth, scfAct, dZoneQuantEnable); 720 721 if (sfbDistNew[sfb] > qcOutChannel->sfbThresholdLdData[sfb]) { 722 /* no improvement, skip further dist. calculations */ 723 distNewSum = distOldSum << 1; 724 break; 725 } 726 distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT; 727 } 728 } 729 /* distortion smaller ? -> use new scalefactors */ 730 if (distNewSum < distOldSum) { 731 deltaPe = deltaPeNew; 732 for (sfb = startSfb; sfb < stopSfb; sfb++) { 733 if (scf[sfb] != FDK_INT_MIN) { 734 sfbWidth = psyOutChan->sfbOffsets[sfb + 1] - 735 psyOutChan->sfbOffsets[sfb]; 736 sfbOffs = psyOutChan->sfbOffsets[sfb]; 737 scf[sfb] = scfAct; 738 sfbDist[sfb] = sfbDistNew[sfb]; 739 740 for (k = 0; k < sfbWidth; k++) 741 quantSpec[sfbOffs + k] = quantSpecTmp[sfbOffs + k]; 742 } 743 } 744 } 745 } 746 } 747 748 } while (stopSfb <= sfbCnt); 749 750 } while (scfAct > scfMin); 751 } 752 } 753 754 /* 755 Function: FDKaacEnc_FDKaacEnc_assimilateMultipleScf2 756 757 */ 758 static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2( 759 PSY_OUT_CHANNEL *psyOutChan, QC_OUT_CHANNEL *qcOutChannel, SHORT *quantSpec, 760 SHORT *quantSpecTmp, INT dZoneQuantEnable, INT *scf, const INT *minScf, 761 FIXP_DBL *sfbDist, FIXP_DBL *sfbConstPePart, FIXP_DBL *sfbFormFactorLdData, 762 FIXP_DBL *sfbNRelevantLines) { 763 INT sfb, startSfb, stopSfb; 764 INT scfTmp[MAX_GROUPED_SFB], scfAct, scfNew; 765 INT scfPrev, scfNext, scfPrevNextMin, scfPrevNextMax, scfLo, scfHi; 766 INT scfMin, scfMax; 767 INT *sfbOffs = psyOutChan->sfbOffsets; 768 FIXP_DBL sfbDistNew[MAX_GROUPED_SFB], sfbDistMax[MAX_GROUPED_SFB]; 769 FIXP_DBL distOldSum, distNewSum; 770 INT deltaScfBits; 771 FIXP_DBL deltaSpecPe; 772 FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f); 773 FIXP_DBL deltaPeNew = FL2FXCONST_DBL(0.0f); 774 INT sfbCnt = psyOutChan->sfbCnt; 775 INT bSuccess, bCheckScf; 776 INT i, k; 777 778 /* calc min and max scalfactors */ 779 scfMin = FDK_INT_MAX; 780 scfMax = FDK_INT_MIN; 781 for (sfb = 0; sfb < sfbCnt; sfb++) { 782 if (scf[sfb] != FDK_INT_MIN) { 783 scfMin = fixMin(scfMin, scf[sfb]); 784 scfMax = fixMax(scfMax, scf[sfb]); 785 } 786 } 787 788 stopSfb = 0; 789 scfAct = FDK_INT_MIN; 790 do { 791 /* search for region with same scf values scfAct */ 792 scfPrev = scfAct; 793 794 sfb = stopSfb; 795 while (sfb < sfbCnt && (scf[sfb] == FDK_INT_MIN)) sfb++; 796 startSfb = sfb; 797 scfAct = scf[startSfb]; 798 sfb++; 799 while (sfb < sfbCnt && 800 ((scf[sfb] == FDK_INT_MIN) || (scf[sfb] == scf[startSfb]))) 801 sfb++; 802 stopSfb = sfb; 803 804 if (stopSfb < sfbCnt) 805 scfNext = scf[stopSfb]; 806 else 807 scfNext = scfAct; 808 809 if (scfPrev == FDK_INT_MIN) scfPrev = scfAct; 810 811 scfPrevNextMax = fixMax(scfPrev, scfNext); 812 scfPrevNextMin = fixMin(scfPrev, scfNext); 813 814 /* try to reduce bits by checking scf values in the range 815 scf[startSfb]...scfHi */ 816 scfHi = fixMax(scfPrevNextMax, scfAct); 817 /* try to find a better solution by reducing the scf difference to 818 the nearest possible lower scf */ 819 if (scfPrevNextMax >= scfAct) 820 scfLo = fixMin(scfAct, scfPrevNextMin); 821 else 822 scfLo = scfPrevNextMax; 823 824 if (startSfb < sfbCnt && 825 scfHi - scfLo <= MAX_SCF_DELTA) { /* region found */ 826 /* 1. try to save bits by coarser quantization */ 827 if (scfHi > scf[startSfb]) { 828 /* calculate the allowed distortion */ 829 for (sfb = startSfb; sfb < stopSfb; sfb++) { 830 if (scf[sfb] != FDK_INT_MIN) { 831 /* sfbDistMax[sfb] = 832 * (float)pow(qcOutChannel->sfbThreshold[sfb]*sfbDist[sfb]*sfbDist[sfb],1.0f/3.0f); 833 */ 834 /* sfbDistMax[sfb] = 835 * fixMax(sfbDistMax[sfb],qcOutChannel->sfbEnergy[sfb]*FL2FXCONST_DBL(1.e-3f)); 836 */ 837 /* -0.15571537944 = ld64(1.e-3f)*/ 838 sfbDistMax[sfb] = fMult(FL2FXCONST_DBL(1.0f / 3.0f), 839 qcOutChannel->sfbThresholdLdData[sfb]) + 840 fMult(FL2FXCONST_DBL(1.0f / 3.0f), sfbDist[sfb]) + 841 fMult(FL2FXCONST_DBL(1.0f / 3.0f), sfbDist[sfb]); 842 sfbDistMax[sfb] = 843 fixMax(sfbDistMax[sfb], qcOutChannel->sfbEnergyLdData[sfb] - 844 FL2FXCONST_DBL(0.15571537944)); 845 sfbDistMax[sfb] = 846 fixMin(sfbDistMax[sfb], qcOutChannel->sfbThresholdLdData[sfb]); 847 } 848 } 849 850 /* loop over all possible scf values for this region */ 851 bCheckScf = 1; 852 for (scfNew = scf[startSfb] + 1; scfNew <= scfHi; scfNew++) { 853 for (k = 0; k < MAX_GROUPED_SFB; k++) scfTmp[k] = scf[k]; 854 855 /* replace scfs in region by scfNew */ 856 for (sfb = startSfb; sfb < stopSfb; sfb++) { 857 if (scfTmp[sfb] != FDK_INT_MIN) scfTmp[sfb] = scfNew; 858 } 859 860 /* estimate change in bit demand for new scfs */ 861 deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt, 862 startSfb, stopSfb); 863 864 deltaSpecPe = FDKaacEnc_calcSpecPeDiff( 865 psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart, 866 sfbFormFactorLdData, sfbNRelevantLines, startSfb, stopSfb); 867 868 deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe; 869 870 /* new bit demand small enough ? */ 871 if (deltaPeNew < FL2FXCONST_DBL(0.0f)) { 872 bSuccess = 1; 873 874 /* quantize and calc sum of new distortion */ 875 for (sfb = startSfb; sfb < stopSfb; sfb++) { 876 if (scfTmp[sfb] != FDK_INT_MIN) { 877 sfbDistNew[sfb] = FDKaacEnc_calcSfbDist( 878 qcOutChannel->mdctSpectrum + sfbOffs[sfb], 879 quantSpecTmp + sfbOffs[sfb], 880 sfbOffs[sfb + 1] - sfbOffs[sfb], scfNew, dZoneQuantEnable); 881 882 if (sfbDistNew[sfb] > sfbDistMax[sfb]) { 883 /* no improvement, skip further dist. calculations */ 884 bSuccess = 0; 885 if (sfbDistNew[sfb] == qcOutChannel->sfbEnergyLdData[sfb]) { 886 /* if whole sfb is already quantized to 0, further 887 checks with even coarser quant. are useless*/ 888 bCheckScf = 0; 889 } 890 break; 891 } 892 } 893 } 894 if (bCheckScf == 0) /* further calculations useless ? */ 895 break; 896 /* distortion small enough ? -> use new scalefactors */ 897 if (bSuccess) { 898 deltaPe = deltaPeNew; 899 for (sfb = startSfb; sfb < stopSfb; sfb++) { 900 if (scf[sfb] != FDK_INT_MIN) { 901 scf[sfb] = scfNew; 902 sfbDist[sfb] = sfbDistNew[sfb]; 903 904 for (k = 0; k < sfbOffs[sfb + 1] - sfbOffs[sfb]; k++) 905 quantSpec[sfbOffs[sfb] + k] = 906 quantSpecTmp[sfbOffs[sfb] + k]; 907 } 908 } 909 } 910 } 911 } 912 } 913 914 /* 2. only if coarser quantization was not successful, try to find 915 a better solution by finer quantization and reducing bits for 916 scalefactor coding */ 917 if (scfAct == scf[startSfb] && scfLo < scfAct && 918 scfMax - scfMin <= MAX_SCF_DELTA) { 919 int bminScfViolation = 0; 920 921 for (k = 0; k < MAX_GROUPED_SFB; k++) scfTmp[k] = scf[k]; 922 923 scfNew = scfLo; 924 925 /* replace scfs in region by scfNew and 926 check if in all sfb scfNew >= minScf[sfb] */ 927 for (sfb = startSfb; sfb < stopSfb; sfb++) { 928 if (scfTmp[sfb] != FDK_INT_MIN) { 929 scfTmp[sfb] = scfNew; 930 if (scfNew < minScf[sfb]) bminScfViolation = 1; 931 } 932 } 933 934 if (!bminScfViolation) { 935 /* estimate change in bit demand for new scfs */ 936 deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt, 937 startSfb, stopSfb); 938 939 deltaSpecPe = FDKaacEnc_calcSpecPeDiff( 940 psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart, 941 sfbFormFactorLdData, sfbNRelevantLines, startSfb, stopSfb); 942 943 deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe; 944 } 945 946 /* new bit demand small enough ? */ 947 if (!bminScfViolation && deltaPeNew < FL2FXCONST_DBL(0.0f)) { 948 /* quantize and calc sum of new distortion */ 949 distOldSum = distNewSum = FL2FXCONST_DBL(0.0f); 950 for (sfb = startSfb; sfb < stopSfb; sfb++) { 951 if (scfTmp[sfb] != FDK_INT_MIN) { 952 distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT; 953 954 sfbDistNew[sfb] = FDKaacEnc_calcSfbDist( 955 qcOutChannel->mdctSpectrum + sfbOffs[sfb], 956 quantSpecTmp + sfbOffs[sfb], sfbOffs[sfb + 1] - sfbOffs[sfb], 957 scfNew, dZoneQuantEnable); 958 959 if (sfbDistNew[sfb] > qcOutChannel->sfbThresholdLdData[sfb]) { 960 /* no improvement, skip further dist. calculations */ 961 distNewSum = distOldSum << 1; 962 break; 963 } 964 distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT; 965 } 966 } 967 /* distortion smaller ? -> use new scalefactors */ 968 if (distNewSum < fMult(FL2FXCONST_DBL(0.8f), distOldSum)) { 969 deltaPe = deltaPeNew; 970 for (sfb = startSfb; sfb < stopSfb; sfb++) { 971 if (scf[sfb] != FDK_INT_MIN) { 972 scf[sfb] = scfNew; 973 sfbDist[sfb] = sfbDistNew[sfb]; 974 975 for (k = 0; k < sfbOffs[sfb + 1] - sfbOffs[sfb]; k++) 976 quantSpec[sfbOffs[sfb] + k] = quantSpecTmp[sfbOffs[sfb] + k]; 977 } 978 } 979 } 980 } 981 } 982 983 /* 3. try to find a better solution (save bits) by only reducing the 984 scalefactor without new quantization */ 985 if (scfMax - scfMin <= 986 MAX_SCF_DELTA - 3) { /* 3 bec. scf is reduced 3 times, 987 see for loop below */ 988 989 for (k = 0; k < sfbCnt; k++) scfTmp[k] = scf[k]; 990 991 for (i = 0; i < 3; i++) { 992 scfNew = scfTmp[startSfb] - 1; 993 /* replace scfs in region by scfNew */ 994 for (sfb = startSfb; sfb < stopSfb; sfb++) { 995 if (scfTmp[sfb] != FDK_INT_MIN) scfTmp[sfb] = scfNew; 996 } 997 /* estimate change in bit demand for new scfs */ 998 deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt, 999 startSfb, stopSfb); 1000 deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits; 1001 /* new bit demand small enough ? */ 1002 if (deltaPeNew <= FL2FXCONST_DBL(0.0f)) { 1003 bSuccess = 1; 1004 distOldSum = distNewSum = FL2FXCONST_DBL(0.0f); 1005 for (sfb = startSfb; sfb < stopSfb; sfb++) { 1006 if (scfTmp[sfb] != FDK_INT_MIN) { 1007 FIXP_DBL sfbEnQ; 1008 /* calc the energy and distortion of the quantized spectrum for 1009 a smaller scf */ 1010 FDKaacEnc_calcSfbQuantEnergyAndDist( 1011 qcOutChannel->mdctSpectrum + sfbOffs[sfb], 1012 quantSpec + sfbOffs[sfb], sfbOffs[sfb + 1] - sfbOffs[sfb], 1013 scfNew, &sfbEnQ, &sfbDistNew[sfb]); 1014 1015 distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT; 1016 distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT; 1017 1018 /* 0.00259488556167 = ld64(1.122f) */ 1019 /* -0.00778722686652 = ld64(0.7079f) */ 1020 if ((sfbDistNew[sfb] > 1021 (sfbDist[sfb] + FL2FXCONST_DBL(0.00259488556167f))) || 1022 (sfbEnQ < (qcOutChannel->sfbEnergyLdData[sfb] - 1023 FL2FXCONST_DBL(0.00778722686652f)))) { 1024 bSuccess = 0; 1025 break; 1026 } 1027 } 1028 } 1029 /* distortion smaller ? -> use new scalefactors */ 1030 if (distNewSum < distOldSum && bSuccess) { 1031 deltaPe = deltaPeNew; 1032 for (sfb = startSfb; sfb < stopSfb; sfb++) { 1033 if (scf[sfb] != FDK_INT_MIN) { 1034 scf[sfb] = scfNew; 1035 sfbDist[sfb] = sfbDistNew[sfb]; 1036 } 1037 } 1038 } 1039 } 1040 } 1041 } 1042 } 1043 } while (stopSfb <= sfbCnt); 1044 } 1045 1046 static void FDKaacEnc_EstimateScaleFactorsChannel( 1047 QC_OUT_CHANNEL *qcOutChannel, PSY_OUT_CHANNEL *psyOutChannel, 1048 INT *RESTRICT scf, INT *RESTRICT globalGain, 1049 FIXP_DBL *RESTRICT sfbFormFactorLdData, const INT invQuant, 1050 SHORT *RESTRICT quantSpec, const INT dZoneQuantEnable) { 1051 INT i, j, sfb, sfbOffs; 1052 INT scfInt; 1053 INT maxSf; 1054 INT minSf; 1055 FIXP_DBL threshLdData; 1056 FIXP_DBL energyLdData; 1057 FIXP_DBL energyPartLdData; 1058 FIXP_DBL thresholdPartLdData; 1059 FIXP_DBL scfFract; 1060 FIXP_DBL maxSpec; 1061 INT minScfCalculated[MAX_GROUPED_SFB]; 1062 FIXP_DBL sfbDistLdData[MAX_GROUPED_SFB]; 1063 C_ALLOC_SCRATCH_START(quantSpecTmp, SHORT, (1024)) 1064 INT minSfMaxQuant[MAX_GROUPED_SFB]; 1065 1066 FIXP_DBL threshConstLdData = 1067 FL2FXCONST_DBL(0.04304511722f); /* log10(6.75)/log10(2.0)/64.0 */ 1068 FIXP_DBL convConst = FL2FXCONST_DBL(0.30102999566f); /* log10(2.0) */ 1069 FIXP_DBL c1Const = 1070 FL2FXCONST_DBL(-0.27083183594f); /* C1 = -69.33295 => C1/2^8 */ 1071 1072 if (invQuant > 0) { 1073 FDKmemclear(quantSpec, (1024) * sizeof(SHORT)); 1074 } 1075 1076 /* scfs without energy or with thresh>energy are marked with FDK_INT_MIN */ 1077 for (i = 0; i < psyOutChannel->sfbCnt; i++) { 1078 scf[i] = FDK_INT_MIN; 1079 } 1080 1081 for (i = 0; i < MAX_GROUPED_SFB; i++) { 1082 minSfMaxQuant[i] = FDK_INT_MIN; 1083 } 1084 1085 for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt; 1086 sfbOffs += psyOutChannel->sfbPerGroup) { 1087 for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { 1088 threshLdData = qcOutChannel->sfbThresholdLdData[sfbOffs + sfb]; 1089 energyLdData = qcOutChannel->sfbEnergyLdData[sfbOffs + sfb]; 1090 1091 sfbDistLdData[sfbOffs + sfb] = energyLdData; 1092 1093 if (energyLdData > threshLdData) { 1094 FIXP_DBL tmp; 1095 1096 /* energyPart = (float)log10(sfbFormFactor[sfbOffs+sfb]); */ 1097 /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */ 1098 energyPartLdData = 1099 sfbFormFactorLdData[sfbOffs + sfb] + FL2FXCONST_DBL(0.09375f); 1100 1101 /* influence of allowed distortion */ 1102 /* thresholdPart = (float)log10(6.75*thresh+FLT_MIN); */ 1103 thresholdPartLdData = threshConstLdData + threshLdData; 1104 1105 /* scf calc */ 1106 /* scfFloat = 8.8585f * (thresholdPart - energyPart); */ 1107 scfFract = thresholdPartLdData - energyPartLdData; 1108 /* conversion from log2 to log10 */ 1109 scfFract = fMult(convConst, scfFract); 1110 /* (8.8585f * scfFract)/8 = 8/8 * scfFract + 0.8585 * scfFract/8 */ 1111 scfFract = scfFract + fMult(FL2FXCONST_DBL(0.8585f), scfFract >> 3); 1112 1113 /* integer scalefactor */ 1114 /* scfInt = (int)floor(scfFloat); */ 1115 scfInt = 1116 (INT)(scfFract >> 1117 ((DFRACT_BITS - 1) - 3 - 1118 LD_DATA_SHIFT)); /* 3 bits => scfFract/8.0; 6 bits => ld64 */ 1119 1120 /* maximum of spectrum */ 1121 maxSpec = FL2FXCONST_DBL(0.0f); 1122 1123 /* Unroll by 4, allow dual memory access */ 1124 DWORD_ALIGNED(qcOutChannel->mdctSpectrum); 1125 for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb]; 1126 j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j += 4) { 1127 maxSpec = fMax(maxSpec, 1128 fMax(fMax(fAbs(qcOutChannel->mdctSpectrum[j + 0]), 1129 fAbs(qcOutChannel->mdctSpectrum[j + 1])), 1130 fMax(fAbs(qcOutChannel->mdctSpectrum[j + 2]), 1131 fAbs(qcOutChannel->mdctSpectrum[j + 3])))); 1132 } 1133 /* lower scf limit to avoid quantized values bigger than MAX_QUANT */ 1134 /* C1 = -69.33295f, C2 = 5.77078f = 4/log(2) */ 1135 /* minSfMaxQuant[sfbOffs+sfb] = (int)ceil(C1 + C2*log(maxSpec)); */ 1136 /* C1/2^8 + 4/log(2.0)*log(maxSpec)/2^8 => C1/2^8 + 1137 * log(maxSpec)/log(2.0)*4/2^8 => C1/2^8 + log(maxSpec)/log(2.0)/64.0 */ 1138 1139 // minSfMaxQuant[sfbOffs+sfb] = ((INT) ((c1Const + CalcLdData(maxSpec)) 1140 // >> ((DFRACT_BITS-1)-8))) + 1; 1141 tmp = CalcLdData(maxSpec); 1142 if (c1Const > FL2FXCONST_DBL(-1.f) - tmp) { 1143 minSfMaxQuant[sfbOffs + sfb] = 1144 ((INT)((c1Const + tmp) >> ((DFRACT_BITS - 1) - 8))) + 1; 1145 } else { 1146 minSfMaxQuant[sfbOffs + sfb] = 1147 ((INT)(FL2FXCONST_DBL(-1.f) >> ((DFRACT_BITS - 1) - 8))) + 1; 1148 } 1149 1150 scfInt = fixMax(scfInt, minSfMaxQuant[sfbOffs + sfb]); 1151 1152 /* find better scalefactor with analysis by synthesis */ 1153 if (invQuant > 0) { 1154 scfInt = FDKaacEnc_improveScf( 1155 qcOutChannel->mdctSpectrum + 1156 psyOutChannel->sfbOffsets[sfbOffs + sfb], 1157 quantSpec + psyOutChannel->sfbOffsets[sfbOffs + sfb], 1158 quantSpecTmp + psyOutChannel->sfbOffsets[sfbOffs + sfb], 1159 psyOutChannel->sfbOffsets[sfbOffs + sfb + 1] - 1160 psyOutChannel->sfbOffsets[sfbOffs + sfb], 1161 threshLdData, scfInt, minSfMaxQuant[sfbOffs + sfb], 1162 &sfbDistLdData[sfbOffs + sfb], &minScfCalculated[sfbOffs + sfb], 1163 dZoneQuantEnable); 1164 } 1165 scf[sfbOffs + sfb] = scfInt; 1166 } 1167 } 1168 } 1169 1170 if (invQuant > 0) { 1171 /* try to decrease scf differences */ 1172 FIXP_DBL sfbConstPePart[MAX_GROUPED_SFB]; 1173 FIXP_DBL sfbNRelevantLines[MAX_GROUPED_SFB]; 1174 1175 for (i = 0; i < psyOutChannel->sfbCnt; i++) 1176 sfbConstPePart[i] = (FIXP_DBL)FDK_INT_MIN; 1177 1178 FDKaacEnc_calcSfbRelevantLines( 1179 sfbFormFactorLdData, qcOutChannel->sfbEnergyLdData, 1180 qcOutChannel->sfbThresholdLdData, psyOutChannel->sfbOffsets, 1181 psyOutChannel->sfbCnt, psyOutChannel->sfbPerGroup, 1182 psyOutChannel->maxSfbPerGroup, sfbNRelevantLines); 1183 1184 FDKaacEnc_assimilateSingleScf( 1185 psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, dZoneQuantEnable, 1186 scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart, sfbFormFactorLdData, 1187 sfbNRelevantLines, minScfCalculated, 1); 1188 1189 if (invQuant > 1) { 1190 FDKaacEnc_assimilateMultipleScf( 1191 psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, 1192 dZoneQuantEnable, scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart, 1193 sfbFormFactorLdData, sfbNRelevantLines); 1194 1195 FDKaacEnc_FDKaacEnc_assimilateMultipleScf2( 1196 psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, 1197 dZoneQuantEnable, scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart, 1198 sfbFormFactorLdData, sfbNRelevantLines); 1199 } 1200 } 1201 1202 /* get min scalefac */ 1203 minSf = FDK_INT_MAX; 1204 for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt; 1205 sfbOffs += psyOutChannel->sfbPerGroup) { 1206 for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { 1207 if (scf[sfbOffs + sfb] != FDK_INT_MIN) 1208 minSf = fixMin(minSf, scf[sfbOffs + sfb]); 1209 } 1210 } 1211 1212 /* limit scf delta */ 1213 for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt; 1214 sfbOffs += psyOutChannel->sfbPerGroup) { 1215 for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { 1216 if ((scf[sfbOffs + sfb] != FDK_INT_MIN) && 1217 (minSf + MAX_SCF_DELTA) < scf[sfbOffs + sfb]) { 1218 scf[sfbOffs + sfb] = minSf + MAX_SCF_DELTA; 1219 if (invQuant > 0) { /* changed bands need to be quantized again */ 1220 sfbDistLdData[sfbOffs + sfb] = FDKaacEnc_calcSfbDist( 1221 qcOutChannel->mdctSpectrum + 1222 psyOutChannel->sfbOffsets[sfbOffs + sfb], 1223 quantSpec + psyOutChannel->sfbOffsets[sfbOffs + sfb], 1224 psyOutChannel->sfbOffsets[sfbOffs + sfb + 1] - 1225 psyOutChannel->sfbOffsets[sfbOffs + sfb], 1226 scf[sfbOffs + sfb], dZoneQuantEnable); 1227 } 1228 } 1229 } 1230 } 1231 1232 /* get max scalefac for global gain */ 1233 maxSf = FDK_INT_MIN; 1234 for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt; 1235 sfbOffs += psyOutChannel->sfbPerGroup) { 1236 for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { 1237 maxSf = fixMax(maxSf, scf[sfbOffs + sfb]); 1238 } 1239 } 1240 1241 /* calc loop scalefactors, if spec is not all zero (i.e. maxSf == -99) */ 1242 if (maxSf > FDK_INT_MIN) { 1243 *globalGain = maxSf; 1244 for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt; 1245 sfbOffs += psyOutChannel->sfbPerGroup) { 1246 for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { 1247 if (scf[sfbOffs + sfb] == FDK_INT_MIN) { 1248 scf[sfbOffs + sfb] = 0; 1249 /* set band explicitely to zero */ 1250 for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb]; 1251 j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j++) { 1252 qcOutChannel->mdctSpectrum[j] = FL2FXCONST_DBL(0.0f); 1253 } 1254 } else { 1255 scf[sfbOffs + sfb] = maxSf - scf[sfbOffs + sfb]; 1256 } 1257 } 1258 } 1259 } else { 1260 *globalGain = 0; 1261 /* set spectrum explicitely to zero */ 1262 for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt; 1263 sfbOffs += psyOutChannel->sfbPerGroup) { 1264 for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { 1265 scf[sfbOffs + sfb] = 0; 1266 /* set band explicitely to zero */ 1267 for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb]; 1268 j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j++) { 1269 qcOutChannel->mdctSpectrum[j] = FL2FXCONST_DBL(0.0f); 1270 } 1271 } 1272 } 1273 } 1274 1275 /* free quantSpecTmp from scratch */ 1276 C_ALLOC_SCRATCH_END(quantSpecTmp, SHORT, (1024)) 1277 } 1278 1279 void FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[], 1280 QC_OUT_CHANNEL *qcOutChannel[], 1281 const INT invQuant, 1282 const INT dZoneQuantEnable, 1283 const INT nChannels) { 1284 int ch; 1285 1286 for (ch = 0; ch < nChannels; ch++) { 1287 FDKaacEnc_EstimateScaleFactorsChannel( 1288 qcOutChannel[ch], psyOutChannel[ch], qcOutChannel[ch]->scf, 1289 &qcOutChannel[ch]->globalGain, qcOutChannel[ch]->sfbFormFactorLdData, 1290 invQuant, qcOutChannel[ch]->quantSpec, dZoneQuantEnable); 1291 } 1292 } 1293