/src/fdk-aac/libAACenc/src/psy_configuration.cpp
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | /* ----------------------------------------------------------------------------- | 
| 2 |  | Software License for The Fraunhofer FDK AAC Codec Library for Android | 
| 3 |  |  | 
| 4 |  | © Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung 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@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 | 0 |                                          INT *const sfbCnt) { | 
| 196 | 0 |   INT i, specStartOffset = 0; | 
| 197 | 0 |   INT granuleLengthWindow = granuleLength; | 
| 198 | 0 |   const UCHAR *sfbWidth = NULL; | 
| 199 | 0 |   const SFB_INFO_TAB *sfbInfo = NULL; | 
| 200 | 0 |   int size; | 
| 201 |  |  | 
| 202 |  |   /* | 
| 203 |  |     select table | 
| 204 |  |   */ | 
| 205 | 0 |   switch (granuleLength) { | 
| 206 | 0 |     case 1024: | 
| 207 | 0 |     case 960: | 
| 208 | 0 |       sfbInfo = sfbInfoTab; | 
| 209 | 0 |       size = (INT)(sizeof(sfbInfoTab) / sizeof(SFB_INFO_TAB)); | 
| 210 | 0 |       break; | 
| 211 | 0 |     case 512: | 
| 212 | 0 |       sfbInfo = sfbInfoTabLD512; | 
| 213 | 0 |       size = sizeof(sfbInfoTabLD512); | 
| 214 | 0 |       break; | 
| 215 | 0 |     case 480: | 
| 216 | 0 |       sfbInfo = sfbInfoTabLD480; | 
| 217 | 0 |       size = sizeof(sfbInfoTabLD480); | 
| 218 | 0 |       break; | 
| 219 | 0 |     default: | 
| 220 | 0 |       return AAC_ENC_INVALID_FRAME_LENGTH; | 
| 221 | 0 |   } | 
| 222 |  |  | 
| 223 | 0 |   for (i = 0; i < size; i++) { | 
| 224 | 0 |     if (sfbInfo[i].sampleRate == sampleRate) { | 
| 225 | 0 |       switch (blockType) { | 
| 226 | 0 |         case LONG_WINDOW: | 
| 227 | 0 |         case START_WINDOW: | 
| 228 | 0 |         case STOP_WINDOW: | 
| 229 | 0 |           sfbWidth = sfbInfo[i].paramLong->sfbWidth; | 
| 230 | 0 |           *sfbCnt = sfbInfo[i].paramLong->sfbCnt; | 
| 231 | 0 |           break; | 
| 232 | 0 |         case SHORT_WINDOW: | 
| 233 | 0 |           sfbWidth = sfbInfo[i].paramShort->sfbWidth; | 
| 234 | 0 |           *sfbCnt = sfbInfo[i].paramShort->sfbCnt; | 
| 235 | 0 |           granuleLengthWindow /= TRANS_FAC; | 
| 236 | 0 |           break; | 
| 237 | 0 |       } | 
| 238 | 0 |       break; | 
| 239 | 0 |     } | 
| 240 | 0 |   } | 
| 241 | 0 |   if (i == size) { | 
| 242 | 0 |     return AAC_ENC_UNSUPPORTED_SAMPLINGRATE; | 
| 243 | 0 |   } | 
| 244 |  |  | 
| 245 |  |   /* | 
| 246 |  |     calc sfb offsets | 
| 247 |  |   */ | 
| 248 | 0 |   for (i = 0; i < *sfbCnt; i++) { | 
| 249 | 0 |     sfbOffset[i] = specStartOffset; | 
| 250 | 0 |     specStartOffset += sfbWidth[i]; | 
| 251 | 0 |     if (specStartOffset >= granuleLengthWindow) { | 
| 252 | 0 |       i++; | 
| 253 | 0 |       break; | 
| 254 | 0 |     } | 
| 255 | 0 |   } | 
| 256 | 0 |   *sfbCnt = fixMin(i, *sfbCnt); | 
| 257 | 0 |   sfbOffset[*sfbCnt] = fixMin(specStartOffset, granuleLengthWindow); | 
| 258 | 0 |   return AAC_ENC_OK; | 
| 259 | 0 | } | 
| 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 | 0 |                                         LONG samplingFreq) { | 
| 272 | 0 |   FIXP_DBL FOURBY3EM4 = (FIXP_DBL)0x45e7b273; /* 4.0/3 * 0.0001 in q43 */ | 
| 273 | 0 |   FIXP_DBL PZZZ76 = (FIXP_DBL)0x639d5e4a;     /* 0.00076 in q41 */ | 
| 274 | 0 |   FIXP_DBL ONE3P3 = (FIXP_DBL)0x35333333;     /* 13.3 in q26 */ | 
| 275 | 0 |   FIXP_DBL THREEP5 = (FIXP_DBL)0x1c000000;    /* 3.5 in q27 */ | 
| 276 | 0 |   FIXP_DBL INV480 = (FIXP_DBL)0x44444444;     // 1/480 in q39 | 
| 277 |  | 
 | 
| 278 | 0 |   FIXP_DBL center_freq, x1, x2; | 
| 279 | 0 |   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 | 0 |   center_freq = fftLine * samplingFreq; /* q11 or q8 */ | 
| 289 |  | 
 | 
| 290 | 0 |   switch (noOfLines) { | 
| 291 | 0 |     case 1024: | 
| 292 | 0 |       center_freq = center_freq << 2; /* q13 */ | 
| 293 | 0 |       break; | 
| 294 | 0 |     case 128: | 
| 295 | 0 |       center_freq = center_freq << 5; /* q13 */ | 
| 296 | 0 |       break; | 
| 297 | 0 |     case 512: | 
| 298 | 0 |       center_freq = (fftLine * samplingFreq) << 3;  // q13 | 
| 299 | 0 |       break; | 
| 300 | 0 |     case 480: | 
| 301 | 0 |       center_freq = fMult(center_freq, INV480) << 4;  // q13 | 
| 302 | 0 |       break; | 
| 303 | 0 |     default: | 
| 304 | 0 |       center_freq = (FIXP_DBL)0; | 
| 305 | 0 |   } | 
| 306 |  |  | 
| 307 | 0 |   x1 = fMult(center_freq, FOURBY3EM4); /* q13 * q43 - (DFRACT_BITS-1) = q25 */ | 
| 308 | 0 |   x2 = fMult(center_freq, PZZZ76) | 
| 309 | 0 |        << 2; /* q13 * q41 - (DFRACT_BITS-1) + 2 = q25 */ | 
| 310 |  | 
 | 
| 311 | 0 |   atan1 = fixp_atan(x1); | 
| 312 | 0 |   atan2 = fixp_atan(x2); | 
| 313 |  |  | 
| 314 |  |   /* q25 (q26 * q30 - (DFRACT_BITS-1)) + q25 (q27 * q30 * q30) */ | 
| 315 | 0 |   bvalFFTLine = fMult(ONE3P3, atan2) + fMult(THREEP5, fMult(atan1, atan1)); | 
| 316 | 0 |   return (bvalFFTLine); | 
| 317 | 0 | } | 
| 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 | 0 |                                            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 | 0 | #define PCM_QUANT_NOISE ((FIXP_DBL)0x00547062) | 
| 330 |  | 
 | 
| 331 | 0 |   for (int i = 0; i < numPb; i++) { | 
| 332 | 0 |     sfbPCMquantThreshold[i] = (pbOffset[i + 1] - pbOffset[i]) * PCM_QUANT_NOISE; | 
| 333 | 0 |   } | 
| 334 | 0 | } | 
| 335 |  |  | 
| 336 |  | static FIXP_DBL getMaskFactor(const FIXP_DBL dbVal_fix, const INT dbVal_e, | 
| 337 | 0 |                               const FIXP_DBL ten_fix, const INT ten_e) { | 
| 338 | 0 |   INT q_msk; | 
| 339 | 0 |   FIXP_DBL mask_factor; | 
| 340 |  | 
 | 
| 341 | 0 |   mask_factor = fPow(ten_fix, DFRACT_BITS - 1 - ten_e, -dbVal_fix, | 
| 342 | 0 |                      DFRACT_BITS - 1 - dbVal_e, &q_msk); | 
| 343 | 0 |   q_msk = fixMin(DFRACT_BITS - 1, fixMax(-(DFRACT_BITS - 1), q_msk)); | 
| 344 |  | 
 | 
| 345 | 0 |   if ((q_msk > 0) && (mask_factor > (FIXP_DBL)MAXVAL_DBL >> q_msk)) { | 
| 346 | 0 |     mask_factor = (FIXP_DBL)MAXVAL_DBL; | 
| 347 | 0 |   } else { | 
| 348 | 0 |     mask_factor = scaleValue(mask_factor, q_msk); | 
| 349 | 0 |   } | 
| 350 |  | 
 | 
| 351 | 0 |   return (mask_factor); | 
| 352 | 0 | } | 
| 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 | 0 | { | 
| 362 | 0 |   INT i; | 
| 363 | 0 |   FIXP_DBL MASKLOWSPREN, MASKHIGHSPREN; | 
| 364 |  | 
 | 
| 365 | 0 |   FIXP_DBL MASKHIGH = (FIXP_DBL)0x30000000;               /* 1.5 in q29 */ | 
| 366 | 0 |   FIXP_DBL MASKLOW = (FIXP_DBL)0x60000000;                /* 3.0 in q29 */ | 
| 367 | 0 |   FIXP_DBL MASKLOWSPRENLONG = (FIXP_DBL)0x60000000;       /* 3.0 in q29 */ | 
| 368 | 0 |   FIXP_DBL MASKHIGHSPRENLONG = (FIXP_DBL)0x40000000;      /* 2.0 in q29 */ | 
| 369 | 0 |   FIXP_DBL MASKHIGHSPRENLONGLOWBR = (FIXP_DBL)0x30000000; /* 1.5 in q29 */ | 
| 370 | 0 |   FIXP_DBL MASKLOWSPRENSHORT = (FIXP_DBL)0x40000000;      /* 2.0 in q29 */ | 
| 371 | 0 |   FIXP_DBL MASKHIGHSPRENSHORT = (FIXP_DBL)0x30000000;     /* 1.5 in q29 */ | 
| 372 | 0 |   FIXP_DBL TEN = (FIXP_DBL)0x50000000;                    /* 10.0 in q27 */ | 
| 373 |  | 
 | 
| 374 | 0 |   if (blockType != SHORT_WINDOW) { | 
| 375 | 0 |     MASKLOWSPREN = MASKLOWSPRENLONG; | 
| 376 | 0 |     MASKHIGHSPREN = | 
| 377 | 0 |         (bitrate > 20000) ? MASKHIGHSPRENLONG : MASKHIGHSPRENLONGLOWBR; | 
| 378 | 0 |   } else { | 
| 379 | 0 |     MASKLOWSPREN = MASKLOWSPRENSHORT; | 
| 380 | 0 |     MASKHIGHSPREN = MASKHIGHSPRENSHORT; | 
| 381 | 0 |   } | 
| 382 |  | 
 | 
| 383 | 0 |   for (i = 0; i < numPb; i++) { | 
| 384 | 0 |     if (i > 0) { | 
| 385 | 0 |       pbMaskHiFactor[i] = getMaskFactor( | 
| 386 | 0 |           fMult(MASKHIGH, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, 27); | 
| 387 |  | 
 | 
| 388 | 0 |       pbMaskLoFactor[i - 1] = getMaskFactor( | 
| 389 | 0 |           fMult(MASKLOW, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, 27); | 
| 390 |  | 
 | 
| 391 | 0 |       pbMaskHiFactorSprEn[i] = getMaskFactor( | 
| 392 | 0 |           fMult(MASKHIGHSPREN, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, | 
| 393 | 0 |           27); | 
| 394 |  | 
 | 
| 395 | 0 |       pbMaskLoFactorSprEn[i - 1] = getMaskFactor( | 
| 396 | 0 |           fMult(MASKLOWSPREN, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, | 
| 397 | 0 |           27); | 
| 398 | 0 |     } else { | 
| 399 | 0 |       pbMaskHiFactor[i] = (FIXP_DBL)0; | 
| 400 | 0 |       pbMaskLoFactor[numPb - 1] = (FIXP_DBL)0; | 
| 401 | 0 |       pbMaskHiFactorSprEn[i] = (FIXP_DBL)0; | 
| 402 | 0 |       pbMaskLoFactorSprEn[numPb - 1] = (FIXP_DBL)0; | 
| 403 | 0 |     } | 
| 404 | 0 |   } | 
| 405 | 0 | } | 
| 406 |  |  | 
| 407 |  | static void FDKaacEnc_initBarcValues(INT numPb, INT *pbOffset, INT numLines, | 
| 408 | 0 |                                      INT samplingFrequency, FIXP_DBL *pbBval) { | 
| 409 | 0 |   INT i; | 
| 410 | 0 |   FIXP_DBL MAX_BARC = (FIXP_DBL)0x30000000; /* 24.0 in q25 */ | 
| 411 |  | 
 | 
| 412 | 0 |   for (i = 0; i < numPb; i++) { | 
| 413 | 0 |     FIXP_DBL v1, v2, cur_bark; | 
| 414 | 0 |     v1 = FDKaacEnc_BarcLineValue(numLines, pbOffset[i], samplingFrequency); | 
| 415 | 0 |     v2 = FDKaacEnc_BarcLineValue(numLines, pbOffset[i + 1], samplingFrequency); | 
| 416 | 0 |     cur_bark = (v1 >> 1) + (v2 >> 1); | 
| 417 | 0 |     pbBval[i] = fixMin(cur_bark, MAX_BARC); | 
| 418 | 0 |   } | 
| 419 | 0 | } | 
| 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 | 0 |                                  FIXP_DBL *sfbMinSnrLdData) { | 
| 425 | 0 |   INT sfb; | 
| 426 |  |  | 
| 427 |  |   /* Fix conversion variables */ | 
| 428 | 0 |   INT qbfac, qperwin, qdiv, qpeprt_const, qpeprt; | 
| 429 | 0 |   INT qtmp, qsnr, sfbWidth; | 
| 430 |  | 
 | 
| 431 | 0 |   FIXP_DBL MAX_BARC = (FIXP_DBL)0x30000000;   /* 24.0 in q25 */ | 
| 432 | 0 |   FIXP_DBL MAX_BARCP1 = (FIXP_DBL)0x32000000; /* 25.0 in q25 */ | 
| 433 | 0 |   FIXP_DBL BITS2PEFAC = (FIXP_DBL)0x4b851eb8; /* 1.18 in q30 */ | 
| 434 | 0 |   FIXP_DBL PERS2P4 = (FIXP_DBL)0x624dd2f2;    /* 0.024 in q36 */ | 
| 435 | 0 |   FIXP_DBL ONEP5 = (FIXP_DBL)0x60000000;      /* 1.5 in q30 */ | 
| 436 | 0 |   FIXP_DBL MAX_SNR = (FIXP_DBL)0x33333333;    /* 0.8 in q30 */ | 
| 437 | 0 |   FIXP_DBL MIN_SNR = (FIXP_DBL)0x003126e9;    /* 0.003 in q30 */ | 
| 438 |  | 
 | 
| 439 | 0 |   FIXP_DBL barcFactor, pePerWindow, pePart, barcWidth; | 
| 440 | 0 |   FIXP_DBL pePart_const, tmp, snr, one_qsnr, one_point5; | 
| 441 |  |  | 
| 442 |  |   /* relative number of active barks */ | 
| 443 | 0 |   barcFactor = fDivNorm(fixMin(FDKaacEnc_BarcLineValue( | 
| 444 | 0 |                                    numLines, sfbOffset[sfbActive], samplerate), | 
| 445 | 0 |                                MAX_BARC), | 
| 446 | 0 |                         MAX_BARCP1, &qbfac); | 
| 447 |  | 
 | 
| 448 | 0 |   qbfac = DFRACT_BITS - 1 - qbfac; | 
| 449 |  | 
 | 
| 450 | 0 |   pePerWindow = fDivNorm(bitrate, samplerate, &qperwin); | 
| 451 | 0 |   qperwin = DFRACT_BITS - 1 - qperwin; | 
| 452 | 0 |   pePerWindow = fMult(pePerWindow, BITS2PEFAC); | 
| 453 | 0 |   qperwin = qperwin + 30 - (DFRACT_BITS - 1); | 
| 454 | 0 |   pePerWindow = fMult(pePerWindow, PERS2P4); | 
| 455 | 0 |   qperwin = qperwin + 36 - (DFRACT_BITS - 1); | 
| 456 |  | 
 | 
| 457 | 0 |   switch (numLines) { | 
| 458 | 0 |     case 1024: | 
| 459 | 0 |       qperwin = qperwin - 10; | 
| 460 | 0 |       break; | 
| 461 | 0 |     case 128: | 
| 462 | 0 |       qperwin = qperwin - 7; | 
| 463 | 0 |       break; | 
| 464 | 0 |     case 512: | 
| 465 | 0 |       qperwin = qperwin - 9; | 
| 466 | 0 |       break; | 
| 467 | 0 |     case 480: | 
| 468 | 0 |       qperwin = qperwin - 9; | 
| 469 | 0 |       pePerWindow = fMult(pePerWindow, FL2FXCONST_DBL(480.f / 512.f)); | 
| 470 | 0 |       break; | 
| 471 | 0 |   } | 
| 472 |  |  | 
| 473 |  |   /* for short blocks it is assumed that more bits are available */ | 
| 474 | 0 |   if (blockType == SHORT_WINDOW) { | 
| 475 | 0 |     pePerWindow = fMult(pePerWindow, ONEP5); | 
| 476 | 0 |     qperwin = qperwin + 30 - (DFRACT_BITS - 1); | 
| 477 | 0 |   } | 
| 478 | 0 |   pePart_const = fDivNorm(pePerWindow, barcFactor, &qdiv); | 
| 479 | 0 |   qpeprt_const = qperwin - qbfac + DFRACT_BITS - 1 - qdiv; | 
| 480 |  | 
 | 
| 481 | 0 |   for (sfb = 0; sfb < sfbActive; sfb++) { | 
| 482 | 0 |     barcWidth = | 
| 483 | 0 |         FDKaacEnc_BarcLineValue(numLines, sfbOffset[sfb + 1], samplerate) - | 
| 484 | 0 |         FDKaacEnc_BarcLineValue(numLines, sfbOffset[sfb], samplerate); | 
| 485 |  |  | 
| 486 |  |     /* adapt to sfb bands */ | 
| 487 | 0 |     pePart = fMult(pePart_const, barcWidth); | 
| 488 | 0 |     qpeprt = qpeprt_const + 25 - (DFRACT_BITS - 1); | 
| 489 |  |  | 
| 490 |  |     /* pe -> snr calculation */ | 
| 491 | 0 |     sfbWidth = (sfbOffset[sfb + 1] - sfbOffset[sfb]); | 
| 492 | 0 |     pePart = fDivNorm(pePart, sfbWidth, &qdiv); | 
| 493 | 0 |     qpeprt += DFRACT_BITS - 1 - qdiv; | 
| 494 |  | 
 | 
| 495 | 0 |     tmp = f2Pow(pePart, DFRACT_BITS - 1 - qpeprt, &qtmp); | 
| 496 | 0 |     qtmp = DFRACT_BITS - 1 - qtmp; | 
| 497 |  |  | 
| 498 |  |     /* Subtract 1.5 */ | 
| 499 | 0 |     qsnr = fixMin(qtmp, 30); | 
| 500 | 0 |     tmp = tmp >> (qtmp - qsnr); | 
| 501 |  | 
 | 
| 502 | 0 |     if ((30 + 1 - qsnr) > (DFRACT_BITS - 1)) | 
| 503 | 0 |       one_point5 = (FIXP_DBL)0; | 
| 504 | 0 |     else | 
| 505 | 0 |       one_point5 = (FIXP_DBL)(ONEP5 >> (30 + 1 - qsnr)); | 
| 506 |  | 
 | 
| 507 | 0 |     snr = (tmp >> 1) - (one_point5); | 
| 508 | 0 |     qsnr -= 1; | 
| 509 |  |  | 
| 510 |  |     /* max(snr, 1.0) */ | 
| 511 | 0 |     if (qsnr > 0) | 
| 512 | 0 |       one_qsnr = (FIXP_DBL)(1 << qsnr); | 
| 513 | 0 |     else | 
| 514 | 0 |       one_qsnr = (FIXP_DBL)0; | 
| 515 |  | 
 | 
| 516 | 0 |     snr = fixMax(one_qsnr, snr); | 
| 517 |  |  | 
| 518 |  |     /* 1/snr */ | 
| 519 | 0 |     snr = fDivNorm(one_qsnr, snr, &qsnr); | 
| 520 | 0 |     qsnr = DFRACT_BITS - 1 - qsnr; | 
| 521 | 0 |     snr = (qsnr > 30) ? (snr >> (qsnr - 30)) : snr; | 
| 522 |  |  | 
| 523 |  |     /* upper limit is -1 dB */ | 
| 524 | 0 |     snr = (snr > MAX_SNR) ? MAX_SNR : snr; | 
| 525 |  |  | 
| 526 |  |     /* lower limit is -25 dB */ | 
| 527 | 0 |     snr = (snr < MIN_SNR) ? MIN_SNR : snr; | 
| 528 | 0 |     snr = snr << 1; | 
| 529 |  | 
 | 
| 530 | 0 |     sfbMinSnrLdData[sfb] = CalcLdData(snr); | 
| 531 | 0 |   } | 
| 532 | 0 | } | 
| 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 | 0 |                                                  FB_TYPE filterbank) { | 
| 540 | 0 |   AAC_ENCODER_ERROR ErrorStatus; | 
| 541 | 0 |   INT sfb; | 
| 542 | 0 |   FIXP_DBL sfbBarcVal[MAX_SFB]; | 
| 543 | 0 |   const INT frameLengthLong = granuleLength; | 
| 544 | 0 |   const INT frameLengthShort = granuleLength / TRANS_FAC; | 
| 545 | 0 |   INT downscaleFactor = 1; | 
| 546 |  | 
 | 
| 547 | 0 |   switch (granuleLength) { | 
| 548 | 0 |     case 256: | 
| 549 | 0 |     case 240: | 
| 550 | 0 |       downscaleFactor = 2; | 
| 551 | 0 |       break; | 
| 552 | 0 |     case 128: | 
| 553 | 0 |     case 120: | 
| 554 | 0 |       downscaleFactor = 4; | 
| 555 | 0 |       break; | 
| 556 | 0 |     default: | 
| 557 | 0 |       downscaleFactor = 1; | 
| 558 | 0 |       break; | 
| 559 | 0 |   } | 
| 560 |  |  | 
| 561 | 0 |   FDKmemclear(psyConf, sizeof(PSY_CONFIGURATION)); | 
| 562 | 0 |   psyConf->granuleLength = granuleLength; | 
| 563 | 0 |   psyConf->filterbank = filterbank; | 
| 564 |  | 
 | 
| 565 | 0 |   psyConf->allowIS = (useIS) && ((bitrate / bandwidth) < 5); | 
| 566 | 0 |   psyConf->allowMS = useMS; | 
| 567 |  |  | 
| 568 |  |   /* init sfb table */ | 
| 569 | 0 |   ErrorStatus = FDKaacEnc_initSfbTable(samplerate * downscaleFactor, blocktype, | 
| 570 | 0 |                                        granuleLength * downscaleFactor, | 
| 571 | 0 |                                        psyConf->sfbOffset, &psyConf->sfbCnt); | 
| 572 |  | 
 | 
| 573 | 0 |   if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; | 
| 574 |  |  | 
| 575 |  |   /* calculate barc values for each pb */ | 
| 576 | 0 |   FDKaacEnc_initBarcValues(psyConf->sfbCnt, psyConf->sfbOffset, | 
| 577 | 0 |                            psyConf->sfbOffset[psyConf->sfbCnt], samplerate, | 
| 578 | 0 |                            sfbBarcVal); | 
| 579 |  | 
 | 
| 580 | 0 |   FDKaacEnc_InitMinPCMResolution(psyConf->sfbCnt, psyConf->sfbOffset, | 
| 581 | 0 |                                  psyConf->sfbPcmQuantThreshold); | 
| 582 |  |  | 
| 583 |  |   /* calculate spreading function */ | 
| 584 | 0 |   FDKaacEnc_initSpreading(psyConf->sfbCnt, sfbBarcVal, | 
| 585 | 0 |                           psyConf->sfbMaskLowFactor, psyConf->sfbMaskHighFactor, | 
| 586 | 0 |                           psyConf->sfbMaskLowFactorSprEn, | 
| 587 | 0 |                           psyConf->sfbMaskHighFactorSprEn, bitrate, blocktype); | 
| 588 |  |  | 
| 589 |  |   /* init ratio */ | 
| 590 |  | 
 | 
| 591 | 0 |   psyConf->maxAllowedIncreaseFactor = 2; /* integer */ | 
| 592 | 0 |   psyConf->minRemainingThresholdFactor = (FIXP_SGL)0x0148; | 
| 593 |  |   /* FL2FXCONST_SGL(0.01f); */ /* fract   */ | 
| 594 |  | 
 | 
| 595 | 0 |   psyConf->clipEnergy = | 
| 596 | 0 |       (FIXP_DBL)0x773593ff; /* FL2FXCONST_DBL(1.0e9*NORM_PCM_ENERGY); */ | 
| 597 |  | 
 | 
| 598 | 0 |   if (blocktype != SHORT_WINDOW) { | 
| 599 | 0 |     psyConf->lowpassLine = | 
| 600 | 0 |         (INT)((2 * bandwidth * frameLengthLong) / samplerate); | 
| 601 | 0 |     psyConf->lowpassLineLFE = LFE_LOWPASS_LINE; | 
| 602 | 0 |   } else { | 
| 603 | 0 |     psyConf->lowpassLine = | 
| 604 | 0 |         (INT)((2 * bandwidth * frameLengthShort) / samplerate); | 
| 605 | 0 |     psyConf->lowpassLineLFE = 0; /* LFE only in lonf blocks */ | 
| 606 |  |     /* psyConf->clipEnergy /= (TRANS_FAC * TRANS_FAC); */ | 
| 607 | 0 |     psyConf->clipEnergy >>= 6; | 
| 608 | 0 |   } | 
| 609 |  | 
 | 
| 610 | 0 |   for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) { | 
| 611 | 0 |     if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLine) break; | 
| 612 | 0 |   } | 
| 613 | 0 |   psyConf->sfbActive = fMax(sfb, 1); | 
| 614 |  | 
 | 
| 615 | 0 |   for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) { | 
| 616 | 0 |     if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLineLFE) break; | 
| 617 | 0 |   } | 
| 618 | 0 |   psyConf->sfbActiveLFE = sfb; | 
| 619 | 0 |   psyConf->sfbActive = fMax(psyConf->sfbActive, psyConf->sfbActiveLFE); | 
| 620 |  |  | 
| 621 |  |   /* calculate minSnr */ | 
| 622 | 0 |   FDKaacEnc_initMinSnr(bitrate, samplerate * downscaleFactor, | 
| 623 | 0 |                        psyConf->sfbOffset[psyConf->sfbCnt], psyConf->sfbOffset, | 
| 624 | 0 |                        psyConf->sfbActive, blocktype, psyConf->sfbMinSnrLdData); | 
| 625 |  | 
 | 
| 626 | 0 |   return AAC_ENC_OK; | 
| 627 | 0 | } |