diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2012-07-11 10:15:24 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2012-07-11 10:15:24 -0700 |
commit | 2228e360595641dd906bf1773307f43d304f5b2e (patch) | |
tree | 57f3d390ebb0782cc0de0fb984c8ea7e45b4f386 /libAACdec/src/block.cpp | |
download | fdk-aac-dabplus-2228e360595641dd906bf1773307f43d304f5b2e.tar.gz fdk-aac-dabplus-2228e360595641dd906bf1773307f43d304f5b2e.tar.bz2 fdk-aac-dabplus-2228e360595641dd906bf1773307f43d304f5b2e.zip |
Snapshot 2bda038c163298531d47394bc2c09e1409c5d0db
Change-Id: If584e579464f28b97d50e51fc76ba654a5536c54
Diffstat (limited to 'libAACdec/src/block.cpp')
-rw-r--r-- | libAACdec/src/block.cpp | 765 |
1 files changed, 765 insertions, 0 deletions
diff --git a/libAACdec/src/block.cpp b/libAACdec/src/block.cpp new file mode 100644 index 0000000..1f82780 --- /dev/null +++ b/libAACdec/src/block.cpp @@ -0,0 +1,765 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2012 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/***************************** MPEG-4 AAC Decoder ************************** + + Author(s): Josef Hoepfl + Description: long/short-block decoding + +******************************************************************************/ + +#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 + ); +} |