--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/videoeditorengine/mp3aacManipLib/AACGain/src/aacaud.cpp Fri Jan 29 14:08:33 2010 +0200
@@ -0,0 +1,973 @@
+/*
+* Copyright (c) 2010 Ixonos Plc.
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - Initial contribution
+*
+* Contributors:
+* Ixonos Plc
+*
+* Description:
+*
+*/
+
+
+/**************************************************************************
+ aacaud.cpp - High level interface implementations for AAC decoder.
+
+ Author(s): Juha Ojanpera
+ Copyright (c) 2000-2004 by Nokia Research Center, Speech and Audio Systems.
+ *************************************************************************/
+
+/*-- System Headers. --*/
+#include <math.h>
+
+/*-- Project Headers. --*/
+#include "aacaud.h"
+#include "dec_huf.h"
+#include "tool2.h"
+
+CAACAudDec* CAACAudDec::NewL(int16 aNumCh, int16 aNumCCh)
+ {
+ CAACAudDec* self = new (ELeave) CAACAudDec();
+ CleanupStack::PushL(self);
+ self->ConstructL(aNumCh, aNumCCh);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+void CAACAudDec::ConstructL(int16 aNumCh, int16 aNumCCh)
+ {
+
+ //----------------->
+
+ int16 i, tmp;
+
+ numCh = aNumCh;
+ numCCh = aNumCCh;
+
+ /*-- Set the limit for the number of decoded audio elements. --*/
+ if(numCh > ChansD - XChansD)
+ numCh = ChansD - XChansD;
+
+ /*-- How many coupling channels are accepted ? --*/
+ if(numCCh > CChansD - XCChansD)
+ numCCh = CChansD - XCChansD;
+
+ /*-- # of channels outputted. --*/
+ numOutCh = numCh;
+
+ /*-- Allocate main channel elements. --*/
+ tmp = (int16) (numCh + XChansD);
+
+ winInfo = new (ELeave) CWindowInfo*[tmp];
+ tool = new (ELeave) CToolInfo*[tmp];
+
+ windowAmount = tmp;
+
+ for(i = 0; i < tmp; i++)
+ {
+ winInfo[i] = CWindowInfo::NewL();
+ tool[i] = CToolInfo::NewL();
+ }
+
+ /*-- Allocate coupling channel elements. --*/
+ tmp = (int16) (numCCh + XCChansD);
+ ccInfo = new (ELeave) CCInfo*[tmp];
+
+ for(i = 0; i < tmp; i++)
+ {
+ ccInfo[i] = CCInfo::NewL();
+ }
+
+ /*-- Get spectral codebooks parameters. --*/
+ huf = LoadHuffmanDecTablesL();
+
+ /*-- Get scalefactor codebook parameters. --*/
+ sf_huf = LoadSfHuffmanTableL();
+
+ mc_info = CMC_Info::NewL();
+
+ for(i = 0; i < ChansD; i++)
+ {
+ mc_info->ch_info[i].huf = huf;
+ mc_info->ch_info[i].sf_huf = sf_huf;
+ }
+
+ //<------------------
+
+ }
+
+CAACAudDec::CAACAudDec() : tool(0), mc_info(0), ccInfo(0), winInfo(0),
+ huf(0), sf_huf(0)
+ {
+#ifdef EAACPLUS_DECODER
+ sbrStream = NULL;
+ sbrDecInfo = NULL;
+#endif /*-- EAACPLUS_DECODER --*/
+ }
+
+CAACAudDec::~CAACAudDec()
+ {
+
+ /*-- Allocate main channel elements. --*/
+ TInt tmp = (int16) (numCh + XChansD);
+ TInt i = 0;
+ if (winInfo != 0)
+ {
+ for(i = 0; i < tmp; i++)
+ {
+ if (winInfo[i] != 0) delete winInfo[i];
+ if (tool[i] != 0) delete tool[i];
+ }
+
+ delete[] winInfo;
+ }
+
+ if (tool != 0) delete[] tool;
+
+
+ /*-- Allocate coupling channel elements. --*/
+ tmp = (int16) (numCCh + XCChansD);
+
+ if (ccInfo != 0)
+ {
+ for(i = 0; i < tmp; i++)
+ {
+ if (ccInfo[i] != 0) delete ccInfo[i];
+ }
+ }
+
+ if (ccInfo != 0) delete[] ccInfo;
+
+ CloseHuffmanDecTables(huf); huf = NULL;
+ CloseSfHuffmanTable(sf_huf); sf_huf = NULL;
+
+ if (mc_info != 0) delete mc_info;
+
+
+ sbrStream = CloseSBRBitStream(sbrStream);
+ sbrDecInfo = CloseSBR(sbrDecInfo);
+
+ }
+
+/*
+ * Prepares Ch_Info structure for given audio element. The return value is
+ * channel index into 'mip->ch_into' structure.
+ */
+static INLINE int16
+enter_chn(int16 nch, int16 tag, int16 common_window, CMC_Info *mip)
+{
+ TCh_Info *cip;
+ BOOL parseCh;
+ int16 cidx = 0;
+
+ /*-- Build configuration. --*/
+ if(mip->nch + nch > (mip->maxnCh + 1) || mip->dummyAlways)
+ {
+ parseCh = FALSE;
+ cidx = mip->dummyCh;
+ mip->dummyAlways = TRUE;
+ }
+ else
+ {
+ parseCh = TRUE;
+ cidx = mip->nch;
+ mip->nch = (int16) (mip->nch + nch);
+ }
+
+ if(nch == 1) /*-- SCE. --*/
+ {
+ cip = &mip->ch_info[cidx];
+
+ cip->cpe = 0;
+ cip->ncch = 0;
+ cip->tag = tag;
+ cip->widx = cidx;
+ cip->present = 1;
+ cip->paired_ch = cidx;
+ cip->parseCh = parseCh;
+ }
+ else /*-- CPE. --*/
+ {
+ /*-- Left. --*/
+ cip = &mip->ch_info[cidx];
+ cip->cpe = 1;
+ cip->ncch = 0;
+ cip->tag = tag;
+ cip->widx = cidx;
+ cip->present = 1;
+ cip->parseCh = parseCh;
+ cip->paired_ch = (int16) (cidx + 1);
+
+ /*-- Right. ---*/
+ cip = &mip->ch_info[cidx + 1];
+ cip->cpe = 1;
+ cip->ncch = 0;
+ cip->tag = tag;
+ cip->present = 1;
+ cip->paired_ch = cidx;
+ cip->parseCh = parseCh;
+ cip->widx = (common_window) ? (int16) cidx : (int16) (cidx + 1);
+ }
+
+ return (cidx);
+}
+
+/*
+ * Retrieve appropriate channel index for the program and decoder configuration.
+ */
+int16
+ChIndex(int16 nch, int16 tag, int16 wnd, CMC_Info *mip)
+{
+ /*
+ * Channel index to position mapping for 5.1 configuration is :
+ * 0 center
+ * 1 left front
+ * 2 right front
+ * 3 left surround
+ * 4 right surround
+ * 5 lfe
+ */
+ return (enter_chn(nch, tag, wnd, mip));
+}
+
+/*
+ * Given cpe and tag, returns channel index of SCE or left channel in CPE.
+ */
+int16
+CCChIndex(CMC_Info *mip, int16 cpe, int16 tag)
+{
+ int16 ch;
+ TCh_Info *cip = &mip->ch_info[0];
+
+ for(ch = 0; ch < mip->nch; ch++, cip++)
+ if(cip->cpe == cpe && cip->tag == tag)
+ return (ch);
+
+ /*
+ * No match, so channel is not in this program. Just parse the channel(s).
+ */
+ cip = &mip->ch_info[mip->dummyCh];
+ cip->cpe = cpe;
+ cip->widx = mip->dummyCh;
+ cip->parseCh = TRUE;
+
+ return (mip->dummyCh);
+}
+
+/*
+ * Checks continuity of configuration from one block to next.
+ */
+static INLINE void
+ResetMCInfo(CMC_Info *mip)
+{
+ /*-- Reset channels counts. --*/
+ mip->nch = 0;
+ mip->ncch = 0;
+ mip->dummyAlways = 0;
+}
+
+/*
+ * Deletes resources allocated to the specified AAC decoder.
+ */
+EXPORT_C CAACAudDec *
+DeleteAACAudDec(CAACAudDec *aac)
+{
+ if(aac)
+ {
+ delete (aac);
+ aac = 0;
+ }
+
+ return (NULL);
+}
+
+/*
+ * Creates handle to AAC decoder core. The input parameters are
+ * the number of main ('numCh') and coupling ('numCCh') channels
+ * to be supported.
+ *
+ * Return AAC decoder handle on success, NULL on failure.
+ */
+EXPORT_C void
+CreateAACAudDecL(CAACAudDec*& aDecHandle, int16 numCh, int16 numCCh)
+{
+ aDecHandle = CAACAudDec::NewL(numCh, numCCh);
+
+ return;
+}
+
+/*
+ * Creates handle to eAAC+ decoder.
+ */
+EXPORT_C uint8
+CreateAACPlusAudDecL(CAACAudDec *aDecHandle, int16 sampleRateIdx, uint8 isStereo, uint8 isDualMono)
+{
+
+ int32 sampleRate = AACSampleRate(sampleRateIdx);
+
+ aDecHandle->sbrStream = OpenSBRBitStreamL();
+ aDecHandle->sbrDecInfo = OpenSBRDecoderL(sampleRate, 1024, isStereo, isDualMono);
+
+ return (1);
+
+
+}
+
+/*
+ * Prepares AAC core engine for decoding. The input parameters are the
+ * AAC profile ID (or object type in case MPEG-4 AAC) and the sampling
+ * rate index.
+ */
+EXPORT_C void
+InitAACAudDec(CAACAudDec *aac, int16 profile, int16 sampleRateIdx, uint8 is960)
+{
+ int16 i, j;
+ CMC_Info *mip;
+ PredType predType;
+
+ mip = aac->mc_info;
+
+ mip->profile = (uint8) profile;
+ mip->sfreq_idx = (uint8) sampleRateIdx;
+
+ mip->cur_prog = -1;
+ mip->default_config = 1;
+
+ /*
+ * Set channel restrictions so that we know how to handle
+ * unused channel elements.
+ */
+ mip->maxnCh = aac->numCh;
+ mip->dummyCh = mip->maxnCh;
+ mip->maxnCCh = aac->numCCh;
+ mip->dummyCCh = mip->maxnCCh;
+
+ /*-- Initialize sfb parameters. --*/
+ AACSfbInfoInit(mip->sfbInfo, mip->sfreq_idx, is960);
+
+ ResetAACAudDec(aac);
+
+ /*-- How many bands used for prediction (BWAP or LTP). --*/
+ if(profile == LTP_Object)
+ {
+ predType = LTP_PRED;
+ j = LTP_MAX_PRED_BANDS;
+ }
+ else
+ {
+ j = 0;
+ predType = NO_PRED;
+ }
+
+ for(i = 0; i < aac->numCh + XChansD; i++)
+ {
+ aac->winInfo[i]->predBands = (uint8) j;
+ aac->winInfo[i]->predType = predType;
+ }
+ for(i = 0; i < aac->numCCh + XCChansD; i++)
+ {
+ aac->ccInfo[i]->winInfo->predBands = (uint8) j;
+ aac->ccInfo[i]->winInfo->predType = predType;
+ }
+
+ aac->samplesPerFrame = (is960) ? (int16) LN2_960 : (int16) LN2;
+}
+
+/*
+ * Resets internal members from the specified AAC decoder core.
+ */
+EXPORT_C void
+ResetAACAudDec(CAACAudDec *aac)
+{
+ int16 i;
+ CMC_Info *mip;
+ CWindowInfo *winInfo;
+
+ mip = aac->mc_info;
+
+ /*-- Reset some modules. --*/
+ ResetMCInfo(mip);
+
+ /*
+ * Assume that the first window shape is of type Kaiser-Bessel
+ * Derived (KBD). If not, then we use it anyway. The mismatch
+ * in the first frame is not of prime importance.
+ */
+
+ for(i = 0; i < aac->numCh; i++)
+ {
+ //tool = aac->tool[i];
+ winInfo = aac->winInfo[i];
+
+ winInfo->wshape[0].prev_bk = WS_KBD;
+ winInfo->wshape[1].prev_bk = WS_KBD;
+ }
+
+ for(i = 0; i < aac->numCCh; i++)
+ {
+ //tool = aac->ccInfo[i]->tool;
+
+ aac->ccInfo[i]->winInfo->wshape[0].prev_bk = WS_KBD;
+ aac->ccInfo[i]->winInfo->wshape[1].prev_bk = WS_KBD;
+ }
+}
+
+/*
+ * Reads data stream element from the specified bitstream.
+ *
+ * Returns # of read bits.
+ */
+static INLINE int16
+GetDSE(TBitStream *bs)
+{
+ int16 align_flag, cnt, bitsRead;
+
+ bitsRead = (int16) BsGetBitsRead(bs);
+
+ // read tag
+ BsGetBits(bs, LEN_TAG);
+ align_flag = (int16) BsGetBits(bs, LEN_D_ALIGN);
+ cnt = (int16) BsGetBits(bs, LEN_D_CNT);
+
+ if(cnt == (1 << LEN_D_CNT) - 1)
+ cnt = (int16) (cnt + BsGetBits(bs, LEN_D_ESC));
+
+ if(align_flag) BsByteAlign(bs);
+
+ BsSkipNBits(bs, cnt << 3);
+
+ bitsRead = (int16) (BsGetBitsRead(bs) - bitsRead);
+
+ return (bitsRead);
+}
+
+/*
+ * Reads fill element from the bitstream.
+ */
+int32
+CAACAudDec::extension_payload(TBitStream *bs, int32 cnt, uint32 prevEleID)
+{
+ uint8 extType = (uint8) BsGetBits(bs, LEN_EX_TYPE);
+
+ switch(extType)
+ {
+ case EX_FILL_DATA:
+ default:
+ if(sbrStream && !ReadSBRExtensionData(bs, sbrStream, extType, prevEleID, cnt))
+ {
+
+ BsGetBits(bs, LEN_NIBBLE);
+ BsSkipNBits(bs, (cnt - 1) << 3);
+ break;
+
+ }
+ else if (!sbrStream)
+ {
+ BsGetBits(bs, LEN_NIBBLE);
+ BsSkipNBits(bs, (cnt - 1) << 3);
+ break;
+
+ }
+
+
+
+ }
+
+ return (cnt);
+}
+
+/*
+ * Reads fill data from the bitstream.
+ */
+void
+CAACAudDec::GetFIL(TBitStream *bs, uint32 prevEleID)
+{
+ int32 cnt;
+
+ cnt = BsGetBits(bs, LEN_F_CNT);
+ if(cnt == (1 << LEN_F_CNT) - 1)
+ cnt += BsGetBits(bs, LEN_F_ESC) - 1;
+
+ while(cnt > 0)
+ cnt -= extension_payload(bs, cnt, prevEleID);
+}
+
+/*
+ * Reads program configuration element from the specified bitstream.
+ */
+int16
+GetPCE(TBitStream *bs, TProgConfig *p)
+{
+ int16 i;
+
+ p->pce_present = TRUE;
+ p->tag = (int16) BsGetBits(bs, LEN_TAG);
+ p->profile = (int16) BsGetBits(bs, LEN_PROFILE);
+ p->sample_rate_idx = (int16) BsGetBits(bs, LEN_SAMP_IDX);
+ p->front.num_ele = (int16) BsGetBits(bs, LEN_NUM_ELE);
+ p->side.num_ele = (int16) BsGetBits(bs, LEN_NUM_ELE);
+ p->back.num_ele = (int16) BsGetBits(bs, LEN_NUM_ELE);
+ p->lfe.num_ele = (int16) BsGetBits(bs, LEN_NUM_LFE);
+ p->data.num_ele = (int16) BsGetBits(bs, LEN_NUM_DAT);
+ p->coupling.num_ele = (int16) BsGetBits(bs, LEN_NUM_CCE);
+
+ p->mono_mix.present = (int16) BsGetBits(bs, 1);
+ if(p->mono_mix.present == 1)
+ p->mono_mix.ele_tag = (int16) BsGetBits(bs, LEN_TAG);
+
+ p->stereo_mix.present = (int16) BsGetBits(bs, 1);
+ if(p->stereo_mix.present == 1)
+ p->stereo_mix.ele_tag = (int16) BsGetBits(bs, LEN_TAG);
+
+ p->matrix_mix.present = (int16) BsGetBits(bs, 1);
+ if(p->matrix_mix.present == 1)
+ {
+ p->matrix_mix.ele_tag = (int16) BsGetBits(bs, LEN_MMIX_IDX);
+ p->matrix_mix.pseudo_enab = (int16) BsGetBits(bs, LEN_PSUR_ENAB);
+ }
+
+ for(i = 0; i < p->front.num_ele; i++)
+ {
+ p->front.ele_is_cpe[i] = (int16) BsGetBits(bs, LEN_ELE_IS_CPE);
+ p->front.ele_tag[i] = (int16) BsGetBits(bs, LEN_TAG);
+ }
+
+ for(i = 0; i < p->side.num_ele; i++)
+ {
+ p->side.ele_is_cpe[i] = (int16) BsGetBits(bs, LEN_ELE_IS_CPE);
+ p->side.ele_tag[i] = (int16) BsGetBits(bs, LEN_TAG);
+ }
+
+ for(i = 0; i < p->back.num_ele; i++)
+ {
+ p->back.ele_is_cpe[i] = (int16) BsGetBits(bs, LEN_ELE_IS_CPE);
+ p->back.ele_tag[i] = (int16) BsGetBits(bs, LEN_TAG);
+ }
+
+ for(i = 0; i < p->lfe.num_ele; i++)
+ {
+ p->lfe.ele_is_cpe[i] = 0;
+ p->lfe.ele_tag[i] = (int16) BsGetBits(bs, LEN_TAG);
+ }
+
+ for(i = 0; i < p->data.num_ele; i++)
+ {
+ p->data.ele_is_cpe[i] = 0;
+ p->data.ele_tag[i] = (int16) BsGetBits(bs, LEN_TAG);
+ }
+
+ for(i = 0; i < p->coupling.num_ele; i++)
+ {
+ p->coupling.ele_is_cpe[i] = (int16) BsGetBits(bs, LEN_ELE_IS_CPE);
+ p->coupling.ele_tag[i] = (int16) BsGetBits(bs, LEN_TAG);
+ }
+
+ BsByteAlign(bs);
+
+ p->num_comment_bytes = (int16) BsGetBits(bs, LEN_COMMENT_BYTES);
+ BsSkipNBits(bs, p->num_comment_bytes << 3);
+
+ return (p->tag);
+}
+
+/**
+ * Saves the start position of the channel element within the AAC frame.
+ */
+static void
+SaveSBRChannelElementPos(SbrBitStream *sbrStream, uint32 bitOffset, uint32 ele_id)
+{
+ if(sbrStream->NrElements < MAX_NR_ELEMENTS)
+ {
+ /*-- Save starting position of the channel element. --*/
+ sbrStream->sbrElement[sbrStream->NrElements].elementOffset = bitOffset - 3;
+ sbrStream->sbrElement[sbrStream->NrElements].ElementID = ele_id;
+ }
+}
+
+/**
+ * Saves the length of the channel element within the AAC frame.
+ */
+static void
+SaveSBRChannelElementLen(SbrBitStream *sbrStream, uint32 presentPos)
+{
+ if(sbrStream->NrElements < MAX_NR_ELEMENTS)
+ {
+ /*-- Save length of the channel element. --*/
+ sbrStream->sbrElement[sbrStream->NrElements].chElementLen =
+ presentPos - sbrStream->sbrElement[sbrStream->NrElements].elementOffset;
+ }
+}
+/**************************************************************************
+ Title : CountAACChunkLength
+
+ Purpose : Counts the number of bytes reserved for the payload part of
+ current AAC frame. This functions should only be called if
+ no other methods exist to determine the payload legth
+ (e.g., ADIF does not include this kind of information).
+
+ Usage : y = CountAACChunkLength(bs, aac, bytesInFrame)
+
+ Input : bs - input bitstream
+ aac - AAC decoder parameters
+
+ Output : y - status of operation
+ bytesInFrame - # of bytes reserved for this frame
+
+ Author(s) : Juha Ojanpera
+ *************************************************************************/
+
+EXPORT_C int16
+CountAACChunkLength(TBitStream *bs, CAACAudDec *aac, int16 *bytesInFrame)
+{
+ uint32 bitsRead;
+ int16 frameStatus;
+
+ /*-- Save the status of input bitstream. --*/
+ bitsRead = BsGetBitsRead(bs);
+
+ /*-- Parse the frame. --*/
+ frameStatus = (!GetAACGlobalGains(bs, aac, 15, NULL, NULL)) ? (int16) 0 : (int16) 1;
+ ResetMCInfo(aac->mc_info);
+
+ /*-- Determine the # of bytes for this frame. --*/
+ bitsRead = BsGetBitsRead(bs) - bitsRead;
+ *bytesInFrame = (int16) ((bitsRead >> 3) + ((bitsRead & 0x7) ? 1 : 0));
+
+ return (frameStatus);
+}
+
+/**************************************************************************
+ Title : GetAACGlobalGains
+
+ Purpose : Extracts 'global_gain' bitstream elements from the specified
+ AAC data buffer.
+
+ Usage : y = GetAACGlobalGains(bs, aac, nBufs, globalGain, globalGainPos)
+
+ Input : bs - input bitstream
+ aac - AAC decoder handle
+ nBufs - # of gain buffers present
+
+ Output : y - # of gain elements extracted
+ globalGain - 'global_gain' elements
+ globalGainPos - position location (in bits) of each gain value.
+ This information is used when storing the gain
+ elements back to bitstream.
+
+ Author(s) : Juha Ojanpera
+ *************************************************************************/
+
+EXPORT_C uint8
+GetAACGlobalGains(TBitStream* bs, CAACAudDec *aac, uint8 nBufs, uint8 *globalGain, uint32 *globalGainPos)
+{
+ uint8 numGains;
+ uint8 loopControl;
+ TProgConfig progCfg;
+ CMC_Info *mip = aac->mc_info;
+ uint32 ele_id, prevEleID, bufBitOffset;
+
+ numGains = 0;
+ loopControl = 0;
+ prevEleID = ID_END;
+ bufBitOffset = BsGetBitsRead(bs);
+
+ /*-- Reset some modules. --*/
+ ResetMCInfo(mip);
+
+ /*-- No SBR elements present by default. --*/
+ if(aac->sbrStream)
+ aac->sbrStream->NrElements = 0;
+
+ /*-- Loop until termination code found. --*/
+ while((ele_id = BsGetBits(bs, LEN_SE_ID)) != ID_END)
+ {
+ int16 parserErr;
+
+ if(loopControl > 64) break;
+
+ /*-- Get audio syntactic element. --*/
+ switch(ele_id)
+ {
+ /*-- Single and lfe channel. --*/
+ case ID_SCE:
+ case ID_LFE:
+ if((numGains + 1) > nBufs) break;
+
+ if(aac->sbrStream)
+ SaveSBRChannelElementPos(aac->sbrStream, BsGetBitsRead(bs) - bufBitOffset, ele_id);
+
+ if(globalGain)
+ parserErr = GetSCEGain(aac, bs, &globalGain[numGains], &globalGainPos[numGains], bufBitOffset);
+ else
+ parserErr = GetSCE(aac, bs, mip, NULL, NULL, 0);
+
+ if(parserErr < 0)
+ goto f_out;
+ numGains += 1;
+
+ if(aac->sbrStream)
+ SaveSBRChannelElementLen(aac->sbrStream, BsGetBitsRead(bs));
+ break;
+
+ /*-- Channel pair element. --*/
+ case ID_CPE:
+ if((numGains + 2) > nBufs) break;
+ if(aac->sbrStream)
+ SaveSBRChannelElementPos(aac->sbrStream, BsGetBitsRead(bs) - bufBitOffset, ele_id);
+
+ if(globalGain)
+ parserErr = GetCPEGain(aac, bs, &globalGain[numGains], &globalGainPos[numGains], bufBitOffset);
+ else
+ parserErr = GetCPE(aac, bs, mip, NULL, NULL, 0);
+
+ if(parserErr < 0)
+ goto f_out;
+ numGains += 2;
+
+ if(aac->sbrStream)
+ SaveSBRChannelElementLen(aac->sbrStream, BsGetBitsRead(bs));
+ break;
+
+ /*-- Coupling channel. --*/
+ case ID_CCE:
+ if(GetCCE(aac, bs, mip, aac->ccInfo) < 0)
+ goto f_out;
+ break;
+
+ /*-- Data element. --*/
+ case ID_DSE:
+ loopControl++;
+ GetDSE(bs);
+ break;
+
+ /*-- Program config element. --*/
+ case ID_PCE:
+ loopControl++;
+ GetPCE(bs, &progCfg);
+ break;
+
+ /*-- Fill element. --*/
+ case ID_FIL:
+ loopControl++;
+ TInt error;
+ TRAP( error, aac->GetFIL(bs, prevEleID) );
+ if (error != KErrNone)
+ goto f_out;
+ break;
+
+ default:
+ goto f_out;
+ }
+
+ prevEleID = ele_id;
+
+ bufBitOffset = BsGetBitsRead(bs) - bufBitOffset;
+ }
+
+ BsByteAlign(bs);
+
+f_out:
+
+ return (numGains);
+}
+
+/*
+ * Stores 'global_gain' bitstream elements to AAC data buffer.
+ */
+INLINE void
+SetAACGain(TBitStream* bs, uint32 gainPos, uint8 globalGains)
+{
+ BsSkipNBits(bs, gainPos);
+ BsPutBits(bs, LEN_SCL_PCM, globalGains);
+}
+
+/*
+ * Saves modified 'global_gain' bitstream elements to specified AAC data buffer.
+ */
+EXPORT_C void
+SetAACGlobalGains(TBitStream* bs, uint8 numGains, uint8 *globalGain, uint32 *globalGainPos)
+{
+ int16 i;
+ TBitStream bsIn;
+
+ BsSaveBufState(bs, &bsIn);
+
+ /*-- Store the gain element back to bitstream. --*/
+ for(i = 0; i < numGains; i++)
+ SetAACGain(bs, globalGainPos[i], globalGain[i]);
+
+
+}
+
+/*
+ * Retrieves sample rate index corresponding to the specified sample rate.
+ */
+INLINE uint8
+GetSampleRateIndex(int32 sampleRate)
+{
+ uint8 sIndex = 0xF;
+
+ switch(sampleRate)
+ {
+ case 96000:
+ sIndex = 0x0;
+ break;
+
+ case 88200:
+ sIndex = 0x1;
+ break;
+
+ case 64000:
+ sIndex = 0x2;
+ break;
+
+ case 48000:
+ sIndex = 0x3;
+ break;
+
+ case 44100:
+ sIndex = 0x4;
+ break;
+
+ case 32000:
+ sIndex = 0x5;
+ break;
+
+ case 24000:
+ sIndex = 0x6;
+ break;
+
+ case 22050:
+ sIndex = 0x7;
+ break;
+
+ case 16000:
+ sIndex = 0x8;
+ break;
+
+ case 12000:
+ sIndex = 0x9;
+ break;
+
+ case 11025:
+ sIndex = 0xa;
+ break;
+
+ case 8000:
+ sIndex = 0xb;
+ break;
+ }
+
+ return (sIndex);
+}
+
+INLINE int16
+WriteGASpecificConfig(TBitStream *bsOut, int16 bitsWritten, int16 frameLen)
+{
+ /*-- Frame length flag (1024-point or 960-point MDCT). --*/
+ bitsWritten += 1;
+ BsPutBits(bsOut, 1, (frameLen == LN2) ? 0 : 1);
+
+ /*-- No core coder. --*/
+ bitsWritten += 1;
+ BsPutBits(bsOut, 1, 0);
+
+ /*-- No extension flag. --*/
+ bitsWritten += 1;
+ BsPutBits(bsOut, 1, 0);
+
+ return (bitsWritten);
+}
+
+
+
+EXPORT_C int16
+AACGetMP4ConfigInfo(int32 sampleRate, uint8 profile, uint8 nChannels,
+ int16 frameLen, uint8 *pBuf, uint8 nBytesInBuf)
+{
+ TBitStream bsOut;
+ int16 nConfigBytes, bitsWritten;
+
+ BsInit(&bsOut, pBuf, nBytesInBuf);
+
+ /*-- Object type. --*/
+ bitsWritten = 5;
+ BsPutBits(&bsOut, 5, profile + 1);
+
+ /*-- Sample rate index. --*/
+ bitsWritten += 4;
+ BsPutBits(&bsOut, 4, GetSampleRateIndex(sampleRate));
+ if(GetSampleRateIndex(sampleRate) == 0xF)
+ {
+ bitsWritten += 24;
+ BsPutBits(&bsOut, 24, sampleRate);
+ }
+
+ /*-- # of channels. --*/
+ bitsWritten += 4;
+ BsPutBits(&bsOut, 4, nChannels);
+
+ /*-- Write GA specific info. --*/
+ bitsWritten = WriteGASpecificConfig(&bsOut, bitsWritten, frameLen);
+
+ nConfigBytes = int16 ((bitsWritten & 7) ? (bitsWritten >> 3) + 1 : (bitsWritten >> 3));
+
+ return (nConfigBytes);
+}
+
+/*
+ * Saves modified 'global_gain' bitstream elements to specified AAC data buffer.
+ */
+EXPORT_C void
+SetAACPlusGlobalGains(TBitStream* bs, TBitStream* bsOut, CAACAudDec *aac, int16 gainChangeValue,
+ uint8 numGains, uint8 *globalGain, uint32 *globalGainPos)
+ {
+ int16 i;
+ TBitStream bsIn;
+
+ BsSaveBufState(bs, &bsIn);
+
+ /*-- Store the gain element back to bitstream. --*/
+ for(i = 0; i < numGains; i++)
+ {
+ SetAACGain(bs, globalGainPos[i], globalGain[i]);
+ }
+
+
+ if(aac->sbrStream && aac->sbrDecInfo)
+ {
+
+ if(aac->sbrStream->NrElements)
+ {
+ ParseSBR(&bsIn, bsOut, aac->sbrDecInfo, aac->sbrStream, gainChangeValue);
+ }
+
+
+ }
+
+ }
+
+
+EXPORT_C uint8
+IsAACParametricStereoEnabled(CAACAudDec *aac)
+ {
+
+ return (IsSBRParametricStereoEnabled(aac->sbrDecInfo, aac->sbrStream));
+
+ }
+
+EXPORT_C uint8
+IsAACSBREnabled(CAACAudDec *aac)
+ {
+
+ return (IsSBREnabled(aac->sbrStream));
+
+
+ }