• 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.Werner
98 
99    Description: Noiseless coder module
100 
101 *******************************************************************************/
102 
103 #include "dyn_bits.h"
104 #include "bit_cnt.h"
105 #include "psy_const.h"
106 #include "aacenc_pns.h"
107 #include "aacEnc_ram.h"
108 #include "aacEnc_rom.h"
109 
110 typedef INT (*lookUpTable)[CODE_BOOK_ESC_NDX + 1];
111 
FDKaacEnc_getSideInfoBits(const SECTION_INFO * const huffsection,const SHORT * const sideInfoTab,const INT useHCR)112 static INT FDKaacEnc_getSideInfoBits(const SECTION_INFO* const huffsection,
113                                      const SHORT* const sideInfoTab,
114                                      const INT useHCR) {
115   INT sideInfoBits;
116 
117   if (useHCR &&
118       ((huffsection->codeBook == 11) || (huffsection->codeBook >= 16))) {
119     sideInfoBits = 5;
120   } else {
121     sideInfoBits = sideInfoTab[huffsection->sfbCnt];
122   }
123 
124   return (sideInfoBits);
125 }
126 
127 /* count bits using all possible tables */
FDKaacEnc_buildBitLookUp(const SHORT * const quantSpectrum,const INT maxSfb,const INT * const sfbOffset,const UINT * const sfbMax,INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX+1],SECTION_INFO * const huffsection)128 static void FDKaacEnc_buildBitLookUp(
129     const SHORT* const quantSpectrum, const INT maxSfb,
130     const INT* const sfbOffset, const UINT* const sfbMax,
131     INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
132     SECTION_INFO* const huffsection) {
133   INT i, sfbWidth;
134 
135   for (i = 0; i < maxSfb; i++) {
136     huffsection[i].sfbCnt = 1;
137     huffsection[i].sfbStart = i;
138     huffsection[i].sectionBits = INVALID_BITCOUNT;
139     huffsection[i].codeBook = -1;
140     sfbWidth = sfbOffset[i + 1] - sfbOffset[i];
141     FDKaacEnc_bitCount(quantSpectrum + sfbOffset[i], sfbWidth, sfbMax[i],
142                        bitLookUp[i]);
143   }
144 }
145 
146 /* essential helper functions */
FDKaacEnc_findBestBook(const INT * const bc,INT * const book,const INT useVCB11)147 static inline INT FDKaacEnc_findBestBook(const INT* const bc, INT* const book,
148                                          const INT useVCB11) {
149   INT minBits = INVALID_BITCOUNT, j;
150 
151   int end = CODE_BOOK_ESC_NDX;
152 
153   for (j = 0; j <= end; j++) {
154     if (bc[j] < minBits) {
155       minBits = bc[j];
156       *book = j;
157     }
158   }
159   return (minBits);
160 }
161 
FDKaacEnc_findMinMergeBits(const INT * const bc1,const INT * const bc2,const INT useVCB11)162 static inline INT FDKaacEnc_findMinMergeBits(const INT* const bc1,
163                                              const INT* const bc2,
164                                              const INT useVCB11) {
165   INT minBits = INVALID_BITCOUNT, j;
166 
167   DWORD_ALIGNED(bc1);
168   DWORD_ALIGNED(bc2);
169 
170   for (j = 0; j <= CODE_BOOK_ESC_NDX; j++) {
171     minBits = fixMin(minBits, bc1[j] + bc2[j]);
172   }
173   return (minBits);
174 }
175 
FDKaacEnc_mergeBitLookUp(INT * const RESTRICT bc1,const INT * const RESTRICT bc2)176 static inline void FDKaacEnc_mergeBitLookUp(INT* const RESTRICT bc1,
177                                             const INT* const RESTRICT bc2) {
178   int j;
179 
180   for (j = 0; j <= CODE_BOOK_ESC_NDX; j++) {
181     FDK_ASSERT(INVALID_BITCOUNT == 0x1FFFFFFF);
182     bc1[j] = fixMin(bc1[j] + bc2[j], INVALID_BITCOUNT);
183   }
184 }
185 
FDKaacEnc_findMaxMerge(const INT * const mergeGainLookUp,const SECTION_INFO * const huffsection,const INT maxSfb,INT * const maxNdx)186 static inline INT FDKaacEnc_findMaxMerge(const INT* const mergeGainLookUp,
187                                          const SECTION_INFO* const huffsection,
188                                          const INT maxSfb, INT* const maxNdx) {
189   INT i, maxMergeGain = 0;
190   int lastMaxNdx = 0;
191 
192   for (i = 0; i + huffsection[i].sfbCnt < maxSfb; i += huffsection[i].sfbCnt) {
193     if (mergeGainLookUp[i] > maxMergeGain) {
194       maxMergeGain = mergeGainLookUp[i];
195       lastMaxNdx = i;
196     }
197   }
198   *maxNdx = lastMaxNdx;
199   return (maxMergeGain);
200 }
201 
FDKaacEnc_CalcMergeGain(const SECTION_INFO * const huffsection,const INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX+1],const SHORT * const sideInfoTab,const INT ndx1,const INT ndx2,const INT useVCB11)202 static inline INT FDKaacEnc_CalcMergeGain(
203     const SECTION_INFO* const huffsection,
204     const INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
205     const SHORT* const sideInfoTab, const INT ndx1, const INT ndx2,
206     const INT useVCB11) {
207   INT MergeGain, MergeBits, SplitBits;
208 
209   MergeBits =
210       sideInfoTab[huffsection[ndx1].sfbCnt + huffsection[ndx2].sfbCnt] +
211       FDKaacEnc_findMinMergeBits(bitLookUp[ndx1], bitLookUp[ndx2], useVCB11);
212   SplitBits =
213       huffsection[ndx1].sectionBits +
214       huffsection[ndx2].sectionBits; /* Bit amount for splitted huffsections */
215   MergeGain = SplitBits - MergeBits;
216 
217   if ((huffsection[ndx1].codeBook == CODE_BOOK_PNS_NO) ||
218       (huffsection[ndx2].codeBook == CODE_BOOK_PNS_NO) ||
219       (huffsection[ndx1].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
220       (huffsection[ndx2].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
221       (huffsection[ndx1].codeBook == CODE_BOOK_IS_IN_PHASE_NO) ||
222       (huffsection[ndx2].codeBook == CODE_BOOK_IS_IN_PHASE_NO)) {
223     MergeGain = -1;
224   }
225 
226   return (MergeGain);
227 }
228 
229 /* sectioning Stage 0:find minimum codbooks */
FDKaacEnc_gmStage0(SECTION_INFO * const RESTRICT huffsection,const INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX+1],const INT maxSfb,const INT * const noiseNrg,const INT * const isBook)230 static void FDKaacEnc_gmStage0(
231     SECTION_INFO* const RESTRICT huffsection,
232     const INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], const INT maxSfb,
233     const INT* const noiseNrg, const INT* const isBook) {
234   INT i;
235 
236   for (i = 0; i < maxSfb; i++) {
237     /* Side-Info bits will be calculated in Stage 1! */
238     if (huffsection[i].sectionBits == INVALID_BITCOUNT) {
239       /* intensity and pns codebooks are already allocated in bitcount.c */
240       if (noiseNrg[i] != NO_NOISE_PNS) {
241         huffsection[i].codeBook = CODE_BOOK_PNS_NO;
242         huffsection[i].sectionBits = 0;
243       } else if (isBook[i]) {
244         huffsection[i].codeBook = isBook[i];
245         huffsection[i].sectionBits = 0;
246       } else {
247         huffsection[i].sectionBits =
248             FDKaacEnc_findBestBook(bitLookUp[i], &(huffsection[i].codeBook),
249                                    0); /* useVCB11 must be 0!!! */
250       }
251     }
252   }
253 }
254 
255 /*
256    sectioning Stage 1:merge all connected regions with the same code book and
257    calculate side info
258  */
FDKaacEnc_gmStage1(SECTION_INFO * const RESTRICT huffsection,INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX+1],const INT maxSfb,const SHORT * const sideInfoTab,const INT useVCB11)259 static void FDKaacEnc_gmStage1(
260     SECTION_INFO* const RESTRICT huffsection,
261     INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], const INT maxSfb,
262     const SHORT* const sideInfoTab, const INT useVCB11) {
263   INT mergeStart = 0, mergeEnd;
264 
265   do {
266     for (mergeEnd = mergeStart + 1; mergeEnd < maxSfb; mergeEnd++) {
267       if (huffsection[mergeStart].codeBook != huffsection[mergeEnd].codeBook)
268         break;
269 
270       /* we can merge. update tables, side info bits will be updated outside of
271        * this loop */
272       huffsection[mergeStart].sfbCnt++;
273       huffsection[mergeStart].sectionBits += huffsection[mergeEnd].sectionBits;
274 
275       /* update bit look up for all code books */
276       FDKaacEnc_mergeBitLookUp(bitLookUp[mergeStart], bitLookUp[mergeEnd]);
277     }
278 
279     /* add side info info bits */
280     huffsection[mergeStart].sectionBits += FDKaacEnc_getSideInfoBits(
281         &huffsection[mergeStart], sideInfoTab, useVCB11);
282     huffsection[mergeEnd - 1].sfbStart =
283         huffsection[mergeStart].sfbStart; /* speed up prev search */
284 
285     mergeStart = mergeEnd;
286 
287   } while (mergeStart < maxSfb);
288 }
289 
290 /*
291    sectioning Stage 2:greedy merge algorithm, merge connected sections with
292    maximum bit gain until no more gain is possible
293  */
FDKaacEnc_gmStage2(SECTION_INFO * const RESTRICT huffsection,INT * const RESTRICT mergeGainLookUp,INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX+1],const INT maxSfb,const SHORT * const sideInfoTab,const INT useVCB11)294 static inline void FDKaacEnc_gmStage2(
295     SECTION_INFO* const RESTRICT huffsection,
296     INT* const RESTRICT mergeGainLookUp,
297     INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], const INT maxSfb,
298     const SHORT* const sideInfoTab, const INT useVCB11) {
299   INT i;
300 
301   for (i = 0; i + huffsection[i].sfbCnt < maxSfb; i += huffsection[i].sfbCnt) {
302     mergeGainLookUp[i] =
303         FDKaacEnc_CalcMergeGain(huffsection, bitLookUp, sideInfoTab, i,
304                                 i + huffsection[i].sfbCnt, useVCB11);
305   }
306 
307   while (TRUE) {
308     INT maxMergeGain, maxNdx, maxNdxNext, maxNdxLast;
309 
310     maxMergeGain =
311         FDKaacEnc_findMaxMerge(mergeGainLookUp, huffsection, maxSfb, &maxNdx);
312 
313     /* exit while loop if no more gain is possible */
314     if (maxMergeGain <= 0) break;
315 
316     maxNdxNext = maxNdx + huffsection[maxNdx].sfbCnt;
317 
318     /* merge sections with maximum bit gain */
319     huffsection[maxNdx].sfbCnt += huffsection[maxNdxNext].sfbCnt;
320     huffsection[maxNdx].sectionBits +=
321         huffsection[maxNdxNext].sectionBits - maxMergeGain;
322 
323     /* update bit look up table for merged huffsection  */
324     FDKaacEnc_mergeBitLookUp(bitLookUp[maxNdx], bitLookUp[maxNdxNext]);
325 
326     /* update mergeLookUpTable */
327     if (maxNdx != 0) {
328       maxNdxLast = huffsection[maxNdx - 1].sfbStart;
329       mergeGainLookUp[maxNdxLast] = FDKaacEnc_CalcMergeGain(
330           huffsection, bitLookUp, sideInfoTab, maxNdxLast, maxNdx, useVCB11);
331     }
332     maxNdxNext = maxNdx + huffsection[maxNdx].sfbCnt;
333 
334     huffsection[maxNdxNext - 1].sfbStart = huffsection[maxNdx].sfbStart;
335 
336     if (maxNdxNext < maxSfb)
337       mergeGainLookUp[maxNdx] = FDKaacEnc_CalcMergeGain(
338           huffsection, bitLookUp, sideInfoTab, maxNdx, maxNdxNext, useVCB11);
339   }
340 }
341 
342 /* count bits used by the noiseless coder */
FDKaacEnc_noiselessCounter(SECTION_DATA * const RESTRICT sectionData,INT mergeGainLookUp[MAX_SFB_LONG],INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX+1],const SHORT * const quantSpectrum,const UINT * const maxValueInSfb,const INT * const sfbOffset,const INT blockType,const INT * const noiseNrg,const INT * const isBook,const INT useVCB11)343 static void FDKaacEnc_noiselessCounter(
344     SECTION_DATA* const RESTRICT sectionData, INT mergeGainLookUp[MAX_SFB_LONG],
345     INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
346     const SHORT* const quantSpectrum, const UINT* const maxValueInSfb,
347     const INT* const sfbOffset, const INT blockType, const INT* const noiseNrg,
348     const INT* const isBook, const INT useVCB11) {
349   INT grpNdx, i;
350   const SHORT* sideInfoTab = NULL;
351   SECTION_INFO* huffsection;
352 
353   /* use appropriate side info table */
354   switch (blockType) {
355     case LONG_WINDOW:
356     case START_WINDOW:
357     case STOP_WINDOW:
358     default:
359       sideInfoTab = FDKaacEnc_sideInfoTabLong;
360       break;
361     case SHORT_WINDOW:
362       sideInfoTab = FDKaacEnc_sideInfoTabShort;
363       break;
364   }
365 
366   sectionData->noOfSections = 0;
367   sectionData->huffmanBits = 0;
368   sectionData->sideInfoBits = 0;
369 
370   if (sectionData->maxSfbPerGroup == 0) return;
371 
372   /* loop trough groups */
373   for (grpNdx = 0; grpNdx < sectionData->sfbCnt;
374        grpNdx += sectionData->sfbPerGroup) {
375     huffsection = sectionData->huffsection + sectionData->noOfSections;
376 
377     /* count bits in this group */
378     FDKaacEnc_buildBitLookUp(quantSpectrum, sectionData->maxSfbPerGroup,
379                              sfbOffset + grpNdx, maxValueInSfb + grpNdx,
380                              bitLookUp, huffsection);
381 
382     /* 0.Stage :Find minimum Codebooks */
383     FDKaacEnc_gmStage0(huffsection, bitLookUp, sectionData->maxSfbPerGroup,
384                        noiseNrg + grpNdx, isBook + grpNdx);
385 
386     /* 1.Stage :Merge all connected regions with the same code book */
387     FDKaacEnc_gmStage1(huffsection, bitLookUp, sectionData->maxSfbPerGroup,
388                        sideInfoTab, useVCB11);
389 
390     /*
391        2.Stage
392        greedy merge algorithm, merge connected huffsections with maximum bit
393        gain until no more gain is possible
394      */
395 
396     FDKaacEnc_gmStage2(huffsection, mergeGainLookUp, bitLookUp,
397                        sectionData->maxSfbPerGroup, sideInfoTab, useVCB11);
398 
399     /*
400        compress output, calculate total huff and side bits
401        since we did not update the actual codebook in stage 2
402        to save time, we must set it here for later use in bitenc
403      */
404 
405     for (i = 0; i < sectionData->maxSfbPerGroup; i += huffsection[i].sfbCnt) {
406       if ((huffsection[i].codeBook == CODE_BOOK_PNS_NO) ||
407           (huffsection[i].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
408           (huffsection[i].codeBook == CODE_BOOK_IS_IN_PHASE_NO)) {
409         huffsection[i].sectionBits = 0;
410       } else {
411         /* the sections in the sectionData are now marked with the optimal code
412          * book */
413 
414         FDKaacEnc_findBestBook(bitLookUp[i], &(huffsection[i].codeBook),
415                                useVCB11);
416 
417         sectionData->huffmanBits +=
418             huffsection[i].sectionBits -
419             FDKaacEnc_getSideInfoBits(&huffsection[i], sideInfoTab, useVCB11);
420       }
421 
422       huffsection[i].sfbStart += grpNdx;
423 
424       /* sum up side info bits (section data bits) */
425       sectionData->sideInfoBits +=
426           FDKaacEnc_getSideInfoBits(&huffsection[i], sideInfoTab, useVCB11);
427       sectionData->huffsection[sectionData->noOfSections++] = huffsection[i];
428     }
429   }
430 }
431 
432 /*******************************************************************************
433 
434      functionname: FDKaacEnc_scfCount
435      returns     : ---
436      description : count bits used by scalefactors.
437 
438                    not in all cases if maxValueInSfb[] == 0 we set deltaScf
439                    to zero. only if the difference of the last and future
440                    scalefacGain is not greater then CODE_BOOK_SCF_LAV (60).
441 
442      example:
443                   ^
444      scalefacGain |
445                   |
446                   |       last 75
447                   |          |
448                   |          |
449                   |          |
450                   |          |      current 50
451                   |          |          |
452                   |          |          |
453                   |          |          |
454                   |          |          |
455                   |          |          |      future 5
456                   |          |          |          |
457                   --- ... ---------------------------- ... --------->
458                                                                 sfb
459 
460 
461                   if maxValueInSfb[] of current is zero because of a
462                   notfallstrategie, we do not save bits and transmit a
463                   deltaScf of 25. otherwise the deltaScf between the last
464                   scalfacGain (75) and the future scalefacGain (5) is 70.
465 
466 ********************************************************************************/
FDKaacEnc_scfCount(const INT * const scalefacGain,const UINT * const maxValueInSfb,SECTION_DATA * const RESTRICT sectionData,const INT * const isScale)467 static void FDKaacEnc_scfCount(const INT* const scalefacGain,
468                                const UINT* const maxValueInSfb,
469                                SECTION_DATA* const RESTRICT sectionData,
470                                const INT* const isScale) {
471   INT i, j, k, m, n;
472 
473   INT lastValScf = 0;
474   INT deltaScf = 0;
475   INT found = 0;
476   INT scfSkipCounter = 0;
477   INT lastValIs = 0;
478 
479   sectionData->scalefacBits = 0;
480 
481   if (scalefacGain == NULL) return;
482 
483   sectionData->firstScf = 0;
484 
485   for (i = 0; i < sectionData->noOfSections; i++) {
486     if (sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) {
487       sectionData->firstScf = sectionData->huffsection[i].sfbStart;
488       lastValScf = scalefacGain[sectionData->firstScf];
489       break;
490     }
491   }
492 
493   for (i = 0; i < sectionData->noOfSections; i++) {
494     if ((sectionData->huffsection[i].codeBook ==
495          CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
496         (sectionData->huffsection[i].codeBook == CODE_BOOK_IS_IN_PHASE_NO)) {
497       for (j = sectionData->huffsection[i].sfbStart;
498            j < sectionData->huffsection[i].sfbStart +
499                    sectionData->huffsection[i].sfbCnt;
500            j++) {
501         INT deltaIs = isScale[j] - lastValIs;
502         lastValIs = isScale[j];
503         sectionData->scalefacBits +=
504             FDKaacEnc_bitCountScalefactorDelta(deltaIs);
505       }
506     } /* Intensity */
507     else if ((sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) &&
508              (sectionData->huffsection[i].codeBook != CODE_BOOK_PNS_NO)) {
509       INT tmp = sectionData->huffsection[i].sfbStart +
510                 sectionData->huffsection[i].sfbCnt;
511       for (j = sectionData->huffsection[i].sfbStart; j < tmp; j++) {
512         /* check if we can repeat the last value to save bits */
513         if (maxValueInSfb[j] == 0) {
514           found = 0;
515           /* are scalefactors skipped? */
516           if (scfSkipCounter == 0) {
517             /* end of section */
518             if (j == (tmp - 1))
519               found = 0; /* search in other sections for maxValueInSfb != 0 */
520             else {
521               /* search in this section for the next maxValueInSfb[] != 0 */
522               for (k = (j + 1); k < tmp; k++) {
523                 if (maxValueInSfb[k] != 0) {
524                   found = 1;
525                   if ((fixp_abs(scalefacGain[k] - lastValScf)) <=
526                       CODE_BOOK_SCF_LAV)
527                     deltaScf = 0; /* save bits */
528                   else {
529                     /* do not save bits */
530                     deltaScf = lastValScf - scalefacGain[j];
531                     lastValScf = scalefacGain[j];
532                     scfSkipCounter = 0;
533                   }
534                   break;
535                 }
536                 /* count scalefactor skip */
537                 scfSkipCounter++;
538               }
539             }
540 
541             /* search for the next maxValueInSfb[] != 0 in all other sections */
542             for (m = (i + 1); (m < sectionData->noOfSections) && (found == 0);
543                  m++) {
544               if ((sectionData->huffsection[m].codeBook != CODE_BOOK_ZERO_NO) &&
545                   (sectionData->huffsection[m].codeBook != CODE_BOOK_PNS_NO)) {
546                 INT end = sectionData->huffsection[m].sfbStart +
547                           sectionData->huffsection[m].sfbCnt;
548                 for (n = sectionData->huffsection[m].sfbStart; n < end; n++) {
549                   if (maxValueInSfb[n] != 0) {
550                     found = 1;
551                     if (fixp_abs(scalefacGain[n] - lastValScf) <=
552                         CODE_BOOK_SCF_LAV)
553                       deltaScf = 0; /* save bits */
554                     else {
555                       /* do not save bits */
556                       deltaScf = lastValScf - scalefacGain[j];
557                       lastValScf = scalefacGain[j];
558                       scfSkipCounter = 0;
559                     }
560                     break;
561                   }
562                   /* count scalefactor skip */
563                   scfSkipCounter++;
564                 }
565               }
566             }
567             /* no maxValueInSfb[] != 0 found */
568             if (found == 0) {
569               deltaScf = 0;
570               scfSkipCounter = 0;
571             }
572           } else {
573             /* consider skipped scalefactors */
574             deltaScf = 0;
575             scfSkipCounter--;
576           }
577         } else {
578           deltaScf = lastValScf - scalefacGain[j];
579           lastValScf = scalefacGain[j];
580         }
581         sectionData->scalefacBits +=
582             FDKaacEnc_bitCountScalefactorDelta(deltaScf);
583       }
584     }
585   } /* for (i=0; i<sectionData->noOfSections; i++) */
586 }
587 
588 /* count bits used by pns */
FDKaacEnc_noiseCount(SECTION_DATA * const RESTRICT sectionData,const INT * const noiseNrg)589 static void FDKaacEnc_noiseCount(SECTION_DATA* const RESTRICT sectionData,
590                                  const INT* const noiseNrg) {
591   INT noisePCMFlag = TRUE;
592   INT lastValPns = 0, deltaPns;
593   int i, j;
594 
595   sectionData->noiseNrgBits = 0;
596 
597   for (i = 0; i < sectionData->noOfSections; i++) {
598     if (sectionData->huffsection[i].codeBook == CODE_BOOK_PNS_NO) {
599       int sfbStart = sectionData->huffsection[i].sfbStart;
600       int sfbEnd = sfbStart + sectionData->huffsection[i].sfbCnt;
601       for (j = sfbStart; j < sfbEnd; j++) {
602         if (noisePCMFlag) {
603           sectionData->noiseNrgBits += PNS_PCM_BITS;
604           lastValPns = noiseNrg[j];
605           noisePCMFlag = FALSE;
606         } else {
607           deltaPns = noiseNrg[j] - lastValPns;
608           lastValPns = noiseNrg[j];
609           sectionData->noiseNrgBits +=
610               FDKaacEnc_bitCountScalefactorDelta(deltaPns);
611         }
612       }
613     }
614   }
615 }
616 
FDKaacEnc_dynBitCount(BITCNTR_STATE * const hBC,const SHORT * const quantSpectrum,const UINT * const maxValueInSfb,const INT * const scalefac,const INT blockType,const INT sfbCnt,const INT maxSfbPerGroup,const INT sfbPerGroup,const INT * const sfbOffset,SECTION_DATA * const RESTRICT sectionData,const INT * const noiseNrg,const INT * const isBook,const INT * const isScale,const UINT syntaxFlags)617 INT FDKaacEnc_dynBitCount(BITCNTR_STATE* const hBC,
618                           const SHORT* const quantSpectrum,
619                           const UINT* const maxValueInSfb,
620                           const INT* const scalefac, const INT blockType,
621                           const INT sfbCnt, const INT maxSfbPerGroup,
622                           const INT sfbPerGroup, const INT* const sfbOffset,
623                           SECTION_DATA* const RESTRICT sectionData,
624                           const INT* const noiseNrg, const INT* const isBook,
625                           const INT* const isScale, const UINT syntaxFlags) {
626   sectionData->blockType = blockType;
627   sectionData->sfbCnt = sfbCnt;
628   sectionData->sfbPerGroup = sfbPerGroup;
629   sectionData->noOfGroups = sfbCnt / sfbPerGroup;
630   sectionData->maxSfbPerGroup = maxSfbPerGroup;
631 
632   FDKaacEnc_noiselessCounter(sectionData, hBC->mergeGainLookUp,
633                              (lookUpTable)hBC->bitLookUp, quantSpectrum,
634                              maxValueInSfb, sfbOffset, blockType, noiseNrg,
635                              isBook, (syntaxFlags & AC_ER_VCB11) ? 1 : 0);
636 
637   FDKaacEnc_scfCount(scalefac, maxValueInSfb, sectionData, isScale);
638 
639   FDKaacEnc_noiseCount(sectionData, noiseNrg);
640 
641   return (sectionData->huffmanBits + sectionData->sideInfoBits +
642           sectionData->scalefacBits + sectionData->noiseNrgBits);
643 }
644 
FDKaacEnc_BCNew(BITCNTR_STATE ** phBC,UCHAR * dynamic_RAM)645 INT FDKaacEnc_BCNew(BITCNTR_STATE** phBC, UCHAR* dynamic_RAM) {
646   BITCNTR_STATE* hBC = GetRam_aacEnc_BitCntrState();
647 
648   if (hBC) {
649     *phBC = hBC;
650     hBC->bitLookUp = GetRam_aacEnc_BitLookUp(0, dynamic_RAM);
651     hBC->mergeGainLookUp = GetRam_aacEnc_MergeGainLookUp(0, dynamic_RAM);
652     if (hBC->bitLookUp == 0 || hBC->mergeGainLookUp == 0) {
653       return 1;
654     }
655   }
656   return (hBC == 0) ? 1 : 0;
657 }
658 
FDKaacEnc_BCClose(BITCNTR_STATE ** phBC)659 void FDKaacEnc_BCClose(BITCNTR_STATE** phBC) {
660   if (*phBC != NULL) {
661     FreeRam_aacEnc_BitCntrState(phBC);
662   }
663 }
664