• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4 
5 � Copyright  1995 - 2012 Fraunhofer-Gesellschaft zur F�rderung 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@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 
CProgramConfig_Reset(CProgramConfig * pPce)95 void CProgramConfig_Reset(CProgramConfig *pPce)
96 {
97   pPce->elCounter = 0;
98 }
99 
CProgramConfig_Init(CProgramConfig * pPce)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 
CProgramConfig_IsValid(const CProgramConfig * pPce)108 int  CProgramConfig_IsValid ( const CProgramConfig *pPce )
109 {
110   return ( (pPce->isValid) ? 1 : 0);
111 }
112 
113 #ifdef TP_PCE_ENABLE
CProgramConfig_Read(CProgramConfig * pPce,HANDLE_FDK_BITSTREAM bs,UINT alignmentAnchor)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  */
getImplicitAudioChannelTypeAndIndex(AUDIO_CHANNEL_TYPE * chType,UCHAR * chIndex,UINT channelConfig,UINT index)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 
CProgramConfig_LookupElement(CProgramConfig * pPce,const UINT channelConfig,const UINT tag,const UINT channelIdx,UCHAR chMapping[],AUDIO_CHANNEL_TYPE chType[],UCHAR chIndex[],UCHAR * elMapping,MP4_ELEMENT_ID elList[],MP4_ELEMENT_ID elType)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
CProgramConfig_GetElementTable(const CProgramConfig * pPce,MP4_ELEMENT_ID elList[],const INT elListSize)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 
getAOT(HANDLE_FDK_BITSTREAM bs)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 
getSampleRate(HANDLE_FDK_BITSTREAM bs,UCHAR * index,int nBits)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
GaSpecificConfig_Parse(CSGaSpecificConfig * self,CSAudioSpecificConfig * asc,HANDLE_FDK_BITSTREAM bs,UINT ascStartAnchor)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 
ld_sbr_header(const CSAudioSpecificConfig * asc,HANDLE_FDK_BITSTREAM hBs,CSTpCallBacks * cb)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
EldSpecificConfig_Parse(CSAudioSpecificConfig * asc,HANDLE_FDK_BITSTREAM hBs,CSTpCallBacks * cb)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 
AudioSpecificConfig_Init(CSAudioSpecificConfig * asc)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 
AudioSpecificConfig_Parse(CSAudioSpecificConfig * self,HANDLE_FDK_BITSTREAM bs,int fExplicitBackwardCompatible,CSTpCallBacks * cb)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