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: Psychoaccoustic configuration 100 101 *******************************************************************************/ 102 103 #include "psy_configuration.h" 104 #include "adj_thr.h" 105 #include "aacEnc_rom.h" 106 107 #include "genericStds.h" 108 109 #include "FDK_trigFcts.h" 110 111 typedef struct { 112 LONG sampleRate; 113 const SFB_PARAM_LONG *paramLong; 114 const SFB_PARAM_SHORT *paramShort; 115 } SFB_INFO_TAB; 116 117 static const SFB_INFO_TAB sfbInfoTab[] = { 118 {8000, &p_FDKaacEnc_8000_long_1024, &p_FDKaacEnc_8000_short_128}, 119 {11025, &p_FDKaacEnc_11025_long_1024, &p_FDKaacEnc_11025_short_128}, 120 {12000, &p_FDKaacEnc_12000_long_1024, &p_FDKaacEnc_12000_short_128}, 121 {16000, &p_FDKaacEnc_16000_long_1024, &p_FDKaacEnc_16000_short_128}, 122 {22050, &p_FDKaacEnc_22050_long_1024, &p_FDKaacEnc_22050_short_128}, 123 {24000, &p_FDKaacEnc_24000_long_1024, &p_FDKaacEnc_24000_short_128}, 124 {32000, &p_FDKaacEnc_32000_long_1024, &p_FDKaacEnc_32000_short_128}, 125 {44100, &p_FDKaacEnc_44100_long_1024, &p_FDKaacEnc_44100_short_128}, 126 {48000, &p_FDKaacEnc_48000_long_1024, &p_FDKaacEnc_48000_short_128}, 127 {64000, &p_FDKaacEnc_64000_long_1024, &p_FDKaacEnc_64000_short_128}, 128 {88200, &p_FDKaacEnc_88200_long_1024, &p_FDKaacEnc_88200_short_128}, 129 {96000, &p_FDKaacEnc_96000_long_1024, &p_FDKaacEnc_96000_short_128} 130 131 }; 132 133 /* 22050 and 24000 Hz */ 134 static const SFB_PARAM_LONG p_22050_long_512 = { 135 31, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 136 12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}}; 137 138 /* 32000 Hz */ 139 static const SFB_PARAM_LONG p_32000_long_512 = { 140 37, 141 {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 142 12, 12, 12, 12, 16, 16, 16, 20, 24, 24, 28, 32, 32, 32, 32, 32, 32, 32}}; 143 144 /* 44100 Hz */ 145 static const SFB_PARAM_LONG p_44100_long_512 = { 146 36, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 147 8, 8, 12, 12, 12, 12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32, 32, 52}}; 148 149 static const SFB_INFO_TAB sfbInfoTabLD512[] = { 150 {8000, &p_22050_long_512, NULL}, {11025, &p_22050_long_512, NULL}, 151 {12000, &p_22050_long_512, NULL}, {16000, &p_22050_long_512, NULL}, 152 {22050, &p_22050_long_512, NULL}, {24000, &p_22050_long_512, NULL}, 153 {32000, &p_32000_long_512, NULL}, {44100, &p_44100_long_512, NULL}, 154 {48000, &p_44100_long_512, NULL}, {64000, &p_44100_long_512, NULL}, 155 {88200, &p_44100_long_512, NULL}, {96000, &p_44100_long_512, NULL}, 156 {128000, &p_44100_long_512, NULL}, {176400, &p_44100_long_512, NULL}, 157 {192000, &p_44100_long_512, NULL}, {256000, &p_44100_long_512, NULL}, 158 {352800, &p_44100_long_512, NULL}, {384000, &p_44100_long_512, NULL}, 159 }; 160 161 /* 22050 and 24000 Hz */ 162 static const SFB_PARAM_LONG p_22050_long_480 = { 163 30, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 164 12, 12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32}}; 165 166 /* 32000 Hz */ 167 static const SFB_PARAM_LONG p_32000_long_480 = { 168 37, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 169 8, 8, 8, 12, 12, 12, 16, 16, 20, 24, 32, 32, 32, 32, 32, 32, 32, 32}}; 170 171 /* 44100 Hz */ 172 static const SFB_PARAM_LONG p_44100_long_480 = { 173 35, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 174 8, 12, 12, 12, 12, 12, 16, 16, 24, 28, 32, 32, 32, 32, 32, 32, 48}}; 175 176 static const SFB_INFO_TAB sfbInfoTabLD480[] = { 177 {8000, &p_22050_long_480, NULL}, {11025, &p_22050_long_480, NULL}, 178 {12000, &p_22050_long_480, NULL}, {16000, &p_22050_long_480, NULL}, 179 {22050, &p_22050_long_480, NULL}, {24000, &p_22050_long_480, NULL}, 180 {32000, &p_32000_long_480, NULL}, {44100, &p_44100_long_480, NULL}, 181 {48000, &p_44100_long_480, NULL}, {64000, &p_44100_long_480, NULL}, 182 {88200, &p_44100_long_480, NULL}, {96000, &p_44100_long_480, NULL}, 183 {128000, &p_44100_long_480, NULL}, {176400, &p_44100_long_480, NULL}, 184 {192000, &p_44100_long_480, NULL}, {256000, &p_44100_long_480, NULL}, 185 {352800, &p_44100_long_480, NULL}, {384000, &p_44100_long_480, NULL}, 186 }; 187 188 /* Fixed point precision definitions */ 189 #define Q_BARCVAL (25) 190 191 AAC_ENCODER_ERROR FDKaacEnc_initSfbTable(const LONG sampleRate, 192 const INT blockType, 193 const INT granuleLength, 194 INT *const sfbOffset, 195 INT *const sfbCnt) { 196 INT i, specStartOffset = 0; 197 INT granuleLengthWindow = granuleLength; 198 const UCHAR *sfbWidth = NULL; 199 const SFB_INFO_TAB *sfbInfo = NULL; 200 int size; 201 202 /* 203 select table 204 */ 205 switch (granuleLength) { 206 case 1024: 207 case 960: 208 sfbInfo = sfbInfoTab; 209 size = (INT)(sizeof(sfbInfoTab) / sizeof(SFB_INFO_TAB)); 210 break; 211 case 512: 212 sfbInfo = sfbInfoTabLD512; 213 size = sizeof(sfbInfoTabLD512); 214 break; 215 case 480: 216 sfbInfo = sfbInfoTabLD480; 217 size = sizeof(sfbInfoTabLD480); 218 break; 219 default: 220 return AAC_ENC_INVALID_FRAME_LENGTH; 221 } 222 223 for (i = 0; i < size; i++) { 224 if (sfbInfo[i].sampleRate == sampleRate) { 225 switch (blockType) { 226 case LONG_WINDOW: 227 case START_WINDOW: 228 case STOP_WINDOW: 229 sfbWidth = sfbInfo[i].paramLong->sfbWidth; 230 *sfbCnt = sfbInfo[i].paramLong->sfbCnt; 231 break; 232 case SHORT_WINDOW: 233 sfbWidth = sfbInfo[i].paramShort->sfbWidth; 234 *sfbCnt = sfbInfo[i].paramShort->sfbCnt; 235 granuleLengthWindow /= TRANS_FAC; 236 break; 237 } 238 break; 239 } 240 } 241 if (i == size) { 242 return AAC_ENC_UNSUPPORTED_SAMPLINGRATE; 243 } 244 245 /* 246 calc sfb offsets 247 */ 248 for (i = 0; i < *sfbCnt; i++) { 249 sfbOffset[i] = specStartOffset; 250 specStartOffset += sfbWidth[i]; 251 if (specStartOffset >= granuleLengthWindow) { 252 i++; 253 break; 254 } 255 } 256 *sfbCnt = fixMin(i, *sfbCnt); 257 sfbOffset[*sfbCnt] = fixMin(specStartOffset, granuleLengthWindow); 258 return AAC_ENC_OK; 259 } 260 261 /***************************************************************************** 262 263 functionname: FDKaacEnc_BarcLineValue 264 description: Calculates barc value for one frequency line 265 returns: barc value of line 266 input: number of lines in transform, index of line to check, Fs 267 output: 268 269 *****************************************************************************/ 270 static FIXP_DBL FDKaacEnc_BarcLineValue(INT noOfLines, INT fftLine, 271 LONG samplingFreq) { 272 FIXP_DBL FOURBY3EM4 = (FIXP_DBL)0x45e7b273; /* 4.0/3 * 0.0001 in q43 */ 273 FIXP_DBL PZZZ76 = (FIXP_DBL)0x639d5e4a; /* 0.00076 in q41 */ 274 FIXP_DBL ONE3P3 = (FIXP_DBL)0x35333333; /* 13.3 in q26 */ 275 FIXP_DBL THREEP5 = (FIXP_DBL)0x1c000000; /* 3.5 in q27 */ 276 FIXP_DBL INV480 = (FIXP_DBL)0x44444444; // 1/480 in q39 277 278 FIXP_DBL center_freq, x1, x2; 279 FIXP_DBL bvalFFTLine, atan1, atan2; 280 281 /* Theoritical maximum of center_freq (samp_freq*0.5) is 96khz * 0.5 = 48000 282 */ 283 /* Theoritical maximum of x1 is 1.3333333e-4f * center_freq = 6.4, can keep in 284 * q28 */ 285 /* Theoritical maximum of x2 is 0.00076f * center_freq = 36.48, can keep in 286 * q25 */ 287 288 center_freq = fftLine * samplingFreq; /* q11 or q8 */ 289 290 switch (noOfLines) { 291 case 1024: 292 center_freq = center_freq << 2; /* q13 */ 293 break; 294 case 128: 295 center_freq = center_freq << 5; /* q13 */ 296 break; 297 case 512: 298 center_freq = (fftLine * samplingFreq) << 3; // q13 299 break; 300 case 480: 301 center_freq = fMult(center_freq, INV480) << 4; // q13 302 break; 303 default: 304 center_freq = (FIXP_DBL)0; 305 } 306 307 x1 = fMult(center_freq, FOURBY3EM4); /* q13 * q43 - (DFRACT_BITS-1) = q25 */ 308 x2 = fMult(center_freq, PZZZ76) 309 << 2; /* q13 * q41 - (DFRACT_BITS-1) + 2 = q25 */ 310 311 atan1 = fixp_atan(x1); 312 atan2 = fixp_atan(x2); 313 314 /* q25 (q26 * q30 - (DFRACT_BITS-1)) + q25 (q27 * q30 * q30) */ 315 bvalFFTLine = fMult(ONE3P3, atan2) + fMult(THREEP5, fMult(atan1, atan1)); 316 return (bvalFFTLine); 317 } 318 319 /* 320 do not consider energies below a certain input signal level, 321 i.e. of -96dB or 1 bit at 16 bit PCM resolution, 322 might need to be configurable to e.g. 24 bit PCM Input or a lower 323 resolution for low bit rates 324 */ 325 static void FDKaacEnc_InitMinPCMResolution(int numPb, int *pbOffset, 326 FIXP_DBL *sfbPCMquantThreshold) { 327 /* PCM_QUANT_NOISE = FDKpow(10.0f, - 20.f / 10.0f) * ABS_LOW * NORM_PCM_ENERGY * 328 * FDKpow(2,PCM_QUANT_THR_SCALE) */ 329 #define PCM_QUANT_NOISE ((FIXP_DBL)0x00547062) 330 331 for (int i = 0; i < numPb; i++) { 332 sfbPCMquantThreshold[i] = (pbOffset[i + 1] - pbOffset[i]) * PCM_QUANT_NOISE; 333 } 334 } 335 336 static FIXP_DBL getMaskFactor(const FIXP_DBL dbVal_fix, const INT dbVal_e, 337 const FIXP_DBL ten_fix, const INT ten_e) { 338 INT q_msk; 339 FIXP_DBL mask_factor; 340 341 mask_factor = fPow(ten_fix, DFRACT_BITS - 1 - ten_e, -dbVal_fix, 342 DFRACT_BITS - 1 - dbVal_e, &q_msk); 343 q_msk = fixMin(DFRACT_BITS - 1, fixMax(-(DFRACT_BITS - 1), q_msk)); 344 345 if ((q_msk > 0) && (mask_factor > (FIXP_DBL)MAXVAL_DBL >> q_msk)) { 346 mask_factor = (FIXP_DBL)MAXVAL_DBL; 347 } else { 348 mask_factor = scaleValue(mask_factor, q_msk); 349 } 350 351 return (mask_factor); 352 } 353 354 static void FDKaacEnc_initSpreading(INT numPb, FIXP_DBL *pbBarcValue, 355 FIXP_DBL *pbMaskLoFactor, 356 FIXP_DBL *pbMaskHiFactor, 357 FIXP_DBL *pbMaskLoFactorSprEn, 358 FIXP_DBL *pbMaskHiFactorSprEn, 359 const LONG bitrate, const INT blockType) 360 361 { 362 INT i; 363 FIXP_DBL MASKLOWSPREN, MASKHIGHSPREN; 364 365 FIXP_DBL MASKHIGH = (FIXP_DBL)0x30000000; /* 1.5 in q29 */ 366 FIXP_DBL MASKLOW = (FIXP_DBL)0x60000000; /* 3.0 in q29 */ 367 FIXP_DBL MASKLOWSPRENLONG = (FIXP_DBL)0x60000000; /* 3.0 in q29 */ 368 FIXP_DBL MASKHIGHSPRENLONG = (FIXP_DBL)0x40000000; /* 2.0 in q29 */ 369 FIXP_DBL MASKHIGHSPRENLONGLOWBR = (FIXP_DBL)0x30000000; /* 1.5 in q29 */ 370 FIXP_DBL MASKLOWSPRENSHORT = (FIXP_DBL)0x40000000; /* 2.0 in q29 */ 371 FIXP_DBL MASKHIGHSPRENSHORT = (FIXP_DBL)0x30000000; /* 1.5 in q29 */ 372 FIXP_DBL TEN = (FIXP_DBL)0x50000000; /* 10.0 in q27 */ 373 374 if (blockType != SHORT_WINDOW) { 375 MASKLOWSPREN = MASKLOWSPRENLONG; 376 MASKHIGHSPREN = 377 (bitrate > 20000) ? MASKHIGHSPRENLONG : MASKHIGHSPRENLONGLOWBR; 378 } else { 379 MASKLOWSPREN = MASKLOWSPRENSHORT; 380 MASKHIGHSPREN = MASKHIGHSPRENSHORT; 381 } 382 383 for (i = 0; i < numPb; i++) { 384 if (i > 0) { 385 pbMaskHiFactor[i] = getMaskFactor( 386 fMult(MASKHIGH, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, 27); 387 388 pbMaskLoFactor[i - 1] = getMaskFactor( 389 fMult(MASKLOW, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, 27); 390 391 pbMaskHiFactorSprEn[i] = getMaskFactor( 392 fMult(MASKHIGHSPREN, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, 393 27); 394 395 pbMaskLoFactorSprEn[i - 1] = getMaskFactor( 396 fMult(MASKLOWSPREN, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, 397 27); 398 } else { 399 pbMaskHiFactor[i] = (FIXP_DBL)0; 400 pbMaskLoFactor[numPb - 1] = (FIXP_DBL)0; 401 pbMaskHiFactorSprEn[i] = (FIXP_DBL)0; 402 pbMaskLoFactorSprEn[numPb - 1] = (FIXP_DBL)0; 403 } 404 } 405 } 406 407 static void FDKaacEnc_initBarcValues(INT numPb, INT *pbOffset, INT numLines, 408 INT samplingFrequency, FIXP_DBL *pbBval) { 409 INT i; 410 FIXP_DBL MAX_BARC = (FIXP_DBL)0x30000000; /* 24.0 in q25 */ 411 412 for (i = 0; i < numPb; i++) { 413 FIXP_DBL v1, v2, cur_bark; 414 v1 = FDKaacEnc_BarcLineValue(numLines, pbOffset[i], samplingFrequency); 415 v2 = FDKaacEnc_BarcLineValue(numLines, pbOffset[i + 1], samplingFrequency); 416 cur_bark = (v1 >> 1) + (v2 >> 1); 417 pbBval[i] = fixMin(cur_bark, MAX_BARC); 418 } 419 } 420 421 static void FDKaacEnc_initMinSnr(const LONG bitrate, const LONG samplerate, 422 const INT numLines, const INT *sfbOffset, 423 const INT sfbActive, const INT blockType, 424 FIXP_DBL *sfbMinSnrLdData) { 425 INT sfb; 426 427 /* Fix conversion variables */ 428 INT qbfac, qperwin, qdiv, qpeprt_const, qpeprt; 429 INT qtmp, qsnr, sfbWidth; 430 431 FIXP_DBL MAX_BARC = (FIXP_DBL)0x30000000; /* 24.0 in q25 */ 432 FIXP_DBL MAX_BARCP1 = (FIXP_DBL)0x32000000; /* 25.0 in q25 */ 433 FIXP_DBL BITS2PEFAC = (FIXP_DBL)0x4b851eb8; /* 1.18 in q30 */ 434 FIXP_DBL PERS2P4 = (FIXP_DBL)0x624dd2f2; /* 0.024 in q36 */ 435 FIXP_DBL ONEP5 = (FIXP_DBL)0x60000000; /* 1.5 in q30 */ 436 FIXP_DBL MAX_SNR = (FIXP_DBL)0x33333333; /* 0.8 in q30 */ 437 FIXP_DBL MIN_SNR = (FIXP_DBL)0x003126e9; /* 0.003 in q30 */ 438 439 FIXP_DBL barcFactor, pePerWindow, pePart, barcWidth; 440 FIXP_DBL pePart_const, tmp, snr, one_qsnr, one_point5; 441 442 /* relative number of active barks */ 443 barcFactor = fDivNorm(fixMin(FDKaacEnc_BarcLineValue( 444 numLines, sfbOffset[sfbActive], samplerate), 445 MAX_BARC), 446 MAX_BARCP1, &qbfac); 447 448 qbfac = DFRACT_BITS - 1 - qbfac; 449 450 pePerWindow = fDivNorm(bitrate, samplerate, &qperwin); 451 qperwin = DFRACT_BITS - 1 - qperwin; 452 pePerWindow = fMult(pePerWindow, BITS2PEFAC); 453 qperwin = qperwin + 30 - (DFRACT_BITS - 1); 454 pePerWindow = fMult(pePerWindow, PERS2P4); 455 qperwin = qperwin + 36 - (DFRACT_BITS - 1); 456 457 switch (numLines) { 458 case 1024: 459 qperwin = qperwin - 10; 460 break; 461 case 128: 462 qperwin = qperwin - 7; 463 break; 464 case 512: 465 qperwin = qperwin - 9; 466 break; 467 case 480: 468 qperwin = qperwin - 9; 469 pePerWindow = fMult(pePerWindow, FL2FXCONST_DBL(480.f / 512.f)); 470 break; 471 } 472 473 /* for short blocks it is assumed that more bits are available */ 474 if (blockType == SHORT_WINDOW) { 475 pePerWindow = fMult(pePerWindow, ONEP5); 476 qperwin = qperwin + 30 - (DFRACT_BITS - 1); 477 } 478 pePart_const = fDivNorm(pePerWindow, barcFactor, &qdiv); 479 qpeprt_const = qperwin - qbfac + DFRACT_BITS - 1 - qdiv; 480 481 for (sfb = 0; sfb < sfbActive; sfb++) { 482 barcWidth = 483 FDKaacEnc_BarcLineValue(numLines, sfbOffset[sfb + 1], samplerate) - 484 FDKaacEnc_BarcLineValue(numLines, sfbOffset[sfb], samplerate); 485 486 /* adapt to sfb bands */ 487 pePart = fMult(pePart_const, barcWidth); 488 qpeprt = qpeprt_const + 25 - (DFRACT_BITS - 1); 489 490 /* pe -> snr calculation */ 491 sfbWidth = (sfbOffset[sfb + 1] - sfbOffset[sfb]); 492 pePart = fDivNorm(pePart, sfbWidth, &qdiv); 493 qpeprt += DFRACT_BITS - 1 - qdiv; 494 495 tmp = f2Pow(pePart, DFRACT_BITS - 1 - qpeprt, &qtmp); 496 qtmp = DFRACT_BITS - 1 - qtmp; 497 498 /* Subtract 1.5 */ 499 qsnr = fixMin(qtmp, 30); 500 tmp = tmp >> (qtmp - qsnr); 501 502 if ((30 + 1 - qsnr) > (DFRACT_BITS - 1)) 503 one_point5 = (FIXP_DBL)0; 504 else 505 one_point5 = (FIXP_DBL)(ONEP5 >> (30 + 1 - qsnr)); 506 507 snr = (tmp >> 1) - (one_point5); 508 qsnr -= 1; 509 510 /* max(snr, 1.0) */ 511 if (qsnr > 0) 512 one_qsnr = (FIXP_DBL)(1 << qsnr); 513 else 514 one_qsnr = (FIXP_DBL)0; 515 516 snr = fixMax(one_qsnr, snr); 517 518 /* 1/snr */ 519 snr = fDivNorm(one_qsnr, snr, &qsnr); 520 qsnr = DFRACT_BITS - 1 - qsnr; 521 snr = (qsnr > 30) ? (snr >> (qsnr - 30)) : snr; 522 523 /* upper limit is -1 dB */ 524 snr = (snr > MAX_SNR) ? MAX_SNR : snr; 525 526 /* lower limit is -25 dB */ 527 snr = (snr < MIN_SNR) ? MIN_SNR : snr; 528 snr = snr << 1; 529 530 sfbMinSnrLdData[sfb] = CalcLdData(snr); 531 } 532 } 533 534 AAC_ENCODER_ERROR FDKaacEnc_InitPsyConfiguration(INT bitrate, INT samplerate, 535 INT bandwidth, INT blocktype, 536 INT granuleLength, INT useIS, 537 INT useMS, 538 PSY_CONFIGURATION *psyConf, 539 FB_TYPE filterbank) { 540 AAC_ENCODER_ERROR ErrorStatus; 541 INT sfb; 542 FIXP_DBL sfbBarcVal[MAX_SFB]; 543 const INT frameLengthLong = granuleLength; 544 const INT frameLengthShort = granuleLength / TRANS_FAC; 545 INT downscaleFactor = 1; 546 547 switch (granuleLength) { 548 case 256: 549 case 240: 550 downscaleFactor = 2; 551 break; 552 case 128: 553 case 120: 554 downscaleFactor = 4; 555 break; 556 default: 557 downscaleFactor = 1; 558 break; 559 } 560 561 FDKmemclear(psyConf, sizeof(PSY_CONFIGURATION)); 562 psyConf->granuleLength = granuleLength; 563 psyConf->filterbank = filterbank; 564 565 psyConf->allowIS = (useIS) && ((bitrate / bandwidth) < 5); 566 psyConf->allowMS = useMS; 567 568 /* init sfb table */ 569 ErrorStatus = FDKaacEnc_initSfbTable(samplerate * downscaleFactor, blocktype, 570 granuleLength * downscaleFactor, 571 psyConf->sfbOffset, &psyConf->sfbCnt); 572 573 if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; 574 575 /* calculate barc values for each pb */ 576 FDKaacEnc_initBarcValues(psyConf->sfbCnt, psyConf->sfbOffset, 577 psyConf->sfbOffset[psyConf->sfbCnt], samplerate, 578 sfbBarcVal); 579 580 FDKaacEnc_InitMinPCMResolution(psyConf->sfbCnt, psyConf->sfbOffset, 581 psyConf->sfbPcmQuantThreshold); 582 583 /* calculate spreading function */ 584 FDKaacEnc_initSpreading(psyConf->sfbCnt, sfbBarcVal, 585 psyConf->sfbMaskLowFactor, psyConf->sfbMaskHighFactor, 586 psyConf->sfbMaskLowFactorSprEn, 587 psyConf->sfbMaskHighFactorSprEn, bitrate, blocktype); 588 589 /* init ratio */ 590 591 psyConf->maxAllowedIncreaseFactor = 2; /* integer */ 592 psyConf->minRemainingThresholdFactor = (FIXP_SGL)0x0148; 593 /* FL2FXCONST_SGL(0.01f); */ /* fract */ 594 595 psyConf->clipEnergy = 596 (FIXP_DBL)0x773593ff; /* FL2FXCONST_DBL(1.0e9*NORM_PCM_ENERGY); */ 597 598 if (blocktype != SHORT_WINDOW) { 599 psyConf->lowpassLine = 600 (INT)((2 * bandwidth * frameLengthLong) / samplerate); 601 psyConf->lowpassLineLFE = LFE_LOWPASS_LINE; 602 } else { 603 psyConf->lowpassLine = 604 (INT)((2 * bandwidth * frameLengthShort) / samplerate); 605 psyConf->lowpassLineLFE = 0; /* LFE only in lonf blocks */ 606 /* psyConf->clipEnergy /= (TRANS_FAC * TRANS_FAC); */ 607 psyConf->clipEnergy >>= 6; 608 } 609 610 for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) { 611 if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLine) break; 612 } 613 psyConf->sfbActive = fMax(sfb, 1); 614 615 for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) { 616 if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLineLFE) break; 617 } 618 psyConf->sfbActiveLFE = sfb; 619 psyConf->sfbActive = fMax(psyConf->sfbActive, psyConf->sfbActiveLFE); 620 621 /* calculate minSnr */ 622 FDKaacEnc_initMinSnr(bitrate, samplerate * downscaleFactor, 623 psyConf->sfbOffset[psyConf->sfbCnt], psyConf->sfbOffset, 624 psyConf->sfbActive, blocktype, psyConf->sfbMinSnrLdData); 625 626 return AAC_ENC_OK; 627 } 628