2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
5 © Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
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.
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.
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.
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.
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:
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.
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.
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
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.
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."
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.
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
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.
73 5. CONTACT INFORMATION
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
78 91058 Erlangen, Germany
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
84 /***************************** MPEG-4 AAC Decoder **************************
86 Author(s): Daniel Homm
89 ******************************************************************************/
91 #include "tpdec_lib.h"
95 void CProgramConfig_Reset(CProgramConfig
*pPce
)
100 void CProgramConfig_Init(CProgramConfig
*pPce
)
102 FDKmemclear(pPce
, sizeof(CProgramConfig
));
104 pPce
->SamplingFrequencyIndex
= 0xf;
108 int CProgramConfig_IsValid ( const CProgramConfig
*pPce
)
110 return ( (pPce
->isValid
) ? 1 : 0);
114 void CProgramConfig_Read(
115 CProgramConfig
*pPce
,
116 HANDLE_FDK_BITSTREAM bs
,
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);
134 if ((pPce
->MonoMixdownPresent
= (UCHAR
) FDKreadBits(bs
,1)) != 0)
136 pPce
->MonoMixdownElementNumber
= (UCHAR
) FDKreadBits(bs
,4);
139 if ((pPce
->StereoMixdownPresent
= (UCHAR
) FDKreadBits(bs
,1)) != 0)
141 pPce
->StereoMixdownElementNumber
= (UCHAR
) FDKreadBits(bs
,4);
144 if ((pPce
->MatrixMixdownIndexPresent
= (UCHAR
) FDKreadBits(bs
,1)) != 0)
146 pPce
->MatrixMixdownIndex
= (UCHAR
) FDKreadBits(bs
,2);
147 pPce
->PseudoSurroundEnable
= (UCHAR
) FDKreadBits(bs
,1);
150 for (i
=0; i
< pPce
->NumFrontChannelElements
; i
++)
152 pPce
->FrontElementIsCpe
[i
] = (UCHAR
) FDKreadBits(bs
,1);
153 pPce
->FrontElementTagSelect
[i
] = (UCHAR
) FDKreadBits(bs
,4);
154 pPce
->NumChannels
+= pPce
->FrontElementIsCpe
[i
] ? 2 : 1;
157 for (i
=0; i
< pPce
->NumSideChannelElements
; i
++)
159 pPce
->SideElementIsCpe
[i
] = (UCHAR
) FDKreadBits(bs
,1);
160 pPce
->SideElementTagSelect
[i
] = (UCHAR
) FDKreadBits(bs
,4);
161 pPce
->NumChannels
+= pPce
->SideElementIsCpe
[i
] ? 2 : 1;
164 for (i
=0; i
< pPce
->NumBackChannelElements
; i
++)
166 pPce
->BackElementIsCpe
[i
] = (UCHAR
) FDKreadBits(bs
,1);
167 pPce
->BackElementTagSelect
[i
] = (UCHAR
) FDKreadBits(bs
,4);
168 pPce
->NumChannels
+= pPce
->BackElementIsCpe
[i
] ? 2 : 1;
171 pPce
->NumEffectiveChannels
= pPce
->NumChannels
;
173 for (i
=0; i
< pPce
->NumLfeChannelElements
; i
++)
175 pPce
->LfeElementTagSelect
[i
] = (UCHAR
) FDKreadBits(bs
,4);
176 pPce
->NumChannels
+= 1;
179 for (i
=0; i
< pPce
->NumAssocDataElements
; i
++)
181 pPce
->AssocDataElementTagSelect
[i
] = (UCHAR
) FDKreadBits(bs
,4);
184 for (i
=0; i
< pPce
->NumValidCcElements
; i
++)
186 pPce
->CcElementIsIndSw
[i
] = (UCHAR
) FDKreadBits(bs
,1);
187 pPce
->ValidCcElementTagSelect
[i
] = (UCHAR
) FDKreadBits(bs
,4);
190 FDKbyteAlign(bs
, alignmentAnchor
);
192 pPce
->CommentFieldBytes
= (UCHAR
) FDKreadBits(bs
,8);
194 for (i
=0; i
< pPce
->CommentFieldBytes
; i
++)
198 text
= (UCHAR
)FDKreadBits(bs
,8);
200 if (i
< PC_COMMENTLENGTH
)
202 pPce
->Comment
[i
] = text
;
210 * Compare two program configurations.
211 * Returns the result of the comparison:
212 * -1 - completely different
213 * 0 - completely equal
214 * 1 - different but same channel configuration
215 * 2 - different channel configuration but same number of channels
217 int CProgramConfig_Compare ( const CProgramConfig
* const pPce1
,
218 const CProgramConfig
* const pPce2
)
220 int result
= 0; /* Innocent until proven false. */
222 if (FDKmemcmp(pPce1
, pPce2
, sizeof(CProgramConfig
)) != 0)
223 { /* Configurations are not completely different.
224 So look into details and analyse the channel configurations: */
227 if (pPce1
->NumChannels
== pPce2
->NumChannels
)
228 { /* Now the logic changes. We first assume to have the same channel configuration
229 and then prove if this assumption is true. */
233 if (pPce1
->NumFrontChannelElements
!= pPce2
->NumFrontChannelElements
) {
234 result
= 2; /* different number of front channel elements */
236 int el
, numCh1
= 0, numCh2
= 0;
237 for (el
= 0; el
< pPce1
->NumFrontChannelElements
; el
+= 1) {
238 numCh1
+= pPce1
->FrontElementIsCpe
[el
] ? 2 : 1;
239 numCh2
+= pPce2
->FrontElementIsCpe
[el
] ? 2 : 1;
241 if (numCh1
!= numCh2
) {
242 result
= 2; /* different number of front channels */
246 if (pPce1
->NumSideChannelElements
!= pPce2
->NumSideChannelElements
) {
247 result
= 2; /* different number of side channel elements */
249 int el
, numCh1
= 0, numCh2
= 0;
250 for (el
= 0; el
< pPce1
->NumSideChannelElements
; el
+= 1) {
251 numCh1
+= pPce1
->SideElementIsCpe
[el
] ? 2 : 1;
252 numCh2
+= pPce2
->SideElementIsCpe
[el
] ? 2 : 1;
254 if (numCh1
!= numCh2
) {
255 result
= 2; /* different number of side channels */
259 if (pPce1
->NumBackChannelElements
!= pPce2
->NumBackChannelElements
) {
260 result
= 2; /* different number of back channel elements */
262 int el
, numCh1
= 0, numCh2
= 0;
263 for (el
= 0; el
< pPce1
->NumBackChannelElements
; el
+= 1) {
264 numCh1
+= pPce1
->BackElementIsCpe
[el
] ? 2 : 1;
265 numCh2
+= pPce2
->BackElementIsCpe
[el
] ? 2 : 1;
267 if (numCh1
!= numCh2
) {
268 result
= 2; /* different number of back channels */
272 if (pPce1
->NumLfeChannelElements
!= pPce2
->NumLfeChannelElements
) {
273 result
= 2; /* different number of lfe channels */
275 /* LFEs are always SCEs so we don't need to count the channels. */
282 void CProgramConfig_GetDefault( CProgramConfig
*pPce
,
283 const UINT channelConfig
)
285 FDK_ASSERT(pPce
!= NULL
);
288 CProgramConfig_Init(pPce
);
289 pPce
->Profile
= 1; /* Set AAC LC because it is the only supported object type. */
291 switch (channelConfig
) {
292 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
293 case 6: /* 3/0/2.1ch */
294 pPce
->NumLfeChannelElements
+= 1;
295 pPce
->NumChannels
+= 1;
296 case 5: /* 3/0/2.0ch */
297 case 4: /* 3/0/1.0ch */
298 pPce
->NumBackChannelElements
+= 1;
299 pPce
->BackElementIsCpe
[0] = (channelConfig
>4) ? 1 : 0;
300 pPce
->NumChannels
+= (channelConfig
>4) ? 2 : 1;
301 pPce
->NumEffectiveChannels
+= (channelConfig
>4) ? 2 : 1;
302 case 3: /* 3/0/0.0ch */
303 pPce
->NumFrontChannelElements
+= 1;
304 pPce
->FrontElementIsCpe
[1] = 1;
305 pPce
->NumChannels
+= 2;
306 pPce
->NumEffectiveChannels
+= 2;
307 case 1: /* 1/0/0.0ch */
308 pPce
->NumFrontChannelElements
+= 1;
309 pPce
->FrontElementIsCpe
[0] = 0;
310 pPce
->NumChannels
+= 1;
311 pPce
->NumEffectiveChannels
+= 1;
314 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
315 case 2: /* 2/0/0.ch */
316 pPce
->NumFrontChannelElements
= 1;
317 pPce
->FrontElementIsCpe
[0] = 1;
318 pPce
->NumChannels
+= 2;
319 pPce
->NumEffectiveChannels
+= 2;
322 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
324 pPce
->isValid
= 0; /* To be explicit! */
329 /* Create valid element instance tags */
330 int el
, elTagSce
= 0, elTagCpe
= 0;
332 for (el
= 0; el
< pPce
->NumFrontChannelElements
; el
+= 1) {
333 pPce
->FrontElementTagSelect
[el
] = (pPce
->FrontElementIsCpe
) ? elTagCpe
++ : elTagSce
++;
335 for (el
= 0; el
< pPce
->NumSideChannelElements
; el
+= 1) {
336 pPce
->SideElementTagSelect
[el
] = (pPce
->SideElementIsCpe
) ? elTagCpe
++ : elTagSce
++;
338 for (el
= 0; el
< pPce
->NumBackChannelElements
; el
+= 1) {
339 pPce
->BackElementTagSelect
[el
] = (pPce
->BackElementIsCpe
) ? elTagCpe
++ : elTagSce
++;
342 for (el
= 0; el
< pPce
->NumLfeChannelElements
; el
+= 1) {
343 pPce
->LfeElementTagSelect
[el
] = elTagSce
++;
347 #endif /* TP_PCE_ENABLE */
350 * \brief get implicit audio channel type for given channelConfig and MPEG ordered channel index
351 * \param channelConfig MPEG channelConfiguration from 1 upto 7
352 * \param index MPEG channel order index
353 * \return audio channel type.
355 void getImplicitAudioChannelTypeAndIndex(
356 AUDIO_CHANNEL_TYPE
*chType
,
366 switch (channelConfig
) {
374 *chIndex
= index
- 3;
387 *chIndex
= index
- 3;
392 *chIndex
= index
- 5;
407 int CProgramConfig_LookupElement(
408 CProgramConfig
*pPce
,
411 const UINT channelIdx
,
413 AUDIO_CHANNEL_TYPE chType
[],
416 MP4_ELEMENT_ID elList
[],
417 MP4_ELEMENT_ID elType
420 if (channelConfig
> 0)
422 /* Constant channel mapping must have
423 been set during initialization. */
424 if ( elType
== ID_SCE
426 || elType
== ID_LFE
)
428 *elMapping
= pPce
->elCounter
;
429 if (elList
[pPce
->elCounter
] != elType
) {
430 /* Not in the list */
431 if ( (channelConfig
== 2) && (elType
== ID_SCE
) )
432 { /* This scenario occurs with HE-AAC v2 streams of buggy encoders.
433 Due to other decoder implementations decoding of these kind of streams is desired. */
439 /* Assume all front channels */
440 getImplicitAudioChannelTypeAndIndex(&chType
[channelIdx
], &chIndex
[channelIdx
], channelConfig
, channelIdx
);
441 if (elType
== ID_CPE
) {
442 chType
[channelIdx
+1] = chType
[channelIdx
];
443 chIndex
[channelIdx
+1] = chIndex
[channelIdx
]+1;
447 /* Accept all non-channel elements, too. */
454 #endif /* TP_PCE_ENABLE */
456 /* Implicit channel mapping. */
457 if ( elType
== ID_SCE
459 || elType
== ID_LFE
)
461 /* Store all channel element IDs */
462 elList
[pPce
->elCounter
] = elType
;
463 *elMapping
= pPce
->elCounter
++;
468 /* Accept the additional channel(s), only if the tag is in the lists */
470 int cc
= 0, fc
= 0, sc
= 0, bc
= 0, lc
= 0, ec
= 0; /* Channel and element counters */
477 /* search in front channels */
478 for (i
= 0; i
< pPce
->NumFrontChannelElements
; i
++) {
479 if (isCpe
== pPce
->FrontElementIsCpe
[i
] && pPce
->FrontElementTagSelect
[i
] == tag
) {
480 chMapping
[cc
] = channelIdx
;
481 chType
[cc
] = ACT_FRONT
;
484 chMapping
[cc
+1] = channelIdx
+1;
485 chType
[cc
+1] = ACT_FRONT
;
486 chIndex
[cc
+1] = fc
+1;
492 if (pPce
->FrontElementIsCpe
[i
]) {
498 /* search in side channels */
499 for (i
= 0; i
< pPce
->NumSideChannelElements
; i
++) {
500 if (isCpe
== pPce
->SideElementIsCpe
[i
] && pPce
->SideElementTagSelect
[i
] == tag
) {
501 chMapping
[cc
] = channelIdx
;
502 chType
[cc
] = ACT_SIDE
;
505 chMapping
[cc
+1] = channelIdx
+1;
506 chType
[cc
+1] = ACT_SIDE
;
507 chIndex
[cc
+1] = sc
+1;
513 if (pPce
->SideElementIsCpe
[i
]) {
519 /* search in back channels */
520 for (i
= 0; i
< pPce
->NumBackChannelElements
; i
++) {
521 if (isCpe
== pPce
->BackElementIsCpe
[i
] && pPce
->BackElementTagSelect
[i
] == tag
) {
522 chMapping
[cc
] = channelIdx
;
523 chType
[cc
] = ACT_BACK
;
526 chMapping
[cc
+1] = channelIdx
+1;
527 chType
[cc
+1] = ACT_BACK
;
528 chIndex
[cc
+1] = bc
+1;
534 if (pPce
->BackElementIsCpe
[i
]) {
543 /* Initialize channel counter and element counter */
544 cc
= pPce
->NumEffectiveChannels
;
545 ec
= pPce
->NumFrontChannelElements
+ pPce
->NumSideChannelElements
+ pPce
->NumBackChannelElements
;
546 /* search in lfe channels */
547 for (i
= 0; i
< pPce
->NumLfeChannelElements
; i
++) {
548 if ( pPce
->LfeElementTagSelect
[i
] == tag
) {
549 chMapping
[cc
] = channelIdx
;
551 chType
[cc
] = ACT_LFE
;
561 /* Non audio elements */
563 /* search in cce channels */
564 for (i
= 0; i
< pPce
->NumValidCcElements
; i
++) {
565 if (pPce
->ValidCcElementTagSelect
[i
] == tag
) {
571 /* search associated data elements */
572 for (i
= 0; i
< pPce
->NumAssocDataElements
; i
++) {
573 if (pPce
->AssocDataElementTagSelect
[i
] == tag
) {
581 return 0; /* not found in any list */
583 #endif /* TP_PCE_ENABLE */
590 int CProgramConfig_GetElementTable(
591 const CProgramConfig
*pPce
,
592 MP4_ELEMENT_ID elList
[],
599 < pPce
->NumFrontChannelElements
+ pPce
->NumSideChannelElements
+ pPce
->NumBackChannelElements
+ pPce
->NumLfeChannelElements
605 for (i
=0; i
< pPce
->NumFrontChannelElements
; i
++)
607 elList
[el
++] = (pPce
->FrontElementIsCpe
[i
]) ? ID_CPE
: ID_SCE
;
610 for (i
=0; i
< pPce
->NumSideChannelElements
; i
++)
612 elList
[el
++] = (pPce
->SideElementIsCpe
[i
]) ? ID_CPE
: ID_SCE
;
615 for (i
=0; i
< pPce
->NumBackChannelElements
; i
++)
617 elList
[el
++] = (pPce
->BackElementIsCpe
[i
]) ? ID_CPE
: ID_SCE
;
620 for (i
=0; i
< pPce
->NumLfeChannelElements
; i
++)
622 elList
[el
++] = ID_LFE
;
630 static AUDIO_OBJECT_TYPE
getAOT(HANDLE_FDK_BITSTREAM bs
)
634 tmp
= FDKreadBits(bs
,5);
635 if (tmp
== AOT_ESCAPE
) {
636 int tmp2
= FDKreadBits(bs
,6);
640 return (AUDIO_OBJECT_TYPE
)tmp
;
643 static INT
getSampleRate(HANDLE_FDK_BITSTREAM bs
, UCHAR
*index
, int nBits
)
648 idx
= FDKreadBits(bs
, nBits
);
649 if( idx
== (1<<nBits
)-1 ) {
650 if(FDKgetValidBits(bs
) < 24) {
653 sampleRate
= FDKreadBits(bs
,24);
655 sampleRate
= SamplingRateTable
[idx
];
665 TRANSPORTDEC_ERROR
GaSpecificConfig_Parse( CSGaSpecificConfig
*self
,
666 CSAudioSpecificConfig
*asc
,
667 HANDLE_FDK_BITSTREAM bs
,
668 UINT ascStartAnchor
)
670 TRANSPORTDEC_ERROR ErrorStatus
= TRANSPORTDEC_OK
;
672 self
->m_frameLengthFlag
= FDKreadBits(bs
,1);
674 self
->m_dependsOnCoreCoder
= FDKreadBits(bs
,1);
676 if( self
->m_dependsOnCoreCoder
)
677 self
->m_coreCoderDelay
= FDKreadBits(bs
,14);
679 self
->m_extensionFlag
= FDKreadBits(bs
,1);
681 if( asc
->m_channelConfiguration
== 0 ) {
682 CProgramConfig_Read(&asc
->m_progrConfigElement
, bs
, ascStartAnchor
);
685 if ((asc
->m_aot
== AOT_AAC_SCAL
) || (asc
->m_aot
== AOT_ER_AAC_SCAL
)) {
686 self
->m_layer
= FDKreadBits(bs
,3);
689 if (self
->m_extensionFlag
) {
690 if (asc
->m_aot
== AOT_ER_BSAC
) {
691 self
->m_numOfSubFrame
= FDKreadBits(bs
,5);
692 self
->m_layerLength
= FDKreadBits(bs
,11);
695 if ((asc
->m_aot
== AOT_ER_AAC_LC
) || (asc
->m_aot
== AOT_ER_AAC_LTP
) ||
696 (asc
->m_aot
== AOT_ER_AAC_SCAL
) || (asc
->m_aot
== AOT_ER_AAC_LD
))
698 asc
->m_vcb11Flag
= FDKreadBits(bs
,1); /* aacSectionDataResilienceFlag */
699 asc
->m_rvlcFlag
= FDKreadBits(bs
,1); /* aacScalefactorDataResilienceFlag */
700 asc
->m_hcrFlag
= FDKreadBits(bs
,1); /* aacSpectralDataResilienceFlag */
703 self
->m_extensionFlag3
= FDKreadBits(bs
,1);
706 return (ErrorStatus
);
708 #endif /* TP_GA_ENABLE */
716 static INT
ld_sbr_header( const CSAudioSpecificConfig
*asc
,
717 HANDLE_FDK_BITSTREAM hBs
,
720 const int channelConfiguration
= asc
->m_channelConfiguration
;
724 if (channelConfiguration
== 2) {
725 error
= cb
->cbSbr(cb
->cbSbrData
, hBs
, asc
->m_samplingFrequency
, asc
->m_extensionSamplingFrequency
, asc
->m_samplesPerFrame
, AOT_ER_AAC_ELD
, ID_CPE
, i
++);
727 error
= cb
->cbSbr(cb
->cbSbrData
, hBs
, asc
->m_samplingFrequency
, asc
->m_extensionSamplingFrequency
, asc
->m_samplesPerFrame
, AOT_ER_AAC_ELD
, ID_SCE
, i
++);
730 switch ( channelConfiguration
) {
732 error
|= cb
->cbSbr(cb
->cbSbrData
, hBs
, asc
->m_samplingFrequency
, asc
->m_extensionSamplingFrequency
, asc
->m_samplesPerFrame
, AOT_ER_AAC_ELD
, ID_CPE
, i
++);
735 error
|= cb
->cbSbr(cb
->cbSbrData
, hBs
, asc
->m_samplingFrequency
, asc
->m_extensionSamplingFrequency
, asc
->m_samplesPerFrame
, AOT_ER_AAC_ELD
, ID_CPE
, i
++);
737 error
|= cb
->cbSbr(cb
->cbSbrData
, hBs
, asc
->m_samplingFrequency
, asc
->m_extensionSamplingFrequency
, asc
->m_samplesPerFrame
, AOT_ER_AAC_ELD
, ID_CPE
, i
++);
741 error
|= cb
->cbSbr(cb
->cbSbrData
, hBs
, asc
->m_samplingFrequency
, asc
->m_extensionSamplingFrequency
, asc
->m_samplesPerFrame
, AOT_ER_AAC_ELD
, ID_CPE
, i
++);
742 error
|= cb
->cbSbr(cb
->cbSbrData
, hBs
, asc
->m_samplingFrequency
, asc
->m_extensionSamplingFrequency
, asc
->m_samplesPerFrame
, AOT_ER_AAC_ELD
, ID_SCE
, i
++);
750 TRANSPORTDEC_ERROR
EldSpecificConfig_Parse(
751 CSAudioSpecificConfig
*asc
,
752 HANDLE_FDK_BITSTREAM hBs
,
756 TRANSPORTDEC_ERROR ErrorStatus
= TRANSPORTDEC_OK
;
757 CSEldSpecificConfig
*esc
= &asc
->m_sc
.m_eldSpecificConfig
;
758 ASC_ELD_EXT_TYPE eldExtType
;
759 int eldExtLen
, len
, cnt
;
761 FDKmemclear(esc
, sizeof(CSEldSpecificConfig
));
763 esc
->m_frameLengthFlag
= FDKreadBits(hBs
, 1 );
764 if (esc
->m_frameLengthFlag
) {
765 asc
->m_samplesPerFrame
= 480;
767 asc
->m_samplesPerFrame
= 512;
770 asc
->m_vcb11Flag
= FDKreadBits(hBs
, 1 );
771 asc
->m_rvlcFlag
= FDKreadBits(hBs
, 1 );
772 asc
->m_hcrFlag
= FDKreadBits(hBs
, 1 );
774 esc
->m_sbrPresentFlag
= FDKreadBits(hBs
, 1 );
776 if (esc
->m_sbrPresentFlag
== 1) {
777 esc
->m_sbrSamplingRate
= FDKreadBits(hBs
, 1 ); /* 0: single rate, 1: dual rate */
778 esc
->m_sbrCrcFlag
= FDKreadBits(hBs
, 1 );
780 asc
->m_extensionSamplingFrequency
= asc
->m_samplingFrequency
<< esc
->m_sbrSamplingRate
;
782 if (cb
->cbSbr
!= NULL
){
783 if ( 0 != ld_sbr_header(asc
, hBs
, cb
) ) {
784 return TRANSPORTDEC_PARSE_ERROR
;
788 esc
->m_useLdQmfTimeAlign
= 0;
791 /* parse ExtTypeConfigData */
792 while ((eldExtType
= (ASC_ELD_EXT_TYPE
)FDKreadBits(hBs
, 4 )) != ELDEXT_TERM
) {
793 eldExtLen
= len
= FDKreadBits(hBs
, 4 );
795 len
= FDKreadBits(hBs
, 8 );
799 len
= FDKreadBits(hBs
, 16 );
804 switch (eldExtType
) {
806 esc
->m_useLdQmfTimeAlign
= 1;
807 if (cb
->cbSsc
!= NULL
) {
808 ErrorStatus
= (TRANSPORTDEC_ERROR
)cb
->cbSsc(
812 asc
->m_samplingFrequency
,
817 ErrorStatus
= TRANSPORTDEC_UNSUPPORTED_FORMAT
;
819 if (ErrorStatus
!= TRANSPORTDEC_OK
) {
824 for(cnt
=0; cnt
<len
; cnt
++) {
825 FDKreadBits(hBs
, 8 );
828 /* add future eld extension configs here */
832 return (ErrorStatus
);
834 #endif /* TP_ELD_ENABLE */
838 TRANSPORTDEC_ERROR
AudioSpecificConfig_ExtensionParse(CSAudioSpecificConfig
*self
, HANDLE_FDK_BITSTREAM bs
, CSTpCallBacks
*cb
)
840 TP_ASC_EXTENSION_ID lastAscExt
, ascExtId
= ASCEXT_UNKOWN
;
841 INT bitsAvailable
= (INT
)FDKgetValidBits(bs
);
843 while (bitsAvailable
>= 11)
845 lastAscExt
= ascExtId
;
846 ascExtId
= (TP_ASC_EXTENSION_ID
)FDKreadBits(bs
, 11);
850 case ASCEXT_SBR
: /* 0x2b7 */
851 if ( (self
->m_extensionAudioObjectType
!= AOT_SBR
) && (bitsAvailable
>= 5) ) {
852 self
->m_extensionAudioObjectType
= getAOT(bs
);
854 if ( (self
->m_extensionAudioObjectType
== AOT_SBR
)
855 || (self
->m_extensionAudioObjectType
== AOT_ER_BSAC
) )
856 { /* Get SBR extension configuration */
857 self
->m_sbrPresentFlag
= FDKreadBits(bs
, 1);
860 if ( self
->m_sbrPresentFlag
== 1 ) {
861 self
->m_extensionSamplingFrequency
= getSampleRate(bs
, &self
->m_extensionSamplingFrequencyIndex
, 4);
863 if ((INT
)self
->m_extensionSamplingFrequency
<= 0) {
864 return TRANSPORTDEC_PARSE_ERROR
;
867 if ( self
->m_extensionAudioObjectType
== AOT_ER_BSAC
) {
868 self
->m_extensionChannelConfiguration
= FDKreadBits(bs
, 4);
872 /* Update counter because of variable length fields (AOT and sampling rate) */
873 bitsAvailable
= (INT
)FDKgetValidBits(bs
);
876 case ASCEXT_PS
: /* 0x548 */
877 if ( (lastAscExt
== ASCEXT_SBR
)
878 && (self
->m_extensionAudioObjectType
== AOT_SBR
)
879 && (bitsAvailable
> 0) )
880 { /* Get PS extension configuration */
881 self
->m_psPresentFlag
= FDKreadBits(bs
, 1);
886 /* Just ignore anything. */
887 return TRANSPORTDEC_OK
;
891 return TRANSPORTDEC_OK
;
898 void AudioSpecificConfig_Init(CSAudioSpecificConfig
*asc
)
900 FDKmemclear(asc
, sizeof(CSAudioSpecificConfig
));
902 /* Init all values that should not be zero. */
903 asc
->m_aot
= AOT_NONE
;
904 asc
->m_samplingFrequencyIndex
= 0xf;
905 asc
->m_epConfig
= -1;
906 asc
->m_extensionAudioObjectType
= AOT_NULL_OBJECT
;
908 CProgramConfig_Init(&asc
->m_progrConfigElement
);
912 TRANSPORTDEC_ERROR
AudioSpecificConfig_Parse(
913 CSAudioSpecificConfig
*self
,
914 HANDLE_FDK_BITSTREAM bs
,
915 int fExplicitBackwardCompatible
,
919 TRANSPORTDEC_ERROR ErrorStatus
= TRANSPORTDEC_OK
;
920 UINT ascStartAnchor
= FDKgetValidBits(bs
);
921 int frameLengthFlag
= -1;
923 AudioSpecificConfig_Init(self
);
925 self
->m_aot
= getAOT(bs
);
926 self
->m_samplingFrequency
= getSampleRate(bs
, &self
->m_samplingFrequencyIndex
, 4);
927 if (self
->m_samplingFrequency
<= 0) {
928 return TRANSPORTDEC_PARSE_ERROR
;
931 self
->m_channelConfiguration
= FDKreadBits(bs
,4);
933 /* SBR extension ( explicit non-backwards compatible mode ) */
934 self
->m_sbrPresentFlag
= 0;
935 self
->m_psPresentFlag
= 0;
937 if ( self
->m_aot
== AOT_SBR
|| self
->m_aot
== AOT_PS
) {
938 self
->m_extensionAudioObjectType
= AOT_SBR
;
940 self
->m_sbrPresentFlag
= 1;
941 if ( self
->m_aot
== AOT_PS
) {
942 self
->m_psPresentFlag
= 1;
945 self
->m_extensionSamplingFrequency
= getSampleRate(bs
, &self
->m_extensionSamplingFrequencyIndex
, 4);
946 self
->m_aot
= getAOT(bs
);
949 self
->m_extensionAudioObjectType
= AOT_NULL_OBJECT
;
952 /* Parse whatever specific configs */
959 case AOT_ER_AAC_SCAL
:
961 if ((ErrorStatus
= GaSpecificConfig_Parse(&self
->m_sc
.m_gaSpecificConfig
, self
, bs
, ascStartAnchor
)) != TRANSPORTDEC_OK
) {
962 return (ErrorStatus
);
964 frameLengthFlag
= self
->m_sc
.m_gaSpecificConfig
.m_frameLengthFlag
;
966 #endif /* TP_GA_ENABLE */
968 if (cb
->cbSsc
!= NULL
) {
973 self
->m_samplingFrequency
,
975 0 /* don't know the length */
978 return TRANSPORTDEC_UNSUPPORTED_FORMAT
;
983 if ((ErrorStatus
= EldSpecificConfig_Parse(self
, bs
, cb
)) != TRANSPORTDEC_OK
) {
984 return (ErrorStatus
);
986 frameLengthFlag
= self
->m_sc
.m_eldSpecificConfig
.m_frameLengthFlag
;
987 self
->m_sbrPresentFlag
= self
->m_sc
.m_eldSpecificConfig
.m_sbrPresentFlag
;
988 self
->m_extensionSamplingFrequency
= (self
->m_sc
.m_eldSpecificConfig
.m_sbrSamplingRate
+1) * self
->m_samplingFrequency
;
990 #endif /* TP_ELD_ENABLE */
993 return TRANSPORTDEC_UNSUPPORTED_FORMAT
;
1000 #if defined(TP_GA_ENABLE) || defined(TP_USAC_ENABLE)
1003 case AOT_ER_AAC_SCAL
:
1006 if (!frameLengthFlag
)
1007 self
->m_samplesPerFrame
= 1024;
1009 self
->m_samplesPerFrame
= 960;
1011 #endif /* TP_GA_ENABLE */
1012 #if defined(TP_GA_ENABLE)
1014 if (!frameLengthFlag
)
1015 self
->m_samplesPerFrame
= 512;
1017 self
->m_samplesPerFrame
= 480;
1019 #endif /* defined(TP_GA_ENABLE) */
1024 switch (self
->m_aot
)
1028 case AOT_ER_AAC_ELD
:
1029 case AOT_ER_AAC_SCAL
:
1033 self
->m_epConfig
= FDKreadBits(bs
,2);
1035 if (self
->m_epConfig
> 1) {
1036 return TRANSPORTDEC_UNSUPPORTED_FORMAT
; // EPCONFIG;
1043 if (fExplicitBackwardCompatible
) {
1044 ErrorStatus
= AudioSpecificConfig_ExtensionParse(self
, bs
, cb
);
1047 return (ErrorStatus
);