xref: /aosp_15_r20/external/aac/libAACenc/src/bandwidth.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 - 2019 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. Schug / A. Groeschel
98*e5436536SAndroid Build Coastguard Worker 
99*e5436536SAndroid Build Coastguard Worker    Description: bandwidth expert
100*e5436536SAndroid Build Coastguard Worker 
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker 
103*e5436536SAndroid Build Coastguard Worker #include "channel_map.h"
104*e5436536SAndroid Build Coastguard Worker #include "bandwidth.h"
105*e5436536SAndroid Build Coastguard Worker #include "aacEnc_ram.h"
106*e5436536SAndroid Build Coastguard Worker 
107*e5436536SAndroid Build Coastguard Worker typedef struct {
108*e5436536SAndroid Build Coastguard Worker   INT chanBitRate;
109*e5436536SAndroid Build Coastguard Worker   INT bandWidthMono;
110*e5436536SAndroid Build Coastguard Worker   INT bandWidth2AndMoreChan;
111*e5436536SAndroid Build Coastguard Worker 
112*e5436536SAndroid Build Coastguard Worker } BANDWIDTH_TAB;
113*e5436536SAndroid Build Coastguard Worker 
114*e5436536SAndroid Build Coastguard Worker static const BANDWIDTH_TAB bandWidthTable[] = {
115*e5436536SAndroid Build Coastguard Worker     {0, 3700, 5000},       {12000, 5000, 6400},   {20000, 6900, 9640},
116*e5436536SAndroid Build Coastguard Worker     {28000, 9600, 13050},  {40000, 12060, 14260}, {56000, 13950, 15500},
117*e5436536SAndroid Build Coastguard Worker     {72000, 14200, 16120}, {96000, 17000, 17000}, {576001, 17000, 17000}};
118*e5436536SAndroid Build Coastguard Worker 
119*e5436536SAndroid Build Coastguard Worker static const BANDWIDTH_TAB bandWidthTable_LD_22050[] = {
120*e5436536SAndroid Build Coastguard Worker     {8000, 2000, 2400},    {12000, 2500, 2700},   {16000, 3300, 3100},
121*e5436536SAndroid Build Coastguard Worker     {24000, 6250, 7200},   {32000, 9200, 10500},  {40000, 16000, 16000},
122*e5436536SAndroid Build Coastguard Worker     {48000, 16000, 16000}, {282241, 16000, 16000}};
123*e5436536SAndroid Build Coastguard Worker 
124*e5436536SAndroid Build Coastguard Worker static const BANDWIDTH_TAB bandWidthTable_LD_24000[] = {
125*e5436536SAndroid Build Coastguard Worker     {8000, 2000, 2000},    {12000, 2000, 2300},   {16000, 2200, 2500},
126*e5436536SAndroid Build Coastguard Worker     {24000, 5650, 7200},   {32000, 11600, 12000}, {40000, 12000, 16000},
127*e5436536SAndroid Build Coastguard Worker     {48000, 16000, 16000}, {64000, 16000, 16000}, {307201, 16000, 16000}};
128*e5436536SAndroid Build Coastguard Worker 
129*e5436536SAndroid Build Coastguard Worker static const BANDWIDTH_TAB bandWidthTable_LD_32000[] = {
130*e5436536SAndroid Build Coastguard Worker     {8000, 2000, 2000},    {12000, 2000, 2000},   {24000, 4250, 7200},
131*e5436536SAndroid Build Coastguard Worker     {32000, 8400, 9000},   {40000, 9400, 11300},  {48000, 11900, 14700},
132*e5436536SAndroid Build Coastguard Worker     {64000, 14800, 16000}, {76000, 16000, 16000}, {409601, 16000, 16000}};
133*e5436536SAndroid Build Coastguard Worker 
134*e5436536SAndroid Build Coastguard Worker static const BANDWIDTH_TAB bandWidthTable_LD_44100[] = {
135*e5436536SAndroid Build Coastguard Worker     {8000, 2000, 2000},     {24000, 2000, 2000},   {32000, 4400, 5700},
136*e5436536SAndroid Build Coastguard Worker     {40000, 7400, 8800},    {48000, 9000, 10700},  {56000, 11000, 12900},
137*e5436536SAndroid Build Coastguard Worker     {64000, 14400, 15500},  {80000, 16000, 16200}, {96000, 16500, 16000},
138*e5436536SAndroid Build Coastguard Worker     {128000, 16000, 16000}, {564481, 16000, 16000}};
139*e5436536SAndroid Build Coastguard Worker 
140*e5436536SAndroid Build Coastguard Worker static const BANDWIDTH_TAB bandWidthTable_LD_48000[] = {
141*e5436536SAndroid Build Coastguard Worker     {8000, 2000, 2000},     {24000, 2000, 2000},   {32000, 4400, 5700},
142*e5436536SAndroid Build Coastguard Worker     {40000, 7400, 8800},    {48000, 9000, 10700},  {56000, 11000, 12800},
143*e5436536SAndroid Build Coastguard Worker     {64000, 14300, 15400},  {80000, 16000, 16200}, {96000, 16500, 16000},
144*e5436536SAndroid Build Coastguard Worker     {128000, 16000, 16000}, {614401, 16000, 16000}};
145*e5436536SAndroid Build Coastguard Worker 
146*e5436536SAndroid Build Coastguard Worker typedef struct {
147*e5436536SAndroid Build Coastguard Worker   AACENC_BITRATE_MODE bitrateMode;
148*e5436536SAndroid Build Coastguard Worker   int bandWidthMono;
149*e5436536SAndroid Build Coastguard Worker   int bandWidth2AndMoreChan;
150*e5436536SAndroid Build Coastguard Worker } BANDWIDTH_TAB_VBR;
151*e5436536SAndroid Build Coastguard Worker 
152*e5436536SAndroid Build Coastguard Worker static const BANDWIDTH_TAB_VBR bandWidthTableVBR[] = {
153*e5436536SAndroid Build Coastguard Worker     {AACENC_BR_MODE_CBR, 0, 0},
154*e5436536SAndroid Build Coastguard Worker     {AACENC_BR_MODE_VBR_1, 13000, 13000},
155*e5436536SAndroid Build Coastguard Worker     {AACENC_BR_MODE_VBR_2, 13000, 13000},
156*e5436536SAndroid Build Coastguard Worker     {AACENC_BR_MODE_VBR_3, 15750, 15750},
157*e5436536SAndroid Build Coastguard Worker     {AACENC_BR_MODE_VBR_4, 16500, 16500},
158*e5436536SAndroid Build Coastguard Worker     {AACENC_BR_MODE_VBR_5, 19293, 19293},
159*e5436536SAndroid Build Coastguard Worker     {AACENC_BR_MODE_SFR, 0, 0},
160*e5436536SAndroid Build Coastguard Worker     {AACENC_BR_MODE_FF, 0, 0}
161*e5436536SAndroid Build Coastguard Worker 
162*e5436536SAndroid Build Coastguard Worker };
163*e5436536SAndroid Build Coastguard Worker 
GetBandwidthEntry(const INT frameLength,const INT sampleRate,const INT chanBitRate,const INT entryNo)164*e5436536SAndroid Build Coastguard Worker static INT GetBandwidthEntry(const INT frameLength, const INT sampleRate,
165*e5436536SAndroid Build Coastguard Worker                              const INT chanBitRate, const INT entryNo) {
166*e5436536SAndroid Build Coastguard Worker   INT bandwidth = -1;
167*e5436536SAndroid Build Coastguard Worker   const BANDWIDTH_TAB *pBwTab = NULL;
168*e5436536SAndroid Build Coastguard Worker   INT bwTabSize = 0;
169*e5436536SAndroid Build Coastguard Worker 
170*e5436536SAndroid Build Coastguard Worker   switch (frameLength) {
171*e5436536SAndroid Build Coastguard Worker     case 960:
172*e5436536SAndroid Build Coastguard Worker     case 1024:
173*e5436536SAndroid Build Coastguard Worker       pBwTab = bandWidthTable;
174*e5436536SAndroid Build Coastguard Worker       bwTabSize = sizeof(bandWidthTable) / sizeof(BANDWIDTH_TAB);
175*e5436536SAndroid Build Coastguard Worker       break;
176*e5436536SAndroid Build Coastguard Worker     case 120:
177*e5436536SAndroid Build Coastguard Worker     case 128:
178*e5436536SAndroid Build Coastguard Worker     case 240:
179*e5436536SAndroid Build Coastguard Worker     case 256:
180*e5436536SAndroid Build Coastguard Worker     case 480:
181*e5436536SAndroid Build Coastguard Worker     case 512:
182*e5436536SAndroid Build Coastguard Worker       switch (sampleRate) {
183*e5436536SAndroid Build Coastguard Worker         case 8000:
184*e5436536SAndroid Build Coastguard Worker         case 11025:
185*e5436536SAndroid Build Coastguard Worker         case 12000:
186*e5436536SAndroid Build Coastguard Worker         case 16000:
187*e5436536SAndroid Build Coastguard Worker         case 22050:
188*e5436536SAndroid Build Coastguard Worker           pBwTab = bandWidthTable_LD_22050;
189*e5436536SAndroid Build Coastguard Worker           bwTabSize = sizeof(bandWidthTable_LD_22050) / sizeof(BANDWIDTH_TAB);
190*e5436536SAndroid Build Coastguard Worker           break;
191*e5436536SAndroid Build Coastguard Worker         case 24000:
192*e5436536SAndroid Build Coastguard Worker           pBwTab = bandWidthTable_LD_24000;
193*e5436536SAndroid Build Coastguard Worker           bwTabSize = sizeof(bandWidthTable_LD_24000) / sizeof(BANDWIDTH_TAB);
194*e5436536SAndroid Build Coastguard Worker           break;
195*e5436536SAndroid Build Coastguard Worker         case 32000:
196*e5436536SAndroid Build Coastguard Worker           pBwTab = bandWidthTable_LD_32000;
197*e5436536SAndroid Build Coastguard Worker           bwTabSize = sizeof(bandWidthTable_LD_32000) / sizeof(BANDWIDTH_TAB);
198*e5436536SAndroid Build Coastguard Worker           break;
199*e5436536SAndroid Build Coastguard Worker         case 44100:
200*e5436536SAndroid Build Coastguard Worker           pBwTab = bandWidthTable_LD_44100;
201*e5436536SAndroid Build Coastguard Worker           bwTabSize = sizeof(bandWidthTable_LD_44100) / sizeof(BANDWIDTH_TAB);
202*e5436536SAndroid Build Coastguard Worker           break;
203*e5436536SAndroid Build Coastguard Worker         case 48000:
204*e5436536SAndroid Build Coastguard Worker         case 64000:
205*e5436536SAndroid Build Coastguard Worker         case 88200:
206*e5436536SAndroid Build Coastguard Worker         case 96000:
207*e5436536SAndroid Build Coastguard Worker           pBwTab = bandWidthTable_LD_48000;
208*e5436536SAndroid Build Coastguard Worker           bwTabSize = sizeof(bandWidthTable_LD_48000) / sizeof(BANDWIDTH_TAB);
209*e5436536SAndroid Build Coastguard Worker           break;
210*e5436536SAndroid Build Coastguard Worker       }
211*e5436536SAndroid Build Coastguard Worker       break;
212*e5436536SAndroid Build Coastguard Worker     default:
213*e5436536SAndroid Build Coastguard Worker       pBwTab = NULL;
214*e5436536SAndroid Build Coastguard Worker       bwTabSize = 0;
215*e5436536SAndroid Build Coastguard Worker   }
216*e5436536SAndroid Build Coastguard Worker 
217*e5436536SAndroid Build Coastguard Worker   if (pBwTab != NULL) {
218*e5436536SAndroid Build Coastguard Worker     int i;
219*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < bwTabSize - 1; i++) {
220*e5436536SAndroid Build Coastguard Worker       if (chanBitRate >= pBwTab[i].chanBitRate &&
221*e5436536SAndroid Build Coastguard Worker           chanBitRate < pBwTab[i + 1].chanBitRate) {
222*e5436536SAndroid Build Coastguard Worker         switch (frameLength) {
223*e5436536SAndroid Build Coastguard Worker           case 960:
224*e5436536SAndroid Build Coastguard Worker           case 1024:
225*e5436536SAndroid Build Coastguard Worker             bandwidth = (entryNo == 0) ? pBwTab[i].bandWidthMono
226*e5436536SAndroid Build Coastguard Worker                                        : pBwTab[i].bandWidth2AndMoreChan;
227*e5436536SAndroid Build Coastguard Worker             break;
228*e5436536SAndroid Build Coastguard Worker           case 120:
229*e5436536SAndroid Build Coastguard Worker           case 128:
230*e5436536SAndroid Build Coastguard Worker           case 240:
231*e5436536SAndroid Build Coastguard Worker           case 256:
232*e5436536SAndroid Build Coastguard Worker           case 480:
233*e5436536SAndroid Build Coastguard Worker           case 512: {
234*e5436536SAndroid Build Coastguard Worker             INT q_res = 0;
235*e5436536SAndroid Build Coastguard Worker             INT startBw = (entryNo == 0) ? pBwTab[i].bandWidthMono
236*e5436536SAndroid Build Coastguard Worker                                          : pBwTab[i].bandWidth2AndMoreChan;
237*e5436536SAndroid Build Coastguard Worker             INT endBw = (entryNo == 0) ? pBwTab[i + 1].bandWidthMono
238*e5436536SAndroid Build Coastguard Worker                                        : pBwTab[i + 1].bandWidth2AndMoreChan;
239*e5436536SAndroid Build Coastguard Worker             INT startBr = pBwTab[i].chanBitRate;
240*e5436536SAndroid Build Coastguard Worker             INT endBr = pBwTab[i + 1].chanBitRate;
241*e5436536SAndroid Build Coastguard Worker 
242*e5436536SAndroid Build Coastguard Worker             FIXP_DBL bwFac_fix =
243*e5436536SAndroid Build Coastguard Worker                 fDivNorm(chanBitRate - startBr, endBr - startBr, &q_res);
244*e5436536SAndroid Build Coastguard Worker             bandwidth =
245*e5436536SAndroid Build Coastguard Worker                 (INT)scaleValue(fMult(bwFac_fix, (FIXP_DBL)(endBw - startBw)),
246*e5436536SAndroid Build Coastguard Worker                                 q_res) +
247*e5436536SAndroid Build Coastguard Worker                 startBw;
248*e5436536SAndroid Build Coastguard Worker           } break;
249*e5436536SAndroid Build Coastguard Worker           default:
250*e5436536SAndroid Build Coastguard Worker             bandwidth = -1;
251*e5436536SAndroid Build Coastguard Worker         }
252*e5436536SAndroid Build Coastguard Worker         break;
253*e5436536SAndroid Build Coastguard Worker       } /* within bitrate range */
254*e5436536SAndroid Build Coastguard Worker     }
255*e5436536SAndroid Build Coastguard Worker   } /* pBwTab!=NULL */
256*e5436536SAndroid Build Coastguard Worker 
257*e5436536SAndroid Build Coastguard Worker   return bandwidth;
258*e5436536SAndroid Build Coastguard Worker }
259*e5436536SAndroid Build Coastguard Worker 
FDKaacEnc_DetermineBandWidth(const INT proposedBandWidth,const INT bitrate,const AACENC_BITRATE_MODE bitrateMode,const INT sampleRate,const INT frameLength,const CHANNEL_MAPPING * const cm,const CHANNEL_MODE encoderMode,INT * const bandWidth)260*e5436536SAndroid Build Coastguard Worker AAC_ENCODER_ERROR FDKaacEnc_DetermineBandWidth(
261*e5436536SAndroid Build Coastguard Worker     const INT proposedBandWidth, const INT bitrate,
262*e5436536SAndroid Build Coastguard Worker     const AACENC_BITRATE_MODE bitrateMode, const INT sampleRate,
263*e5436536SAndroid Build Coastguard Worker     const INT frameLength, const CHANNEL_MAPPING *const cm,
264*e5436536SAndroid Build Coastguard Worker     const CHANNEL_MODE encoderMode, INT *const bandWidth) {
265*e5436536SAndroid Build Coastguard Worker   AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
266*e5436536SAndroid Build Coastguard Worker   INT chanBitRate = bitrate / cm->nChannelsEff;
267*e5436536SAndroid Build Coastguard Worker 
268*e5436536SAndroid Build Coastguard Worker   switch (bitrateMode) {
269*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_1:
270*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_2:
271*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_3:
272*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_4:
273*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_5:
274*e5436536SAndroid Build Coastguard Worker       if (proposedBandWidth != 0) {
275*e5436536SAndroid Build Coastguard Worker         /* use given bw */
276*e5436536SAndroid Build Coastguard Worker         *bandWidth = proposedBandWidth;
277*e5436536SAndroid Build Coastguard Worker       } else {
278*e5436536SAndroid Build Coastguard Worker         /* take bw from table */
279*e5436536SAndroid Build Coastguard Worker         switch (encoderMode) {
280*e5436536SAndroid Build Coastguard Worker           case MODE_1:
281*e5436536SAndroid Build Coastguard Worker             *bandWidth = bandWidthTableVBR[bitrateMode].bandWidthMono;
282*e5436536SAndroid Build Coastguard Worker             break;
283*e5436536SAndroid Build Coastguard Worker           case MODE_2:
284*e5436536SAndroid Build Coastguard Worker           case MODE_1_2:
285*e5436536SAndroid Build Coastguard Worker           case MODE_1_2_1:
286*e5436536SAndroid Build Coastguard Worker           case MODE_1_2_2:
287*e5436536SAndroid Build Coastguard Worker           case MODE_1_2_2_1:
288*e5436536SAndroid Build Coastguard Worker           case MODE_6_1:
289*e5436536SAndroid Build Coastguard Worker           case MODE_1_2_2_2_1:
290*e5436536SAndroid Build Coastguard Worker           case MODE_7_1_REAR_SURROUND:
291*e5436536SAndroid Build Coastguard Worker           case MODE_7_1_FRONT_CENTER:
292*e5436536SAndroid Build Coastguard Worker           case MODE_7_1_BACK:
293*e5436536SAndroid Build Coastguard Worker           case MODE_7_1_TOP_FRONT:
294*e5436536SAndroid Build Coastguard Worker             *bandWidth = bandWidthTableVBR[bitrateMode].bandWidth2AndMoreChan;
295*e5436536SAndroid Build Coastguard Worker             break;
296*e5436536SAndroid Build Coastguard Worker           default:
297*e5436536SAndroid Build Coastguard Worker             return AAC_ENC_UNSUPPORTED_CHANNELCONFIG;
298*e5436536SAndroid Build Coastguard Worker         }
299*e5436536SAndroid Build Coastguard Worker       }
300*e5436536SAndroid Build Coastguard Worker       break;
301*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_CBR:
302*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_SFR:
303*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_FF:
304*e5436536SAndroid Build Coastguard Worker 
305*e5436536SAndroid Build Coastguard Worker       /* bandwidth limiting */
306*e5436536SAndroid Build Coastguard Worker       if (proposedBandWidth != 0) {
307*e5436536SAndroid Build Coastguard Worker         *bandWidth = fMin(proposedBandWidth, fMin(20000, sampleRate >> 1));
308*e5436536SAndroid Build Coastguard Worker       } else { /* search reasonable bandwidth */
309*e5436536SAndroid Build Coastguard Worker 
310*e5436536SAndroid Build Coastguard Worker         int entryNo = 0;
311*e5436536SAndroid Build Coastguard Worker 
312*e5436536SAndroid Build Coastguard Worker         switch (encoderMode) {
313*e5436536SAndroid Build Coastguard Worker           case MODE_1:   /* mono      */
314*e5436536SAndroid Build Coastguard Worker             entryNo = 0; /* use mono bandwidth settings */
315*e5436536SAndroid Build Coastguard Worker             break;
316*e5436536SAndroid Build Coastguard Worker 
317*e5436536SAndroid Build Coastguard Worker           case MODE_2:       /* stereo    */
318*e5436536SAndroid Build Coastguard Worker           case MODE_1_2:     /* sce + cpe */
319*e5436536SAndroid Build Coastguard Worker           case MODE_1_2_1:   /* sce + cpe + sce */
320*e5436536SAndroid Build Coastguard Worker           case MODE_1_2_2:   /* sce + cpe + cpe */
321*e5436536SAndroid Build Coastguard Worker           case MODE_1_2_2_1: /* (5.1) sce + cpe + cpe + lfe */
322*e5436536SAndroid Build Coastguard Worker           case MODE_6_1:
323*e5436536SAndroid Build Coastguard Worker           case MODE_1_2_2_2_1:
324*e5436536SAndroid Build Coastguard Worker           case MODE_7_1_REAR_SURROUND:
325*e5436536SAndroid Build Coastguard Worker           case MODE_7_1_FRONT_CENTER:
326*e5436536SAndroid Build Coastguard Worker           case MODE_7_1_BACK:
327*e5436536SAndroid Build Coastguard Worker           case MODE_7_1_TOP_FRONT:
328*e5436536SAndroid Build Coastguard Worker             entryNo = 1; /* use stereo bandwidth settings */
329*e5436536SAndroid Build Coastguard Worker             break;
330*e5436536SAndroid Build Coastguard Worker 
331*e5436536SAndroid Build Coastguard Worker           default:
332*e5436536SAndroid Build Coastguard Worker             return AAC_ENC_UNSUPPORTED_CHANNELCONFIG;
333*e5436536SAndroid Build Coastguard Worker         }
334*e5436536SAndroid Build Coastguard Worker 
335*e5436536SAndroid Build Coastguard Worker         *bandWidth =
336*e5436536SAndroid Build Coastguard Worker             GetBandwidthEntry(frameLength, sampleRate, chanBitRate, entryNo);
337*e5436536SAndroid Build Coastguard Worker 
338*e5436536SAndroid Build Coastguard Worker         if (*bandWidth == -1) {
339*e5436536SAndroid Build Coastguard Worker           switch (frameLength) {
340*e5436536SAndroid Build Coastguard Worker             case 120:
341*e5436536SAndroid Build Coastguard Worker             case 128:
342*e5436536SAndroid Build Coastguard Worker             case 240:
343*e5436536SAndroid Build Coastguard Worker             case 256:
344*e5436536SAndroid Build Coastguard Worker               *bandWidth = 16000;
345*e5436536SAndroid Build Coastguard Worker               break;
346*e5436536SAndroid Build Coastguard Worker             default:
347*e5436536SAndroid Build Coastguard Worker               ErrorStatus = AAC_ENC_INVALID_CHANNEL_BITRATE;
348*e5436536SAndroid Build Coastguard Worker           }
349*e5436536SAndroid Build Coastguard Worker         }
350*e5436536SAndroid Build Coastguard Worker       }
351*e5436536SAndroid Build Coastguard Worker       break;
352*e5436536SAndroid Build Coastguard Worker     default:
353*e5436536SAndroid Build Coastguard Worker       *bandWidth = 0;
354*e5436536SAndroid Build Coastguard Worker       return AAC_ENC_UNSUPPORTED_BITRATE_MODE;
355*e5436536SAndroid Build Coastguard Worker   }
356*e5436536SAndroid Build Coastguard Worker 
357*e5436536SAndroid Build Coastguard Worker   *bandWidth = fMin(*bandWidth, sampleRate / 2);
358*e5436536SAndroid Build Coastguard Worker 
359*e5436536SAndroid Build Coastguard Worker   return ErrorStatus;
360*e5436536SAndroid Build Coastguard Worker }
361