aboutsummaryrefslogtreecommitdiffstats
path: root/libAACenc/src/dyn_bits.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libAACenc/src/dyn_bits.cpp')
-rw-r--r--libAACenc/src/dyn_bits.cpp805
1 files changed, 805 insertions, 0 deletions
diff --git a/libAACenc/src/dyn_bits.cpp b/libAACenc/src/dyn_bits.cpp
new file mode 100644
index 0000000..8cac2ef
--- /dev/null
+++ b/libAACenc/src/dyn_bits.cpp
@@ -0,0 +1,805 @@
+
+/* -----------------------------------------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2012 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+ All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
+the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
+This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
+audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
+independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
+of the MPEG specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
+may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
+individually for the purpose of encoding or decoding bit streams in products that are compliant with
+the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
+these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
+software may already be covered under those patent licenses when it is used for those licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
+are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
+applications information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification, are permitted without
+payment of copyright license fees provided that you satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
+your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation and/or other materials
+provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
+You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived from this library without
+prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
+software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
+and the date of any change. For modified versions of the FDK AAC Codec, the term
+"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
+"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
+ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
+respect to this software.
+
+You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
+by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
+"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
+of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
+including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
+or business interruption, however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of this software, even if
+advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------------------------------------- */
+
+/******************************** MPEG Audio Encoder **************************
+
+ Initial author: M.Werner
+ contents/description: Noiseless coder module
+
+******************************************************************************/
+
+#include "dyn_bits.h"
+#include "bit_cnt.h"
+#include "psy_const.h"
+#include "aacenc_pns.h"
+#include "aacEnc_ram.h"
+#include "aacEnc_rom.h"
+
+typedef INT (*lookUpTable)[CODE_BOOK_ESC_NDX + 1];
+
+static INT FDKaacEnc_getSideInfoBits(
+ const SECTION_INFO* const huffsection,
+ const SHORT* const sideInfoTab,
+ const INT useHCR
+ )
+{
+ INT sideInfoBits;
+
+ if ( useHCR && ((huffsection->codeBook == 11) || (huffsection->codeBook >= 16)) ) {
+ sideInfoBits = 5;
+ }
+ else {
+ sideInfoBits = sideInfoTab[huffsection->sfbCnt];
+ }
+
+ return (sideInfoBits);
+}
+
+/* count bits using all possible tables */
+static void 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
+ )
+{
+ INT i, sfbWidth;
+
+ for (i = 0; i < maxSfb; i++)
+ {
+ huffsection[i].sfbCnt = 1;
+ huffsection[i].sfbStart = i;
+ huffsection[i].sectionBits = INVALID_BITCOUNT;
+ huffsection[i].codeBook = -1;
+ sfbWidth = sfbOffset[i + 1] - sfbOffset[i];
+ FDKaacEnc_bitCount(quantSpectrum + sfbOffset[i], sfbWidth, sfbMax[i], bitLookUp[i]);
+ }
+}
+
+/* essential helper functions */
+static INT FDKaacEnc_findBestBook(
+ const INT* const bc,
+ INT* const book,
+ const INT useVCB11
+ )
+{
+ INT minBits = INVALID_BITCOUNT, j;
+
+ int end = CODE_BOOK_ESC_NDX;
+
+
+ for (j = 0; j <= end; j++)
+ {
+ if (bc[j] < minBits)
+ {
+ minBits = bc[j];
+ *book = j;
+ }
+ }
+ return (minBits);
+}
+
+static INT FDKaacEnc_findMinMergeBits(
+ const INT* const bc1,
+ const INT* const bc2,
+ const INT useVCB11
+ )
+{
+ INT minBits = INVALID_BITCOUNT, j;
+
+ int end = CODE_BOOK_ESC_NDX;
+
+
+ for (j = 0; j <= end; j++)
+ {
+ if (bc1[j] + bc2[j] < minBits)
+ {
+ minBits = bc1[j] + bc2[j];
+ }
+ }
+ return (minBits);
+}
+
+static void FDKaacEnc_mergeBitLookUp(
+ INT* const bc1,
+ const INT* const bc2
+ )
+{
+ int j;
+
+ for (j = 0; j <= CODE_BOOK_ESC_NDX; j++)
+ {
+ bc1[j] = fixMin(bc1[j] + bc2[j], INVALID_BITCOUNT);
+ }
+}
+
+static INT FDKaacEnc_findMaxMerge(
+ const INT* const mergeGainLookUp,
+ const SECTION_INFO* const huffsection,
+ const INT maxSfb,
+ INT* const maxNdx
+ )
+{
+ INT i, maxMergeGain = 0;
+
+ for (i = 0; i + huffsection[i].sfbCnt < maxSfb; i += huffsection[i].sfbCnt)
+ {
+ if (mergeGainLookUp[i] > maxMergeGain)
+ {
+ maxMergeGain = mergeGainLookUp[i];
+ *maxNdx = i;
+ }
+ }
+ return (maxMergeGain);
+}
+
+static INT 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
+ )
+{
+ INT MergeGain, MergeBits, SplitBits;
+
+ MergeBits = sideInfoTab[huffsection[ndx1].sfbCnt + huffsection[ndx2].sfbCnt] + FDKaacEnc_findMinMergeBits(bitLookUp[ndx1], bitLookUp[ndx2], useVCB11);
+ SplitBits = huffsection[ndx1].sectionBits + huffsection[ndx2].sectionBits; /* Bit amount for splitted huffsections */
+ MergeGain = SplitBits - MergeBits;
+
+ if ( (huffsection[ndx1].codeBook==CODE_BOOK_PNS_NO)||(huffsection[ndx2].codeBook==CODE_BOOK_PNS_NO)
+ || (huffsection[ndx1].codeBook==CODE_BOOK_IS_OUT_OF_PHASE_NO)||(huffsection[ndx2].codeBook==CODE_BOOK_IS_OUT_OF_PHASE_NO)
+ || (huffsection[ndx1].codeBook==CODE_BOOK_IS_IN_PHASE_NO)||(huffsection[ndx2].codeBook==CODE_BOOK_IS_IN_PHASE_NO)
+ )
+ {
+ MergeGain = -1;
+ }
+
+ return (MergeGain);
+}
+
+
+/* sectioning Stage 0:find minimum codbooks */
+static void 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
+ )
+{
+ INT i;
+
+ for (i = 0; i < maxSfb; i++)
+ {
+ /* Side-Info bits will be calculated in Stage 1! */
+ if (huffsection[i].sectionBits == INVALID_BITCOUNT)
+ {
+ /* intensity and pns codebooks are already allocated in bitcount.c */
+ if(noiseNrg[i] != NO_NOISE_PNS){
+ huffsection[i].codeBook=CODE_BOOK_PNS_NO;
+ huffsection[i].sectionBits = 0;
+ }
+ else if( isBook[i] ) {
+ huffsection[i].codeBook=isBook[i];
+ huffsection[i].sectionBits = 0;
+ }
+ else {
+ huffsection[i].sectionBits = FDKaacEnc_findBestBook(bitLookUp[i], &(huffsection[i].codeBook), 0); /* useVCB11 must be 0!!! */
+ }
+ }
+ }
+}
+
+/*
+ sectioning Stage 1:merge all connected regions with the same code book and
+ calculate side info
+ */
+static void 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
+ )
+{
+ INT mergeStart = 0, mergeEnd;
+
+ do
+ {
+ for (mergeEnd = mergeStart + 1; mergeEnd < maxSfb; mergeEnd++)
+ {
+ if (huffsection[mergeStart].codeBook != huffsection[mergeEnd].codeBook)
+ break;
+
+
+ /* we can merge. update tables, side info bits will be updated outside of this loop */
+ huffsection[mergeStart].sfbCnt++;
+ huffsection[mergeStart].sectionBits += huffsection[mergeEnd].sectionBits;
+
+ /* update bit look up for all code books */
+ FDKaacEnc_mergeBitLookUp(bitLookUp[mergeStart], bitLookUp[mergeEnd]);
+ }
+
+ /* add side info info bits */
+ huffsection[mergeStart].sectionBits += FDKaacEnc_getSideInfoBits(&huffsection[mergeStart], sideInfoTab, useVCB11);
+ huffsection[mergeEnd - 1].sfbStart = huffsection[mergeStart].sfbStart; /* speed up prev search */
+
+ mergeStart = mergeEnd;
+
+ } while (mergeStart < maxSfb);
+}
+
+/*
+ sectioning Stage 2:greedy merge algorithm, merge connected sections with
+ maximum bit gain until no more gain is possible
+ */
+static void
+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
+ )
+{
+ INT i;
+
+ for (i = 0; i + huffsection[i].sfbCnt < maxSfb; i += huffsection[i].sfbCnt)
+ {
+ mergeGainLookUp[i] = FDKaacEnc_CalcMergeGain(huffsection,
+ bitLookUp,
+ sideInfoTab,
+ i,
+ i + huffsection[i].sfbCnt,
+ useVCB11);
+ }
+
+ while (TRUE)
+ {
+ INT maxMergeGain, maxNdx = 0, maxNdxNext, maxNdxLast;
+
+ maxMergeGain = FDKaacEnc_findMaxMerge(mergeGainLookUp, huffsection, maxSfb, &maxNdx);
+
+ /* exit while loop if no more gain is possible */
+ if (maxMergeGain <= 0)
+ break;
+
+ maxNdxNext = maxNdx + huffsection[maxNdx].sfbCnt;
+
+ /* merge sections with maximum bit gain */
+ huffsection[maxNdx].sfbCnt += huffsection[maxNdxNext].sfbCnt;
+ huffsection[maxNdx].sectionBits += huffsection[maxNdxNext].sectionBits - maxMergeGain;
+
+ /* update bit look up table for merged huffsection */
+ FDKaacEnc_mergeBitLookUp(bitLookUp[maxNdx], bitLookUp[maxNdxNext]);
+
+ /* update mergeLookUpTable */
+ if (maxNdx != 0)
+ {
+ maxNdxLast = huffsection[maxNdx - 1].sfbStart;
+ mergeGainLookUp[maxNdxLast] = FDKaacEnc_CalcMergeGain(huffsection,
+ bitLookUp,
+ sideInfoTab,
+ maxNdxLast,
+ maxNdx,
+ useVCB11);
+
+ }
+ maxNdxNext = maxNdx + huffsection[maxNdx].sfbCnt;
+
+ huffsection[maxNdxNext - 1].sfbStart = huffsection[maxNdx].sfbStart;
+
+ if (maxNdxNext < maxSfb)
+ mergeGainLookUp[maxNdx] = FDKaacEnc_CalcMergeGain(huffsection,
+ bitLookUp,
+ sideInfoTab,
+ maxNdx,
+ maxNdxNext,
+ useVCB11);
+
+ }
+}
+
+/* count bits used by the noiseless coder */
+static void 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
+ )
+{
+ INT grpNdx, i;
+ const SHORT *sideInfoTab = NULL;
+ SECTION_INFO *huffsection;
+
+ /* use appropriate side info table */
+ switch (blockType)
+ {
+ case LONG_WINDOW:
+ case START_WINDOW:
+ case STOP_WINDOW:
+ sideInfoTab = FDKaacEnc_sideInfoTabLong;
+ break;
+ case SHORT_WINDOW:
+ sideInfoTab = FDKaacEnc_sideInfoTabShort;
+ break;
+ }
+
+ sectionData->noOfSections = 0;
+ sectionData->huffmanBits = 0;
+ sectionData->sideInfoBits = 0;
+
+
+ if (sectionData->maxSfbPerGroup == 0)
+ return;
+
+ /* loop trough groups */
+ for (grpNdx = 0; grpNdx < sectionData->sfbCnt; grpNdx += sectionData->sfbPerGroup)
+ {
+ huffsection = sectionData->huffsection + sectionData->noOfSections;
+
+ /* count bits in this group */
+ FDKaacEnc_buildBitLookUp(quantSpectrum,
+ sectionData->maxSfbPerGroup,
+ sfbOffset + grpNdx,
+ maxValueInSfb + grpNdx,
+ bitLookUp,
+ huffsection);
+
+ /* 0.Stage :Find minimum Codebooks */
+ FDKaacEnc_gmStage0(huffsection, bitLookUp, sectionData->maxSfbPerGroup, noiseNrg+grpNdx, isBook+grpNdx);
+
+ /* 1.Stage :Merge all connected regions with the same code book */
+ FDKaacEnc_gmStage1(huffsection, bitLookUp, sectionData->maxSfbPerGroup, sideInfoTab, useVCB11);
+
+
+ /*
+ 2.Stage
+ greedy merge algorithm, merge connected huffsections with maximum bit
+ gain until no more gain is possible
+ */
+
+ FDKaacEnc_gmStage2(huffsection,
+ mergeGainLookUp,
+ bitLookUp,
+ sectionData->maxSfbPerGroup,
+ sideInfoTab,
+ useVCB11);
+
+
+
+ /*
+ compress output, calculate total huff and side bits
+ since we did not update the actual codebook in stage 2
+ to save time, we must set it here for later use in bitenc
+ */
+
+ for (i = 0; i < sectionData->maxSfbPerGroup; i += huffsection[i].sfbCnt)
+ {
+ if ((huffsection[i].codeBook==CODE_BOOK_PNS_NO) ||
+ (huffsection[i].codeBook==CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
+ (huffsection[i].codeBook==CODE_BOOK_IS_IN_PHASE_NO))
+ {
+ huffsection[i].sectionBits=0;
+ } else {
+ /* the sections in the sectionData are now marked with the optimal code book */
+
+ FDKaacEnc_findBestBook(bitLookUp[i], &(huffsection[i].codeBook), useVCB11);
+
+ sectionData->huffmanBits += huffsection[i].sectionBits - FDKaacEnc_getSideInfoBits(&huffsection[i], sideInfoTab, useVCB11);
+ }
+
+ huffsection[i].sfbStart += grpNdx;
+
+ /* sum up side info bits (section data bits) */
+ sectionData->sideInfoBits += FDKaacEnc_getSideInfoBits(&huffsection[i], sideInfoTab, useVCB11);
+ sectionData->huffsection[sectionData->noOfSections++] = huffsection[i];
+ }
+ }
+}
+
+
+/*******************************************************************************
+
+ functionname: FDKaacEnc_scfCount
+ returns : ---
+ description : count bits used by scalefactors.
+
+ not in all cases if maxValueInSfb[] == 0 we set deltaScf
+ to zero. only if the difference of the last and future
+ scalefacGain is not greater then CODE_BOOK_SCF_LAV (60).
+
+ example:
+ ^
+ scalefacGain |
+ |
+ | last 75
+ | |
+ | |
+ | |
+ | | current 50
+ | | |
+ | | |
+ | | |
+ | | |
+ | | | future 5
+ | | | |
+ --- ... ---------------------------- ... --------->
+ sfb
+
+
+ if maxValueInSfb[] of current is zero because of a
+ notfallstrategie, we do not save bits and transmit a
+ deltaScf of 25. otherwise the deltaScf between the last
+ scalfacGain (75) and the future scalefacGain (5) is 70.
+
+********************************************************************************/
+static void FDKaacEnc_scfCount(
+ const INT* const scalefacGain,
+ const UINT* const maxValueInSfb,
+ SECTION_DATA* const RESTRICT sectionData,
+ const INT* const isScale
+ )
+{
+ INT i, j, k, m, n;
+
+ INT lastValScf = 0;
+ INT deltaScf = 0;
+ INT found = 0;
+ INT scfSkipCounter = 0;
+ INT lastValIs = 0;
+
+ sectionData->scalefacBits = 0;
+
+ if (scalefacGain == NULL)
+ return;
+
+ sectionData->firstScf = 0;
+
+ for (i=0; i<sectionData->noOfSections; i++)
+ {
+ if (sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO)
+ {
+ sectionData->firstScf = sectionData->huffsection[i].sfbStart;
+ lastValScf = scalefacGain[sectionData->firstScf];
+ break;
+ }
+ }
+
+ for (i=0; i<sectionData->noOfSections; i++)
+ {
+ if ((sectionData->huffsection[i].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
+ (sectionData->huffsection[i].codeBook == CODE_BOOK_IS_IN_PHASE_NO))
+ {
+ for (j = sectionData->huffsection[i].sfbStart;
+ j < sectionData->huffsection[i].sfbStart + sectionData->huffsection[i].sfbCnt;
+ j++)
+ {
+ INT deltaIs = isScale[j]-lastValIs;
+ lastValIs = isScale[j];
+ sectionData->scalefacBits+=FDKaacEnc_bitCountScalefactorDelta(deltaIs);
+ }
+ } /* Intensity */
+ else if ((sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) &&
+ (sectionData->huffsection[i].codeBook != CODE_BOOK_PNS_NO))
+ {
+ INT tmp = sectionData->huffsection[i].sfbStart + sectionData->huffsection[i].sfbCnt;
+ for (j = sectionData->huffsection[i].sfbStart; j<tmp; j++)
+ {
+ /* check if we can repeat the last value to save bits */
+ if (maxValueInSfb[j] == 0)
+ {
+ found = 0;
+ /* are scalefactors skipped? */
+ if (scfSkipCounter == 0)
+ {
+ /* end of section */
+ if (j == (tmp - 1) )
+ found = 0; /* search in other sections for maxValueInSfb != 0 */
+ else
+ {
+ /* search in this section for the next maxValueInSfb[] != 0 */
+ for (k = (j+1); k < tmp; k++)
+ {
+ if (maxValueInSfb[k] != 0)
+ {
+ found = 1;
+ if ( (fixp_abs(scalefacGain[k] - lastValScf)) <= CODE_BOOK_SCF_LAV)
+ deltaScf = 0; /* save bits */
+ else
+ {
+ /* do not save bits */
+ deltaScf = lastValScf - scalefacGain[j];
+ lastValScf = scalefacGain[j];
+ scfSkipCounter = 0;
+ }
+ break;
+ }
+ /* count scalefactor skip */
+ scfSkipCounter++;
+ }
+ }
+
+ /* search for the next maxValueInSfb[] != 0 in all other sections */
+ for (m=(i+1); (m < sectionData->noOfSections) && (found == 0); m++)
+ {
+ if ((sectionData->huffsection[m].codeBook != CODE_BOOK_ZERO_NO) && (sectionData->huffsection[m].codeBook != CODE_BOOK_PNS_NO))
+ {
+ INT end = sectionData->huffsection[m].sfbStart + sectionData->huffsection[m].sfbCnt;
+ for (n = sectionData->huffsection[m].sfbStart; n<end; n++)
+ {
+ if (maxValueInSfb[n] != 0)
+ {
+ found = 1;
+ if (fixp_abs(scalefacGain[n] - lastValScf) <= CODE_BOOK_SCF_LAV)
+ deltaScf = 0; /* save bits */
+ else
+ {
+ /* do not save bits */
+ deltaScf = lastValScf - scalefacGain[j];
+ lastValScf = scalefacGain[j];
+ scfSkipCounter = 0;
+ }
+ break;
+ }
+ /* count scalefactor skip */
+ scfSkipCounter++;
+ }
+ }
+ }
+ /* no maxValueInSfb[] != 0 found */
+ if (found == 0)
+ {
+ deltaScf = 0;
+ scfSkipCounter = 0;
+ }
+ }
+ else {
+ /* consider skipped scalefactors */
+ deltaScf = 0;
+ scfSkipCounter--;
+ }
+ }
+ else {
+ deltaScf = lastValScf - scalefacGain[j];
+ lastValScf = scalefacGain[j];
+ }
+ sectionData->scalefacBits += FDKaacEnc_bitCountScalefactorDelta(deltaScf);
+ }
+ }
+ } /* for (i=0; i<sectionData->noOfSections; i++) */
+}
+
+#ifdef PNS_PRECOUNT_ENABLE
+/*
+ preCount bits used pns
+*/
+/* estimate bits used by pns for correction of static bits */
+/* no codebook switch estimation, see AAC LD FASTENC */
+INT noisePreCount(const INT *noiseNrg, INT maxSfb)
+{
+ INT noisePCMFlag = TRUE;
+ INT lastValPns = 0, deltaPns;
+ int i, bits=0;
+
+ for (i = 0; i < maxSfb; i++) {
+ if (noiseNrg[i] != NO_NOISE_PNS) {
+
+ if (noisePCMFlag) {
+ bits+=PNS_PCM_BITS;
+ lastValPns = noiseNrg[i];
+ noisePCMFlag = FALSE;
+ }else {
+ deltaPns = noiseNrg[i]-lastValPns;
+ lastValPns = noiseNrg[i];
+ bits+=FDKaacEnc_bitCountScalefactorDelta(deltaPns);
+ }
+ }
+ }
+ return ( bits );
+}
+#endif /* PNS_PRECOUNT_ENABLE */
+
+/* count bits used by pns */
+static void FDKaacEnc_noiseCount(
+ SECTION_DATA* const RESTRICT sectionData,
+ const INT* const noiseNrg
+ )
+{
+ INT noisePCMFlag = TRUE;
+ INT lastValPns = 0, deltaPns;
+ int i, j;
+
+ sectionData->noiseNrgBits = 0;
+
+ for (i = 0; i < sectionData->noOfSections; i++) {
+ if (sectionData->huffsection[i].codeBook == CODE_BOOK_PNS_NO) {
+ int sfbStart = sectionData->huffsection[i].sfbStart;
+ int sfbEnd = sfbStart + sectionData->huffsection[i].sfbCnt;
+ for (j=sfbStart; j<sfbEnd; j++) {
+
+ if (noisePCMFlag) {
+ sectionData->noiseNrgBits+=PNS_PCM_BITS;
+ lastValPns = noiseNrg[j];
+ noisePCMFlag = FALSE;
+ } else {
+ deltaPns = noiseNrg[j]-lastValPns;
+ lastValPns = noiseNrg[j];
+ sectionData->noiseNrgBits+=FDKaacEnc_bitCountScalefactorDelta(deltaPns);
+ }
+ }
+ }
+ }
+}
+
+INT 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
+ )
+{
+ sectionData->blockType = blockType;
+ sectionData->sfbCnt = sfbCnt;
+ sectionData->sfbPerGroup = sfbPerGroup;
+ sectionData->noOfGroups = sfbCnt / sfbPerGroup;
+ sectionData->maxSfbPerGroup = maxSfbPerGroup;
+
+ FDKaacEnc_noiselessCounter(
+ sectionData,
+ hBC->mergeGainLookUp,
+ (lookUpTable)hBC->bitLookUp,
+ quantSpectrum,
+ maxValueInSfb,
+ sfbOffset,
+ blockType,
+ noiseNrg,
+ isBook,
+ (syntaxFlags & AC_ER_VCB11)?1:0);
+
+ FDKaacEnc_scfCount(
+ scalefac,
+ maxValueInSfb,
+ sectionData,
+ isScale);
+
+ FDKaacEnc_noiseCount(sectionData,
+ noiseNrg);
+
+ return (sectionData->huffmanBits +
+ sectionData->sideInfoBits +
+ sectionData->scalefacBits +
+ sectionData->noiseNrgBits);
+}
+
+INT FDKaacEnc_BCNew(BITCNTR_STATE **phBC
+ ,UCHAR* dynamic_RAM
+ )
+{
+ BITCNTR_STATE *hBC = GetRam_aacEnc_BitCntrState();
+
+ if (hBC)
+ {
+ *phBC = hBC;
+ hBC->bitLookUp = GetRam_aacEnc_BitLookUp(0,dynamic_RAM);
+ hBC->mergeGainLookUp = GetRam_aacEnc_MergeGainLookUp(0,dynamic_RAM);
+ if (hBC->bitLookUp == 0 ||
+ hBC->mergeGainLookUp == 0)
+ {
+ return 1;
+ }
+ }
+ return (hBC == 0) ? 1 : 0;
+}
+
+void FDKaacEnc_BCClose(BITCNTR_STATE **phBC)
+{
+ if (*phBC!=NULL) {
+
+ FreeRam_aacEnc_BitCntrState(phBC);
+ }
+}
+
+
+