xref: /aosp_15_r20/external/aac/libAACenc/src/psy_configuration.cpp (revision e54365361535b070c2db7374cec45c159c7d0e7a)
1*e5436536SAndroid Build Coastguard Worker /* -----------------------------------------------------------------------------
2*e5436536SAndroid Build Coastguard Worker Software License for The Fraunhofer FDK AAC Codec Library for Android
3*e5436536SAndroid Build Coastguard Worker 
4*e5436536SAndroid Build Coastguard Worker © Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
5*e5436536SAndroid Build Coastguard Worker Forschung e.V. All rights reserved.
6*e5436536SAndroid Build Coastguard Worker 
7*e5436536SAndroid Build Coastguard Worker  1.    INTRODUCTION
8*e5436536SAndroid Build Coastguard Worker The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9*e5436536SAndroid Build Coastguard Worker that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10*e5436536SAndroid Build Coastguard Worker scheme for digital audio. This FDK AAC Codec software is intended to be used on
11*e5436536SAndroid Build Coastguard Worker a wide variety of Android devices.
12*e5436536SAndroid Build Coastguard Worker 
13*e5436536SAndroid Build Coastguard Worker AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14*e5436536SAndroid Build Coastguard Worker general perceptual audio codecs. AAC-ELD is considered the best-performing
15*e5436536SAndroid Build Coastguard Worker full-bandwidth communications codec by independent studies and is widely
16*e5436536SAndroid Build Coastguard Worker deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17*e5436536SAndroid Build Coastguard Worker specifications.
18*e5436536SAndroid Build Coastguard Worker 
19*e5436536SAndroid Build Coastguard Worker Patent licenses for necessary patent claims for the FDK AAC Codec (including
20*e5436536SAndroid Build Coastguard Worker those of Fraunhofer) may be obtained through Via Licensing
21*e5436536SAndroid Build Coastguard Worker (www.vialicensing.com) or through the respective patent owners individually for
22*e5436536SAndroid Build Coastguard Worker the purpose of encoding or decoding bit streams in products that are compliant
23*e5436536SAndroid Build Coastguard Worker with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24*e5436536SAndroid Build Coastguard Worker Android devices already license these patent claims through Via Licensing or
25*e5436536SAndroid Build Coastguard Worker directly from the patent owners, and therefore FDK AAC Codec software may
26*e5436536SAndroid Build Coastguard Worker already be covered under those patent licenses when it is used for those
27*e5436536SAndroid Build Coastguard Worker licensed purposes only.
28*e5436536SAndroid Build Coastguard Worker 
29*e5436536SAndroid Build Coastguard Worker Commercially-licensed AAC software libraries, including floating-point versions
30*e5436536SAndroid Build Coastguard Worker with enhanced sound quality, are also available from Fraunhofer. Users are
31*e5436536SAndroid Build Coastguard Worker encouraged to check the Fraunhofer website for additional applications
32*e5436536SAndroid Build Coastguard Worker information and documentation.
33*e5436536SAndroid Build Coastguard Worker 
34*e5436536SAndroid Build Coastguard Worker 2.    COPYRIGHT LICENSE
35*e5436536SAndroid Build Coastguard Worker 
36*e5436536SAndroid Build Coastguard Worker Redistribution and use in source and binary forms, with or without modification,
37*e5436536SAndroid Build Coastguard Worker are permitted without payment of copyright license fees provided that you
38*e5436536SAndroid Build Coastguard Worker satisfy the following conditions:
39*e5436536SAndroid Build Coastguard Worker 
40*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in redistributions of
41*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec or your modifications thereto in source code form.
42*e5436536SAndroid Build Coastguard Worker 
43*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in the documentation
44*e5436536SAndroid Build Coastguard Worker and/or other materials provided with redistributions of the FDK AAC Codec or
45*e5436536SAndroid Build Coastguard Worker your modifications thereto in binary form. You must make available free of
46*e5436536SAndroid Build Coastguard Worker charge copies of the complete source code of the FDK AAC Codec and your
47*e5436536SAndroid Build Coastguard Worker modifications thereto to recipients of copies in binary form.
48*e5436536SAndroid Build Coastguard Worker 
49*e5436536SAndroid Build Coastguard Worker The name of Fraunhofer may not be used to endorse or promote products derived
50*e5436536SAndroid Build Coastguard Worker from this library without prior written permission.
51*e5436536SAndroid Build Coastguard Worker 
52*e5436536SAndroid Build Coastguard Worker You may not charge copyright license fees for anyone to use, copy or distribute
53*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec software or your modifications thereto.
54*e5436536SAndroid Build Coastguard Worker 
55*e5436536SAndroid Build Coastguard Worker Your modified versions of the FDK AAC Codec must carry prominent notices stating
56*e5436536SAndroid Build Coastguard Worker that you changed the software and the date of any change. For modified versions
57*e5436536SAndroid Build Coastguard Worker of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58*e5436536SAndroid Build Coastguard Worker must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59*e5436536SAndroid Build Coastguard Worker AAC Codec Library for Android."
60*e5436536SAndroid Build Coastguard Worker 
61*e5436536SAndroid Build Coastguard Worker 3.    NO PATENT LICENSE
62*e5436536SAndroid Build Coastguard Worker 
63*e5436536SAndroid Build Coastguard Worker NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64*e5436536SAndroid Build Coastguard Worker limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65*e5436536SAndroid Build Coastguard Worker Fraunhofer provides no warranty of patent non-infringement with respect to this
66*e5436536SAndroid Build Coastguard Worker software.
67*e5436536SAndroid Build Coastguard Worker 
68*e5436536SAndroid Build Coastguard Worker You may use this FDK AAC Codec software or modifications thereto only for
69*e5436536SAndroid Build Coastguard Worker purposes that are authorized by appropriate patent licenses.
70*e5436536SAndroid Build Coastguard Worker 
71*e5436536SAndroid Build Coastguard Worker 4.    DISCLAIMER
72*e5436536SAndroid Build Coastguard Worker 
73*e5436536SAndroid Build Coastguard Worker This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74*e5436536SAndroid Build Coastguard Worker holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75*e5436536SAndroid Build Coastguard Worker including but not limited to the implied warranties of merchantability and
76*e5436536SAndroid Build Coastguard Worker fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77*e5436536SAndroid Build Coastguard Worker CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78*e5436536SAndroid Build Coastguard Worker or consequential damages, including but not limited to procurement of substitute
79*e5436536SAndroid Build Coastguard Worker goods or services; loss of use, data, or profits, or business interruption,
80*e5436536SAndroid Build Coastguard Worker however caused and on any theory of liability, whether in contract, strict
81*e5436536SAndroid Build Coastguard Worker liability, or tort (including negligence), arising in any way out of the use of
82*e5436536SAndroid Build Coastguard Worker this software, even if advised of the possibility of such damage.
83*e5436536SAndroid Build Coastguard Worker 
84*e5436536SAndroid Build Coastguard Worker 5.    CONTACT INFORMATION
85*e5436536SAndroid Build Coastguard Worker 
86*e5436536SAndroid Build Coastguard Worker Fraunhofer Institute for Integrated Circuits IIS
87*e5436536SAndroid Build Coastguard Worker Attention: Audio and Multimedia Departments - FDK AAC LL
88*e5436536SAndroid Build Coastguard Worker Am Wolfsmantel 33
89*e5436536SAndroid Build Coastguard Worker 91058 Erlangen, Germany
90*e5436536SAndroid Build Coastguard Worker 
91*e5436536SAndroid Build Coastguard Worker www.iis.fraunhofer.de/amm
92*e5436536SAndroid Build Coastguard Worker [email protected]
93*e5436536SAndroid Build Coastguard Worker ----------------------------------------------------------------------------- */
94*e5436536SAndroid Build Coastguard Worker 
95*e5436536SAndroid Build Coastguard Worker /**************************** AAC encoder library ******************************
96*e5436536SAndroid Build Coastguard Worker 
97*e5436536SAndroid Build Coastguard Worker    Author(s):   M.Werner
98*e5436536SAndroid Build Coastguard Worker 
99*e5436536SAndroid Build Coastguard Worker    Description: Psychoaccoustic configuration
100*e5436536SAndroid Build Coastguard Worker 
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker 
103*e5436536SAndroid Build Coastguard Worker #include "psy_configuration.h"
104*e5436536SAndroid Build Coastguard Worker #include "adj_thr.h"
105*e5436536SAndroid Build Coastguard Worker #include "aacEnc_rom.h"
106*e5436536SAndroid Build Coastguard Worker 
107*e5436536SAndroid Build Coastguard Worker #include "genericStds.h"
108*e5436536SAndroid Build Coastguard Worker 
109*e5436536SAndroid Build Coastguard Worker #include "FDK_trigFcts.h"
110*e5436536SAndroid Build Coastguard Worker 
111*e5436536SAndroid Build Coastguard Worker typedef struct {
112*e5436536SAndroid Build Coastguard Worker   LONG sampleRate;
113*e5436536SAndroid Build Coastguard Worker   const SFB_PARAM_LONG *paramLong;
114*e5436536SAndroid Build Coastguard Worker   const SFB_PARAM_SHORT *paramShort;
115*e5436536SAndroid Build Coastguard Worker } SFB_INFO_TAB;
116*e5436536SAndroid Build Coastguard Worker 
117*e5436536SAndroid Build Coastguard Worker static const SFB_INFO_TAB sfbInfoTab[] = {
118*e5436536SAndroid Build Coastguard Worker     {8000, &p_FDKaacEnc_8000_long_1024, &p_FDKaacEnc_8000_short_128},
119*e5436536SAndroid Build Coastguard Worker     {11025, &p_FDKaacEnc_11025_long_1024, &p_FDKaacEnc_11025_short_128},
120*e5436536SAndroid Build Coastguard Worker     {12000, &p_FDKaacEnc_12000_long_1024, &p_FDKaacEnc_12000_short_128},
121*e5436536SAndroid Build Coastguard Worker     {16000, &p_FDKaacEnc_16000_long_1024, &p_FDKaacEnc_16000_short_128},
122*e5436536SAndroid Build Coastguard Worker     {22050, &p_FDKaacEnc_22050_long_1024, &p_FDKaacEnc_22050_short_128},
123*e5436536SAndroid Build Coastguard Worker     {24000, &p_FDKaacEnc_24000_long_1024, &p_FDKaacEnc_24000_short_128},
124*e5436536SAndroid Build Coastguard Worker     {32000, &p_FDKaacEnc_32000_long_1024, &p_FDKaacEnc_32000_short_128},
125*e5436536SAndroid Build Coastguard Worker     {44100, &p_FDKaacEnc_44100_long_1024, &p_FDKaacEnc_44100_short_128},
126*e5436536SAndroid Build Coastguard Worker     {48000, &p_FDKaacEnc_48000_long_1024, &p_FDKaacEnc_48000_short_128},
127*e5436536SAndroid Build Coastguard Worker     {64000, &p_FDKaacEnc_64000_long_1024, &p_FDKaacEnc_64000_short_128},
128*e5436536SAndroid Build Coastguard Worker     {88200, &p_FDKaacEnc_88200_long_1024, &p_FDKaacEnc_88200_short_128},
129*e5436536SAndroid Build Coastguard Worker     {96000, &p_FDKaacEnc_96000_long_1024, &p_FDKaacEnc_96000_short_128}
130*e5436536SAndroid Build Coastguard Worker 
131*e5436536SAndroid Build Coastguard Worker };
132*e5436536SAndroid Build Coastguard Worker 
133*e5436536SAndroid Build Coastguard Worker /* 22050 and 24000 Hz */
134*e5436536SAndroid Build Coastguard Worker static const SFB_PARAM_LONG p_22050_long_512 = {
135*e5436536SAndroid Build Coastguard Worker     31, {4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  8,  8,  8,  12, 12,
136*e5436536SAndroid Build Coastguard Worker          12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}};
137*e5436536SAndroid Build Coastguard Worker 
138*e5436536SAndroid Build Coastguard Worker /* 32000 Hz */
139*e5436536SAndroid Build Coastguard Worker static const SFB_PARAM_LONG p_32000_long_512 = {
140*e5436536SAndroid Build Coastguard Worker     37,
141*e5436536SAndroid Build Coastguard Worker     {4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  8,  8,  8,  8, 8,
142*e5436536SAndroid Build Coastguard Worker      12, 12, 12, 12, 16, 16, 16, 20, 24, 24, 28, 32, 32, 32, 32, 32, 32, 32}};
143*e5436536SAndroid Build Coastguard Worker 
144*e5436536SAndroid Build Coastguard Worker /* 44100 Hz */
145*e5436536SAndroid Build Coastguard Worker static const SFB_PARAM_LONG p_44100_long_512 = {
146*e5436536SAndroid Build Coastguard Worker     36, {4, 4, 4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  8,  8,  8,
147*e5436536SAndroid Build Coastguard Worker          8, 8, 12, 12, 12, 12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32, 32, 52}};
148*e5436536SAndroid Build Coastguard Worker 
149*e5436536SAndroid Build Coastguard Worker static const SFB_INFO_TAB sfbInfoTabLD512[] = {
150*e5436536SAndroid Build Coastguard Worker     {8000, &p_22050_long_512, NULL},   {11025, &p_22050_long_512, NULL},
151*e5436536SAndroid Build Coastguard Worker     {12000, &p_22050_long_512, NULL},  {16000, &p_22050_long_512, NULL},
152*e5436536SAndroid Build Coastguard Worker     {22050, &p_22050_long_512, NULL},  {24000, &p_22050_long_512, NULL},
153*e5436536SAndroid Build Coastguard Worker     {32000, &p_32000_long_512, NULL},  {44100, &p_44100_long_512, NULL},
154*e5436536SAndroid Build Coastguard Worker     {48000, &p_44100_long_512, NULL},  {64000, &p_44100_long_512, NULL},
155*e5436536SAndroid Build Coastguard Worker     {88200, &p_44100_long_512, NULL},  {96000, &p_44100_long_512, NULL},
156*e5436536SAndroid Build Coastguard Worker     {128000, &p_44100_long_512, NULL}, {176400, &p_44100_long_512, NULL},
157*e5436536SAndroid Build Coastguard Worker     {192000, &p_44100_long_512, NULL}, {256000, &p_44100_long_512, NULL},
158*e5436536SAndroid Build Coastguard Worker     {352800, &p_44100_long_512, NULL}, {384000, &p_44100_long_512, NULL},
159*e5436536SAndroid Build Coastguard Worker };
160*e5436536SAndroid Build Coastguard Worker 
161*e5436536SAndroid Build Coastguard Worker /* 22050 and 24000 Hz */
162*e5436536SAndroid Build Coastguard Worker static const SFB_PARAM_LONG p_22050_long_480 = {
163*e5436536SAndroid Build Coastguard Worker     30, {4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  8,  8,  8,  12,
164*e5436536SAndroid Build Coastguard Worker          12, 12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32}};
165*e5436536SAndroid Build Coastguard Worker 
166*e5436536SAndroid Build Coastguard Worker /* 32000 Hz */
167*e5436536SAndroid Build Coastguard Worker static const SFB_PARAM_LONG p_32000_long_480 = {
168*e5436536SAndroid Build Coastguard Worker     37, {4, 4, 4, 4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  8,  8, 8,
169*e5436536SAndroid Build Coastguard Worker          8, 8, 8, 12, 12, 12, 16, 16, 20, 24, 32, 32, 32, 32, 32, 32, 32, 32}};
170*e5436536SAndroid Build Coastguard Worker 
171*e5436536SAndroid Build Coastguard Worker /* 44100 Hz */
172*e5436536SAndroid Build Coastguard Worker static const SFB_PARAM_LONG p_44100_long_480 = {
173*e5436536SAndroid Build Coastguard Worker     35, {4, 4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  8,  8,  8, 8,
174*e5436536SAndroid Build Coastguard Worker          8, 12, 12, 12, 12, 12, 16, 16, 24, 28, 32, 32, 32, 32, 32, 32, 48}};
175*e5436536SAndroid Build Coastguard Worker 
176*e5436536SAndroid Build Coastguard Worker static const SFB_INFO_TAB sfbInfoTabLD480[] = {
177*e5436536SAndroid Build Coastguard Worker     {8000, &p_22050_long_480, NULL},   {11025, &p_22050_long_480, NULL},
178*e5436536SAndroid Build Coastguard Worker     {12000, &p_22050_long_480, NULL},  {16000, &p_22050_long_480, NULL},
179*e5436536SAndroid Build Coastguard Worker     {22050, &p_22050_long_480, NULL},  {24000, &p_22050_long_480, NULL},
180*e5436536SAndroid Build Coastguard Worker     {32000, &p_32000_long_480, NULL},  {44100, &p_44100_long_480, NULL},
181*e5436536SAndroid Build Coastguard Worker     {48000, &p_44100_long_480, NULL},  {64000, &p_44100_long_480, NULL},
182*e5436536SAndroid Build Coastguard Worker     {88200, &p_44100_long_480, NULL},  {96000, &p_44100_long_480, NULL},
183*e5436536SAndroid Build Coastguard Worker     {128000, &p_44100_long_480, NULL}, {176400, &p_44100_long_480, NULL},
184*e5436536SAndroid Build Coastguard Worker     {192000, &p_44100_long_480, NULL}, {256000, &p_44100_long_480, NULL},
185*e5436536SAndroid Build Coastguard Worker     {352800, &p_44100_long_480, NULL}, {384000, &p_44100_long_480, NULL},
186*e5436536SAndroid Build Coastguard Worker };
187*e5436536SAndroid Build Coastguard Worker 
188*e5436536SAndroid Build Coastguard Worker /* Fixed point precision definitions */
189*e5436536SAndroid Build Coastguard Worker #define Q_BARCVAL (25)
190*e5436536SAndroid Build Coastguard Worker 
FDKaacEnc_initSfbTable(const LONG sampleRate,const INT blockType,const INT granuleLength,INT * const sfbOffset,INT * const sfbCnt)191*e5436536SAndroid Build Coastguard Worker AAC_ENCODER_ERROR FDKaacEnc_initSfbTable(const LONG sampleRate,
192*e5436536SAndroid Build Coastguard Worker                                          const INT blockType,
193*e5436536SAndroid Build Coastguard Worker                                          const INT granuleLength,
194*e5436536SAndroid Build Coastguard Worker                                          INT *const sfbOffset,
195*e5436536SAndroid Build Coastguard Worker                                          INT *const sfbCnt) {
196*e5436536SAndroid Build Coastguard Worker   INT i, specStartOffset = 0;
197*e5436536SAndroid Build Coastguard Worker   INT granuleLengthWindow = granuleLength;
198*e5436536SAndroid Build Coastguard Worker   const UCHAR *sfbWidth = NULL;
199*e5436536SAndroid Build Coastguard Worker   const SFB_INFO_TAB *sfbInfo = NULL;
200*e5436536SAndroid Build Coastguard Worker   int size;
201*e5436536SAndroid Build Coastguard Worker 
202*e5436536SAndroid Build Coastguard Worker   /*
203*e5436536SAndroid Build Coastguard Worker     select table
204*e5436536SAndroid Build Coastguard Worker   */
205*e5436536SAndroid Build Coastguard Worker   switch (granuleLength) {
206*e5436536SAndroid Build Coastguard Worker     case 1024:
207*e5436536SAndroid Build Coastguard Worker     case 960:
208*e5436536SAndroid Build Coastguard Worker       sfbInfo = sfbInfoTab;
209*e5436536SAndroid Build Coastguard Worker       size = (INT)(sizeof(sfbInfoTab) / sizeof(SFB_INFO_TAB));
210*e5436536SAndroid Build Coastguard Worker       break;
211*e5436536SAndroid Build Coastguard Worker     case 512:
212*e5436536SAndroid Build Coastguard Worker       sfbInfo = sfbInfoTabLD512;
213*e5436536SAndroid Build Coastguard Worker       size = sizeof(sfbInfoTabLD512);
214*e5436536SAndroid Build Coastguard Worker       break;
215*e5436536SAndroid Build Coastguard Worker     case 480:
216*e5436536SAndroid Build Coastguard Worker       sfbInfo = sfbInfoTabLD480;
217*e5436536SAndroid Build Coastguard Worker       size = sizeof(sfbInfoTabLD480);
218*e5436536SAndroid Build Coastguard Worker       break;
219*e5436536SAndroid Build Coastguard Worker     default:
220*e5436536SAndroid Build Coastguard Worker       return AAC_ENC_INVALID_FRAME_LENGTH;
221*e5436536SAndroid Build Coastguard Worker   }
222*e5436536SAndroid Build Coastguard Worker 
223*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < size; i++) {
224*e5436536SAndroid Build Coastguard Worker     if (sfbInfo[i].sampleRate == sampleRate) {
225*e5436536SAndroid Build Coastguard Worker       switch (blockType) {
226*e5436536SAndroid Build Coastguard Worker         case LONG_WINDOW:
227*e5436536SAndroid Build Coastguard Worker         case START_WINDOW:
228*e5436536SAndroid Build Coastguard Worker         case STOP_WINDOW:
229*e5436536SAndroid Build Coastguard Worker           sfbWidth = sfbInfo[i].paramLong->sfbWidth;
230*e5436536SAndroid Build Coastguard Worker           *sfbCnt = sfbInfo[i].paramLong->sfbCnt;
231*e5436536SAndroid Build Coastguard Worker           break;
232*e5436536SAndroid Build Coastguard Worker         case SHORT_WINDOW:
233*e5436536SAndroid Build Coastguard Worker           sfbWidth = sfbInfo[i].paramShort->sfbWidth;
234*e5436536SAndroid Build Coastguard Worker           *sfbCnt = sfbInfo[i].paramShort->sfbCnt;
235*e5436536SAndroid Build Coastguard Worker           granuleLengthWindow /= TRANS_FAC;
236*e5436536SAndroid Build Coastguard Worker           break;
237*e5436536SAndroid Build Coastguard Worker       }
238*e5436536SAndroid Build Coastguard Worker       break;
239*e5436536SAndroid Build Coastguard Worker     }
240*e5436536SAndroid Build Coastguard Worker   }
241*e5436536SAndroid Build Coastguard Worker   if (i == size) {
242*e5436536SAndroid Build Coastguard Worker     return AAC_ENC_UNSUPPORTED_SAMPLINGRATE;
243*e5436536SAndroid Build Coastguard Worker   }
244*e5436536SAndroid Build Coastguard Worker 
245*e5436536SAndroid Build Coastguard Worker   /*
246*e5436536SAndroid Build Coastguard Worker     calc sfb offsets
247*e5436536SAndroid Build Coastguard Worker   */
248*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < *sfbCnt; i++) {
249*e5436536SAndroid Build Coastguard Worker     sfbOffset[i] = specStartOffset;
250*e5436536SAndroid Build Coastguard Worker     specStartOffset += sfbWidth[i];
251*e5436536SAndroid Build Coastguard Worker     if (specStartOffset >= granuleLengthWindow) {
252*e5436536SAndroid Build Coastguard Worker       i++;
253*e5436536SAndroid Build Coastguard Worker       break;
254*e5436536SAndroid Build Coastguard Worker     }
255*e5436536SAndroid Build Coastguard Worker   }
256*e5436536SAndroid Build Coastguard Worker   *sfbCnt = fixMin(i, *sfbCnt);
257*e5436536SAndroid Build Coastguard Worker   sfbOffset[*sfbCnt] = fixMin(specStartOffset, granuleLengthWindow);
258*e5436536SAndroid Build Coastguard Worker   return AAC_ENC_OK;
259*e5436536SAndroid Build Coastguard Worker }
260*e5436536SAndroid Build Coastguard Worker 
261*e5436536SAndroid Build Coastguard Worker /*****************************************************************************
262*e5436536SAndroid Build Coastguard Worker 
263*e5436536SAndroid Build Coastguard Worker     functionname: FDKaacEnc_BarcLineValue
264*e5436536SAndroid Build Coastguard Worker     description:  Calculates barc value for one frequency line
265*e5436536SAndroid Build Coastguard Worker     returns:      barc value of line
266*e5436536SAndroid Build Coastguard Worker     input:        number of lines in transform, index of line to check, Fs
267*e5436536SAndroid Build Coastguard Worker     output:
268*e5436536SAndroid Build Coastguard Worker 
269*e5436536SAndroid Build Coastguard Worker *****************************************************************************/
FDKaacEnc_BarcLineValue(INT noOfLines,INT fftLine,LONG samplingFreq)270*e5436536SAndroid Build Coastguard Worker static FIXP_DBL FDKaacEnc_BarcLineValue(INT noOfLines, INT fftLine,
271*e5436536SAndroid Build Coastguard Worker                                         LONG samplingFreq) {
272*e5436536SAndroid Build Coastguard Worker   FIXP_DBL FOURBY3EM4 = (FIXP_DBL)0x45e7b273; /* 4.0/3 * 0.0001 in q43 */
273*e5436536SAndroid Build Coastguard Worker   FIXP_DBL PZZZ76 = (FIXP_DBL)0x639d5e4a;     /* 0.00076 in q41 */
274*e5436536SAndroid Build Coastguard Worker   FIXP_DBL ONE3P3 = (FIXP_DBL)0x35333333;     /* 13.3 in q26 */
275*e5436536SAndroid Build Coastguard Worker   FIXP_DBL THREEP5 = (FIXP_DBL)0x1c000000;    /* 3.5 in q27 */
276*e5436536SAndroid Build Coastguard Worker   FIXP_DBL INV480 = (FIXP_DBL)0x44444444;     // 1/480 in q39
277*e5436536SAndroid Build Coastguard Worker 
278*e5436536SAndroid Build Coastguard Worker   FIXP_DBL center_freq, x1, x2;
279*e5436536SAndroid Build Coastguard Worker   FIXP_DBL bvalFFTLine, atan1, atan2;
280*e5436536SAndroid Build Coastguard Worker 
281*e5436536SAndroid Build Coastguard Worker   /* Theoritical maximum of center_freq (samp_freq*0.5) is 96khz * 0.5 = 48000
282*e5436536SAndroid Build Coastguard Worker    */
283*e5436536SAndroid Build Coastguard Worker   /* Theoritical maximum of x1 is 1.3333333e-4f * center_freq = 6.4, can keep in
284*e5436536SAndroid Build Coastguard Worker    * q28  */
285*e5436536SAndroid Build Coastguard Worker   /* Theoritical maximum of x2 is 0.00076f * center_freq = 36.48, can keep in
286*e5436536SAndroid Build Coastguard Worker    * q25     */
287*e5436536SAndroid Build Coastguard Worker 
288*e5436536SAndroid Build Coastguard Worker   center_freq = fftLine * samplingFreq; /* q11 or q8 */
289*e5436536SAndroid Build Coastguard Worker 
290*e5436536SAndroid Build Coastguard Worker   switch (noOfLines) {
291*e5436536SAndroid Build Coastguard Worker     case 1024:
292*e5436536SAndroid Build Coastguard Worker       center_freq = center_freq << 2; /* q13 */
293*e5436536SAndroid Build Coastguard Worker       break;
294*e5436536SAndroid Build Coastguard Worker     case 128:
295*e5436536SAndroid Build Coastguard Worker       center_freq = center_freq << 5; /* q13 */
296*e5436536SAndroid Build Coastguard Worker       break;
297*e5436536SAndroid Build Coastguard Worker     case 512:
298*e5436536SAndroid Build Coastguard Worker       center_freq = (fftLine * samplingFreq) << 3;  // q13
299*e5436536SAndroid Build Coastguard Worker       break;
300*e5436536SAndroid Build Coastguard Worker     case 480:
301*e5436536SAndroid Build Coastguard Worker       center_freq = fMult(center_freq, INV480) << 4;  // q13
302*e5436536SAndroid Build Coastguard Worker       break;
303*e5436536SAndroid Build Coastguard Worker     default:
304*e5436536SAndroid Build Coastguard Worker       center_freq = (FIXP_DBL)0;
305*e5436536SAndroid Build Coastguard Worker   }
306*e5436536SAndroid Build Coastguard Worker 
307*e5436536SAndroid Build Coastguard Worker   x1 = fMult(center_freq, FOURBY3EM4); /* q13 * q43 - (DFRACT_BITS-1) = q25 */
308*e5436536SAndroid Build Coastguard Worker   x2 = fMult(center_freq, PZZZ76)
309*e5436536SAndroid Build Coastguard Worker        << 2; /* q13 * q41 - (DFRACT_BITS-1) + 2 = q25 */
310*e5436536SAndroid Build Coastguard Worker 
311*e5436536SAndroid Build Coastguard Worker   atan1 = fixp_atan(x1);
312*e5436536SAndroid Build Coastguard Worker   atan2 = fixp_atan(x2);
313*e5436536SAndroid Build Coastguard Worker 
314*e5436536SAndroid Build Coastguard Worker   /* q25 (q26 * q30 - (DFRACT_BITS-1)) + q25 (q27 * q30 * q30) */
315*e5436536SAndroid Build Coastguard Worker   bvalFFTLine = fMult(ONE3P3, atan2) + fMult(THREEP5, fMult(atan1, atan1));
316*e5436536SAndroid Build Coastguard Worker   return (bvalFFTLine);
317*e5436536SAndroid Build Coastguard Worker }
318*e5436536SAndroid Build Coastguard Worker 
319*e5436536SAndroid Build Coastguard Worker /*
320*e5436536SAndroid Build Coastguard Worker    do not consider energies below a certain input signal level,
321*e5436536SAndroid Build Coastguard Worker    i.e. of -96dB or 1 bit at 16 bit PCM resolution,
322*e5436536SAndroid Build Coastguard Worker    might need to be configurable to e.g. 24 bit PCM Input or a lower
323*e5436536SAndroid Build Coastguard Worker    resolution for low bit rates
324*e5436536SAndroid Build Coastguard Worker */
FDKaacEnc_InitMinPCMResolution(int numPb,int * pbOffset,FIXP_DBL * sfbPCMquantThreshold)325*e5436536SAndroid Build Coastguard Worker static void FDKaacEnc_InitMinPCMResolution(int numPb, int *pbOffset,
326*e5436536SAndroid Build Coastguard Worker                                            FIXP_DBL *sfbPCMquantThreshold) {
327*e5436536SAndroid Build Coastguard Worker /* PCM_QUANT_NOISE = FDKpow(10.0f, - 20.f / 10.0f) * ABS_LOW * NORM_PCM_ENERGY *
328*e5436536SAndroid Build Coastguard Worker  * FDKpow(2,PCM_QUANT_THR_SCALE) */
329*e5436536SAndroid Build Coastguard Worker #define PCM_QUANT_NOISE ((FIXP_DBL)0x00547062)
330*e5436536SAndroid Build Coastguard Worker 
331*e5436536SAndroid Build Coastguard Worker   for (int i = 0; i < numPb; i++) {
332*e5436536SAndroid Build Coastguard Worker     sfbPCMquantThreshold[i] = (pbOffset[i + 1] - pbOffset[i]) * PCM_QUANT_NOISE;
333*e5436536SAndroid Build Coastguard Worker   }
334*e5436536SAndroid Build Coastguard Worker }
335*e5436536SAndroid Build Coastguard Worker 
getMaskFactor(const FIXP_DBL dbVal_fix,const INT dbVal_e,const FIXP_DBL ten_fix,const INT ten_e)336*e5436536SAndroid Build Coastguard Worker static FIXP_DBL getMaskFactor(const FIXP_DBL dbVal_fix, const INT dbVal_e,
337*e5436536SAndroid Build Coastguard Worker                               const FIXP_DBL ten_fix, const INT ten_e) {
338*e5436536SAndroid Build Coastguard Worker   INT q_msk;
339*e5436536SAndroid Build Coastguard Worker   FIXP_DBL mask_factor;
340*e5436536SAndroid Build Coastguard Worker 
341*e5436536SAndroid Build Coastguard Worker   mask_factor = fPow(ten_fix, DFRACT_BITS - 1 - ten_e, -dbVal_fix,
342*e5436536SAndroid Build Coastguard Worker                      DFRACT_BITS - 1 - dbVal_e, &q_msk);
343*e5436536SAndroid Build Coastguard Worker   q_msk = fixMin(DFRACT_BITS - 1, fixMax(-(DFRACT_BITS - 1), q_msk));
344*e5436536SAndroid Build Coastguard Worker 
345*e5436536SAndroid Build Coastguard Worker   if ((q_msk > 0) && (mask_factor > (FIXP_DBL)MAXVAL_DBL >> q_msk)) {
346*e5436536SAndroid Build Coastguard Worker     mask_factor = (FIXP_DBL)MAXVAL_DBL;
347*e5436536SAndroid Build Coastguard Worker   } else {
348*e5436536SAndroid Build Coastguard Worker     mask_factor = scaleValue(mask_factor, q_msk);
349*e5436536SAndroid Build Coastguard Worker   }
350*e5436536SAndroid Build Coastguard Worker 
351*e5436536SAndroid Build Coastguard Worker   return (mask_factor);
352*e5436536SAndroid Build Coastguard Worker }
353*e5436536SAndroid Build Coastguard Worker 
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*e5436536SAndroid Build Coastguard Worker static void FDKaacEnc_initSpreading(INT numPb, FIXP_DBL *pbBarcValue,
355*e5436536SAndroid Build Coastguard Worker                                     FIXP_DBL *pbMaskLoFactor,
356*e5436536SAndroid Build Coastguard Worker                                     FIXP_DBL *pbMaskHiFactor,
357*e5436536SAndroid Build Coastguard Worker                                     FIXP_DBL *pbMaskLoFactorSprEn,
358*e5436536SAndroid Build Coastguard Worker                                     FIXP_DBL *pbMaskHiFactorSprEn,
359*e5436536SAndroid Build Coastguard Worker                                     const LONG bitrate, const INT blockType)
360*e5436536SAndroid Build Coastguard Worker 
361*e5436536SAndroid Build Coastguard Worker {
362*e5436536SAndroid Build Coastguard Worker   INT i;
363*e5436536SAndroid Build Coastguard Worker   FIXP_DBL MASKLOWSPREN, MASKHIGHSPREN;
364*e5436536SAndroid Build Coastguard Worker 
365*e5436536SAndroid Build Coastguard Worker   FIXP_DBL MASKHIGH = (FIXP_DBL)0x30000000;               /* 1.5 in q29 */
366*e5436536SAndroid Build Coastguard Worker   FIXP_DBL MASKLOW = (FIXP_DBL)0x60000000;                /* 3.0 in q29 */
367*e5436536SAndroid Build Coastguard Worker   FIXP_DBL MASKLOWSPRENLONG = (FIXP_DBL)0x60000000;       /* 3.0 in q29 */
368*e5436536SAndroid Build Coastguard Worker   FIXP_DBL MASKHIGHSPRENLONG = (FIXP_DBL)0x40000000;      /* 2.0 in q29 */
369*e5436536SAndroid Build Coastguard Worker   FIXP_DBL MASKHIGHSPRENLONGLOWBR = (FIXP_DBL)0x30000000; /* 1.5 in q29 */
370*e5436536SAndroid Build Coastguard Worker   FIXP_DBL MASKLOWSPRENSHORT = (FIXP_DBL)0x40000000;      /* 2.0 in q29 */
371*e5436536SAndroid Build Coastguard Worker   FIXP_DBL MASKHIGHSPRENSHORT = (FIXP_DBL)0x30000000;     /* 1.5 in q29 */
372*e5436536SAndroid Build Coastguard Worker   FIXP_DBL TEN = (FIXP_DBL)0x50000000;                    /* 10.0 in q27 */
373*e5436536SAndroid Build Coastguard Worker 
374*e5436536SAndroid Build Coastguard Worker   if (blockType != SHORT_WINDOW) {
375*e5436536SAndroid Build Coastguard Worker     MASKLOWSPREN = MASKLOWSPRENLONG;
376*e5436536SAndroid Build Coastguard Worker     MASKHIGHSPREN =
377*e5436536SAndroid Build Coastguard Worker         (bitrate > 20000) ? MASKHIGHSPRENLONG : MASKHIGHSPRENLONGLOWBR;
378*e5436536SAndroid Build Coastguard Worker   } else {
379*e5436536SAndroid Build Coastguard Worker     MASKLOWSPREN = MASKLOWSPRENSHORT;
380*e5436536SAndroid Build Coastguard Worker     MASKHIGHSPREN = MASKHIGHSPRENSHORT;
381*e5436536SAndroid Build Coastguard Worker   }
382*e5436536SAndroid Build Coastguard Worker 
383*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < numPb; i++) {
384*e5436536SAndroid Build Coastguard Worker     if (i > 0) {
385*e5436536SAndroid Build Coastguard Worker       pbMaskHiFactor[i] = getMaskFactor(
386*e5436536SAndroid Build Coastguard Worker           fMult(MASKHIGH, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, 27);
387*e5436536SAndroid Build Coastguard Worker 
388*e5436536SAndroid Build Coastguard Worker       pbMaskLoFactor[i - 1] = getMaskFactor(
389*e5436536SAndroid Build Coastguard Worker           fMult(MASKLOW, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, 27);
390*e5436536SAndroid Build Coastguard Worker 
391*e5436536SAndroid Build Coastguard Worker       pbMaskHiFactorSprEn[i] = getMaskFactor(
392*e5436536SAndroid Build Coastguard Worker           fMult(MASKHIGHSPREN, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN,
393*e5436536SAndroid Build Coastguard Worker           27);
394*e5436536SAndroid Build Coastguard Worker 
395*e5436536SAndroid Build Coastguard Worker       pbMaskLoFactorSprEn[i - 1] = getMaskFactor(
396*e5436536SAndroid Build Coastguard Worker           fMult(MASKLOWSPREN, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN,
397*e5436536SAndroid Build Coastguard Worker           27);
398*e5436536SAndroid Build Coastguard Worker     } else {
399*e5436536SAndroid Build Coastguard Worker       pbMaskHiFactor[i] = (FIXP_DBL)0;
400*e5436536SAndroid Build Coastguard Worker       pbMaskLoFactor[numPb - 1] = (FIXP_DBL)0;
401*e5436536SAndroid Build Coastguard Worker       pbMaskHiFactorSprEn[i] = (FIXP_DBL)0;
402*e5436536SAndroid Build Coastguard Worker       pbMaskLoFactorSprEn[numPb - 1] = (FIXP_DBL)0;
403*e5436536SAndroid Build Coastguard Worker     }
404*e5436536SAndroid Build Coastguard Worker   }
405*e5436536SAndroid Build Coastguard Worker }
406*e5436536SAndroid Build Coastguard Worker 
FDKaacEnc_initBarcValues(INT numPb,INT * pbOffset,INT numLines,INT samplingFrequency,FIXP_DBL * pbBval)407*e5436536SAndroid Build Coastguard Worker static void FDKaacEnc_initBarcValues(INT numPb, INT *pbOffset, INT numLines,
408*e5436536SAndroid Build Coastguard Worker                                      INT samplingFrequency, FIXP_DBL *pbBval) {
409*e5436536SAndroid Build Coastguard Worker   INT i;
410*e5436536SAndroid Build Coastguard Worker   FIXP_DBL MAX_BARC = (FIXP_DBL)0x30000000; /* 24.0 in q25 */
411*e5436536SAndroid Build Coastguard Worker 
412*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < numPb; i++) {
413*e5436536SAndroid Build Coastguard Worker     FIXP_DBL v1, v2, cur_bark;
414*e5436536SAndroid Build Coastguard Worker     v1 = FDKaacEnc_BarcLineValue(numLines, pbOffset[i], samplingFrequency);
415*e5436536SAndroid Build Coastguard Worker     v2 = FDKaacEnc_BarcLineValue(numLines, pbOffset[i + 1], samplingFrequency);
416*e5436536SAndroid Build Coastguard Worker     cur_bark = (v1 >> 1) + (v2 >> 1);
417*e5436536SAndroid Build Coastguard Worker     pbBval[i] = fixMin(cur_bark, MAX_BARC);
418*e5436536SAndroid Build Coastguard Worker   }
419*e5436536SAndroid Build Coastguard Worker }
420*e5436536SAndroid Build Coastguard Worker 
FDKaacEnc_initMinSnr(const LONG bitrate,const LONG samplerate,const INT numLines,const INT * sfbOffset,const INT sfbActive,const INT blockType,FIXP_DBL * sfbMinSnrLdData)421*e5436536SAndroid Build Coastguard Worker static void FDKaacEnc_initMinSnr(const LONG bitrate, const LONG samplerate,
422*e5436536SAndroid Build Coastguard Worker                                  const INT numLines, const INT *sfbOffset,
423*e5436536SAndroid Build Coastguard Worker                                  const INT sfbActive, const INT blockType,
424*e5436536SAndroid Build Coastguard Worker                                  FIXP_DBL *sfbMinSnrLdData) {
425*e5436536SAndroid Build Coastguard Worker   INT sfb;
426*e5436536SAndroid Build Coastguard Worker 
427*e5436536SAndroid Build Coastguard Worker   /* Fix conversion variables */
428*e5436536SAndroid Build Coastguard Worker   INT qbfac, qperwin, qdiv, qpeprt_const, qpeprt;
429*e5436536SAndroid Build Coastguard Worker   INT qtmp, qsnr, sfbWidth;
430*e5436536SAndroid Build Coastguard Worker 
431*e5436536SAndroid Build Coastguard Worker   FIXP_DBL MAX_BARC = (FIXP_DBL)0x30000000;   /* 24.0 in q25 */
432*e5436536SAndroid Build Coastguard Worker   FIXP_DBL MAX_BARCP1 = (FIXP_DBL)0x32000000; /* 25.0 in q25 */
433*e5436536SAndroid Build Coastguard Worker   FIXP_DBL BITS2PEFAC = (FIXP_DBL)0x4b851eb8; /* 1.18 in q30 */
434*e5436536SAndroid Build Coastguard Worker   FIXP_DBL PERS2P4 = (FIXP_DBL)0x624dd2f2;    /* 0.024 in q36 */
435*e5436536SAndroid Build Coastguard Worker   FIXP_DBL ONEP5 = (FIXP_DBL)0x60000000;      /* 1.5 in q30 */
436*e5436536SAndroid Build Coastguard Worker   FIXP_DBL MAX_SNR = (FIXP_DBL)0x33333333;    /* 0.8 in q30 */
437*e5436536SAndroid Build Coastguard Worker   FIXP_DBL MIN_SNR = (FIXP_DBL)0x003126e9;    /* 0.003 in q30 */
438*e5436536SAndroid Build Coastguard Worker 
439*e5436536SAndroid Build Coastguard Worker   FIXP_DBL barcFactor, pePerWindow, pePart, barcWidth;
440*e5436536SAndroid Build Coastguard Worker   FIXP_DBL pePart_const, tmp, snr, one_qsnr, one_point5;
441*e5436536SAndroid Build Coastguard Worker 
442*e5436536SAndroid Build Coastguard Worker   /* relative number of active barks */
443*e5436536SAndroid Build Coastguard Worker   barcFactor = fDivNorm(fixMin(FDKaacEnc_BarcLineValue(
444*e5436536SAndroid Build Coastguard Worker                                    numLines, sfbOffset[sfbActive], samplerate),
445*e5436536SAndroid Build Coastguard Worker                                MAX_BARC),
446*e5436536SAndroid Build Coastguard Worker                         MAX_BARCP1, &qbfac);
447*e5436536SAndroid Build Coastguard Worker 
448*e5436536SAndroid Build Coastguard Worker   qbfac = DFRACT_BITS - 1 - qbfac;
449*e5436536SAndroid Build Coastguard Worker 
450*e5436536SAndroid Build Coastguard Worker   pePerWindow = fDivNorm(bitrate, samplerate, &qperwin);
451*e5436536SAndroid Build Coastguard Worker   qperwin = DFRACT_BITS - 1 - qperwin;
452*e5436536SAndroid Build Coastguard Worker   pePerWindow = fMult(pePerWindow, BITS2PEFAC);
453*e5436536SAndroid Build Coastguard Worker   qperwin = qperwin + 30 - (DFRACT_BITS - 1);
454*e5436536SAndroid Build Coastguard Worker   pePerWindow = fMult(pePerWindow, PERS2P4);
455*e5436536SAndroid Build Coastguard Worker   qperwin = qperwin + 36 - (DFRACT_BITS - 1);
456*e5436536SAndroid Build Coastguard Worker 
457*e5436536SAndroid Build Coastguard Worker   switch (numLines) {
458*e5436536SAndroid Build Coastguard Worker     case 1024:
459*e5436536SAndroid Build Coastguard Worker       qperwin = qperwin - 10;
460*e5436536SAndroid Build Coastguard Worker       break;
461*e5436536SAndroid Build Coastguard Worker     case 128:
462*e5436536SAndroid Build Coastguard Worker       qperwin = qperwin - 7;
463*e5436536SAndroid Build Coastguard Worker       break;
464*e5436536SAndroid Build Coastguard Worker     case 512:
465*e5436536SAndroid Build Coastguard Worker       qperwin = qperwin - 9;
466*e5436536SAndroid Build Coastguard Worker       break;
467*e5436536SAndroid Build Coastguard Worker     case 480:
468*e5436536SAndroid Build Coastguard Worker       qperwin = qperwin - 9;
469*e5436536SAndroid Build Coastguard Worker       pePerWindow = fMult(pePerWindow, FL2FXCONST_DBL(480.f / 512.f));
470*e5436536SAndroid Build Coastguard Worker       break;
471*e5436536SAndroid Build Coastguard Worker   }
472*e5436536SAndroid Build Coastguard Worker 
473*e5436536SAndroid Build Coastguard Worker   /* for short blocks it is assumed that more bits are available */
474*e5436536SAndroid Build Coastguard Worker   if (blockType == SHORT_WINDOW) {
475*e5436536SAndroid Build Coastguard Worker     pePerWindow = fMult(pePerWindow, ONEP5);
476*e5436536SAndroid Build Coastguard Worker     qperwin = qperwin + 30 - (DFRACT_BITS - 1);
477*e5436536SAndroid Build Coastguard Worker   }
478*e5436536SAndroid Build Coastguard Worker   pePart_const = fDivNorm(pePerWindow, barcFactor, &qdiv);
479*e5436536SAndroid Build Coastguard Worker   qpeprt_const = qperwin - qbfac + DFRACT_BITS - 1 - qdiv;
480*e5436536SAndroid Build Coastguard Worker 
481*e5436536SAndroid Build Coastguard Worker   for (sfb = 0; sfb < sfbActive; sfb++) {
482*e5436536SAndroid Build Coastguard Worker     barcWidth =
483*e5436536SAndroid Build Coastguard Worker         FDKaacEnc_BarcLineValue(numLines, sfbOffset[sfb + 1], samplerate) -
484*e5436536SAndroid Build Coastguard Worker         FDKaacEnc_BarcLineValue(numLines, sfbOffset[sfb], samplerate);
485*e5436536SAndroid Build Coastguard Worker 
486*e5436536SAndroid Build Coastguard Worker     /* adapt to sfb bands */
487*e5436536SAndroid Build Coastguard Worker     pePart = fMult(pePart_const, barcWidth);
488*e5436536SAndroid Build Coastguard Worker     qpeprt = qpeprt_const + 25 - (DFRACT_BITS - 1);
489*e5436536SAndroid Build Coastguard Worker 
490*e5436536SAndroid Build Coastguard Worker     /* pe -> snr calculation */
491*e5436536SAndroid Build Coastguard Worker     sfbWidth = (sfbOffset[sfb + 1] - sfbOffset[sfb]);
492*e5436536SAndroid Build Coastguard Worker     pePart = fDivNorm(pePart, sfbWidth, &qdiv);
493*e5436536SAndroid Build Coastguard Worker     qpeprt += DFRACT_BITS - 1 - qdiv;
494*e5436536SAndroid Build Coastguard Worker 
495*e5436536SAndroid Build Coastguard Worker     tmp = f2Pow(pePart, DFRACT_BITS - 1 - qpeprt, &qtmp);
496*e5436536SAndroid Build Coastguard Worker     qtmp = DFRACT_BITS - 1 - qtmp;
497*e5436536SAndroid Build Coastguard Worker 
498*e5436536SAndroid Build Coastguard Worker     /* Subtract 1.5 */
499*e5436536SAndroid Build Coastguard Worker     qsnr = fixMin(qtmp, 30);
500*e5436536SAndroid Build Coastguard Worker     tmp = tmp >> (qtmp - qsnr);
501*e5436536SAndroid Build Coastguard Worker 
502*e5436536SAndroid Build Coastguard Worker     if ((30 + 1 - qsnr) > (DFRACT_BITS - 1))
503*e5436536SAndroid Build Coastguard Worker       one_point5 = (FIXP_DBL)0;
504*e5436536SAndroid Build Coastguard Worker     else
505*e5436536SAndroid Build Coastguard Worker       one_point5 = (FIXP_DBL)(ONEP5 >> (30 + 1 - qsnr));
506*e5436536SAndroid Build Coastguard Worker 
507*e5436536SAndroid Build Coastguard Worker     snr = (tmp >> 1) - (one_point5);
508*e5436536SAndroid Build Coastguard Worker     qsnr -= 1;
509*e5436536SAndroid Build Coastguard Worker 
510*e5436536SAndroid Build Coastguard Worker     /* max(snr, 1.0) */
511*e5436536SAndroid Build Coastguard Worker     if (qsnr > 0)
512*e5436536SAndroid Build Coastguard Worker       one_qsnr = (FIXP_DBL)(1 << qsnr);
513*e5436536SAndroid Build Coastguard Worker     else
514*e5436536SAndroid Build Coastguard Worker       one_qsnr = (FIXP_DBL)0;
515*e5436536SAndroid Build Coastguard Worker 
516*e5436536SAndroid Build Coastguard Worker     snr = fixMax(one_qsnr, snr);
517*e5436536SAndroid Build Coastguard Worker 
518*e5436536SAndroid Build Coastguard Worker     /* 1/snr */
519*e5436536SAndroid Build Coastguard Worker     snr = fDivNorm(one_qsnr, snr, &qsnr);
520*e5436536SAndroid Build Coastguard Worker     qsnr = DFRACT_BITS - 1 - qsnr;
521*e5436536SAndroid Build Coastguard Worker     snr = (qsnr > 30) ? (snr >> (qsnr - 30)) : snr;
522*e5436536SAndroid Build Coastguard Worker 
523*e5436536SAndroid Build Coastguard Worker     /* upper limit is -1 dB */
524*e5436536SAndroid Build Coastguard Worker     snr = (snr > MAX_SNR) ? MAX_SNR : snr;
525*e5436536SAndroid Build Coastguard Worker 
526*e5436536SAndroid Build Coastguard Worker     /* lower limit is -25 dB */
527*e5436536SAndroid Build Coastguard Worker     snr = (snr < MIN_SNR) ? MIN_SNR : snr;
528*e5436536SAndroid Build Coastguard Worker     snr = snr << 1;
529*e5436536SAndroid Build Coastguard Worker 
530*e5436536SAndroid Build Coastguard Worker     sfbMinSnrLdData[sfb] = CalcLdData(snr);
531*e5436536SAndroid Build Coastguard Worker   }
532*e5436536SAndroid Build Coastguard Worker }
533*e5436536SAndroid Build Coastguard Worker 
FDKaacEnc_InitPsyConfiguration(INT bitrate,INT samplerate,INT bandwidth,INT blocktype,INT granuleLength,INT useIS,INT useMS,PSY_CONFIGURATION * psyConf,FB_TYPE filterbank)534*e5436536SAndroid Build Coastguard Worker AAC_ENCODER_ERROR FDKaacEnc_InitPsyConfiguration(INT bitrate, INT samplerate,
535*e5436536SAndroid Build Coastguard Worker                                                  INT bandwidth, INT blocktype,
536*e5436536SAndroid Build Coastguard Worker                                                  INT granuleLength, INT useIS,
537*e5436536SAndroid Build Coastguard Worker                                                  INT useMS,
538*e5436536SAndroid Build Coastguard Worker                                                  PSY_CONFIGURATION *psyConf,
539*e5436536SAndroid Build Coastguard Worker                                                  FB_TYPE filterbank) {
540*e5436536SAndroid Build Coastguard Worker   AAC_ENCODER_ERROR ErrorStatus;
541*e5436536SAndroid Build Coastguard Worker   INT sfb;
542*e5436536SAndroid Build Coastguard Worker   FIXP_DBL sfbBarcVal[MAX_SFB];
543*e5436536SAndroid Build Coastguard Worker   const INT frameLengthLong = granuleLength;
544*e5436536SAndroid Build Coastguard Worker   const INT frameLengthShort = granuleLength / TRANS_FAC;
545*e5436536SAndroid Build Coastguard Worker   INT downscaleFactor = 1;
546*e5436536SAndroid Build Coastguard Worker 
547*e5436536SAndroid Build Coastguard Worker   switch (granuleLength) {
548*e5436536SAndroid Build Coastguard Worker     case 256:
549*e5436536SAndroid Build Coastguard Worker     case 240:
550*e5436536SAndroid Build Coastguard Worker       downscaleFactor = 2;
551*e5436536SAndroid Build Coastguard Worker       break;
552*e5436536SAndroid Build Coastguard Worker     case 128:
553*e5436536SAndroid Build Coastguard Worker     case 120:
554*e5436536SAndroid Build Coastguard Worker       downscaleFactor = 4;
555*e5436536SAndroid Build Coastguard Worker       break;
556*e5436536SAndroid Build Coastguard Worker     default:
557*e5436536SAndroid Build Coastguard Worker       downscaleFactor = 1;
558*e5436536SAndroid Build Coastguard Worker       break;
559*e5436536SAndroid Build Coastguard Worker   }
560*e5436536SAndroid Build Coastguard Worker 
561*e5436536SAndroid Build Coastguard Worker   FDKmemclear(psyConf, sizeof(PSY_CONFIGURATION));
562*e5436536SAndroid Build Coastguard Worker   psyConf->granuleLength = granuleLength;
563*e5436536SAndroid Build Coastguard Worker   psyConf->filterbank = filterbank;
564*e5436536SAndroid Build Coastguard Worker 
565*e5436536SAndroid Build Coastguard Worker   psyConf->allowIS = (useIS) && ((bitrate / bandwidth) < 5);
566*e5436536SAndroid Build Coastguard Worker   psyConf->allowMS = useMS;
567*e5436536SAndroid Build Coastguard Worker 
568*e5436536SAndroid Build Coastguard Worker   /* init sfb table */
569*e5436536SAndroid Build Coastguard Worker   ErrorStatus = FDKaacEnc_initSfbTable(samplerate * downscaleFactor, blocktype,
570*e5436536SAndroid Build Coastguard Worker                                        granuleLength * downscaleFactor,
571*e5436536SAndroid Build Coastguard Worker                                        psyConf->sfbOffset, &psyConf->sfbCnt);
572*e5436536SAndroid Build Coastguard Worker 
573*e5436536SAndroid Build Coastguard Worker   if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
574*e5436536SAndroid Build Coastguard Worker 
575*e5436536SAndroid Build Coastguard Worker   /* calculate barc values for each pb */
576*e5436536SAndroid Build Coastguard Worker   FDKaacEnc_initBarcValues(psyConf->sfbCnt, psyConf->sfbOffset,
577*e5436536SAndroid Build Coastguard Worker                            psyConf->sfbOffset[psyConf->sfbCnt], samplerate,
578*e5436536SAndroid Build Coastguard Worker                            sfbBarcVal);
579*e5436536SAndroid Build Coastguard Worker 
580*e5436536SAndroid Build Coastguard Worker   FDKaacEnc_InitMinPCMResolution(psyConf->sfbCnt, psyConf->sfbOffset,
581*e5436536SAndroid Build Coastguard Worker                                  psyConf->sfbPcmQuantThreshold);
582*e5436536SAndroid Build Coastguard Worker 
583*e5436536SAndroid Build Coastguard Worker   /* calculate spreading function */
584*e5436536SAndroid Build Coastguard Worker   FDKaacEnc_initSpreading(psyConf->sfbCnt, sfbBarcVal,
585*e5436536SAndroid Build Coastguard Worker                           psyConf->sfbMaskLowFactor, psyConf->sfbMaskHighFactor,
586*e5436536SAndroid Build Coastguard Worker                           psyConf->sfbMaskLowFactorSprEn,
587*e5436536SAndroid Build Coastguard Worker                           psyConf->sfbMaskHighFactorSprEn, bitrate, blocktype);
588*e5436536SAndroid Build Coastguard Worker 
589*e5436536SAndroid Build Coastguard Worker   /* init ratio */
590*e5436536SAndroid Build Coastguard Worker 
591*e5436536SAndroid Build Coastguard Worker   psyConf->maxAllowedIncreaseFactor = 2; /* integer */
592*e5436536SAndroid Build Coastguard Worker   psyConf->minRemainingThresholdFactor = (FIXP_SGL)0x0148;
593*e5436536SAndroid Build Coastguard Worker   /* FL2FXCONST_SGL(0.01f); */ /* fract   */
594*e5436536SAndroid Build Coastguard Worker 
595*e5436536SAndroid Build Coastguard Worker   psyConf->clipEnergy =
596*e5436536SAndroid Build Coastguard Worker       (FIXP_DBL)0x773593ff; /* FL2FXCONST_DBL(1.0e9*NORM_PCM_ENERGY); */
597*e5436536SAndroid Build Coastguard Worker 
598*e5436536SAndroid Build Coastguard Worker   if (blocktype != SHORT_WINDOW) {
599*e5436536SAndroid Build Coastguard Worker     psyConf->lowpassLine =
600*e5436536SAndroid Build Coastguard Worker         (INT)((2 * bandwidth * frameLengthLong) / samplerate);
601*e5436536SAndroid Build Coastguard Worker     psyConf->lowpassLineLFE = LFE_LOWPASS_LINE;
602*e5436536SAndroid Build Coastguard Worker   } else {
603*e5436536SAndroid Build Coastguard Worker     psyConf->lowpassLine =
604*e5436536SAndroid Build Coastguard Worker         (INT)((2 * bandwidth * frameLengthShort) / samplerate);
605*e5436536SAndroid Build Coastguard Worker     psyConf->lowpassLineLFE = 0; /* LFE only in lonf blocks */
606*e5436536SAndroid Build Coastguard Worker     /* psyConf->clipEnergy /= (TRANS_FAC * TRANS_FAC); */
607*e5436536SAndroid Build Coastguard Worker     psyConf->clipEnergy >>= 6;
608*e5436536SAndroid Build Coastguard Worker   }
609*e5436536SAndroid Build Coastguard Worker 
610*e5436536SAndroid Build Coastguard Worker   for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) {
611*e5436536SAndroid Build Coastguard Worker     if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLine) break;
612*e5436536SAndroid Build Coastguard Worker   }
613*e5436536SAndroid Build Coastguard Worker   psyConf->sfbActive = fMax(sfb, 1);
614*e5436536SAndroid Build Coastguard Worker 
615*e5436536SAndroid Build Coastguard Worker   for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) {
616*e5436536SAndroid Build Coastguard Worker     if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLineLFE) break;
617*e5436536SAndroid Build Coastguard Worker   }
618*e5436536SAndroid Build Coastguard Worker   psyConf->sfbActiveLFE = sfb;
619*e5436536SAndroid Build Coastguard Worker   psyConf->sfbActive = fMax(psyConf->sfbActive, psyConf->sfbActiveLFE);
620*e5436536SAndroid Build Coastguard Worker 
621*e5436536SAndroid Build Coastguard Worker   /* calculate minSnr */
622*e5436536SAndroid Build Coastguard Worker   FDKaacEnc_initMinSnr(bitrate, samplerate * downscaleFactor,
623*e5436536SAndroid Build Coastguard Worker                        psyConf->sfbOffset[psyConf->sfbCnt], psyConf->sfbOffset,
624*e5436536SAndroid Build Coastguard Worker                        psyConf->sfbActive, blocktype, psyConf->sfbMinSnrLdData);
625*e5436536SAndroid Build Coastguard Worker 
626*e5436536SAndroid Build Coastguard Worker   return AAC_ENC_OK;
627*e5436536SAndroid Build Coastguard Worker }
628