summaryrefslogtreecommitdiffstats
path: root/libAACenc/src/dyn_bits.cpp
diff options
context:
space:
mode:
authorDave Burke <daveburke@google.com>2012-04-17 09:51:45 -0700
committerDave Burke <daveburke@google.com>2012-04-17 23:04:43 -0700
commit9bf37cc9712506b2483650c82d3c41152337ef7e (patch)
tree77db44e2bae06e3d144b255628be2b7a55c581d3 /libAACenc/src/dyn_bits.cpp
parenta37315fe10ee143d6d0b28c19d41a476a23e63ea (diff)
downloadODR-AudioEnc-9bf37cc9712506b2483650c82d3c41152337ef7e.tar.gz
ODR-AudioEnc-9bf37cc9712506b2483650c82d3c41152337ef7e.tar.bz2
ODR-AudioEnc-9bf37cc9712506b2483650c82d3c41152337ef7e.zip
Fraunhofer AAC codec.
License boilerplate update to follow. Change-Id: I2810460c11a58b6d148d84673cc031f3685e79b5
Diffstat (limited to 'libAACenc/src/dyn_bits.cpp')
-rw-r--r--libAACenc/src/dyn_bits.cpp743
1 files changed, 743 insertions, 0 deletions
diff --git a/libAACenc/src/dyn_bits.cpp b/libAACenc/src/dyn_bits.cpp
new file mode 100644
index 0000000..8a94b6c
--- /dev/null
+++ b/libAACenc/src/dyn_bits.cpp
@@ -0,0 +1,743 @@
+/******************************** MPEG Audio Encoder **************************
+
+ (C) Copyright Fraunhofer IIS (1999)
+ All Rights Reserved
+
+ Please be advised that this software and/or program delivery is
+ Confidential Information of Fraunhofer and subject to and covered by the
+
+ Fraunhofer IIS Software Evaluation Agreement
+ between Google Inc. and Fraunhofer
+ effective and in full force since March 1, 2012.
+
+ You may use this software and/or program only under the terms and
+ conditions described in the above mentioned Fraunhofer IIS Software
+ Evaluation Agreement. Any other and/or further use requires a separate agreement.
+
+
+ This software and/or program is protected by copyright law and international
+ treaties. Any reproduction or distribution of this software and/or program,
+ or any portion of it, may result in severe civil and criminal penalties, and
+ will be prosecuted to the maximum extent possible under law.
+
+ $Id$
+ 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);
+ }
+}
+
+
+