• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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. Schug / A. Groeschel
98 
99    Description: fast aac coder functions
100 
101 *******************************************************************************/
102 
103 #include "aacenc.h"
104 
105 #include "bitenc.h"
106 #include "interface.h"
107 #include "psy_configuration.h"
108 #include "psy_main.h"
109 #include "qc_main.h"
110 #include "bandwidth.h"
111 #include "channel_map.h"
112 #include "tns_func.h"
113 #include "aacEnc_ram.h"
114 
115 #include "genericStds.h"
116 
117 #define BITRES_MAX_LD 4000
118 #define BITRES_MIN_LD 500
119 #define BITRATE_MAX_LD 70000 /* Max assumed bitrate for bitres calculation */
120 #define BITRATE_MIN_LD 12000 /* Min assumed bitrate for bitres calculation */
121 
FDKaacEnc_CalcBitsPerFrame(const INT bitRate,const INT frameLength,const INT samplingRate)122 INT FDKaacEnc_CalcBitsPerFrame(const INT bitRate, const INT frameLength,
123                                const INT samplingRate) {
124   int shift = 0;
125   while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength &&
126          (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate) {
127     shift++;
128   }
129 
130   return (bitRate * (frameLength >> shift)) / (samplingRate >> shift);
131 }
132 
FDKaacEnc_CalcBitrate(const INT bitsPerFrame,const INT frameLength,const INT samplingRate)133 INT FDKaacEnc_CalcBitrate(const INT bitsPerFrame, const INT frameLength,
134                           const INT samplingRate) {
135   int shift = 0;
136   while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength &&
137          (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate) {
138     shift++;
139   }
140 
141   return (bitsPerFrame * (samplingRate >> shift)) / (frameLength >> shift);
142 }
143 
144 static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(
145     INT bitRate, INT framelength, INT ancillaryRate, INT *ancillaryBitsPerFrame,
146     INT sampleRate);
147 
FDKaacEnc_LimitBitrate(HANDLE_TRANSPORTENC hTpEnc,AUDIO_OBJECT_TYPE aot,INT coreSamplingRate,INT frameLength,INT nChannels,INT nChannelsEff,INT bitRate,INT averageBits,INT * pAverageBitsPerFrame,AACENC_BITRATE_MODE bitrateMode,INT nSubFrames)148 INT FDKaacEnc_LimitBitrate(HANDLE_TRANSPORTENC hTpEnc, AUDIO_OBJECT_TYPE aot,
149                            INT coreSamplingRate, INT frameLength, INT nChannels,
150                            INT nChannelsEff, INT bitRate, INT averageBits,
151                            INT *pAverageBitsPerFrame,
152                            AACENC_BITRATE_MODE bitrateMode, INT nSubFrames) {
153   INT transportBits, prevBitRate, averageBitsPerFrame, minBitrate = 0, iter = 0;
154   INT minBitsPerFrame = 40 * nChannels;
155   if (isLowDelay(aot)) {
156     minBitrate = 8000 * nChannelsEff;
157   }
158 
159   do {
160     prevBitRate = bitRate;
161     averageBitsPerFrame =
162         FDKaacEnc_CalcBitsPerFrame(bitRate, frameLength, coreSamplingRate) /
163         nSubFrames;
164 
165     if (pAverageBitsPerFrame != NULL) {
166       *pAverageBitsPerFrame = averageBitsPerFrame;
167     }
168 
169     if (hTpEnc != NULL) {
170       transportBits = transportEnc_GetStaticBits(hTpEnc, averageBitsPerFrame);
171     } else {
172       /* Assume some worst case */
173       transportBits = 208;
174     }
175 
176     bitRate = fMax(bitRate,
177                    fMax(minBitrate,
178                         FDKaacEnc_CalcBitrate((minBitsPerFrame + transportBits),
179                                               frameLength, coreSamplingRate)));
180     FDK_ASSERT(bitRate >= 0);
181 
182     bitRate = fMin(bitRate, FDKaacEnc_CalcBitrate(
183                                 (nChannelsEff * MIN_BUFSIZE_PER_EFF_CHAN),
184                                 frameLength, coreSamplingRate));
185     FDK_ASSERT(bitRate >= 0);
186 
187   } while (prevBitRate != bitRate && iter++ < 3);
188 
189   return bitRate;
190 }
191 
192 typedef struct {
193   AACENC_BITRATE_MODE bitrateMode;
194   int chanBitrate[2]; /* mono/stereo settings */
195 } CONFIG_TAB_ENTRY_VBR;
196 
197 static const CONFIG_TAB_ENTRY_VBR configTabVBR[] = {
198     {AACENC_BR_MODE_CBR, {0, 0}},
199     {AACENC_BR_MODE_VBR_1, {32000, 20000}},
200     {AACENC_BR_MODE_VBR_2, {40000, 32000}},
201     {AACENC_BR_MODE_VBR_3, {56000, 48000}},
202     {AACENC_BR_MODE_VBR_4, {72000, 64000}},
203     {AACENC_BR_MODE_VBR_5, {112000, 96000}}};
204 
205 /*-----------------------------------------------------------------------------
206 
207      functionname: FDKaacEnc_GetVBRBitrate
208      description:  Get VBR bitrate from vbr quality
209      input params: int vbrQuality (VBR0, VBR1, VBR2)
210                    channelMode
211      returns:      vbr bitrate
212 
213  ------------------------------------------------------------------------------*/
FDKaacEnc_GetVBRBitrate(AACENC_BITRATE_MODE bitrateMode,CHANNEL_MODE channelMode)214 INT FDKaacEnc_GetVBRBitrate(AACENC_BITRATE_MODE bitrateMode,
215                             CHANNEL_MODE channelMode) {
216   INT bitrate = 0;
217   INT monoStereoMode = 0; /* default mono */
218 
219   if (FDKaacEnc_GetMonoStereoMode(channelMode) == EL_MODE_STEREO) {
220     monoStereoMode = 1;
221   }
222 
223   switch (bitrateMode) {
224     case AACENC_BR_MODE_VBR_1:
225     case AACENC_BR_MODE_VBR_2:
226     case AACENC_BR_MODE_VBR_3:
227     case AACENC_BR_MODE_VBR_4:
228     case AACENC_BR_MODE_VBR_5:
229       bitrate = configTabVBR[bitrateMode].chanBitrate[monoStereoMode];
230       break;
231     case AACENC_BR_MODE_INVALID:
232     case AACENC_BR_MODE_CBR:
233     case AACENC_BR_MODE_SFR:
234     case AACENC_BR_MODE_FF:
235     default:
236       bitrate = 0;
237       break;
238   }
239 
240   /* convert channel bitrate to overall bitrate*/
241   bitrate *= FDKaacEnc_GetChannelModeConfiguration(channelMode)->nChannelsEff;
242 
243   return bitrate;
244 }
245 
246 /**
247  * \brief  Convert encoder bitreservoir value for transport library.
248  *
249  * \param hAacEnc               Encoder handle
250  *
251  * \return  Corrected bitreservoir level used in transport library.
252  */
FDKaacEnc_EncBitresToTpBitres(const HANDLE_AAC_ENC hAacEnc)253 static INT FDKaacEnc_EncBitresToTpBitres(const HANDLE_AAC_ENC hAacEnc) {
254   INT transportBitreservoir = 0;
255 
256   switch (hAacEnc->bitrateMode) {
257     case AACENC_BR_MODE_CBR:
258       transportBitreservoir =
259           hAacEnc->qcKernel->bitResTot; /* encoder bitreservoir level */
260       break;
261     case AACENC_BR_MODE_VBR_1:
262     case AACENC_BR_MODE_VBR_2:
263     case AACENC_BR_MODE_VBR_3:
264     case AACENC_BR_MODE_VBR_4:
265     case AACENC_BR_MODE_VBR_5:
266       transportBitreservoir = FDK_INT_MAX; /* signal variable bitrate */
267       break;
268     case AACENC_BR_MODE_SFR:
269       transportBitreservoir = 0; /* super framing and fixed framing */
270       break;                     /* without bitreservoir signaling */
271     default:
272     case AACENC_BR_MODE_INVALID:
273       transportBitreservoir = 0; /* invalid configuration*/
274   }
275 
276   if (hAacEnc->config->audioMuxVersion == 2) {
277     transportBitreservoir =
278         MIN_BUFSIZE_PER_EFF_CHAN * hAacEnc->channelMapping.nChannelsEff;
279   }
280 
281   return transportBitreservoir;
282 }
283 
FDKaacEnc_GetBitReservoirState(const HANDLE_AAC_ENC hAacEncoder)284 INT FDKaacEnc_GetBitReservoirState(const HANDLE_AAC_ENC hAacEncoder) {
285   return FDKaacEnc_EncBitresToTpBitres(hAacEncoder);
286 }
287 
288 /*-----------------------------------------------------------------------------
289 
290      functionname: FDKaacEnc_AacInitDefaultConfig
291      description:  gives reasonable default configuration
292      returns:      ---
293 
294  ------------------------------------------------------------------------------*/
FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG * config)295 void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config) {
296   /* make the preinitialization of the structs flexible */
297   FDKmemclear(config, sizeof(AACENC_CONFIG));
298 
299   /* default ancillary */
300   config->anc_Rate = 0;       /* no ancillary data */
301   config->ancDataBitRate = 0; /* no additional consumed bitrate */
302 
303   /* default configurations */
304   config->bitRate = -1; /* bitrate must be set*/
305   config->averageBits =
306       -1; /* instead of bitrate/s we can configure bits/superframe */
307   config->bitrateMode =
308       AACENC_BR_MODE_CBR;           /* set bitrate mode to constant bitrate */
309   config->bandWidth = 0;            /* get bandwidth from table */
310   config->useTns = TNS_ENABLE_MASK; /* tns enabled completly */
311   config->usePns =
312       1; /* depending on channelBitrate this might be set to 0 later */
313   config->useIS = 1;        /* Intensity Stereo Configuration */
314   config->useMS = 1;        /* MS Stereo tool */
315   config->framelength = -1; /* Framesize not configured */
316   config->syntaxFlags = 0;  /* default syntax with no specialities */
317   config->epConfig = -1;    /* no ER syntax -> no additional error protection */
318   config->nSubFrames = 1;   /* default, no sub frames */
319   config->channelOrder = CH_ORDER_MPEG; /* Use MPEG channel ordering. */
320   config->channelMode = MODE_UNKNOWN;
321   config->minBitsPerFrame = -1; /* minum number of bits in each AU */
322   config->maxBitsPerFrame = -1; /* minum number of bits in each AU */
323   config->audioMuxVersion = -1; /* audio mux version not configured */
324   config->downscaleFactor =
325       1; /* downscale factor for ELD reduced delay mode, 1 is normal ELD */
326 }
327 
328 /*---------------------------------------------------------------------------
329 
330     functionname: FDKaacEnc_Open
331     description:  allocate and initialize a new encoder instance
332     returns:      error code
333 
334   ---------------------------------------------------------------------------*/
FDKaacEnc_Open(HANDLE_AAC_ENC * phAacEnc,const INT nElements,const INT nChannels,const INT nSubFrames)335 AAC_ENCODER_ERROR FDKaacEnc_Open(HANDLE_AAC_ENC *phAacEnc, const INT nElements,
336                                  const INT nChannels, const INT nSubFrames) {
337   AAC_ENCODER_ERROR ErrorStatus;
338   AAC_ENC *hAacEnc = NULL;
339   UCHAR *dynamicRAM = NULL;
340 
341   if (phAacEnc == NULL) {
342     return AAC_ENC_INVALID_HANDLE;
343   }
344 
345   /* allocate encoder structure */
346   hAacEnc = GetRam_aacEnc_AacEncoder();
347   if (hAacEnc == NULL) {
348     ErrorStatus = AAC_ENC_NO_MEMORY;
349     goto bail;
350   }
351   FDKmemclear(hAacEnc, sizeof(AAC_ENC));
352 
353   if (NULL == (hAacEnc->dynamic_RAM = GetAACdynamic_RAM())) {
354     ErrorStatus = AAC_ENC_NO_MEMORY;
355     goto bail;
356   }
357   dynamicRAM = (UCHAR *)hAacEnc->dynamic_RAM;
358 
359   /* allocate the Psy aud Psy Out structure */
360   ErrorStatus =
361       FDKaacEnc_PsyNew(&hAacEnc->psyKernel, nElements, nChannels, dynamicRAM);
362   if (ErrorStatus != AAC_ENC_OK) goto bail;
363 
364   ErrorStatus = FDKaacEnc_PsyOutNew(hAacEnc->psyOut, nElements, nChannels,
365                                     nSubFrames, dynamicRAM);
366   if (ErrorStatus != AAC_ENC_OK) goto bail;
367 
368   /* allocate the Q&C Out structure */
369   ErrorStatus = FDKaacEnc_QCOutNew(hAacEnc->qcOut, nElements, nChannels,
370                                    nSubFrames, dynamicRAM);
371   if (ErrorStatus != AAC_ENC_OK) goto bail;
372 
373   /* allocate the Q&C kernel */
374   ErrorStatus = FDKaacEnc_QCNew(&hAacEnc->qcKernel, nElements, dynamicRAM);
375   if (ErrorStatus != AAC_ENC_OK) goto bail;
376 
377   hAacEnc->maxChannels = nChannels;
378   hAacEnc->maxElements = nElements;
379   hAacEnc->maxFrames = nSubFrames;
380 
381 bail:
382   *phAacEnc = hAacEnc;
383   return ErrorStatus;
384 }
385 
FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc,AACENC_CONFIG * config,HANDLE_TRANSPORTENC hTpEnc,ULONG initFlags)386 AAC_ENCODER_ERROR FDKaacEnc_Initialize(
387     HANDLE_AAC_ENC hAacEnc,
388     AACENC_CONFIG *config, /* pre-initialized config struct */
389     HANDLE_TRANSPORTENC hTpEnc, ULONG initFlags) {
390   AAC_ENCODER_ERROR ErrorStatus;
391   INT psyBitrate, tnsMask;  // INT profile = 1;
392   CHANNEL_MAPPING *cm = NULL;
393 
394   INT mbfac_e, qbw;
395   FIXP_DBL mbfac, bw_ratio;
396   QC_INIT qcInit;
397   INT averageBitsPerFrame = 0;
398   int bitresMin = 0; /* the bitreservoir is always big for AAC-LC */
399   const CHANNEL_MODE prevChannelMode = hAacEnc->encoderMode;
400 
401   if (config == NULL) return AAC_ENC_INVALID_HANDLE;
402 
403   /******************* sanity checks *******************/
404 
405   /* check config structure */
406   if (config->nChannels < 1 || config->nChannels > (8)) {
407     return AAC_ENC_UNSUPPORTED_CHANNELCONFIG;
408   }
409 
410   /* check sample rate */
411   switch (config->sampleRate) {
412     case 8000:
413     case 11025:
414     case 12000:
415     case 16000:
416     case 22050:
417     case 24000:
418     case 32000:
419     case 44100:
420     case 48000:
421     case 64000:
422     case 88200:
423     case 96000:
424       break;
425     default:
426       return AAC_ENC_UNSUPPORTED_SAMPLINGRATE;
427   }
428 
429   /* bitrate has to be set */
430   if (config->bitRate == -1) {
431     return AAC_ENC_UNSUPPORTED_BITRATE;
432   }
433 
434   /* check bit rate */
435 
436   if (FDKaacEnc_LimitBitrate(
437           hTpEnc, config->audioObjectType, config->sampleRate,
438           config->framelength, config->nChannels,
439           FDKaacEnc_GetChannelModeConfiguration(config->channelMode)
440               ->nChannelsEff,
441           config->bitRate, config->averageBits, &averageBitsPerFrame,
442           config->bitrateMode, config->nSubFrames) != config->bitRate &&
443       !(AACENC_BR_MODE_IS_VBR(config->bitrateMode))) {
444     return AAC_ENC_UNSUPPORTED_BITRATE;
445   }
446 
447   if (config->syntaxFlags & AC_ER_VCB11) {
448     return AAC_ENC_UNSUPPORTED_ER_FORMAT;
449   }
450   if (config->syntaxFlags & AC_ER_HCR) {
451     return AAC_ENC_UNSUPPORTED_ER_FORMAT;
452   }
453 
454   /* check frame length */
455   switch (config->framelength) {
456     case 1024:
457       if (isLowDelay(config->audioObjectType)) {
458         return AAC_ENC_INVALID_FRAME_LENGTH;
459       }
460       break;
461     case 128:
462     case 256:
463     case 512:
464     case 120:
465     case 240:
466     case 480:
467       if (!isLowDelay(config->audioObjectType)) {
468         return AAC_ENC_INVALID_FRAME_LENGTH;
469       }
470       break;
471     default:
472       return AAC_ENC_INVALID_FRAME_LENGTH;
473   }
474 
475   if (config->anc_Rate != 0) {
476     ErrorStatus = FDKaacEnc_InitCheckAncillary(
477         config->bitRate, config->framelength, config->anc_Rate,
478         &hAacEnc->ancillaryBitsPerFrame, config->sampleRate);
479     if (ErrorStatus != AAC_ENC_OK) goto bail;
480 
481     /* update estimated consumed bitrate */
482     config->ancDataBitRate +=
483         FDKaacEnc_CalcBitrate(hAacEnc->ancillaryBitsPerFrame,
484                               config->framelength, config->sampleRate);
485   }
486 
487   /* maximal allowed DSE bytes in frame */
488   config->maxAncBytesPerAU =
489       fMin((256), fMax(0, FDKaacEnc_CalcBitsPerFrame(
490                               (config->bitRate - (config->nChannels * 8000)),
491                               config->framelength, config->sampleRate) >>
492                               3));
493 
494   /* bind config to hAacEnc->config */
495   hAacEnc->config = config;
496 
497   /* set hAacEnc->bitrateMode */
498   hAacEnc->bitrateMode = config->bitrateMode;
499 
500   hAacEnc->encoderMode = config->channelMode;
501 
502   ErrorStatus = FDKaacEnc_InitChannelMapping(
503       hAacEnc->encoderMode, config->channelOrder, &hAacEnc->channelMapping);
504   if (ErrorStatus != AAC_ENC_OK) goto bail;
505 
506   cm = &hAacEnc->channelMapping;
507 
508   ErrorStatus = FDKaacEnc_DetermineBandWidth(
509       config->bandWidth, config->bitRate - config->ancDataBitRate,
510       hAacEnc->bitrateMode, config->sampleRate, config->framelength, cm,
511       hAacEnc->encoderMode, &hAacEnc->config->bandWidth);
512   if (ErrorStatus != AAC_ENC_OK) goto bail;
513 
514   hAacEnc->bandwidth90dB = (INT)hAacEnc->config->bandWidth;
515 
516   tnsMask = config->useTns ? TNS_ENABLE_MASK : 0x0;
517   psyBitrate = config->bitRate - config->ancDataBitRate;
518 
519   if ((hAacEnc->encoderMode != prevChannelMode) || (initFlags != 0)) {
520     /* Reinitialize psych states in case of channel configuration change ore if
521      * full reset requested. */
522     ErrorStatus = FDKaacEnc_psyInit(hAacEnc->psyKernel, hAacEnc->psyOut,
523                                     hAacEnc->maxFrames, hAacEnc->maxChannels,
524                                     config->audioObjectType, cm);
525     if (ErrorStatus != AAC_ENC_OK) goto bail;
526   }
527 
528   ErrorStatus = FDKaacEnc_psyMainInit(
529       hAacEnc->psyKernel, config->audioObjectType, cm, config->sampleRate,
530       config->framelength, psyBitrate, tnsMask, hAacEnc->bandwidth90dB,
531       config->usePns, config->useIS, config->useMS, config->syntaxFlags,
532       initFlags);
533   if (ErrorStatus != AAC_ENC_OK) goto bail;
534 
535   ErrorStatus = FDKaacEnc_QCOutInit(hAacEnc->qcOut, hAacEnc->maxFrames, cm);
536   if (ErrorStatus != AAC_ENC_OK) goto bail;
537 
538   qcInit.channelMapping = &hAacEnc->channelMapping;
539   qcInit.sceCpe = 0;
540 
541   if (AACENC_BR_MODE_IS_VBR(config->bitrateMode)) {
542     qcInit.averageBits = (averageBitsPerFrame + 7) & ~7;
543     qcInit.bitRes = MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff;
544     qcInit.maxBits = MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff;
545     qcInit.maxBits = (config->maxBitsPerFrame != -1)
546                          ? fixMin(qcInit.maxBits, config->maxBitsPerFrame)
547                          : qcInit.maxBits;
548     qcInit.maxBits = fixMax(qcInit.maxBits, (averageBitsPerFrame + 7) & ~7);
549     qcInit.minBits =
550         (config->minBitsPerFrame != -1) ? config->minBitsPerFrame : 0;
551     qcInit.minBits = fixMin(qcInit.minBits, averageBitsPerFrame & ~7);
552   } else {
553     INT bitreservoir = -1; /* default bitrservoir size*/
554     if (isLowDelay(config->audioObjectType)) {
555       INT brPerChannel = config->bitRate / config->nChannels;
556       brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel));
557 
558       /* bitreservoir  =
559        * (maxBitRes-minBitRes)/(maxBitRate-minBitrate)*(bitRate-minBitrate)+minBitRes;
560        */
561       FIXP_DBL slope = fDivNorm(
562           (brPerChannel - BITRATE_MIN_LD),
563           BITRATE_MAX_LD - BITRATE_MIN_LD); /* calc slope for interpolation */
564       bitreservoir = fMultI(slope, (INT)(BITRES_MAX_LD - BITRES_MIN_LD)) +
565                      BITRES_MIN_LD;     /* interpolate */
566       bitreservoir = bitreservoir & ~7; /* align to bytes */
567       bitresMin = BITRES_MIN_LD;
568     }
569 
570     int maxBitres;
571     qcInit.averageBits = (averageBitsPerFrame + 7) & ~7;
572     maxBitres =
573         (MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff) - qcInit.averageBits;
574     qcInit.bitRes =
575         (bitreservoir != -1) ? fMin(bitreservoir, maxBitres) : maxBitres;
576 
577     qcInit.maxBits = fixMin(MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff,
578                             ((averageBitsPerFrame + 7) & ~7) + qcInit.bitRes);
579     qcInit.maxBits = (config->maxBitsPerFrame != -1)
580                          ? fixMin(qcInit.maxBits, config->maxBitsPerFrame)
581                          : qcInit.maxBits;
582     qcInit.maxBits =
583         fixMin(MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff,
584                fixMax(qcInit.maxBits, (averageBitsPerFrame + 7 + 8) & ~7));
585 
586     qcInit.minBits = fixMax(
587         0, ((averageBitsPerFrame - 1) & ~7) - qcInit.bitRes -
588                transportEnc_GetStaticBits(
589                    hTpEnc, ((averageBitsPerFrame + 7) & ~7) + qcInit.bitRes));
590     qcInit.minBits = (config->minBitsPerFrame != -1)
591                          ? fixMax(qcInit.minBits, config->minBitsPerFrame)
592                          : qcInit.minBits;
593     qcInit.minBits = fixMin(
594         qcInit.minBits, (averageBitsPerFrame -
595                          transportEnc_GetStaticBits(hTpEnc, qcInit.maxBits)) &
596                             ~7);
597   }
598 
599   qcInit.sampleRate = config->sampleRate;
600   qcInit.isLowDelay = isLowDelay(config->audioObjectType) ? 1 : 0;
601   qcInit.nSubFrames = config->nSubFrames;
602   qcInit.padding.paddingRest = config->sampleRate;
603 
604   if (qcInit.bitRes >= bitresMin * config->nChannels) {
605     qcInit.bitResMode = AACENC_BR_MODE_FULL; /* full bitreservoir */
606   } else if (qcInit.bitRes > 0) {
607     qcInit.bitResMode = AACENC_BR_MODE_REDUCED; /* reduced bitreservoir */
608   } else {
609     qcInit.bitResMode = AACENC_BR_MODE_DISABLED; /* disabled bitreservoir */
610   }
611 
612   /* Configure bitrate distribution strategy. */
613   switch (config->channelMode) {
614     case MODE_1_2:
615     case MODE_1_2_1:
616     case MODE_1_2_2:
617     case MODE_1_2_2_1:
618     case MODE_6_1:
619     case MODE_1_2_2_2_1:
620     case MODE_7_1_BACK:
621     case MODE_7_1_TOP_FRONT:
622     case MODE_7_1_REAR_SURROUND:
623     case MODE_7_1_FRONT_CENTER:
624       qcInit.bitDistributionMode = 0; /* over all elements bitrate estimation */
625       break;
626     case MODE_1:
627     case MODE_2:
628     default:                          /* all non mpeg defined channel modes */
629       qcInit.bitDistributionMode = 1; /* element-wise bit bitrate estimation */
630   }                                   /* config->channelMode */
631 
632   /* Calc meanPe: qcInit.meanPe = 10.0f * FRAME_LEN_LONG *
633    * hAacEnc->bandwidth90dB/(config->sampleRate/2.0f); */
634   bw_ratio =
635       fDivNorm((FIXP_DBL)(10 * config->framelength * hAacEnc->bandwidth90dB),
636                (FIXP_DBL)(config->sampleRate), &qbw);
637   qcInit.meanPe =
638       fMax((INT)scaleValue(bw_ratio, qbw + 1 - (DFRACT_BITS - 1)), 1);
639 
640   /* Calc maxBitFac, scale it to 24 bit accuracy */
641   mbfac = fDivNorm(qcInit.maxBits, qcInit.averageBits / qcInit.nSubFrames,
642                    &mbfac_e);
643   qcInit.maxBitFac = scaleValue(mbfac, -(DFRACT_BITS - 1 - 24 - mbfac_e));
644 
645   switch (config->bitrateMode) {
646     case AACENC_BR_MODE_CBR:
647       qcInit.bitrateMode = QCDATA_BR_MODE_CBR;
648       break;
649     case AACENC_BR_MODE_VBR_1:
650       qcInit.bitrateMode = QCDATA_BR_MODE_VBR_1;
651       break;
652     case AACENC_BR_MODE_VBR_2:
653       qcInit.bitrateMode = QCDATA_BR_MODE_VBR_2;
654       break;
655     case AACENC_BR_MODE_VBR_3:
656       qcInit.bitrateMode = QCDATA_BR_MODE_VBR_3;
657       break;
658     case AACENC_BR_MODE_VBR_4:
659       qcInit.bitrateMode = QCDATA_BR_MODE_VBR_4;
660       break;
661     case AACENC_BR_MODE_VBR_5:
662       qcInit.bitrateMode = QCDATA_BR_MODE_VBR_5;
663       break;
664     case AACENC_BR_MODE_SFR:
665       qcInit.bitrateMode = QCDATA_BR_MODE_SFR;
666       break;
667     case AACENC_BR_MODE_FF:
668       qcInit.bitrateMode = QCDATA_BR_MODE_FF;
669       break;
670     default:
671       ErrorStatus = AAC_ENC_UNSUPPORTED_BITRATE_MODE;
672       goto bail;
673   }
674 
675   qcInit.invQuant = (config->useRequant) ? 2 : 0;
676 
677   /* maxIterations should be set to the maximum number of requantization
678    * iterations that are allowed before the crash recovery functionality is
679    * activated. This setting should be adjusted to the processing power
680    * available, i.e. to the processing power headroom in one frame that is still
681    * left after normal encoding without requantization. Please note that if
682    * activated this functionality is used most likely only in cases where the
683    * encoder is operating beyond recommended settings, i.e. the audio quality is
684    * suboptimal anyway. Activating the crash recovery does not further reduce
685    * audio quality significantly in these cases. */
686   if (isLowDelay(config->audioObjectType)) {
687     qcInit.maxIterations = 2;
688   } else {
689     qcInit.maxIterations = 5;
690   }
691 
692   qcInit.bitrate = config->bitRate - config->ancDataBitRate;
693 
694   qcInit.staticBits = transportEnc_GetStaticBits(
695       hTpEnc, qcInit.averageBits / qcInit.nSubFrames);
696 
697   ErrorStatus = FDKaacEnc_QCInit(hAacEnc->qcKernel, &qcInit, initFlags);
698   if (ErrorStatus != AAC_ENC_OK) goto bail;
699 
700   /* Map virtual aot's to intern aot used in bitstream writer. */
701   switch (hAacEnc->config->audioObjectType) {
702     case AOT_MP2_AAC_LC:
703       hAacEnc->aot = AOT_AAC_LC;
704       break;
705     case AOT_MP2_SBR:
706       hAacEnc->aot = AOT_SBR;
707       break;
708     default:
709       hAacEnc->aot = hAacEnc->config->audioObjectType;
710   }
711 
712   /* common things */
713 
714   return AAC_ENC_OK;
715 
716 bail:
717 
718   return ErrorStatus;
719 }
720 
721 /*---------------------------------------------------------------------------
722 
723     functionname: FDKaacEnc_EncodeFrame
724     description:  encodes one frame
725     returns:      error code
726 
727   ---------------------------------------------------------------------------*/
FDKaacEnc_EncodeFrame(HANDLE_AAC_ENC hAacEnc,HANDLE_TRANSPORTENC hTpEnc,INT_PCM * RESTRICT inputBuffer,const UINT inputBufferBufSize,INT * nOutBytes,AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS])728 AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame(
729     HANDLE_AAC_ENC hAacEnc, /* encoder handle */
730     HANDLE_TRANSPORTENC hTpEnc, INT_PCM *RESTRICT inputBuffer,
731     const UINT inputBufferBufSize, INT *nOutBytes,
732     AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS]) {
733   AAC_ENCODER_ERROR ErrorStatus;
734   int el, n, c = 0;
735   UCHAR extPayloadUsed[MAX_TOTAL_EXT_PAYLOADS];
736 
737   CHANNEL_MAPPING *cm = &hAacEnc->channelMapping;
738 
739   PSY_OUT *psyOut = hAacEnc->psyOut[c];
740   QC_OUT *qcOut = hAacEnc->qcOut[c];
741 
742   FDKmemclear(extPayloadUsed, MAX_TOTAL_EXT_PAYLOADS * sizeof(UCHAR));
743 
744   qcOut->elementExtBits = 0; /* sum up all extended bit of each element */
745   qcOut->staticBits = 0;     /* sum up side info bits of each element */
746   qcOut->totalNoRedPe = 0;   /* sum up PE */
747 
748   /* advance psychoacoustics */
749   for (el = 0; el < cm->nElements; el++) {
750     ELEMENT_INFO elInfo = cm->elInfo[el];
751 
752     if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
753         (elInfo.elType == ID_LFE)) {
754       int ch;
755 
756       /* update pointer!*/
757       for (ch = 0; ch < elInfo.nChannelsInEl; ch++) {
758         PSY_OUT_CHANNEL *psyOutChan =
759             psyOut->psyOutElement[el]->psyOutChannel[ch];
760         QC_OUT_CHANNEL *qcOutChan = qcOut->qcElement[el]->qcOutChannel[ch];
761 
762         psyOutChan->mdctSpectrum = qcOutChan->mdctSpectrum;
763         psyOutChan->sfbSpreadEnergy = qcOutChan->sfbSpreadEnergy;
764         psyOutChan->sfbEnergy = qcOutChan->sfbEnergy;
765         psyOutChan->sfbEnergyLdData = qcOutChan->sfbEnergyLdData;
766         psyOutChan->sfbMinSnrLdData = qcOutChan->sfbMinSnrLdData;
767         psyOutChan->sfbThresholdLdData = qcOutChan->sfbThresholdLdData;
768       }
769 
770       ErrorStatus = FDKaacEnc_psyMain(
771           elInfo.nChannelsInEl, hAacEnc->psyKernel->psyElement[el],
772           hAacEnc->psyKernel->psyDynamic, hAacEnc->psyKernel->psyConf,
773           psyOut->psyOutElement[el], inputBuffer, inputBufferBufSize,
774           cm->elInfo[el].ChannelIndex, cm->nChannels);
775 
776       if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
777 
778       /* FormFactor, Pe and staticBitDemand calculation */
779       ErrorStatus = FDKaacEnc_QCMainPrepare(
780           &elInfo, hAacEnc->qcKernel->hAdjThr->adjThrStateElem[el],
781           psyOut->psyOutElement[el], qcOut->qcElement[el], hAacEnc->aot,
782           hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
783 
784       if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
785 
786       /*-------------------------------------------- */
787 
788       qcOut->qcElement[el]->extBitsUsed = 0;
789       qcOut->qcElement[el]->nExtensions = 0;
790       /* reset extension payload */
791       FDKmemclear(&qcOut->qcElement[el]->extension,
792                   (1) * sizeof(QC_OUT_EXTENSION));
793 
794       for (n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++) {
795         if (!extPayloadUsed[n] && (extPayload[n].associatedChElement == el) &&
796             (extPayload[n].dataSize > 0) && (extPayload[n].pData != NULL)) {
797           int idx = qcOut->qcElement[el]->nExtensions++;
798 
799           qcOut->qcElement[el]->extension[idx].type =
800               extPayload[n].dataType; /* Perform a sanity check on the type? */
801           qcOut->qcElement[el]->extension[idx].nPayloadBits =
802               extPayload[n].dataSize;
803           qcOut->qcElement[el]->extension[idx].pPayload = extPayload[n].pData;
804           /* Now ask the bitstream encoder how many bits we need to encode the
805            * data with the current bitstream syntax: */
806           qcOut->qcElement[el]->extBitsUsed += FDKaacEnc_writeExtensionData(
807               NULL, &qcOut->qcElement[el]->extension[idx], 0, 0,
808               hAacEnc->config->syntaxFlags, hAacEnc->aot,
809               hAacEnc->config->epConfig);
810           extPayloadUsed[n] = 1;
811         }
812       }
813 
814       /* sum up extension and static bits for all channel elements */
815       qcOut->elementExtBits += qcOut->qcElement[el]->extBitsUsed;
816       qcOut->staticBits += qcOut->qcElement[el]->staticBitsUsed;
817 
818       /* sum up pe */
819       qcOut->totalNoRedPe += qcOut->qcElement[el]->peData.pe;
820     }
821   }
822 
823   qcOut->nExtensions = 0;
824   qcOut->globalExtBits = 0;
825 
826   /* reset extension payload */
827   FDKmemclear(&qcOut->extension, (2 + 2) * sizeof(QC_OUT_EXTENSION));
828 
829   /* Add extension payload not assigned to an channel element
830     (Ancillary data is the only supported type up to now) */
831   for (n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++) {
832     if (!extPayloadUsed[n] && (extPayload[n].associatedChElement == -1) &&
833         (extPayload[n].pData != NULL)) {
834       UINT payloadBits = 0;
835 
836       if (extPayload[n].dataType == EXT_DATA_ELEMENT) {
837         if (hAacEnc->ancillaryBitsPerFrame) {
838           /* granted frame dse bitrate */
839           payloadBits = hAacEnc->ancillaryBitsPerFrame;
840         } else {
841           /* write anc data if bitrate constraint fulfilled */
842           if ((extPayload[n].dataSize >> 3) <=
843               hAacEnc->config->maxAncBytesPerAU) {
844             payloadBits = extPayload[n].dataSize;
845           }
846         }
847         payloadBits = fixMin(extPayload[n].dataSize, payloadBits);
848       } else {
849         payloadBits = extPayload[n].dataSize;
850       }
851 
852       if (payloadBits > 0) {
853         int idx = qcOut->nExtensions++;
854 
855         qcOut->extension[idx].type =
856             extPayload[n].dataType; /* Perform a sanity check on the type? */
857         qcOut->extension[idx].nPayloadBits = payloadBits;
858         qcOut->extension[idx].pPayload = extPayload[n].pData;
859         /* Now ask the bitstream encoder how many bits we need to encode the
860          * data with the current bitstream syntax: */
861         qcOut->globalExtBits += FDKaacEnc_writeExtensionData(
862             NULL, &qcOut->extension[idx], 0, 0, hAacEnc->config->syntaxFlags,
863             hAacEnc->aot, hAacEnc->config->epConfig);
864         if (extPayload[n].dataType == EXT_DATA_ELEMENT) {
865           /* substract the processed bits */
866           extPayload[n].dataSize -= payloadBits;
867         }
868         extPayloadUsed[n] = 1;
869       }
870     }
871   }
872 
873   if (!(hAacEnc->config->syntaxFlags & (AC_SCALABLE | AC_ER))) {
874     qcOut->globalExtBits += EL_ID_BITS; /* add bits for ID_END */
875   }
876 
877   /* build bitstream all nSubFrames */
878   {
879     INT totalBits = 0; /* Total AU bits */
880     ;
881     INT avgTotalBits = 0;
882 
883     /*-------------------------------------------- */
884     /* Get average total bits */
885     /*-------------------------------------------- */
886     {
887       /* frame wise bitrate adaption */
888       FDKaacEnc_AdjustBitrate(
889           hAacEnc->qcKernel, cm, &avgTotalBits, hAacEnc->config->bitRate,
890           hAacEnc->config->sampleRate, hAacEnc->config->framelength);
891 
892       /* adjust super frame bitrate */
893       avgTotalBits *= hAacEnc->config->nSubFrames;
894     }
895 
896     /* Make first estimate of transport header overhead.
897        Take maximum possible frame size into account to prevent bitreservoir
898        underrun. */
899     hAacEnc->qcKernel->globHdrBits = transportEnc_GetStaticBits(
900         hTpEnc, avgTotalBits + hAacEnc->qcKernel->bitResTot);
901 
902     /*-------------------------------------------- */
903     /*-------------------------------------------- */
904     /*-------------------------------------------- */
905 
906     ErrorStatus = FDKaacEnc_QCMain(
907         hAacEnc->qcKernel, hAacEnc->psyOut, hAacEnc->qcOut, avgTotalBits, cm,
908         hAacEnc->aot, hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
909 
910     if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
911     /*-------------------------------------------- */
912 
913     /*-------------------------------------------- */
914     ErrorStatus = FDKaacEnc_updateFillBits(
915         cm, hAacEnc->qcKernel, hAacEnc->qcKernel->elementBits, hAacEnc->qcOut);
916     if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
917 
918     /*-------------------------------------------- */
919     ErrorStatus = FDKaacEnc_FinalizeBitConsumption(
920         cm, hAacEnc->qcKernel, qcOut, qcOut->qcElement, hTpEnc, hAacEnc->aot,
921         hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
922     if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
923     /*-------------------------------------------- */
924     totalBits += qcOut->totalBits;
925 
926     /*-------------------------------------------- */
927     FDKaacEnc_updateBitres(cm, hAacEnc->qcKernel, hAacEnc->qcOut);
928 
929     /*-------------------------------------------- */
930 
931     /* for ( all sub frames ) ... */
932     /* write bitstream header */
933     if (TRANSPORTENC_OK !=
934         transportEnc_WriteAccessUnit(hTpEnc, totalBits,
935                                      FDKaacEnc_EncBitresToTpBitres(hAacEnc),
936                                      cm->nChannelsEff)) {
937       return AAC_ENC_UNKNOWN;
938     }
939 
940     /* write bitstream */
941     ErrorStatus = FDKaacEnc_WriteBitstream(
942         hTpEnc, cm, qcOut, psyOut, hAacEnc->qcKernel, hAacEnc->aot,
943         hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
944 
945     if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
946 
947     /* transportEnc_EndAccessUnit() is being called inside
948      * FDKaacEnc_WriteBitstream() */
949     if (TRANSPORTENC_OK != transportEnc_GetFrame(hTpEnc, nOutBytes)) {
950       return AAC_ENC_UNKNOWN;
951     }
952 
953   } /* -end- if (curFrame==hAacEnc->qcKernel->nSubFrames) */
954 
955   /*-------------------------------------------- */
956   return AAC_ENC_OK;
957 }
958 
959 /*---------------------------------------------------------------------------
960 
961     functionname:FDKaacEnc_Close
962     description: delete encoder instance
963     returns:
964 
965   ---------------------------------------------------------------------------*/
966 
FDKaacEnc_Close(HANDLE_AAC_ENC * phAacEnc)967 void FDKaacEnc_Close(HANDLE_AAC_ENC *phAacEnc) /* encoder handle */
968 {
969   if (*phAacEnc == NULL) {
970     return;
971   }
972   AAC_ENC *hAacEnc = (AAC_ENC *)*phAacEnc;
973 
974   if (hAacEnc->dynamic_RAM != NULL) FreeAACdynamic_RAM(&hAacEnc->dynamic_RAM);
975 
976   FDKaacEnc_PsyClose(&hAacEnc->psyKernel, hAacEnc->psyOut);
977 
978   FDKaacEnc_QCClose(&hAacEnc->qcKernel, hAacEnc->qcOut);
979 
980   FreeRam_aacEnc_AacEncoder(phAacEnc);
981 }
982 
983 /* The following functions are in this source file only for convenience and */
984 /* need not be visible outside of a possible encoder library. */
985 
986 /* basic defines for ancillary data */
987 #define MAX_ANCRATE 19200 /* ancillary rate >= 19200 isn't valid */
988 
989 /*---------------------------------------------------------------------------
990 
991     functionname:  FDKaacEnc_InitCheckAncillary
992     description:   initialize and check ancillary data struct
993     return:        if success or NULL if error
994 
995   ---------------------------------------------------------------------------*/
FDKaacEnc_InitCheckAncillary(INT bitRate,INT framelength,INT ancillaryRate,INT * ancillaryBitsPerFrame,INT sampleRate)996 static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(
997     INT bitRate, INT framelength, INT ancillaryRate, INT *ancillaryBitsPerFrame,
998     INT sampleRate) {
999   /* don't use negative ancillary rates */
1000   if (ancillaryRate < -1) return AAC_ENC_UNSUPPORTED_ANC_BITRATE;
1001 
1002   /* check if ancillary rate is ok */
1003   if ((ancillaryRate != (-1)) && (ancillaryRate != 0)) {
1004     /* ancRate <= 15% of bitrate && ancRate < 19200 */
1005     if ((ancillaryRate >= MAX_ANCRATE) ||
1006         ((ancillaryRate * 20) > (bitRate * 3))) {
1007       return AAC_ENC_UNSUPPORTED_ANC_BITRATE;
1008     }
1009   } else if (ancillaryRate == -1) {
1010     /* if no special ancRate is requested but a ancillary file is
1011        stated, then generate a ancillary rate matching to the bitrate */
1012     if (bitRate >= (MAX_ANCRATE * 10)) {
1013       /* ancillary rate is 19199 */
1014       ancillaryRate = (MAX_ANCRATE - 1);
1015     } else { /* 10% of bitrate */
1016       ancillaryRate = bitRate / 10;
1017     }
1018   }
1019 
1020   /* make ancillaryBitsPerFrame byte align */
1021   *ancillaryBitsPerFrame =
1022       FDKaacEnc_CalcBitsPerFrame(ancillaryRate, framelength, sampleRate) & ~0x7;
1023 
1024   return AAC_ENC_OK;
1025 }
1026