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
FDKaacEnc_initSfbTable(const LONG sampleRate,const INT blockType,const INT granuleLength,INT * const sfbOffset,INT * const sfbCnt)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 *****************************************************************************/
FDKaacEnc_BarcLineValue(INT noOfLines,INT fftLine,LONG samplingFreq)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 */
FDKaacEnc_InitMinPCMResolution(int numPb,int * pbOffset,FIXP_DBL * sfbPCMquantThreshold)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
getMaskFactor(const FIXP_DBL dbVal_fix,const INT dbVal_e,const FIXP_DBL ten_fix,const INT ten_e)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
FDKaacEnc_initSpreading(INT numPb,FIXP_DBL * pbBarcValue,FIXP_DBL * pbMaskLoFactor,FIXP_DBL * pbMaskHiFactor,FIXP_DBL * pbMaskLoFactorSprEn,FIXP_DBL * pbMaskHiFactorSprEn,const LONG bitrate,const INT blockType)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
FDKaacEnc_initBarcValues(INT numPb,INT * pbOffset,INT numLines,INT samplingFrequency,FIXP_DBL * pbBval)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
FDKaacEnc_initMinSnr(const LONG bitrate,const LONG samplerate,const INT numLines,const INT * sfbOffset,const INT sfbActive,const INT blockType,FIXP_DBL * sfbMinSnrLdData)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
FDKaacEnc_InitPsyConfiguration(INT bitrate,INT samplerate,INT bandwidth,INT blocktype,INT granuleLength,INT useIS,INT useMS,PSY_CONFIGURATION * psyConf,FB_TYPE filterbank)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