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