videoeditorengine/mp3aacManipLib/AACGain/src/aacaud.cpp
changeset 0 951a5db380a0
equal deleted inserted replaced
-1:000000000000 0:951a5db380a0
       
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - Initial contribution
       
    11 *
       
    12 * Contributors:
       
    13 * Ixonos Plc
       
    14 *
       
    15 * Description:
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 /**************************************************************************
       
    21   aacaud.cpp - High level interface implementations for AAC decoder.
       
    22  
       
    23   Author(s): Juha Ojanpera
       
    24   Copyright (c) 2000-2004 by Nokia Research Center, Speech and Audio Systems.
       
    25   *************************************************************************/
       
    26 
       
    27 /*-- System Headers. --*/
       
    28 #include <math.h>
       
    29 
       
    30 /*-- Project Headers. --*/
       
    31 #include "aacaud.h"
       
    32 #include "dec_huf.h"
       
    33 #include "tool2.h"
       
    34 
       
    35 CAACAudDec* CAACAudDec::NewL(int16 aNumCh, int16 aNumCCh)
       
    36     {
       
    37     CAACAudDec* self = new (ELeave) CAACAudDec();
       
    38     CleanupStack::PushL(self);
       
    39     self->ConstructL(aNumCh, aNumCCh);
       
    40     CleanupStack::Pop(self);
       
    41     return self;
       
    42     }
       
    43 
       
    44 void CAACAudDec::ConstructL(int16 aNumCh, int16 aNumCCh)
       
    45     {
       
    46 
       
    47     //----------------->
       
    48 
       
    49     int16 i, tmp;
       
    50 
       
    51     numCh = aNumCh;
       
    52     numCCh = aNumCCh;
       
    53 
       
    54     /*-- Set the limit for the number of decoded audio elements. --*/
       
    55     if(numCh > ChansD - XChansD)
       
    56         numCh = ChansD - XChansD;
       
    57 
       
    58     /*-- How many coupling channels are accepted ? --*/
       
    59     if(numCCh > CChansD - XCChansD)
       
    60         numCCh = CChansD - XCChansD;
       
    61 
       
    62     /*-- # of channels outputted. --*/
       
    63     numOutCh = numCh;
       
    64 
       
    65     /*-- Allocate main channel elements. --*/
       
    66     tmp = (int16) (numCh + XChansD);
       
    67     
       
    68     winInfo = new (ELeave) CWindowInfo*[tmp];
       
    69     tool = new (ELeave) CToolInfo*[tmp];
       
    70 
       
    71     windowAmount = tmp;
       
    72 
       
    73     for(i = 0; i < tmp; i++)
       
    74         {
       
    75         winInfo[i] = CWindowInfo::NewL();
       
    76         tool[i] = CToolInfo::NewL();
       
    77         }
       
    78 
       
    79     /*-- Allocate coupling channel elements. --*/
       
    80     tmp = (int16) (numCCh + XCChansD);
       
    81     ccInfo = new (ELeave) CCInfo*[tmp];
       
    82   
       
    83     for(i = 0; i < tmp; i++)
       
    84         {
       
    85         ccInfo[i] = CCInfo::NewL();
       
    86         }
       
    87 
       
    88     /*-- Get spectral codebooks parameters. --*/
       
    89     huf = LoadHuffmanDecTablesL();
       
    90   
       
    91     /*-- Get scalefactor codebook parameters. --*/
       
    92     sf_huf = LoadSfHuffmanTableL();
       
    93 
       
    94     mc_info = CMC_Info::NewL();
       
    95   
       
    96     for(i = 0; i < ChansD; i++)
       
    97         {
       
    98         mc_info->ch_info[i].huf = huf;
       
    99         mc_info->ch_info[i].sf_huf = sf_huf;
       
   100         }
       
   101 
       
   102     //<------------------
       
   103 
       
   104     }
       
   105 
       
   106 CAACAudDec::CAACAudDec() : tool(0), mc_info(0), ccInfo(0), winInfo(0),
       
   107                            huf(0), sf_huf(0)
       
   108     {
       
   109 #ifdef EAACPLUS_DECODER
       
   110     sbrStream = NULL;
       
   111     sbrDecInfo = NULL;
       
   112 #endif /*-- EAACPLUS_DECODER --*/
       
   113     }
       
   114 
       
   115 CAACAudDec::~CAACAudDec()
       
   116     {
       
   117 
       
   118     /*-- Allocate main channel elements. --*/
       
   119     TInt tmp = (int16) (numCh + XChansD);
       
   120     TInt i = 0;
       
   121     if (winInfo != 0)
       
   122         {
       
   123         for(i = 0; i < tmp; i++)
       
   124             {
       
   125             if (winInfo[i] != 0) delete winInfo[i];
       
   126             if (tool[i] != 0) delete tool[i];
       
   127             }
       
   128 
       
   129         delete[] winInfo;
       
   130         }
       
   131     
       
   132     if (tool != 0) delete[] tool;
       
   133 
       
   134 
       
   135     /*-- Allocate coupling channel elements. --*/
       
   136     tmp = (int16) (numCCh + XCChansD);
       
   137     
       
   138     if (ccInfo != 0)
       
   139         {
       
   140         for(i = 0; i < tmp; i++)
       
   141             {
       
   142             if (ccInfo[i] != 0) delete ccInfo[i];
       
   143             }
       
   144         }
       
   145 
       
   146     if (ccInfo != 0) delete[] ccInfo;
       
   147   
       
   148     CloseHuffmanDecTables(huf); huf = NULL;
       
   149     CloseSfHuffmanTable(sf_huf); sf_huf = NULL;
       
   150 
       
   151     if (mc_info != 0) delete mc_info;
       
   152 
       
   153 
       
   154   sbrStream = CloseSBRBitStream(sbrStream);
       
   155   sbrDecInfo = CloseSBR(sbrDecInfo);
       
   156 
       
   157   }
       
   158 
       
   159 /*
       
   160  * Prepares Ch_Info structure for given audio element. The return value is
       
   161  * channel index into 'mip->ch_into' structure.
       
   162  */
       
   163 static INLINE int16
       
   164 enter_chn(int16 nch, int16 tag, int16 common_window, CMC_Info *mip)
       
   165 {
       
   166   TCh_Info *cip;
       
   167   BOOL parseCh;
       
   168   int16 cidx = 0;
       
   169 
       
   170   /*-- Build configuration. --*/
       
   171   if(mip->nch + nch > (mip->maxnCh + 1) || mip->dummyAlways)
       
   172   {
       
   173     parseCh = FALSE;
       
   174     cidx = mip->dummyCh;
       
   175     mip->dummyAlways = TRUE;
       
   176   }
       
   177   else
       
   178   {
       
   179     parseCh = TRUE;
       
   180     cidx = mip->nch;
       
   181     mip->nch = (int16) (mip->nch + nch);
       
   182   }
       
   183 
       
   184   if(nch == 1) /*-- SCE. --*/
       
   185   {
       
   186     cip = &mip->ch_info[cidx];
       
   187 
       
   188     cip->cpe = 0;
       
   189     cip->ncch = 0;
       
   190     cip->tag = tag;
       
   191     cip->widx = cidx;
       
   192     cip->present = 1;
       
   193     cip->paired_ch = cidx;
       
   194     cip->parseCh = parseCh;
       
   195   }
       
   196   else         /*-- CPE. --*/
       
   197   {
       
   198     /*-- Left. --*/
       
   199     cip = &mip->ch_info[cidx];
       
   200     cip->cpe = 1;
       
   201     cip->ncch = 0;
       
   202     cip->tag = tag;
       
   203     cip->widx = cidx;
       
   204     cip->present = 1;
       
   205     cip->parseCh = parseCh;
       
   206     cip->paired_ch = (int16) (cidx + 1);
       
   207 
       
   208     /*-- Right. ---*/
       
   209     cip = &mip->ch_info[cidx + 1];
       
   210     cip->cpe = 1;
       
   211     cip->ncch = 0;
       
   212     cip->tag = tag;
       
   213     cip->present = 1;
       
   214     cip->paired_ch = cidx;
       
   215     cip->parseCh = parseCh;
       
   216     cip->widx = (common_window) ? (int16) cidx : (int16) (cidx + 1);
       
   217   }
       
   218 
       
   219   return (cidx);
       
   220 }
       
   221 
       
   222 /*
       
   223  * Retrieve appropriate channel index for the program and decoder configuration.
       
   224  */
       
   225 int16
       
   226 ChIndex(int16 nch, int16 tag, int16 wnd, CMC_Info *mip)
       
   227 {
       
   228   /*
       
   229    * Channel index to position mapping for 5.1 configuration is :
       
   230    *  0 center
       
   231    *  1 left  front
       
   232    *  2 right front
       
   233    *  3 left surround
       
   234    *  4 right surround
       
   235    *  5 lfe
       
   236    */
       
   237   return (enter_chn(nch, tag, wnd, mip));
       
   238 }
       
   239 
       
   240 /*
       
   241  * Given cpe and tag, returns channel index of SCE or left channel in CPE.
       
   242  */
       
   243 int16
       
   244 CCChIndex(CMC_Info *mip, int16 cpe, int16 tag)
       
   245 {
       
   246   int16 ch;
       
   247   TCh_Info *cip = &mip->ch_info[0];
       
   248 
       
   249   for(ch = 0; ch < mip->nch; ch++, cip++)
       
   250     if(cip->cpe == cpe && cip->tag == tag)
       
   251       return (ch);
       
   252 
       
   253   /*
       
   254    * No match, so channel is not in this program. Just parse the channel(s).
       
   255    */
       
   256   cip = &mip->ch_info[mip->dummyCh];
       
   257   cip->cpe = cpe;
       
   258   cip->widx = mip->dummyCh;
       
   259   cip->parseCh = TRUE;
       
   260 
       
   261   return (mip->dummyCh);
       
   262 }
       
   263 
       
   264 /* 
       
   265  * Checks continuity of configuration from one block to next.
       
   266  */
       
   267 static INLINE void
       
   268 ResetMCInfo(CMC_Info *mip)
       
   269 {
       
   270   /*-- Reset channels counts. --*/
       
   271   mip->nch = 0;
       
   272   mip->ncch = 0;
       
   273   mip->dummyAlways = 0;
       
   274 }
       
   275 
       
   276 /*
       
   277  * Deletes resources allocated to the specified AAC decoder.
       
   278  */
       
   279 EXPORT_C CAACAudDec *
       
   280 DeleteAACAudDec(CAACAudDec *aac)
       
   281 { 
       
   282   if(aac)
       
   283   {
       
   284     delete (aac);
       
   285     aac = 0;
       
   286   }
       
   287   
       
   288   return (NULL);
       
   289 }
       
   290 
       
   291 /*
       
   292  * Creates handle to AAC decoder core. The input parameters are
       
   293  * the number of main ('numCh') and coupling ('numCCh') channels 
       
   294  * to be supported.
       
   295  *
       
   296  * Return AAC decoder handle on success, NULL on failure.
       
   297  */
       
   298 EXPORT_C void
       
   299 CreateAACAudDecL(CAACAudDec*& aDecHandle, int16 numCh, int16 numCCh)
       
   300 {
       
   301     aDecHandle = CAACAudDec::NewL(numCh, numCCh);
       
   302 
       
   303     return;
       
   304 }
       
   305 
       
   306 /*
       
   307  * Creates handle to eAAC+ decoder.
       
   308  */
       
   309 EXPORT_C uint8
       
   310 CreateAACPlusAudDecL(CAACAudDec *aDecHandle, int16 sampleRateIdx, uint8 isStereo, uint8 isDualMono)
       
   311 {
       
   312 
       
   313   int32 sampleRate = AACSampleRate(sampleRateIdx);
       
   314 
       
   315   aDecHandle->sbrStream = OpenSBRBitStreamL();
       
   316   aDecHandle->sbrDecInfo = OpenSBRDecoderL(sampleRate, 1024, isStereo, isDualMono);
       
   317 
       
   318   return (1);
       
   319 
       
   320 
       
   321 }
       
   322 
       
   323 /*
       
   324  * Prepares AAC core engine for decoding. The input parameters are the 
       
   325  * AAC profile ID (or object type in case MPEG-4 AAC) and the sampling 
       
   326  * rate index.
       
   327  */
       
   328 EXPORT_C void
       
   329 InitAACAudDec(CAACAudDec *aac, int16 profile, int16 sampleRateIdx, uint8 is960)
       
   330 {
       
   331   int16 i, j;
       
   332   CMC_Info *mip;
       
   333   PredType predType;
       
   334 
       
   335   mip = aac->mc_info;
       
   336 
       
   337   mip->profile = (uint8) profile;
       
   338   mip->sfreq_idx = (uint8) sampleRateIdx;
       
   339   
       
   340   mip->cur_prog = -1;
       
   341   mip->default_config = 1;
       
   342 
       
   343   /*
       
   344    * Set channel restrictions so that we know how to handle 
       
   345    * unused channel elements.
       
   346    */
       
   347   mip->maxnCh = aac->numCh;
       
   348   mip->dummyCh = mip->maxnCh;
       
   349   mip->maxnCCh = aac->numCCh;
       
   350   mip->dummyCCh = mip->maxnCCh;
       
   351 
       
   352   /*-- Initialize sfb parameters. --*/
       
   353   AACSfbInfoInit(mip->sfbInfo, mip->sfreq_idx, is960);
       
   354 
       
   355   ResetAACAudDec(aac);
       
   356 
       
   357   /*-- How many bands used for prediction (BWAP or LTP). --*/
       
   358   if(profile == LTP_Object)
       
   359   {
       
   360     predType = LTP_PRED;
       
   361     j = LTP_MAX_PRED_BANDS;
       
   362   }
       
   363   else
       
   364   {
       
   365     j = 0;
       
   366     predType = NO_PRED;
       
   367   }
       
   368   
       
   369   for(i = 0; i < aac->numCh + XChansD; i++)
       
   370   {
       
   371     aac->winInfo[i]->predBands = (uint8) j;
       
   372     aac->winInfo[i]->predType = predType;
       
   373   }
       
   374   for(i = 0; i < aac->numCCh + XCChansD; i++)
       
   375   {
       
   376     aac->ccInfo[i]->winInfo->predBands = (uint8) j;
       
   377     aac->ccInfo[i]->winInfo->predType = predType;
       
   378   }
       
   379 
       
   380   aac->samplesPerFrame = (is960) ? (int16) LN2_960 : (int16) LN2;
       
   381 }
       
   382 
       
   383 /*
       
   384  * Resets internal members from the specified AAC decoder core.
       
   385  */
       
   386 EXPORT_C void
       
   387 ResetAACAudDec(CAACAudDec *aac)
       
   388 {
       
   389   int16 i;
       
   390   CMC_Info *mip;
       
   391   CWindowInfo *winInfo;
       
   392 
       
   393   mip = aac->mc_info;
       
   394 
       
   395   /*-- Reset some modules. --*/
       
   396   ResetMCInfo(mip);
       
   397 
       
   398   /*
       
   399    * Assume that the first window shape is of type Kaiser-Bessel
       
   400    * Derived (KBD). If not, then we use it anyway. The mismatch
       
   401    * in the first frame is not of prime importance.
       
   402    */
       
   403 
       
   404   for(i = 0; i < aac->numCh; i++)
       
   405   {    
       
   406     //tool = aac->tool[i];
       
   407     winInfo = aac->winInfo[i];
       
   408 
       
   409     winInfo->wshape[0].prev_bk = WS_KBD;
       
   410     winInfo->wshape[1].prev_bk = WS_KBD;
       
   411   }
       
   412 
       
   413   for(i = 0; i < aac->numCCh; i++)
       
   414   {
       
   415     //tool = aac->ccInfo[i]->tool;
       
   416 
       
   417     aac->ccInfo[i]->winInfo->wshape[0].prev_bk = WS_KBD;
       
   418     aac->ccInfo[i]->winInfo->wshape[1].prev_bk = WS_KBD;
       
   419   }
       
   420 }
       
   421 
       
   422 /*
       
   423  * Reads data stream element from the specified bitstream.
       
   424  * 
       
   425  * Returns # of read bits.
       
   426  */
       
   427 static INLINE int16
       
   428 GetDSE(TBitStream *bs)
       
   429 {
       
   430   int16 align_flag, cnt, bitsRead;
       
   431   
       
   432   bitsRead = (int16) BsGetBitsRead(bs);
       
   433   
       
   434   // read tag
       
   435   BsGetBits(bs, LEN_TAG);
       
   436   align_flag = (int16) BsGetBits(bs, LEN_D_ALIGN);
       
   437   cnt = (int16) BsGetBits(bs, LEN_D_CNT);
       
   438 
       
   439   if(cnt == (1 << LEN_D_CNT) - 1)
       
   440     cnt = (int16) (cnt + BsGetBits(bs, LEN_D_ESC));
       
   441   
       
   442   if(align_flag) BsByteAlign(bs);
       
   443 
       
   444   BsSkipNBits(bs, cnt << 3);
       
   445 
       
   446   bitsRead = (int16) (BsGetBitsRead(bs) - bitsRead);
       
   447 
       
   448   return (bitsRead);
       
   449 }
       
   450 
       
   451 /*
       
   452  * Reads fill element from the bitstream.
       
   453  */
       
   454 int32
       
   455 CAACAudDec::extension_payload(TBitStream *bs, int32 cnt, uint32 prevEleID)
       
   456 {  
       
   457   uint8 extType = (uint8) BsGetBits(bs, LEN_EX_TYPE);
       
   458 
       
   459   switch(extType)
       
   460   {
       
   461     case EX_FILL_DATA:
       
   462     default:
       
   463       if(sbrStream && !ReadSBRExtensionData(bs, sbrStream, extType, prevEleID, cnt))
       
   464       {
       
   465 
       
   466       BsGetBits(bs, LEN_NIBBLE);
       
   467       BsSkipNBits(bs, (cnt - 1) << 3); 
       
   468       break;  
       
   469 
       
   470       }
       
   471       else if (!sbrStream)
       
   472       {
       
   473       BsGetBits(bs, LEN_NIBBLE);
       
   474       BsSkipNBits(bs, (cnt - 1) << 3); 
       
   475       break;
       
   476           
       
   477       }
       
   478       
       
   479       
       
   480       
       
   481   }
       
   482 
       
   483   return (cnt);
       
   484 }
       
   485 
       
   486 /*
       
   487  * Reads fill data from the bitstream.
       
   488  */
       
   489 void
       
   490 CAACAudDec::GetFIL(TBitStream *bs, uint32 prevEleID)
       
   491 {
       
   492   int32 cnt;
       
   493   
       
   494   cnt = BsGetBits(bs, LEN_F_CNT);
       
   495   if(cnt == (1 << LEN_F_CNT) - 1)
       
   496     cnt += BsGetBits(bs, LEN_F_ESC) - 1;
       
   497 
       
   498   while(cnt > 0)
       
   499     cnt -= extension_payload(bs, cnt, prevEleID);
       
   500 }
       
   501 
       
   502 /*
       
   503  * Reads program configuration element from the specified bitstream.
       
   504  */
       
   505 int16
       
   506 GetPCE(TBitStream *bs, TProgConfig *p)
       
   507 {
       
   508   int16 i;
       
   509 
       
   510   p->pce_present = TRUE;
       
   511   p->tag = (int16) BsGetBits(bs, LEN_TAG);
       
   512   p->profile = (int16) BsGetBits(bs, LEN_PROFILE);
       
   513   p->sample_rate_idx = (int16) BsGetBits(bs, LEN_SAMP_IDX);
       
   514   p->front.num_ele = (int16) BsGetBits(bs, LEN_NUM_ELE);
       
   515   p->side.num_ele = (int16) BsGetBits(bs, LEN_NUM_ELE);
       
   516   p->back.num_ele = (int16) BsGetBits(bs, LEN_NUM_ELE);
       
   517   p->lfe.num_ele = (int16) BsGetBits(bs, LEN_NUM_LFE);
       
   518   p->data.num_ele = (int16) BsGetBits(bs, LEN_NUM_DAT);
       
   519   p->coupling.num_ele = (int16) BsGetBits(bs, LEN_NUM_CCE);
       
   520 
       
   521   p->mono_mix.present = (int16) BsGetBits(bs, 1);
       
   522   if(p->mono_mix.present == 1)
       
   523     p->mono_mix.ele_tag = (int16) BsGetBits(bs, LEN_TAG);
       
   524 
       
   525   p->stereo_mix.present = (int16) BsGetBits(bs, 1);
       
   526   if(p->stereo_mix.present == 1)
       
   527     p->stereo_mix.ele_tag = (int16) BsGetBits(bs, LEN_TAG);
       
   528 
       
   529   p->matrix_mix.present = (int16) BsGetBits(bs, 1);
       
   530   if(p->matrix_mix.present == 1)
       
   531   {
       
   532     p->matrix_mix.ele_tag = (int16) BsGetBits(bs, LEN_MMIX_IDX);
       
   533     p->matrix_mix.pseudo_enab = (int16) BsGetBits(bs, LEN_PSUR_ENAB);
       
   534   }
       
   535 
       
   536   for(i = 0; i < p->front.num_ele; i++)
       
   537   {
       
   538     p->front.ele_is_cpe[i] = (int16) BsGetBits(bs, LEN_ELE_IS_CPE);
       
   539     p->front.ele_tag[i] = (int16) BsGetBits(bs, LEN_TAG);
       
   540   }
       
   541 
       
   542   for(i = 0; i < p->side.num_ele; i++)
       
   543   {
       
   544     p->side.ele_is_cpe[i] = (int16) BsGetBits(bs, LEN_ELE_IS_CPE);
       
   545     p->side.ele_tag[i] = (int16) BsGetBits(bs, LEN_TAG);
       
   546   }
       
   547 
       
   548   for(i = 0; i < p->back.num_ele; i++)
       
   549   {
       
   550     p->back.ele_is_cpe[i] = (int16) BsGetBits(bs, LEN_ELE_IS_CPE);
       
   551     p->back.ele_tag[i] = (int16) BsGetBits(bs, LEN_TAG);
       
   552   }
       
   553 
       
   554   for(i = 0; i < p->lfe.num_ele; i++)
       
   555   {
       
   556     p->lfe.ele_is_cpe[i] = 0;
       
   557     p->lfe.ele_tag[i] = (int16) BsGetBits(bs, LEN_TAG);
       
   558   }
       
   559 
       
   560   for(i = 0; i < p->data.num_ele; i++)
       
   561   {
       
   562     p->data.ele_is_cpe[i] = 0;
       
   563     p->data.ele_tag[i] = (int16) BsGetBits(bs, LEN_TAG);
       
   564   }
       
   565 
       
   566   for(i = 0; i < p->coupling.num_ele; i++)
       
   567   {
       
   568     p->coupling.ele_is_cpe[i] = (int16) BsGetBits(bs, LEN_ELE_IS_CPE);
       
   569     p->coupling.ele_tag[i] = (int16) BsGetBits(bs, LEN_TAG);
       
   570   }
       
   571 
       
   572   BsByteAlign(bs);
       
   573 
       
   574   p->num_comment_bytes = (int16) BsGetBits(bs, LEN_COMMENT_BYTES);
       
   575   BsSkipNBits(bs, p->num_comment_bytes << 3);
       
   576 
       
   577   return (p->tag);
       
   578 }
       
   579 
       
   580 /**
       
   581  * Saves the start position of the channel element within the AAC frame.
       
   582  */
       
   583 static void
       
   584 SaveSBRChannelElementPos(SbrBitStream *sbrStream, uint32 bitOffset, uint32 ele_id)
       
   585 {
       
   586   if(sbrStream->NrElements < MAX_NR_ELEMENTS)
       
   587   {
       
   588     /*-- Save starting position of the channel element. --*/
       
   589     sbrStream->sbrElement[sbrStream->NrElements].elementOffset = bitOffset - 3;  
       
   590     sbrStream->sbrElement[sbrStream->NrElements].ElementID = ele_id;
       
   591   }
       
   592 }
       
   593 
       
   594 /**
       
   595  * Saves the length of the channel element within the AAC frame.
       
   596  */
       
   597 static void
       
   598 SaveSBRChannelElementLen(SbrBitStream *sbrStream, uint32 presentPos)
       
   599 {
       
   600   if(sbrStream->NrElements < MAX_NR_ELEMENTS)
       
   601   {
       
   602     /*-- Save length of the channel element. --*/
       
   603     sbrStream->sbrElement[sbrStream->NrElements].chElementLen = 
       
   604       presentPos - sbrStream->sbrElement[sbrStream->NrElements].elementOffset;
       
   605   }
       
   606 }
       
   607 /**************************************************************************
       
   608   Title        : CountAACChunkLength
       
   609 
       
   610   Purpose      : Counts the number of bytes reserved for the payload part of
       
   611                  current AAC frame. This functions should only be called if
       
   612                  no other methods exist to determine the payload legth
       
   613                  (e.g., ADIF does not include this kind of information).
       
   614 
       
   615   Usage        : y = CountAACChunkLength(bs, aac, bytesInFrame)
       
   616 
       
   617   Input        : bs           - input bitstream
       
   618                  aac          - AAC decoder parameters
       
   619   
       
   620   Output       : y            - status of operation
       
   621                  bytesInFrame - # of bytes reserved for this frame
       
   622 
       
   623   Author(s)    : Juha Ojanpera
       
   624   *************************************************************************/
       
   625 
       
   626 EXPORT_C int16
       
   627 CountAACChunkLength(TBitStream *bs, CAACAudDec *aac, int16 *bytesInFrame)
       
   628 {
       
   629   uint32 bitsRead;
       
   630   int16 frameStatus;
       
   631 
       
   632   /*-- Save the status of input bitstream. --*/
       
   633   bitsRead = BsGetBitsRead(bs);
       
   634 
       
   635   /*-- Parse the frame. --*/
       
   636   frameStatus = (!GetAACGlobalGains(bs, aac, 15, NULL, NULL)) ? (int16) 0 : (int16) 1;
       
   637   ResetMCInfo(aac->mc_info);
       
   638 
       
   639   /*-- Determine the # of bytes for this frame. --*/
       
   640   bitsRead = BsGetBitsRead(bs) - bitsRead;
       
   641   *bytesInFrame = (int16) ((bitsRead >> 3) + ((bitsRead & 0x7) ? 1 : 0));
       
   642 
       
   643   return (frameStatus);
       
   644 }
       
   645 
       
   646 /**************************************************************************
       
   647   Title        : GetAACGlobalGains
       
   648 
       
   649   Purpose      : Extracts 'global_gain' bitstream elements from the specified
       
   650                  AAC data buffer.
       
   651 
       
   652   Usage        : y = GetAACGlobalGains(bs, aac, nBufs, globalGain, globalGainPos)
       
   653 
       
   654   Input        : bs            - input bitstream
       
   655                  aac           - AAC decoder handle
       
   656                  nBufs         - # of gain buffers present
       
   657   
       
   658   Output       : y             - # of gain elements extracted
       
   659                  globalGain    - 'global_gain' elements
       
   660                  globalGainPos - position location (in bits) of each gain value.
       
   661                                  This information is used when storing the gain 
       
   662                                  elements back to bitstream.
       
   663 
       
   664   Author(s)    : Juha Ojanpera
       
   665   *************************************************************************/
       
   666 
       
   667 EXPORT_C uint8
       
   668 GetAACGlobalGains(TBitStream* bs, CAACAudDec *aac, uint8 nBufs, uint8 *globalGain, uint32 *globalGainPos)
       
   669 {
       
   670   uint8 numGains;
       
   671   uint8 loopControl;
       
   672   TProgConfig progCfg;
       
   673   CMC_Info *mip = aac->mc_info;
       
   674   uint32 ele_id, prevEleID, bufBitOffset;
       
   675 
       
   676   numGains = 0;
       
   677   loopControl = 0;
       
   678   prevEleID = ID_END;
       
   679   bufBitOffset = BsGetBitsRead(bs);
       
   680 
       
   681   /*-- Reset some modules. --*/
       
   682   ResetMCInfo(mip);
       
   683 
       
   684   /*-- No SBR elements present by default. --*/
       
   685   if(aac->sbrStream)
       
   686     aac->sbrStream->NrElements = 0;
       
   687 
       
   688   /*-- Loop until termination code found. --*/
       
   689   while((ele_id = BsGetBits(bs, LEN_SE_ID)) != ID_END)
       
   690   {
       
   691     int16 parserErr;
       
   692 
       
   693     if(loopControl > 64) break;
       
   694 
       
   695     /*-- Get audio syntactic element. --*/
       
   696     switch(ele_id)
       
   697     {
       
   698       /*-- Single and lfe channel. --*/
       
   699       case ID_SCE:
       
   700       case ID_LFE:
       
   701         if((numGains + 1) > nBufs) break;
       
   702 
       
   703         if(aac->sbrStream)
       
   704           SaveSBRChannelElementPos(aac->sbrStream, BsGetBitsRead(bs) - bufBitOffset, ele_id);
       
   705 
       
   706         if(globalGain)
       
   707           parserErr = GetSCEGain(aac, bs, &globalGain[numGains], &globalGainPos[numGains], bufBitOffset);
       
   708         else
       
   709           parserErr = GetSCE(aac, bs, mip, NULL, NULL, 0);
       
   710 
       
   711         if(parserErr < 0)
       
   712           goto f_out;
       
   713         numGains += 1;
       
   714 
       
   715         if(aac->sbrStream)
       
   716           SaveSBRChannelElementLen(aac->sbrStream, BsGetBitsRead(bs));
       
   717         break;
       
   718 
       
   719       /*-- Channel pair element. --*/
       
   720       case ID_CPE:
       
   721         if((numGains + 2) > nBufs) break;
       
   722         if(aac->sbrStream)
       
   723           SaveSBRChannelElementPos(aac->sbrStream, BsGetBitsRead(bs) - bufBitOffset, ele_id);
       
   724 
       
   725         if(globalGain)
       
   726           parserErr = GetCPEGain(aac, bs, &globalGain[numGains], &globalGainPos[numGains], bufBitOffset);
       
   727         else
       
   728           parserErr = GetCPE(aac, bs, mip, NULL, NULL, 0);
       
   729 
       
   730         if(parserErr < 0)
       
   731           goto f_out;
       
   732         numGains += 2;
       
   733 
       
   734         if(aac->sbrStream)
       
   735           SaveSBRChannelElementLen(aac->sbrStream, BsGetBitsRead(bs));
       
   736         break;
       
   737 
       
   738       /*-- Coupling channel. --*/
       
   739       case ID_CCE:
       
   740         if(GetCCE(aac, bs, mip, aac->ccInfo) < 0)
       
   741           goto f_out;
       
   742         break;
       
   743 
       
   744       /*-- Data element. --*/
       
   745       case ID_DSE:
       
   746         loopControl++;
       
   747         GetDSE(bs);
       
   748         break;
       
   749 
       
   750       /*-- Program config element. --*/
       
   751       case ID_PCE:
       
   752         loopControl++;
       
   753         GetPCE(bs, &progCfg);
       
   754         break;
       
   755 
       
   756       /*-- Fill element. --*/
       
   757       case ID_FIL:
       
   758         loopControl++;
       
   759         TInt error;
       
   760         TRAP( error, aac->GetFIL(bs, prevEleID) );
       
   761         if (error != KErrNone)
       
   762             goto f_out;
       
   763         break;
       
   764     
       
   765       default:
       
   766         goto f_out;
       
   767     }
       
   768 
       
   769     prevEleID = ele_id;
       
   770 
       
   771     bufBitOffset = BsGetBitsRead(bs) - bufBitOffset;
       
   772   }
       
   773 
       
   774   BsByteAlign(bs);
       
   775 
       
   776 f_out:
       
   777   
       
   778   return (numGains);
       
   779 }
       
   780 
       
   781 /*
       
   782  * Stores 'global_gain' bitstream elements to AAC data buffer.
       
   783  */
       
   784 INLINE void 
       
   785 SetAACGain(TBitStream* bs, uint32 gainPos, uint8 globalGains)
       
   786 {  
       
   787   BsSkipNBits(bs, gainPos); 
       
   788   BsPutBits(bs, LEN_SCL_PCM, globalGains); 
       
   789 }
       
   790 
       
   791 /*
       
   792  * Saves modified 'global_gain' bitstream elements to specified AAC data buffer.
       
   793  */
       
   794 EXPORT_C void
       
   795 SetAACGlobalGains(TBitStream* bs, uint8 numGains, uint8 *globalGain, uint32 *globalGainPos)
       
   796 {
       
   797   int16 i;
       
   798   TBitStream bsIn;
       
   799 
       
   800   BsSaveBufState(bs, &bsIn);
       
   801 
       
   802   /*-- Store the gain element back to bitstream. --*/ 
       
   803   for(i = 0; i < numGains; i++)
       
   804     SetAACGain(bs, globalGainPos[i], globalGain[i]);
       
   805 
       
   806   
       
   807 }
       
   808 
       
   809 /*
       
   810  * Retrieves sample rate index corresponding to the specified sample rate.
       
   811  */
       
   812 INLINE uint8
       
   813 GetSampleRateIndex(int32 sampleRate)
       
   814 {
       
   815   uint8 sIndex = 0xF;
       
   816 
       
   817   switch(sampleRate)
       
   818   {
       
   819     case 96000:
       
   820       sIndex = 0x0;
       
   821       break;
       
   822 
       
   823     case 88200:
       
   824       sIndex = 0x1;
       
   825       break;
       
   826 
       
   827     case 64000:
       
   828       sIndex = 0x2;
       
   829       break;
       
   830 
       
   831     case 48000:
       
   832       sIndex = 0x3;
       
   833       break;
       
   834 
       
   835     case 44100:
       
   836       sIndex = 0x4;
       
   837       break;
       
   838 
       
   839     case 32000:
       
   840       sIndex = 0x5;
       
   841       break;
       
   842 
       
   843     case 24000:
       
   844       sIndex = 0x6;
       
   845       break;
       
   846 
       
   847     case 22050:
       
   848       sIndex = 0x7;
       
   849       break;
       
   850 
       
   851     case 16000:
       
   852       sIndex = 0x8;
       
   853       break;
       
   854 
       
   855     case 12000:
       
   856       sIndex = 0x9;
       
   857       break;
       
   858 
       
   859     case 11025:
       
   860       sIndex = 0xa;
       
   861       break;
       
   862 
       
   863     case 8000:
       
   864       sIndex = 0xb;
       
   865       break;
       
   866   }
       
   867 
       
   868   return (sIndex);
       
   869 }
       
   870 
       
   871 INLINE int16
       
   872 WriteGASpecificConfig(TBitStream *bsOut, int16 bitsWritten, int16 frameLen)
       
   873 { 
       
   874   /*-- Frame length flag (1024-point or 960-point MDCT). --*/
       
   875   bitsWritten += 1;
       
   876   BsPutBits(bsOut, 1, (frameLen == LN2) ? 0 : 1);
       
   877   
       
   878   /*-- No core coder. --*/
       
   879   bitsWritten += 1;
       
   880   BsPutBits(bsOut, 1, 0);
       
   881   
       
   882   /*-- No extension flag. --*/
       
   883   bitsWritten += 1;
       
   884   BsPutBits(bsOut, 1, 0);
       
   885   
       
   886   return (bitsWritten);
       
   887 }
       
   888 
       
   889 
       
   890 
       
   891 EXPORT_C int16
       
   892 AACGetMP4ConfigInfo(int32 sampleRate, uint8 profile, uint8 nChannels, 
       
   893                     int16 frameLen, uint8 *pBuf, uint8 nBytesInBuf)
       
   894 {
       
   895   TBitStream bsOut;
       
   896   int16 nConfigBytes, bitsWritten;
       
   897 
       
   898   BsInit(&bsOut, pBuf, nBytesInBuf);
       
   899 
       
   900   /*-- Object type. --*/
       
   901   bitsWritten = 5;
       
   902   BsPutBits(&bsOut, 5, profile + 1);
       
   903 
       
   904   /*-- Sample rate index. --*/
       
   905   bitsWritten += 4;
       
   906   BsPutBits(&bsOut, 4, GetSampleRateIndex(sampleRate));
       
   907   if(GetSampleRateIndex(sampleRate) == 0xF)
       
   908   {
       
   909     bitsWritten += 24;
       
   910     BsPutBits(&bsOut, 24, sampleRate);
       
   911   }
       
   912   
       
   913   /*-- # of channels. --*/
       
   914   bitsWritten += 4;
       
   915   BsPutBits(&bsOut, 4, nChannels);
       
   916 
       
   917   /*-- Write GA specific info. --*/
       
   918   bitsWritten = WriteGASpecificConfig(&bsOut, bitsWritten, frameLen);
       
   919 
       
   920   nConfigBytes = int16 ((bitsWritten & 7) ? (bitsWritten >> 3) + 1 : (bitsWritten >> 3));
       
   921 
       
   922   return (nConfigBytes);
       
   923 }
       
   924 
       
   925 /*
       
   926  * Saves modified 'global_gain' bitstream elements to specified AAC data buffer.
       
   927  */
       
   928 EXPORT_C void
       
   929 SetAACPlusGlobalGains(TBitStream* bs, TBitStream* bsOut, CAACAudDec *aac, int16 gainChangeValue, 
       
   930                   uint8 numGains, uint8 *globalGain, uint32 *globalGainPos)
       
   931     {
       
   932     int16 i;
       
   933     TBitStream bsIn;
       
   934 
       
   935     BsSaveBufState(bs, &bsIn);
       
   936 
       
   937     /*-- Store the gain element back to bitstream. --*/ 
       
   938     for(i = 0; i < numGains; i++)
       
   939         {
       
   940         SetAACGain(bs, globalGainPos[i], globalGain[i]);
       
   941         }
       
   942         
       
   943 
       
   944     if(aac->sbrStream && aac->sbrDecInfo)
       
   945           {
       
   946     
       
   947         if(aac->sbrStream->NrElements)
       
   948             {
       
   949               ParseSBR(&bsIn, bsOut, aac->sbrDecInfo, aac->sbrStream, gainChangeValue);
       
   950             }
       
   951       
       
   952       
       
   953         }
       
   954 
       
   955       }
       
   956 
       
   957 
       
   958 EXPORT_C uint8
       
   959 IsAACParametricStereoEnabled(CAACAudDec *aac)
       
   960     {
       
   961 
       
   962     return (IsSBRParametricStereoEnabled(aac->sbrDecInfo, aac->sbrStream));
       
   963 
       
   964     }
       
   965 
       
   966 EXPORT_C uint8
       
   967 IsAACSBREnabled(CAACAudDec *aac)
       
   968     {
       
   969 
       
   970     return (IsSBREnabled(aac->sbrStream));
       
   971 
       
   972 
       
   973     }