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