Home | History | Annotate | Download | only in src
      1 
      2 /* -----------------------------------------------------------------------------------------------------------
      3 Software License for The Fraunhofer FDK AAC Codec Library for Android
      4 
      5  Copyright  1995 - 2012 Fraunhofer-Gesellschaft zur Frderung der angewandten Forschung e.V.
      6   All rights reserved.
      7 
      8  1.    INTRODUCTION
      9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
     10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
     11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
     12 
     13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
     14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
     15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
     16 of the MPEG specifications.
     17 
     18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
     19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
     20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
     21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
     22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
     23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
     24 
     25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
     26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
     27 applications information and documentation.
     28 
     29 2.    COPYRIGHT LICENSE
     30 
     31 Redistribution and use in source and binary forms, with or without modification, are permitted without
     32 payment of copyright license fees provided that you satisfy the following conditions:
     33 
     34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
     35 your modifications thereto in source code form.
     36 
     37 You must retain the complete text of this software license in the documentation and/or other materials
     38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
     39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
     40 modifications thereto to recipients of copies in binary form.
     41 
     42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
     43 prior written permission.
     44 
     45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
     46 software or your modifications thereto.
     47 
     48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
     49 and the date of any change. For modified versions of the FDK AAC Codec, the term
     50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
     51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
     52 
     53 3.    NO PATENT LICENSE
     54 
     55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
     56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
     57 respect to this software.
     58 
     59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
     60 by appropriate patent licenses.
     61 
     62 4.    DISCLAIMER
     63 
     64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
     65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
     66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
     68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
     69 or business interruption, however caused and on any theory of liability, whether in contract, strict
     70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
     71 advised of the possibility of such damage.
     72 
     73 5.    CONTACT INFORMATION
     74 
     75 Fraunhofer Institute for Integrated Circuits IIS
     76 Attention: Audio and Multimedia Departments - FDK AAC LL
     77 Am Wolfsmantel 33
     78 91058 Erlangen, Germany
     79 
     80 www.iis.fraunhofer.de/amm
     81 amm-info (at) iis.fraunhofer.de
     82 ----------------------------------------------------------------------------------------------------------- */
     83 
     84 /*****************************  MPEG-4 AAC Decoder  **************************
     85 
     86    Author(s):   Daniel Homm
     87    Description:
     88 
     89 ******************************************************************************/
     90 
     91 #include "tpdec_lib.h"
     92 #include "tp_data.h"
     93 
     94 
     95 void CProgramConfig_Reset(CProgramConfig *pPce)
     96 {
     97   pPce->elCounter = 0;
     98 }
     99 
    100 void CProgramConfig_Init(CProgramConfig *pPce)
    101 {
    102   FDKmemclear(pPce, sizeof(CProgramConfig));
    103 #ifdef TP_PCE_ENABLE
    104   pPce->SamplingFrequencyIndex = 0xf;
    105 #endif
    106 }
    107 
    108 int  CProgramConfig_IsValid ( const CProgramConfig *pPce )
    109 {
    110   return ( (pPce->isValid) ? 1 : 0);
    111 }
    112 
    113 #ifdef TP_PCE_ENABLE
    114 void CProgramConfig_Read(
    115                           CProgramConfig *pPce,
    116                           HANDLE_FDK_BITSTREAM bs,
    117                           UINT alignmentAnchor
    118                         )
    119 {
    120   int i;
    121 
    122   pPce->NumEffectiveChannels = 0;
    123   pPce->NumChannels = 0;
    124   pPce->ElementInstanceTag = (UCHAR) FDKreadBits(bs,4);
    125   pPce->Profile = (UCHAR) FDKreadBits(bs,2);
    126   pPce->SamplingFrequencyIndex = (UCHAR) FDKreadBits(bs,4);
    127   pPce->NumFrontChannelElements = (UCHAR) FDKreadBits(bs,4);
    128   pPce->NumSideChannelElements = (UCHAR) FDKreadBits(bs,4);
    129   pPce->NumBackChannelElements = (UCHAR) FDKreadBits(bs,4);
    130   pPce->NumLfeChannelElements = (UCHAR) FDKreadBits(bs,2);
    131   pPce->NumAssocDataElements = (UCHAR) FDKreadBits(bs,3);
    132   pPce->NumValidCcElements = (UCHAR) FDKreadBits(bs,4);
    133 
    134   if ((pPce->MonoMixdownPresent = (UCHAR) FDKreadBits(bs,1)) != 0)
    135   {
    136     pPce->MonoMixdownElementNumber = (UCHAR) FDKreadBits(bs,4);
    137   }
    138 
    139   if ((pPce->StereoMixdownPresent = (UCHAR) FDKreadBits(bs,1)) != 0)
    140   {
    141     pPce->StereoMixdownElementNumber = (UCHAR) FDKreadBits(bs,4);
    142   }
    143 
    144   if ((pPce->MatrixMixdownIndexPresent = (UCHAR) FDKreadBits(bs,1)) != 0)
    145   {
    146     pPce->MatrixMixdownIndex = (UCHAR) FDKreadBits(bs,2);
    147     pPce->PseudoSurroundEnable = (UCHAR) FDKreadBits(bs,1);
    148   }
    149 
    150   for (i=0; i < pPce->NumFrontChannelElements; i++)
    151   {
    152     pPce->FrontElementIsCpe[i] = (UCHAR) FDKreadBits(bs,1);
    153     pPce->FrontElementTagSelect[i] = (UCHAR) FDKreadBits(bs,4);
    154     pPce->NumChannels += pPce->FrontElementIsCpe[i] ? 2 : 1;
    155   }
    156 
    157   for (i=0; i < pPce->NumSideChannelElements; i++)
    158   {
    159     pPce->SideElementIsCpe[i] = (UCHAR) FDKreadBits(bs,1);
    160     pPce->SideElementTagSelect[i] = (UCHAR) FDKreadBits(bs,4);
    161     pPce->NumChannels += pPce->SideElementIsCpe[i] ? 2 : 1;
    162   }
    163 
    164   for (i=0; i < pPce->NumBackChannelElements; i++)
    165   {
    166     pPce->BackElementIsCpe[i] = (UCHAR) FDKreadBits(bs,1);
    167     pPce->BackElementTagSelect[i] = (UCHAR) FDKreadBits(bs,4);
    168     pPce->NumChannels += pPce->BackElementIsCpe[i] ? 2 : 1;
    169   }
    170 
    171   pPce->NumEffectiveChannels = pPce->NumChannels;
    172 
    173   for (i=0; i < pPce->NumLfeChannelElements; i++)
    174   {
    175     pPce->LfeElementTagSelect[i] = (UCHAR) FDKreadBits(bs,4);
    176     pPce->NumChannels += 1;
    177   }
    178 
    179   for (i=0; i < pPce->NumAssocDataElements; i++)
    180   {
    181     pPce->AssocDataElementTagSelect[i] = (UCHAR) FDKreadBits(bs,4);
    182   }
    183 
    184   for (i=0; i < pPce->NumValidCcElements; i++)
    185   {
    186     pPce->CcElementIsIndSw[i] = (UCHAR) FDKreadBits(bs,1);
    187     pPce->ValidCcElementTagSelect[i] = (UCHAR) FDKreadBits(bs,4);
    188   }
    189 
    190   FDKbyteAlign(bs, alignmentAnchor);
    191 
    192   pPce->CommentFieldBytes = (UCHAR) FDKreadBits(bs,8);
    193 
    194   for (i=0; i < pPce->CommentFieldBytes; i++)
    195   {
    196     UCHAR text;
    197 
    198     text = (UCHAR)FDKreadBits(bs,8);
    199 
    200     if (i < PC_COMMENTLENGTH)
    201     {
    202       pPce->Comment[i] = text;
    203     }
    204   }
    205 
    206   pPce->isValid = 1;
    207 }
    208 #endif /* TP_PCE_ENABLE */
    209 
    210 /**
    211  * \brief get implicit audio channel type for given channelConfig and MPEG ordered channel index
    212  * \param channelConfig MPEG channelConfiguration from 1 upto 7
    213  * \param index MPEG channel order index
    214  * \return audio channel type.
    215  */
    216 void getImplicitAudioChannelTypeAndIndex(
    217         AUDIO_CHANNEL_TYPE *chType,
    218         UCHAR *chIndex,
    219         UINT channelConfig,
    220         UINT index
    221         )
    222 {
    223   if (index < 3) {
    224     *chType = ACT_FRONT;
    225     *chIndex = index;
    226   } else {
    227     switch (channelConfig) {
    228       case MODE_1_2_1:
    229       case MODE_1_2_2:
    230       case MODE_1_2_2_1:
    231         switch (index) {
    232           case 3:
    233           case 4:
    234             *chType = ACT_BACK;
    235             *chIndex = index - 3;
    236             break;
    237           case 5:
    238             *chType = ACT_LFE;
    239             *chIndex = 0;
    240             break;
    241         }
    242         break;
    243       case MODE_1_2_2_2_1:
    244         switch (index) {
    245           case 3:
    246           case 4:
    247             *chType = ACT_SIDE;
    248             *chIndex = index - 3;
    249             break;
    250           case 5:
    251           case 6:
    252             *chType = ACT_BACK;
    253             *chIndex = index - 5;
    254             break;
    255           case 7:
    256             *chType = ACT_LFE;
    257             *chIndex = 0;
    258             break;
    259         }
    260         break;
    261       default:
    262         *chType = ACT_NONE;
    263         break;
    264     }
    265   }
    266 }
    267 
    268 int CProgramConfig_LookupElement(
    269         CProgramConfig *pPce,
    270         const UINT      channelConfig,
    271         const UINT      tag,
    272         const UINT      channelIdx,
    273         UCHAR           chMapping[],
    274         AUDIO_CHANNEL_TYPE chType[],
    275         UCHAR           chIndex[],
    276         UCHAR          *elMapping,
    277         MP4_ELEMENT_ID  elList[],
    278         MP4_ELEMENT_ID  elType
    279        )
    280 {
    281   if (channelConfig > 0)
    282   {
    283     /* Constant channel mapping must have
    284        been set during initialization. */
    285     if ( elType == ID_SCE
    286       || elType == ID_CPE
    287       || elType == ID_LFE )
    288     {
    289       *elMapping = pPce->elCounter;
    290       if (elList[pPce->elCounter] != elType) {
    291         /* Not in the list */
    292         return 0;
    293       }
    294       /* Assume all front channels */
    295       getImplicitAudioChannelTypeAndIndex(&chType[channelIdx], &chIndex[channelIdx], channelConfig, channelIdx);
    296       if (elType == ID_CPE) {
    297         chType[channelIdx+1] = chType[channelIdx];
    298         chIndex[channelIdx+1] = chIndex[channelIdx]+1;
    299       }
    300       pPce->elCounter++;
    301     }
    302     /* Accept all non-channel elements, too. */
    303     return 1;
    304   }
    305   else
    306   {
    307 #ifdef TP_PCE_ENABLE
    308     if (!pPce->isValid)
    309 #endif /* TP_PCE_ENABLE */
    310     {
    311       /* Implicit channel mapping. */
    312       if ( elType == ID_SCE
    313         || elType == ID_CPE
    314         || elType == ID_LFE )
    315       {
    316         /* Store all channel element IDs */
    317         elList[pPce->elCounter] = elType;
    318         *elMapping = pPce->elCounter++;
    319       }
    320     }
    321 #ifdef  TP_PCE_ENABLE
    322     else {
    323       /* Accept the additional channel(s), only if the tag is in the lists */
    324       int isCpe = 0, i;
    325       int cc = 0, fc = 0, sc = 0, bc = 0, lc = 0, ec = 0; /* Channel and element counters */
    326 
    327       switch (elType)
    328       {
    329       case ID_CPE:
    330         isCpe = 1;
    331       case ID_SCE:
    332         /* search in front channels */
    333         for (i = 0; i < pPce->NumFrontChannelElements; i++) {
    334           if (isCpe == pPce->FrontElementIsCpe[i] && pPce->FrontElementTagSelect[i] == tag) {
    335             chMapping[cc] = channelIdx;
    336             chType[cc] = ACT_FRONT;
    337             chIndex[cc] = fc;
    338             if (isCpe) {
    339               chMapping[cc+1] = channelIdx+1;
    340               chType[cc+1] = ACT_FRONT;
    341               chIndex[cc+1] = fc+1;
    342             }
    343             *elMapping = ec;
    344             return 1;
    345           }
    346           ec++;
    347           if (pPce->FrontElementIsCpe[i]) {
    348             cc+=2; fc+=2;
    349           } else {
    350             cc++; fc++;
    351           }
    352         }
    353         /* search in side channels */
    354         for (i = 0; i < pPce->NumSideChannelElements; i++) {
    355           if (isCpe == pPce->SideElementIsCpe[i] && pPce->SideElementTagSelect[i] == tag) {
    356             chMapping[cc] = channelIdx;
    357             chType[cc] = ACT_SIDE;
    358             chIndex[cc] = sc;
    359             if (isCpe) {
    360               chMapping[cc+1] = channelIdx+1;
    361               chType[cc+1] = ACT_SIDE;
    362               chIndex[cc+1] = sc+1;
    363             }
    364             *elMapping = ec;
    365             return 1;
    366           }
    367           ec++;
    368           if (pPce->SideElementIsCpe[i]) {
    369             cc+=2; sc+=2;
    370           } else {
    371             cc++; sc++;
    372           }
    373         }
    374         /* search in back channels */
    375         for (i = 0; i < pPce->NumBackChannelElements; i++) {
    376           if (isCpe == pPce->BackElementIsCpe[i] && pPce->BackElementTagSelect[i] == tag) {
    377             chMapping[cc] = channelIdx;
    378             chType[cc] = ACT_BACK;
    379             chIndex[cc] = bc;
    380             if (isCpe) {
    381               chMapping[cc+1] = channelIdx+1;
    382               chType[cc+1] = ACT_BACK;
    383               chIndex[cc+1] = bc+1;
    384             }
    385             *elMapping = ec;
    386             return 1;
    387           }
    388           ec++;
    389           if (pPce->BackElementIsCpe[i]) {
    390             cc+=2; bc+=2;
    391           } else {
    392             cc++; bc++;
    393           }
    394         }
    395         break;
    396 
    397       case ID_LFE:
    398         /* Initialize channel counter and element counter */
    399         cc = pPce->NumEffectiveChannels;
    400         ec = pPce->NumFrontChannelElements+ pPce->NumSideChannelElements + pPce->NumBackChannelElements;
    401         /* search in lfe channels */
    402         for (i = 0; i < pPce->NumLfeChannelElements; i++) {
    403           if ( pPce->LfeElementTagSelect[i] == tag ) {
    404             chMapping[cc] = channelIdx;
    405             *elMapping = ec;
    406             chType[cc] = ACT_LFE;
    407             chIndex[cc] = lc;
    408             return 1;
    409           }
    410           ec++;
    411           cc++;
    412           lc++;
    413         }
    414         break;
    415 
    416       /* Non audio elements */
    417       case ID_CCE:
    418         /* search in cce channels */
    419         for (i = 0; i < pPce->NumValidCcElements; i++) {
    420           if (pPce->ValidCcElementTagSelect[i] == tag) {
    421             return 1;
    422           }
    423         }
    424         break;
    425       case ID_DSE:
    426         /* search associated data elements */
    427         for (i = 0; i < pPce->NumAssocDataElements; i++) {
    428           if (pPce->AssocDataElementTagSelect[i] == tag) {
    429             return 1;
    430           }
    431         }
    432         break;
    433       default:
    434         return 0;
    435       }
    436       return 0;  /* not found in any list */
    437     }
    438 #endif /* TP_PCE_ENABLE */
    439   }
    440 
    441   return 1;
    442 }
    443 
    444 #ifdef  TP_PCE_ENABLE
    445 int CProgramConfig_GetElementTable(
    446         const CProgramConfig *pPce,
    447         MP4_ELEMENT_ID  elList[],
    448         const INT elListSize
    449        )
    450 {
    451   int i, el = 0;
    452 
    453   if ( elListSize
    454     < pPce->NumFrontChannelElements + pPce->NumSideChannelElements + pPce->NumBackChannelElements + pPce->NumLfeChannelElements
    455     )
    456   {
    457     return 0;
    458   }
    459 
    460   for (i=0; i < pPce->NumFrontChannelElements; i++)
    461   {
    462     elList[el++] = (pPce->FrontElementIsCpe[i]) ?  ID_CPE : ID_SCE;
    463   }
    464 
    465   for (i=0; i < pPce->NumSideChannelElements; i++)
    466   {
    467     elList[el++] = (pPce->SideElementIsCpe[i]) ?  ID_CPE : ID_SCE;
    468   }
    469 
    470   for (i=0; i < pPce->NumBackChannelElements; i++)
    471   {
    472     elList[el++] = (pPce->BackElementIsCpe[i]) ?  ID_CPE : ID_SCE;
    473   }
    474 
    475   for (i=0; i < pPce->NumLfeChannelElements; i++)
    476   {
    477     elList[el++] = ID_LFE;
    478   }
    479 
    480 
    481   return el;
    482 }
    483 #endif
    484 
    485 static AUDIO_OBJECT_TYPE getAOT(HANDLE_FDK_BITSTREAM bs)
    486 {
    487   int tmp = 0;
    488 
    489   tmp = FDKreadBits(bs,5);
    490   if (tmp == AOT_ESCAPE) {
    491     int tmp2 = FDKreadBits(bs,6);
    492     tmp = 32 + tmp2;
    493   }
    494 
    495   return (AUDIO_OBJECT_TYPE)tmp;
    496 }
    497 
    498 static INT getSampleRate(HANDLE_FDK_BITSTREAM bs, UCHAR *index, int nBits)
    499 {
    500   INT sampleRate;
    501   int idx;
    502 
    503   idx = FDKreadBits(bs, nBits);
    504   if( idx == (1<<nBits)-1 ) {
    505     if(FDKgetValidBits(bs) < 24) {
    506       return 0;
    507     }
    508     sampleRate = FDKreadBits(bs,24);
    509   } else {
    510     sampleRate = SamplingRateTable[idx];
    511   }
    512 
    513   *index = idx;
    514 
    515   return sampleRate;
    516 }
    517 
    518 #ifdef TP_GA_ENABLE
    519 static
    520 TRANSPORTDEC_ERROR GaSpecificConfig_Parse( CSGaSpecificConfig    *self,
    521                                            CSAudioSpecificConfig *asc,
    522                                            HANDLE_FDK_BITSTREAM   bs,
    523                                            UINT                   ascStartAnchor )
    524 {
    525   TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
    526 
    527   self->m_frameLengthFlag = FDKreadBits(bs,1);
    528 
    529   self->m_dependsOnCoreCoder = FDKreadBits(bs,1);
    530 
    531   if( self->m_dependsOnCoreCoder )
    532     self->m_coreCoderDelay = FDKreadBits(bs,14);
    533 
    534   self->m_extensionFlag = FDKreadBits(bs,1);
    535 
    536   if( asc->m_channelConfiguration == 0 ) {
    537     CProgramConfig_Read(&asc->m_progrConfigElement, bs, ascStartAnchor);
    538   }
    539 
    540   if ((asc->m_aot == AOT_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_SCAL)) {
    541     self->m_layer = FDKreadBits(bs,3);
    542   }
    543 
    544   if (self->m_extensionFlag) {
    545     if (asc->m_aot == AOT_ER_BSAC) {
    546       self->m_numOfSubFrame = FDKreadBits(bs,5);
    547       self->m_layerLength   = FDKreadBits(bs,11);
    548     }
    549 
    550     if ((asc->m_aot == AOT_ER_AAC_LC)   || (asc->m_aot == AOT_ER_AAC_LTP)  ||
    551         (asc->m_aot == AOT_ER_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_LD))
    552     {
    553       asc->m_vcb11Flag = FDKreadBits(bs,1); /* aacSectionDataResilienceFlag */
    554       asc->m_rvlcFlag  = FDKreadBits(bs,1); /* aacScalefactorDataResilienceFlag */
    555       asc->m_hcrFlag   = FDKreadBits(bs,1); /* aacSpectralDataResilienceFlag */
    556     }
    557 
    558     self->m_extensionFlag3 = FDKreadBits(bs,1);
    559 
    560   }
    561   return (ErrorStatus);
    562 }
    563 #endif /* TP_GA_ENABLE */
    564 
    565 
    566 
    567 
    568 
    569 #ifdef TP_ELD_ENABLE
    570 
    571 static INT ld_sbr_header( const CSAudioSpecificConfig *asc,
    572                            HANDLE_FDK_BITSTREAM hBs,
    573                            CSTpCallBacks *cb )
    574 {
    575   const int channelConfiguration = asc->m_channelConfiguration;
    576   int i = 0;
    577   INT error = 0;
    578 
    579   if (channelConfiguration == 2) {
    580     error = cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++);
    581   } else {
    582     error = cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_SCE, i++);
    583   }
    584 
    585   switch ( channelConfiguration ) {
    586     case 5:
    587       error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++);
    588     case 3:
    589       error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++);
    590       break;
    591 
    592     case 7:
    593       error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_SCE, i++);
    594     case 6:
    595       error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++);
    596     case 4:
    597       error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++);
    598       break;
    599   }
    600 
    601   return error;
    602 }
    603 
    604 static
    605 TRANSPORTDEC_ERROR EldSpecificConfig_Parse(
    606         CSAudioSpecificConfig *asc,
    607         HANDLE_FDK_BITSTREAM hBs,
    608         CSTpCallBacks *cb
    609         )
    610 {
    611   TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
    612   CSEldSpecificConfig *esc = &asc->m_sc.m_eldSpecificConfig;
    613   ASC_ELD_EXT_TYPE eldExtType;
    614   int eldExtLen, len, cnt;
    615 
    616   FDKmemclear(esc, sizeof(CSEldSpecificConfig));
    617 
    618   esc->m_frameLengthFlag = FDKreadBits(hBs, 1 );
    619   if (esc->m_frameLengthFlag) {
    620     asc->m_samplesPerFrame = 480;
    621   } else {
    622     asc->m_samplesPerFrame = 512;
    623   }
    624 
    625   asc->m_vcb11Flag = FDKreadBits(hBs, 1 );
    626   asc->m_rvlcFlag  = FDKreadBits(hBs, 1 );
    627   asc->m_hcrFlag   = FDKreadBits(hBs, 1 );
    628 
    629   esc->m_sbrPresentFlag     = FDKreadBits(hBs, 1 );
    630 
    631   if (esc->m_sbrPresentFlag == 1) {
    632     esc->m_sbrSamplingRate    = FDKreadBits(hBs, 1 ); /* 0: single rate, 1: dual rate */
    633     esc->m_sbrCrcFlag         = FDKreadBits(hBs, 1 );
    634 
    635     asc->m_extensionSamplingFrequency = asc->m_samplingFrequency << esc->m_sbrSamplingRate;
    636 
    637     if (cb->cbSbr != NULL){
    638       if ( 0 != ld_sbr_header(asc, hBs, cb) ) {
    639         return TRANSPORTDEC_PARSE_ERROR;
    640       }
    641     }
    642   }
    643   esc->m_useLdQmfTimeAlign = 0;
    644 
    645   /* new ELD syntax */
    646   /* parse ExtTypeConfigData */
    647   while ((eldExtType = (ASC_ELD_EXT_TYPE)FDKreadBits(hBs, 4 )) != ELDEXT_TERM) {
    648     eldExtLen = len = FDKreadBits(hBs, 4 );
    649     if ( len == 0xf ) {
    650       len = FDKreadBits(hBs, 8 );
    651       eldExtLen += len;
    652 
    653       if ( len == 0xff ) {
    654         len = FDKreadBits(hBs, 16 );
    655         eldExtLen += len;
    656       }
    657     }
    658 
    659     switch (eldExtType) {
    660       case ELDEXT_LDSAC:
    661         esc->m_useLdQmfTimeAlign = 1;
    662         if (cb->cbSsc != NULL) {
    663           ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbSsc(
    664                   cb->cbSscData,
    665                   hBs,
    666                   asc->m_aot,
    667                   asc->m_samplingFrequency,
    668                   1,  /* muxMode */
    669                   len
    670                   );
    671         } else {
    672           ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
    673         }
    674         if (ErrorStatus != TRANSPORTDEC_OK) {
    675           goto bail;
    676         }
    677         break;
    678       default:
    679         for(cnt=0; cnt<len; cnt++) {
    680           FDKreadBits(hBs, 8 );
    681         }
    682         break;
    683       /* add future eld extension configs here */
    684     }
    685   }
    686 bail:
    687   return (ErrorStatus);
    688 }
    689 #endif /* TP_ELD_ENABLE */
    690 
    691 
    692 
    693 /*
    694  * API Functions
    695  */
    696 
    697 void AudioSpecificConfig_Init(CSAudioSpecificConfig *asc)
    698 {
    699   FDKmemclear(asc, sizeof(CSAudioSpecificConfig));
    700 
    701   /* Init all values that should not be zero. */
    702   asc->m_aot                    = AOT_NONE;
    703   asc->m_samplingFrequencyIndex = 0xf;
    704   asc->m_epConfig               = -1;
    705   asc->m_extensionAudioObjectType        = AOT_NULL_OBJECT;
    706 #ifdef TP_PCE_ENABLE
    707   CProgramConfig_Init(&asc->m_progrConfigElement);
    708 #endif
    709 }
    710 
    711 TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
    712         CSAudioSpecificConfig *self,
    713         HANDLE_FDK_BITSTREAM   bs,
    714         int                    fExplicitBackwardCompatible,
    715         CSTpCallBacks      *cb
    716         )
    717 {
    718   TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
    719   UINT ascStartAnchor = FDKgetValidBits(bs);
    720   int frameLengthFlag = -1;
    721 
    722   AudioSpecificConfig_Init(self);
    723 
    724   self->m_aot = getAOT(bs);
    725   self->m_samplingFrequency = getSampleRate(bs, &self->m_samplingFrequencyIndex, 4);
    726   if (self->m_samplingFrequency <= 0) {
    727     return TRANSPORTDEC_PARSE_ERROR;
    728   }
    729 
    730   self->m_channelConfiguration = FDKreadBits(bs,4);
    731 
    732   /* SBR extension ( explicit non-backwards compatible mode ) */
    733   self->m_sbrPresentFlag = 0;
    734   self->m_psPresentFlag  = 0;
    735 
    736   if ( self->m_aot == AOT_SBR || self->m_aot == AOT_PS ) {
    737     self->m_extensionAudioObjectType = AOT_SBR;
    738 
    739     self->m_sbrPresentFlag = 1;
    740     if ( self->m_aot == AOT_PS ) {
    741       self->m_psPresentFlag = 1;
    742     }
    743 
    744     self->m_extensionSamplingFrequency = getSampleRate(bs, &self->m_extensionSamplingFrequencyIndex, 4);
    745     self->m_aot = getAOT(bs);
    746 
    747   } else {
    748     self->m_extensionAudioObjectType = AOT_NULL_OBJECT;
    749   }
    750 
    751   /* Parse whatever specific configs */
    752   switch (self->m_aot)
    753   {
    754 #ifdef TP_GA_ENABLE
    755     case AOT_AAC_LC:
    756     case AOT_ER_AAC_LC:
    757     case AOT_ER_AAC_LD:
    758     case AOT_ER_AAC_SCAL:
    759     case AOT_ER_BSAC:
    760       if ((ErrorStatus = GaSpecificConfig_Parse(&self->m_sc.m_gaSpecificConfig, self, bs, ascStartAnchor)) != TRANSPORTDEC_OK ) {
    761         return (ErrorStatus);
    762       }
    763       frameLengthFlag = self->m_sc.m_gaSpecificConfig.m_frameLengthFlag;
    764       break;
    765 #endif /* TP_GA_ENABLE */
    766     case AOT_MPEGS:
    767       if (cb->cbSsc != NULL) {
    768         cb->cbSsc(
    769                 cb->cbSscData,
    770                 bs,
    771                 self->m_aot,
    772                 self->m_samplingFrequency,
    773                 1,
    774                 0  /* don't know the length */
    775                 );
    776       } else {
    777         return TRANSPORTDEC_UNSUPPORTED_FORMAT;
    778       }
    779       break;
    780 #ifdef TP_ELD_ENABLE
    781     case AOT_ER_AAC_ELD:
    782       if ((ErrorStatus = EldSpecificConfig_Parse(self, bs, cb)) != TRANSPORTDEC_OK ) {
    783         return (ErrorStatus);
    784       }
    785       frameLengthFlag = self->m_sc.m_eldSpecificConfig.m_frameLengthFlag;
    786       self->m_sbrPresentFlag = self->m_sc.m_eldSpecificConfig.m_sbrPresentFlag;
    787       self->m_extensionSamplingFrequency = (self->m_sc.m_eldSpecificConfig.m_sbrSamplingRate+1) * self->m_samplingFrequency;
    788       break;
    789 #endif /* TP_ELD_ENABLE */
    790 
    791     default:
    792       return TRANSPORTDEC_UNSUPPORTED_FORMAT;
    793       break;
    794   }
    795 
    796   /* Frame length */
    797   switch (self->m_aot)
    798   {
    799 #if defined(TP_GA_ENABLE) || defined(TP_USAC_ENABLE)
    800     case AOT_AAC_LC:
    801     case AOT_ER_AAC_LC:
    802     case AOT_ER_AAC_SCAL:
    803     case AOT_ER_BSAC:
    804     /*case AOT_USAC:*/
    805       if (!frameLengthFlag)
    806         self->m_samplesPerFrame = 1024;
    807       else
    808         self->m_samplesPerFrame = 960;
    809       break;
    810 #endif /* TP_GA_ENABLE */
    811 #if defined(TP_GA_ENABLE)
    812     case AOT_ER_AAC_LD:
    813       if (!frameLengthFlag)
    814         self->m_samplesPerFrame = 512;
    815       else
    816         self->m_samplesPerFrame = 480;
    817       break;
    818 #endif /* defined(TP_GA_ENABLE) */
    819     default:
    820       break;
    821   }
    822 
    823   switch (self->m_aot)
    824   {
    825     case AOT_ER_AAC_LC:
    826     case AOT_ER_AAC_LD:
    827     case AOT_ER_AAC_ELD:
    828     case AOT_ER_AAC_SCAL:
    829     case AOT_ER_CELP:
    830     case AOT_ER_HVXC:
    831     case AOT_ER_BSAC:
    832       self->m_epConfig = FDKreadBits(bs,2);
    833 
    834       if (self->m_epConfig > 1) {
    835         return TRANSPORTDEC_UNSUPPORTED_FORMAT; // EPCONFIG;
    836       }
    837       break;
    838     default:
    839       break;
    840   }
    841 
    842 
    843   return (ErrorStatus);
    844 }
    845 
    846 
    847