summaryrefslogtreecommitdiffstats
path: root/libAACdec/src/block.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libAACdec/src/block.cpp')
-rw-r--r--libAACdec/src/block.cpp703
1 files changed, 703 insertions, 0 deletions
diff --git a/libAACdec/src/block.cpp b/libAACdec/src/block.cpp
new file mode 100644
index 0000000..d17e9c4
--- /dev/null
+++ b/libAACdec/src/block.cpp
@@ -0,0 +1,703 @@
+/***************************** MPEG-4 AAC Decoder **************************
+
+ (C) Copyright Fraunhofer IIS (2004)
+ All Rights Reserved
+
+ Please be advised that this software and/or program delivery is
+ Confidential Information of Fraunhofer and subject to and covered by the
+
+ Fraunhofer IIS Software Evaluation Agreement
+ between Google Inc. and Fraunhofer
+ effective and in full force since March 1, 2012.
+
+ You may use this software and/or program only under the terms and
+ conditions described in the above mentioned Fraunhofer IIS Software
+ Evaluation Agreement. Any other and/or further use requires a separate agreement.
+
+
+ $Id$
+ Author(s): Josef Hoepfl
+ Description: long/short-block decoding
+
+ This software and/or program is protected by copyright law and international
+ treaties. Any reproduction or distribution of this software and/or program,
+ or any portion of it, may result in severe civil and criminal penalties, and
+ will be prosecuted to the maximum extent possible under law.
+
+******************************************************************************/
+
+#include "block.h"
+
+#include "aac_rom.h"
+#include "FDK_bitstream.h"
+#include "FDK_tools_rom.h"
+
+
+
+
+#include "aacdec_hcr.h"
+#include "rvlc.h"
+
+
+#if defined(__arm__)
+#include "arm/block_arm.cpp"
+#endif
+
+/*!
+ \brief Read escape sequence of codeword
+
+ The function reads the escape sequence from the bitstream,
+ if the absolute value of the quantized coefficient has the
+ value 16.
+
+ \return quantized coefficient
+*/
+LONG CBlock_GetEscape(HANDLE_FDK_BITSTREAM bs, /*!< pointer to bitstream */
+ const LONG q) /*!< quantized coefficient */
+{
+ LONG i, off, neg ;
+
+ if (q < 0)
+ {
+ if (q != -16) return q;
+ neg = 1;
+ }
+ else
+ {
+ if (q != +16) return q;
+ neg = 0;
+ }
+
+ for (i=4; ; i++)
+ {
+ if (FDKreadBits(bs,1) == 0)
+ break;
+ }
+
+ if (i > 16)
+ {
+ if (i - 16 > CACHE_BITS) { /* cannot read more than "CACHE_BITS" bits at once in the function FDKreadBits() */
+ return (MAX_QUANTIZED_VALUE + 1); /* returning invalid value that will be captured later */
+ }
+
+ off = FDKreadBits(bs,i-16) << 16;
+ off |= FDKreadBits(bs,16);
+ }
+ else
+ {
+ off = FDKreadBits(bs,i);
+ }
+
+ i = off + (1 << i);
+
+ if (neg) i = -i;
+
+ return i;
+}
+
+AAC_DECODER_ERROR CBlock_ReadScaleFactorData(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ HANDLE_FDK_BITSTREAM bs,
+ UINT flags
+ )
+{
+ int temp;
+ int band;
+ int group;
+ int position = 0; /* accu for intensity delta coding */
+ int factor = pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain; /* accu for scale factor delta coding */
+ UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
+ SHORT *pScaleFactor = pAacDecoderChannelInfo->pDynData->aScaleFactor;
+ const CodeBookDescription *hcb =&AACcodeBookDescriptionTable[BOOKSCL];
+
+ int ScaleFactorBandsTransmitted = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+ for (group=0; group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++)
+ {
+ for (band=0; band < ScaleFactorBandsTransmitted; band++)
+ {
+ switch (pCodeBook[group*16+band]) {
+
+ case ZERO_HCB: /* zero book */
+ pScaleFactor[group*16+band] = 0;
+ break;
+
+ default: /* decode scale factor */
+ {
+ temp = CBlock_DecodeHuffmanWord(bs,hcb);
+ factor += temp - 60; /* MIDFAC 1.5 dB */
+ }
+ pScaleFactor[group*16+band] = factor - 100;
+ break;
+
+ case INTENSITY_HCB: /* intensity steering */
+ case INTENSITY_HCB2:
+ temp = CBlock_DecodeHuffmanWord(bs,hcb);
+ position += temp - 60;
+ pScaleFactor[group*16+band] = position - 100;
+ break;
+
+ case NOISE_HCB: /* PNS */
+ if (flags & (AC_MPS_RES|AC_USAC|AC_RSVD50)) {
+ return AAC_DEC_PARSE_ERROR;
+ }
+ CPns_Read( &pAacDecoderChannelInfo->data.aac.PnsData, bs, hcb, pAacDecoderChannelInfo->pDynData->aScaleFactor, pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain, band, group);
+ break;
+ }
+ }
+ }
+
+ return AAC_DEC_OK;
+}
+
+void CBlock_ScaleSpectralData(CAacDecoderChannelInfo *pAacDecoderChannelInfo, SamplingRateInfo *pSamplingRateInfo)
+{
+ int band;
+ int window;
+ const SHORT * RESTRICT pSfbScale = pAacDecoderChannelInfo->pDynData->aSfbScale;
+ SHORT * RESTRICT pSpecScale = pAacDecoderChannelInfo->specScale;
+ int groupwin,group;
+ const SHORT * RESTRICT BandOffsets = GetScaleFactorBandOffsets(&pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
+ SPECTRAL_PTR RESTRICT pSpectralCoefficient = pAacDecoderChannelInfo->pSpectralCoefficient;
+
+
+ FDKmemclear(pSpecScale, 8*sizeof(SHORT));
+
+ int max_band = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+ for (window=0, group=0; group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++)
+ {
+ for (groupwin=0; groupwin < GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo,group); groupwin++, window++)
+ {
+ int SpecScale_window = pSpecScale[window];
+ FIXP_DBL *pSpectrum = SPEC(pSpectralCoefficient, window, pAacDecoderChannelInfo->granuleLength);
+
+ /* find scaling for current window */
+ for (band=0; band < max_band; band++)
+ {
+ SpecScale_window = fMax(SpecScale_window, (int)pSfbScale[window*16+band]);
+ }
+
+ if (pAacDecoderChannelInfo->pDynData->TnsData.Active) {
+ SpecScale_window += TNS_SCALE;
+ }
+
+ /* store scaling of current window */
+ pSpecScale[window] = SpecScale_window;
+
+#ifdef FUNCTION_CBlock_ScaleSpectralData_func1
+
+ CBlock_ScaleSpectralData_func1(pSpectrum, max_band, BandOffsets, SpecScale_window, pSfbScale, window);
+
+#else /* FUNCTION_CBlock_ScaleSpectralData_func1 */
+ for (band=0; band < max_band; band++)
+ {
+ int scale = SpecScale_window - pSfbScale[window*16+band];
+ if (scale)
+ {
+ /* following relation can be used for optimizations: (BandOffsets[i]%4) == 0 for all i */
+ int max_index = BandOffsets[band+1];
+ for (int index = BandOffsets[band]; index < max_index; index++)
+ {
+ pSpectrum[index] >>= scale;
+ }
+ }
+ }
+#endif /* FUNCTION_CBlock_ScaleSpectralData_func1 */
+ }
+ }
+
+}
+
+AAC_DECODER_ERROR CBlock_ReadSectionData(HANDLE_FDK_BITSTREAM bs,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo,
+ const UINT flags)
+{
+ int top, band;
+ int sect_len, sect_len_incr;
+ int group;
+ UCHAR sect_cb;
+ UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
+ /* HCR input (long) */
+ SHORT *pNumLinesInSec = pAacDecoderChannelInfo->pDynData->specificTo.aac.aNumLineInSec4Hcr;
+ int numLinesInSecIdx = 0;
+ UCHAR *pHcrCodeBook = pAacDecoderChannelInfo->pDynData->specificTo.aac.aCodeBooks4Hcr;
+ const SHORT *BandOffsets = GetScaleFactorBandOffsets(&pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.numberSection = 0;
+ AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
+
+ FDKmemclear(pCodeBook, sizeof(UCHAR)*(8*16));
+
+ const int nbits = (IsLongBlock(&pAacDecoderChannelInfo->icsInfo) == 1) ? 5 : 3;
+
+ int sect_esc_val = (1 << nbits) - 1 ;
+
+ UCHAR ScaleFactorBandsTransmitted = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+ for (group=0; group<GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++)
+ {
+ for (band=0; band < ScaleFactorBandsTransmitted; )
+ {
+ sect_len = 0;
+ if ( flags & AC_ER_VCB11 ) {
+ sect_cb = (UCHAR) FDKreadBits(bs,5);
+ }
+ else
+ sect_cb = (UCHAR) FDKreadBits(bs,4);
+
+ if ( ((flags & AC_ER_VCB11) == 0) || ( sect_cb < 11 ) || ((sect_cb > 11) && (sect_cb < 16)) ) {
+ sect_len_incr = FDKreadBits(bs, nbits);
+ while (sect_len_incr == sect_esc_val)
+ {
+ sect_len += sect_esc_val;
+ sect_len_incr = FDKreadBits(bs, nbits);
+ }
+ }
+ else {
+ sect_len_incr = 1;
+ }
+
+ sect_len += sect_len_incr;
+
+
+ top = band + sect_len;
+
+ if (flags & AC_ER_HCR) {
+ /* HCR input (long) -- collecting sideinfo (for HCR-_long_ only) */
+ pNumLinesInSec[numLinesInSecIdx] = BandOffsets[top] - BandOffsets[band];
+ numLinesInSecIdx++;
+ if (numLinesInSecIdx >= MAX_SFB_HCR) {
+ return AAC_DEC_PARSE_ERROR;
+ }
+ if (
+ (sect_cb == BOOKSCL) )
+ {
+ return AAC_DEC_INVALID_CODE_BOOK;
+ } else {
+ *pHcrCodeBook++ = sect_cb;
+ }
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.numberSection++;
+ }
+
+ /* Check spectral line limits */
+ if (IsLongBlock( &(pAacDecoderChannelInfo->icsInfo) ))
+ {
+ if (top > 64) {
+ return AAC_DEC_DECODE_FRAME_ERROR;
+ }
+ } else { /* short block */
+ if (top + group*16 > (8 * 16)) {
+ return AAC_DEC_DECODE_FRAME_ERROR;
+ }
+ }
+
+ /* Check if decoded codebook index is feasible */
+ if ( (sect_cb == BOOKSCL)
+ || ( (sect_cb == INTENSITY_HCB || sect_cb == INTENSITY_HCB2) && pAacDecoderChannelInfo->pDynData->RawDataInfo.CommonWindow == 0)
+ )
+ {
+ return AAC_DEC_INVALID_CODE_BOOK;
+ }
+
+ /* Store codebook index */
+ for (; band < top; band++)
+ {
+ pCodeBook[group*16+band] = sect_cb;
+ }
+ }
+ }
+
+
+ return ErrorStatus;
+}
+
+/* mso: provides a faster way to i-quantize a whole band in one go */
+
+/**
+ * \brief inverse quantize one sfb. Each value of the sfb is processed according to the
+ * formula: spectrum[i] = Sign(spectrum[i]) * Matissa(spectrum[i])^(4/3) * 2^(lsb/4).
+ * \param spectrum pointer to first line of the sfb to be inverse quantized.
+ * \param noLines number of lines belonging to the sfb.
+ * \param lsb last 2 bits of the scale factor of the sfb.
+ * \param scale max allowed shift scale for the sfb.
+ */
+static
+void InverseQuantizeBand( FIXP_DBL * RESTRICT spectrum,
+ INT noLines,
+ INT lsb,
+ INT scale )
+{
+ const FIXP_DBL * RESTRICT InverseQuantTabler=(FIXP_DBL *)InverseQuantTable;
+ const FIXP_DBL * RESTRICT MantissaTabler=(FIXP_DBL *)MantissaTable[lsb];
+ const SCHAR* RESTRICT ExponentTabler=(SCHAR*)ExponentTable[lsb];
+
+ FIXP_DBL *ptr = spectrum;
+ FIXP_DBL signedValue;
+
+ FDK_ASSERT(noLines>2);
+ for (INT i=noLines; i--; )
+ {
+ if ((signedValue = *ptr++) != FL2FXCONST_DBL(0))
+ {
+ FIXP_DBL value = fAbs(signedValue);
+ UINT freeBits = CntLeadingZeros(value);
+ UINT exponent = 32 - freeBits;
+
+ UINT x = (UINT) (LONG)value << (INT) freeBits;
+ x <<= 1; /* shift out sign bit to avoid masking later on */
+ UINT tableIndex = x >> 24;
+ x = (x >> 20) & 0x0F;
+
+ UINT r0=(UINT)(LONG)InverseQuantTabler[tableIndex+0];
+ UINT r1=(UINT)(LONG)InverseQuantTabler[tableIndex+1];
+ UINT temp= (r1 - r0)*x + (r0 << 4);
+
+ value = fMultDiv2((FIXP_DBL)temp, MantissaTabler[exponent]);
+
+ /* + 1 compensates fMultDiv2() */
+ scaleValueInPlace(&value, scale + ExponentTabler[exponent] + 1);
+
+ signedValue = (signedValue < (FIXP_DBL)0) ? -value : value;
+ ptr[-1] = signedValue;
+ }
+ }
+}
+
+AAC_DECODER_ERROR CBlock_InverseQuantizeSpectralData(CAacDecoderChannelInfo *pAacDecoderChannelInfo, SamplingRateInfo *pSamplingRateInfo)
+{
+ int window, group, groupwin, band;
+ int ScaleFactorBandsTransmitted = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+ UCHAR *RESTRICT pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
+ SHORT *RESTRICT pSfbScale = pAacDecoderChannelInfo->pDynData->aSfbScale;
+ SHORT *RESTRICT pScaleFactor = pAacDecoderChannelInfo->pDynData->aScaleFactor;
+ const SHORT *RESTRICT BandOffsets = GetScaleFactorBandOffsets(&pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
+
+ FDKmemclear(pAacDecoderChannelInfo->pDynData->aSfbScale, (8*16)*sizeof(SHORT));
+
+ for (window=0, group=0; group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++)
+ {
+ for (groupwin=0; groupwin < GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo,group); groupwin++, window++)
+ {
+ /* inverse quantization */
+ for (band=0; band < ScaleFactorBandsTransmitted; band++)
+ {
+ FIXP_DBL *pSpectralCoefficient = SPEC(pAacDecoderChannelInfo->pSpectralCoefficient, window, pAacDecoderChannelInfo->granuleLength) + BandOffsets[band];
+
+ int noLines = BandOffsets[band+1] - BandOffsets[band];
+ int bnds = group*16+band;
+ int i;
+
+ if ((pCodeBook[bnds] == ZERO_HCB)
+ || (pCodeBook[bnds] == INTENSITY_HCB)
+ || (pCodeBook[bnds] == INTENSITY_HCB2)
+ )
+ continue;
+
+ if (pCodeBook[bnds] == NOISE_HCB)
+ {
+ /* Leave headroom for PNS values. + 1 because ceil(log2(2^(0.25*3))) = 1,
+ worst case of additional headroom required because of the scalefactor. */
+ pSfbScale[window*16+band] = (pScaleFactor [bnds] >> 2) + 1 ;
+ continue;
+ }
+
+ /* Find max spectral line value of the current sfb */
+ FIXP_DBL locMax = (FIXP_DBL)0;
+
+ for (i = noLines; i-- ; ) {
+ /* Expensive memory access */
+ locMax = fMax(fixp_abs(pSpectralCoefficient[i]), locMax);
+ }
+
+ /* Cheap robustness improvement - Do not remove!!! */
+ if (fixp_abs(locMax) > (FIXP_DBL)MAX_QUANTIZED_VALUE) {
+ return AAC_DEC_DECODE_FRAME_ERROR;
+ }
+
+ /*
+ The inverse quantized spectral lines are defined by:
+ pSpectralCoefficient[i] = Sign(pSpectralCoefficient[i]) * 2^(0.25*pScaleFactor[bnds]) * pSpectralCoefficient[i]^(4/3)
+ This is equivalent to:
+ pSpectralCoefficient[i] = Sign(pSpectralCoefficient[i]) * (2^(pScaleFactor[bnds] % 4) * pSpectralCoefficient[i]^(4/3))
+ pSpectralCoefficient_e[i] += pScaleFactor[bnds]/4
+ */
+ {
+ int msb = pScaleFactor [bnds] >> 2 ;
+ int lsb = pScaleFactor [bnds] & 0x03 ;
+
+ int scale = GetScaleFromValue(locMax, lsb);
+
+ pSfbScale[window*16+band] = msb - scale;
+ InverseQuantizeBand(pSpectralCoefficient, noLines, lsb, scale);
+ }
+ }
+ }
+ }
+
+
+ return AAC_DEC_OK;
+}
+
+
+AAC_DECODER_ERROR CBlock_ReadSpectralData(HANDLE_FDK_BITSTREAM bs,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo,
+ const UINT flags)
+{
+ int i,index;
+ int window,group,groupwin,groupoffset,band;
+ UCHAR *RESTRICT pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
+ const SHORT *RESTRICT BandOffsets = GetScaleFactorBandOffsets(&pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
+
+ SPECTRAL_PTR pSpectralCoefficient = pAacDecoderChannelInfo->pSpectralCoefficient;
+ FIXP_DBL locMax;
+
+ int ScaleFactorBandsTransmitted = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+
+ FDK_ASSERT(BandOffsets != NULL);
+
+ FDKmemclear(pSpectralCoefficient, sizeof(SPECTRUM));
+
+ if ( (flags & AC_ER_HCR) == 0 )
+ {
+ groupoffset = 0;
+
+ /* plain huffman decoder short */
+ for (group=0; group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++)
+ {
+ for (band=0; band < ScaleFactorBandsTransmitted; band++)
+ {
+ int bnds = group*16+band;
+ UCHAR currentCB = pCodeBook[bnds];
+
+ /* patch to run plain-huffman-decoder with vcb11 input codebooks (LAV-checking might be possible below using the virtual cb and a LAV-table) */
+ if ((currentCB >= 16) && (currentCB <= 31)) {
+ pCodeBook[bnds] = currentCB = 11;
+ }
+ if ( !((currentCB == ZERO_HCB)
+ || (currentCB == NOISE_HCB)
+ || (currentCB == INTENSITY_HCB)
+ || (currentCB == INTENSITY_HCB2)) )
+ {
+ const CodeBookDescription *hcb = &AACcodeBookDescriptionTable[currentCB];
+ int step = hcb->Dimension;
+ int offset = hcb->Offset;
+ int bits = hcb->numBits;
+ int mask = (1<<bits)-1;
+
+ for (groupwin=0; groupwin < GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo,group); groupwin++)
+ {
+ window = groupoffset + groupwin;
+
+ FIXP_DBL *mdctSpectrum = SPEC(pSpectralCoefficient, window, pAacDecoderChannelInfo->granuleLength);
+
+ locMax = (FIXP_DBL)0 ;
+
+ for (index=BandOffsets[band]; index < BandOffsets[band+1]; index+=step)
+ {
+ int idx = CBlock_DecodeHuffmanWord(bs,hcb);
+
+ for (i=0; i<step; i++) {
+ FIXP_DBL tmp;
+
+ tmp = (FIXP_DBL)((idx & mask)-offset);
+ idx >>= bits;
+
+ if (offset == 0) {
+ if (tmp != FIXP_DBL(0))
+ tmp = (FDKreadBits(bs,1))? -tmp : tmp;
+ }
+ mdctSpectrum[index+i] = tmp;
+ }
+
+ if (currentCB == ESCBOOK)
+ {
+ mdctSpectrum[index+0] = (FIXP_DBL)CBlock_GetEscape(bs, (LONG)mdctSpectrum[index+0]);
+ mdctSpectrum[index+1] = (FIXP_DBL)CBlock_GetEscape(bs, (LONG)mdctSpectrum[index+1]);
+
+ }
+ }
+ }
+ }
+ }
+ groupoffset += GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo,group);
+ }
+ /* plain huffman decoding (short) finished */
+ }
+ /* HCR - Huffman Codeword Reordering short */
+ else /* if ( flags & AC_ER_HCR ) */
+ {
+ H_HCR_INFO hHcr = &pAacDecoderChannelInfo->pComData->overlay.aac.erHcrInfo;
+ int hcrStatus = 0;
+ int hcrConcealWholeFrame = 0;
+
+ /* advanced Huffman decoding starts here (HCR decoding :) */
+ if ( pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfReorderedSpectralData != 0 ) {
+
+ /* HCR initialization short */
+ hcrStatus = HcrInit(hHcr, pAacDecoderChannelInfo, pSamplingRateInfo, bs);
+
+ if (hcrStatus != 0) {
+#if HCR_ERROR_CONCEALMENT
+ hcrConcealWholeFrame = 1;
+ return AAC_DEC_DECODE_FRAME_ERROR; /* concealment is muting in the first step, therefore return now */
+ // hcr decoding is not skipped because of returning above
+#else
+ return AAC_DEC_DECODE_FRAME_ERROR;
+#endif
+ }
+
+ /* HCR decoding short */
+ hcrStatus = HcrDecoder(hHcr, pAacDecoderChannelInfo, pSamplingRateInfo, bs);
+
+
+#if HCR_ERROR_CONCEALMENT
+ HcrMuteErroneousLines(hHcr);
+#else
+ return AAC_DEC_DECODE_FRAME_ERROR;
+#endif /* HCR_ERROR_CONCEALMENT */
+
+ FDKpushFor (bs, pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfReorderedSpectralData);
+ }
+ }
+ /* HCR - Huffman Codeword Reordering short finished */
+
+
+
+ if ( IsLongBlock(&pAacDecoderChannelInfo->icsInfo) && !(flags & (AC_ELD|AC_SCALABLE)) )
+ {
+ /* apply pulse data */
+ CPulseData_Apply(&pAacDecoderChannelInfo->pDynData->specificTo.aac.PulseData,
+ GetScaleFactorBandOffsets(&pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo),
+ SPEC_LONG(pSpectralCoefficient));
+ }
+
+
+ return AAC_DEC_OK;
+}
+
+
+
+void ApplyTools ( CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
+ const SamplingRateInfo *pSamplingRateInfo,
+ const UINT flags,
+ const int channel )
+{
+
+ if ( !(flags & (AC_USAC|AC_RSVD50|AC_MPS_RES)) ) {
+ CPns_Apply(
+ &pAacDecoderChannelInfo[channel]->data.aac.PnsData,
+ &pAacDecoderChannelInfo[channel]->icsInfo,
+ pAacDecoderChannelInfo[channel]->pSpectralCoefficient,
+ pAacDecoderChannelInfo[channel]->specScale,
+ pAacDecoderChannelInfo[channel]->pDynData->aScaleFactor,
+ pSamplingRateInfo,
+ pAacDecoderChannelInfo[channel]->granuleLength,
+ channel
+ );
+ }
+
+ CTns_Apply (
+ &pAacDecoderChannelInfo[channel]->pDynData->TnsData,
+ &pAacDecoderChannelInfo[channel]->icsInfo,
+ pAacDecoderChannelInfo[channel]->pSpectralCoefficient,
+ pSamplingRateInfo,
+ pAacDecoderChannelInfo[channel]->granuleLength
+ );
+}
+
+static
+int getWindow2Nr(int length, int shape)
+{
+ int nr = 0;
+
+ if (shape == 2) {
+ /* Low Overlap, 3/4 zeroed */
+ nr = (length * 3)>>2;
+ }
+
+ return nr;
+}
+
+void CBlock_FrequencyToTime(CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ INT_PCM outSamples[],
+ const SHORT frameLen,
+ const int stride,
+ const int frameOk,
+ FIXP_DBL *pWorkBuffer1 )
+{
+ int fr, fl, tl, nSamples, nSpec;
+
+ /* Determine left slope length (fl), right slope length (fr) and transform length (tl).
+ USAC: The slope length may mismatch with the previous frame in case of LPD / FD
+ transitions. The adjustment is handled by the imdct implementation.
+ */
+ tl = frameLen;
+ nSpec = 1;
+
+ switch( pAacDecoderChannelInfo->icsInfo.WindowSequence ) {
+ default:
+ case OnlyLongSequence:
+ fl = frameLen;
+ fr = frameLen - getWindow2Nr(frameLen, GetWindowShape(&pAacDecoderChannelInfo->icsInfo));
+ break;
+ case LongStopSequence:
+ fl = frameLen >> 3;
+ fr = frameLen;
+ break;
+ case LongStartSequence: /* or StopStartSequence */
+ fl = frameLen;
+ fr = frameLen >> 3;
+ break;
+ case EightShortSequence:
+ fl = fr = frameLen >> 3;
+ tl >>= 3;
+ nSpec = 8;
+ break;
+ }
+
+ {
+ int i;
+
+ {
+ FIXP_DBL *tmp = pAacDecoderChannelInfo->pComData->workBufferCore1->mdctOutTemp;
+
+ nSamples = imdct_block(
+ &pAacDecoderStaticChannelInfo->IMdct,
+ tmp,
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
+ pAacDecoderChannelInfo->specScale,
+ nSpec,
+ frameLen,
+ tl,
+ FDKgetWindowSlope(fl, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
+ fl,
+ FDKgetWindowSlope(fr, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
+ fr,
+ (FIXP_DBL)0 );
+
+ for (i=0; i<frameLen; i++) {
+ outSamples[i*stride] = IMDCT_SCALE(tmp[i]);
+ }
+ }
+ }
+
+ FDK_ASSERT(nSamples == frameLen);
+
+}
+
+#include "ldfiltbank.h"
+void CBlock_FrequencyToTimeLowDelay( CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ INT_PCM outSamples[],
+ const short frameLen,
+ const char stride )
+{
+ InvMdctTransformLowDelay_fdk (
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
+ pAacDecoderChannelInfo->specScale[0],
+ outSamples,
+ pAacDecoderStaticChannelInfo->pOverlapBuffer,
+ stride,
+ frameLen
+ );
+}