/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android © Copyright 1995 - 2018 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 ----------------------------------------------------------------------------- */ /**************************** AAC decoder library ****************************** Author(s): Josef Hoepfl Description: long/short-block decoding *******************************************************************************/ #include "block.h" #include "aac_rom.h" #include "FDK_bitstream.h" #include "scale.h" #include "FDK_tools_rom.h" #include "usacdec_fac.h" #include "usacdec_lpd.h" #include "usacdec_lpc.h" #include "FDK_trigFcts.h" #include "ac_arith_coder.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. A limitation is implemented to maximal 31 bits to prevent endless loops. If it strikes, MAX_QUANTIZED_VALUE + 1 is returned, independent of the sign of parameter q. \return quantized coefficient */ LONG CBlock_GetEscape(HANDLE_FDK_BITSTREAM bs, /*!< pointer to bitstream */ const LONG q) /*!< quantized coefficient */ { if (fAbs(q) != 16) return (q); LONG i, off; for (i = 4; i < 32; i++) { if (FDKreadBit(bs) == 0) break; } if (i == 32) return (MAX_QUANTIZED_VALUE + 1); off = FDKreadBits(bs, i); i = off + (1 << i); if (q < 0) 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]; const USHORT(*CodeBook)[HuffmanEntries] = hcb->CodeBook; int ScaleFactorBandsTransmitted = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo); for (group = 0; group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++) { for (band = 0; band < ScaleFactorBandsTransmitted; band++) { switch (pCodeBook[band]) { case ZERO_HCB: /* zero book */ pScaleFactor[band] = 0; break; default: /* decode scale factor */ if (!((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) && band == 0 && group == 0)) { temp = CBlock_DecodeHuffmanWordCB(bs, CodeBook); factor += temp - 60; /* MIDFAC 1.5 dB */ } pScaleFactor[band] = factor - 100; break; case INTENSITY_HCB: /* intensity steering */ case INTENSITY_HCB2: temp = CBlock_DecodeHuffmanWordCB(bs, CodeBook); position += temp - 60; pScaleFactor[band] = position - 100; break; case NOISE_HCB: /* PNS */ if (flags & (AC_MPEGD_RES | AC_USAC | AC_RSVD50 | AC_RSV603DA)) { return AAC_DEC_PARSE_ERROR; } CPns_Read(&pAacDecoderChannelInfo->data.aac.PnsData, bs, hcb, pAacDecoderChannelInfo->pDynData->aScaleFactor, pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain, band, group); break; } } pCodeBook += 16; pScaleFactor += 16; } return AAC_DEC_OK; } void CBlock_ScaleSpectralData(CAacDecoderChannelInfo *pAacDecoderChannelInfo, UCHAR maxSfbs, 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)); 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 < maxSfbs; band++) { SpecScale_window = fMax(SpecScale_window, (int)pSfbScale[window * 16 + band]); } if (pAacDecoderChannelInfo->pDynData->TnsData.Active && pAacDecoderChannelInfo->pDynData->TnsData.NumberOfFilters[window] > 0) { int filter_index, SpecScale_window_tns; int tns_start, tns_stop; /* Find max scale of TNS bands */ SpecScale_window_tns = 0; tns_start = GetMaximumTnsBands(&pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo->samplingRateIndex); tns_stop = 0; for (filter_index = 0; filter_index < (int)pAacDecoderChannelInfo->pDynData->TnsData .NumberOfFilters[window]; filter_index++) { for (band = pAacDecoderChannelInfo->pDynData->TnsData .Filter[window][filter_index] .StartBand; band < pAacDecoderChannelInfo->pDynData->TnsData .Filter[window][filter_index] .StopBand; band++) { SpecScale_window_tns = fMax(SpecScale_window_tns, (int)pSfbScale[window * 16 + band]); } /* Find TNS line boundaries for all TNS filters */ tns_start = fMin(tns_start, (int)pAacDecoderChannelInfo->pDynData->TnsData .Filter[window][filter_index] .StartBand); tns_stop = fMax(tns_stop, (int)pAacDecoderChannelInfo->pDynData->TnsData .Filter[window][filter_index] .StopBand); } SpecScale_window_tns = SpecScale_window_tns + pAacDecoderChannelInfo->pDynData->TnsData.GainLd; FDK_ASSERT(tns_stop >= tns_start); /* Consider existing headroom of all MDCT lines inside the TNS bands. */ SpecScale_window_tns -= getScalefactor(pSpectrum + BandOffsets[tns_start], BandOffsets[tns_stop] - BandOffsets[tns_start]); if (SpecScale_window <= 17) { SpecScale_window_tns++; } /* Add enough mantissa head room such that the spectrum is still representable after applying TNS. */ SpecScale_window = fMax(SpecScale_window, SpecScale_window_tns); } /* store scaling of current window */ pSpecScale[window] = SpecScale_window; #ifdef FUNCTION_CBlock_ScaleSpectralData_func1 CBlock_ScaleSpectralData_func1(pSpectrum, maxSfbs, BandOffsets, SpecScale_window, pSfbScale, window); #else /* FUNCTION_CBlock_ScaleSpectralData_func1 */ for (band = 0; band < maxSfbs; band++) { int scale = fMin(DFRACT_BITS - 1, SpecScale_window - pSfbScale[window * 16 + band]); if (scale) { FDK_ASSERT(scale > 0); /* following relation can be used for optimizations: * (BandOffsets[i]%4) == 0 for all i */ int max_index = BandOffsets[band + 1]; DWORD_ALIGNED(pSpectrum); 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) */ if (numLinesInSecIdx >= MAX_SFB_HCR) { return AAC_DEC_PARSE_ERROR; } if (top > (int)GetNumberOfScaleFactorBands( &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo)) { return AAC_DEC_PARSE_ERROR; } pNumLinesInSec[numLinesInSecIdx] = BandOffsets[top] - BandOffsets[band]; numLinesInSecIdx++; 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 inline void InverseQuantizeBand( FIXP_DBL *RESTRICT spectrum, const FIXP_DBL *RESTRICT InverseQuantTabler, const FIXP_DBL *RESTRICT MantissaTabler, const SCHAR *RESTRICT ExponentTabler, INT noLines, INT scale) { scale = scale + 1; /* +1 to compensate fMultDiv2 shift-right in loop */ FIXP_DBL *RESTRICT ptr = spectrum; FIXP_DBL signedValue; 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]); signedValue = (signedValue < (FIXP_DBL)0) ? -value : value; ptr[-1] = signedValue; } } } static inline FIXP_DBL maxabs_D(const FIXP_DBL *pSpectralCoefficient, const int noLines) { /* Find max spectral line value of the current sfb */ FIXP_DBL locMax = (FIXP_DBL)0; int i; DWORD_ALIGNED(pSpectralCoefficient); for (i = noLines; i-- > 0;) { /* Expensive memory access */ locMax = fMax(fixp_abs(pSpectralCoefficient[i]), locMax); } return locMax; } AAC_DECODER_ERROR CBlock_InverseQuantizeSpectralData( CAacDecoderChannelInfo *pAacDecoderChannelInfo, SamplingRateInfo *pSamplingRateInfo, UCHAR *band_is_noise, UCHAR active_band_search) { 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); const SHORT total_bands = GetScaleFactorBandsTotal(&pAacDecoderChannelInfo->icsInfo); 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]; FIXP_DBL locMax; const int noLines = BandOffsets[band + 1] - BandOffsets[band]; const int bnds = group * 16 + band; 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; } locMax = maxabs_D(pSpectralCoefficient, noLines); if (active_band_search) { if (locMax != FIXP_DBL(0)) { band_is_noise[group * 16 + band] = 0; } } /* Cheap robustness improvement - Do not remove!!! */ if (fixp_abs(locMax) > (FIXP_DBL)MAX_QUANTIZED_VALUE) { return AAC_DEC_PARSE_ERROR; } /* Added by Youliy Ninov: The inverse quantization operation is given by (ISO/IEC 14496-3:2009(E)) by: x_invquant=Sign(x_quant). abs(x_quant)^(4/3) We apply a gain, derived from the scale factor for the particular sfb, according to the following function: gain=2^(0.25*ScaleFactor) So, after scaling we have: x_rescale=gain*x_invquant=Sign(x_quant)*2^(0.25*ScaleFactor)*abs(s_quant)^(4/3) We could represent the ScaleFactor as: ScaleFactor= (ScaleFactor >> 2)*4 + ScaleFactor %4 When we substitute it we get: x_rescale=Sign(x_quant)*2^(ScaleFactor>>2)* ( 2^(0.25*(ScaleFactor%4))*abs(s_quant)^(4/3)) When we set: msb=(ScaleFactor>>2) and lsb=(ScaleFactor%4), we obtain: x_rescale=Sign(x_quant)*(2^msb)* ( 2^(lsb/4)*abs(s_quant)^(4/3)) The rescaled output can be represented by: mantissa : Sign(x_quant)*( 2^(lsb/4)*abs(s_quant)^(4/3)) exponent :(2^msb) */ int msb = pScaleFactor[bnds] >> 2; /* Inverse quantize band only if it is not empty */ if (locMax != FIXP_DBL(0)) { int lsb = pScaleFactor[bnds] & 0x03; int scale = EvaluatePower43(&locMax, lsb); scale = CntLeadingZeros(locMax) - scale - 2; pSfbScale[window * 16 + band] = msb - scale; InverseQuantizeBand(pSpectralCoefficient, InverseQuantTable, MantissaTable[lsb], ExponentTable[lsb], noLines, scale); } else { pSfbScale[window * 16 + band] = msb; } } /* for (band=0; band < ScaleFactorBandsTransmitted; band++) */ /* Make sure the array is cleared to the end */ SHORT start_clear = BandOffsets[ScaleFactorBandsTransmitted]; SHORT end_clear = BandOffsets[total_bands]; int diff_clear = (int)(end_clear - start_clear); FIXP_DBL *pSpectralCoefficient = SPEC(pAacDecoderChannelInfo->pSpectralCoefficient, window, pAacDecoderChannelInfo->granuleLength) + start_clear; FDKmemclear(pSpectralCoefficient, diff_clear * sizeof(FIXP_DBL)); } /* for (groupwin=0; groupwin < GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo,group); groupwin++, window++) */ } /* for (window=0, group=0; group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++)*/ return AAC_DEC_OK; } AAC_DECODER_ERROR CBlock_ReadSpectralData( HANDLE_FDK_BITSTREAM bs, CAacDecoderChannelInfo *pAacDecoderChannelInfo, const SamplingRateInfo *pSamplingRateInfo, const UINT flags) { int index, i; const SHORT *RESTRICT BandOffsets = GetScaleFactorBandOffsets( &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo); SPECTRAL_PTR pSpectralCoefficient = pAacDecoderChannelInfo->pSpectralCoefficient; FDK_ASSERT(BandOffsets != NULL); FDKmemclear(pSpectralCoefficient, sizeof(SPECTRUM)); if ((flags & AC_ER_HCR) == 0) { int group; int groupoffset; UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook; int ScaleFactorBandsTransmitted = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo); int granuleLength = pAacDecoderChannelInfo->granuleLength; groupoffset = 0; /* plain huffman decoder short */ int max_group = GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); for (group = 0; group < max_group; group++) { int max_groupwin = GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, group); int band; int bnds = group * 16; int bandOffset1 = BandOffsets[0]; for (band = 0; band < ScaleFactorBandsTransmitted; band++, bnds++) { UCHAR currentCB = pCodeBook[bnds]; int bandOffset0 = bandOffset1; bandOffset1 = BandOffsets[band + 1]; /* 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; const USHORT(*CodeBook)[HuffmanEntries] = hcb->CodeBook; int groupwin; FIXP_DBL *mdctSpectrum = &pSpectralCoefficient[groupoffset * granuleLength]; if (offset == 0) { for (groupwin = 0; groupwin < max_groupwin; groupwin++) { for (index = bandOffset0; index < bandOffset1; index += step) { int idx = CBlock_DecodeHuffmanWordCB(bs, CodeBook); for (i = 0; i < step; i++, idx >>= bits) { FIXP_DBL tmp = (FIXP_DBL)((idx & mask) - offset); if (tmp != FIXP_DBL(0)) tmp = (FDKreadBit(bs)) ? -tmp : tmp; mdctSpectrum[index + i] = tmp; } if (currentCB == ESCBOOK) { for (int j = 0; j < 2; j++) mdctSpectrum[index + j] = (FIXP_DBL)CBlock_GetEscape( bs, (LONG)mdctSpectrum[index + j]); } } mdctSpectrum += granuleLength; } } else { for (groupwin = 0; groupwin < max_groupwin; groupwin++) { for (index = bandOffset0; index < bandOffset1; index += step) { int idx = CBlock_DecodeHuffmanWordCB(bs, CodeBook); for (i = 0; i < step; i++, idx >>= bits) { mdctSpectrum[index + i] = (FIXP_DBL)((idx & mask) - offset); } if (currentCB == ESCBOOK) { for (int j = 0; j < 2; j++) mdctSpectrum[index + j] = (FIXP_DBL)CBlock_GetEscape( bs, (LONG)mdctSpectrum[index + j]); } } mdctSpectrum += granuleLength; } } } } groupoffset += max_groupwin; } /* 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; /* 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) { return AAC_DEC_DECODE_FRAME_ERROR; } /* HCR decoding short */ hcrStatus = HcrDecoder(hHcr, pAacDecoderChannelInfo, pSamplingRateInfo, bs); if (hcrStatus != 0) { #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; } static const FIXP_SGL noise_level_tab[8] = { /* FDKpow(2, (float)(noise_level-14)/3.0f) * 2; (*2 to compensate for fMultDiv2) noise_level_tab(noise_level==0) == 0 by definition */ FX_DBL2FXCONST_SGL(0x00000000 /*0x0a145173*/), FX_DBL2FXCONST_SGL(0x0cb2ff5e), FX_DBL2FXCONST_SGL(0x10000000), FX_DBL2FXCONST_SGL(0x1428a2e7), FX_DBL2FXCONST_SGL(0x1965febd), FX_DBL2FXCONST_SGL(0x20000000), FX_DBL2FXCONST_SGL(0x28514606), FX_DBL2FXCONST_SGL(0x32cbfd33)}; void CBlock_ApplyNoise(CAacDecoderChannelInfo *pAacDecoderChannelInfo, SamplingRateInfo *pSamplingRateInfo, ULONG *nfRandomSeed, UCHAR *band_is_noise) { const SHORT *swb_offset = GetScaleFactorBandOffsets( &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo); int g, win, gwin, sfb, noiseFillingStartOffset, nfStartOffset_sfb; /* Obtain noise level and scale factor offset. */ int noise_level = pAacDecoderChannelInfo->pDynData->specificTo.usac .fd_noise_level_and_offset >> 5; const FIXP_SGL noiseVal_pos = noise_level_tab[noise_level]; /* noise_offset can change even when noise_level=0. Neccesary for IGF stereo * filling */ const int noise_offset = (pAacDecoderChannelInfo->pDynData->specificTo.usac .fd_noise_level_and_offset & 0x1f) - 16; int max_sfb = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo); noiseFillingStartOffset = (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) ? 20 : 160; if (pAacDecoderChannelInfo->granuleLength == 96) { noiseFillingStartOffset = (3 * noiseFillingStartOffset) / 4; /* scale offset with 3/4 for coreCoderFrameLength == 768 */ } /* determine sfb from where on noise filling is applied */ for (sfb = 0; swb_offset[sfb] < noiseFillingStartOffset; sfb++) ; nfStartOffset_sfb = sfb; /* if (noise_level!=0) */ { for (g = 0, win = 0; g < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); g++) { int windowGroupLength = GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, g); for (sfb = nfStartOffset_sfb; sfb < max_sfb; sfb++) { int bin_start = swb_offset[sfb]; int bin_stop = swb_offset[sfb + 1]; int flagN = band_is_noise[g * 16 + sfb]; /* if all bins of one sfb in one window group are zero modify the scale * factor by noise_offset */ if (flagN) { /* Change scaling factors for empty signal bands */ pAacDecoderChannelInfo->pDynData->aScaleFactor[g * 16 + sfb] += noise_offset; /* scale factor "sf" implied gain "g" is g = 2^(sf/4) */ for (gwin = 0; gwin < windowGroupLength; gwin++) { pAacDecoderChannelInfo->pDynData ->aSfbScale[(win + gwin) * 16 + sfb] += (noise_offset >> 2); } } ULONG seed = *nfRandomSeed; /* + 1 because exponent of MantissaTable[lsb][0] is always 1. */ int scale = (pAacDecoderChannelInfo->pDynData->aScaleFactor[g * 16 + sfb] >> 2) + 1; int lsb = pAacDecoderChannelInfo->pDynData->aScaleFactor[g * 16 + sfb] & 3; FIXP_DBL mantissa = MantissaTable[lsb][0]; for (gwin = 0; gwin < windowGroupLength; gwin++) { FIXP_DBL *pSpec = SPEC(pAacDecoderChannelInfo->pSpectralCoefficient, win + gwin, pAacDecoderChannelInfo->granuleLength); int scale1 = scale - pAacDecoderChannelInfo->pDynData ->aSfbScale[(win + gwin) * 16 + sfb]; FIXP_DBL scaled_noiseVal_pos = scaleValue(fMultDiv2(noiseVal_pos, mantissa), scale1); FIXP_DBL scaled_noiseVal_neg = -scaled_noiseVal_pos; /* If the whole band is zero, just fill without checking */ if (flagN) { for (int bin = bin_start; bin < bin_stop; bin++) { seed = (ULONG)( (UINT64)seed * 69069 + 5); /* Inlined: UsacRandomSign - origin in usacdec_lpd.h */ pSpec[bin] = (seed & 0x10000) ? scaled_noiseVal_neg : scaled_noiseVal_pos; } /* for (bin...) */ } /*If band is sparsely filled, check for 0 and fill */ else { for (int bin = bin_start; bin < bin_stop; bin++) { if (pSpec[bin] == (FIXP_DBL)0) { seed = (ULONG)( (UINT64)seed * 69069 + 5); /* Inlined: UsacRandomSign - origin in usacdec_lpd.h */ pSpec[bin] = (seed & 0x10000) ? scaled_noiseVal_neg : scaled_noiseVal_pos; } } /* for (bin...) */ } } /* for (gwin...) */ *nfRandomSeed = seed; } /* for (sfb...) */ win += windowGroupLength; } /* for (g...) */ } /* ... */ } AAC_DECODER_ERROR CBlock_ReadAcSpectralData( HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo, CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, const SamplingRateInfo *pSamplingRateInfo, const UINT frame_length, const UINT flags) { AAC_DECODER_ERROR errorAAC = AAC_DEC_OK; ARITH_CODING_ERROR error = ARITH_CODER_OK; int arith_reset_flag, lg, numWin, win, winLen; const SHORT *RESTRICT BandOffsets; /* number of transmitted spectral coefficients */ BandOffsets = GetScaleFactorBandOffsets(&pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo); lg = BandOffsets[GetScaleFactorBandsTransmitted( &pAacDecoderChannelInfo->icsInfo)]; numWin = GetWindowsPerFrame(&pAacDecoderChannelInfo->icsInfo); winLen = (IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) ? (int)frame_length : (int)frame_length / numWin; if (flags & AC_INDEP) { arith_reset_flag = 1; } else { arith_reset_flag = (USHORT)FDKreadBits(hBs, 1); } for (win = 0; win < numWin; win++) { error = CArco_DecodeArithData(pAacDecoderStaticChannelInfo->hArCo, hBs, SPEC(pAacDecoderChannelInfo->pSpectralCoefficient, win, pAacDecoderChannelInfo->granuleLength), lg, winLen, arith_reset_flag && (win == 0)); if (error != ARITH_CODER_OK) { goto bail; } } bail: if (error == ARITH_CODER_ERROR) { errorAAC = AAC_DEC_PARSE_ERROR; } return errorAAC; } void ApplyTools(CAacDecoderChannelInfo *pAacDecoderChannelInfo[], const SamplingRateInfo *pSamplingRateInfo, const UINT flags, const UINT elFlags, const int channel, const int common_window) { if (!(flags & (AC_USAC | AC_RSVD50 | AC_MPEGD_RES | AC_RSV603DA))) { 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); } UCHAR nbands = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[channel]->icsInfo); CTns_Apply(&pAacDecoderChannelInfo[channel]->pDynData->TnsData, &pAacDecoderChannelInfo[channel]->icsInfo, pAacDecoderChannelInfo[channel]->pSpectralCoefficient, pSamplingRateInfo, pAacDecoderChannelInfo[channel]->granuleLength, nbands, (elFlags & AC_EL_ENHANCED_NOISE) ? 1 : 0, flags); } static int getWindow2Nr(int length, int shape) { int nr = 0; if (shape == 2) { /* Low Overlap, 3/4 zeroed */ nr = (length * 3) >> 2; } return nr; } FIXP_DBL get_gain(const FIXP_DBL *x, const FIXP_DBL *y, int n) { FIXP_DBL corr = (FIXP_DBL)0; FIXP_DBL ener = (FIXP_DBL)1; int headroom_x = getScalefactor(x, n); int headroom_y = getScalefactor(y, n); /*Calculate the normalization necessary due to addition*/ /* Check for power of two /special case */ INT width_shift = (INT)(fNormz((FIXP_DBL)n)); /* Get the number of bits necessary minus one, because we need one sign bit * only */ width_shift = 31 - width_shift; for (int i = 0; i < n; i++) { corr += fMultDiv2((x[i] << headroom_x), (y[i] << headroom_y)) >> width_shift; ener += fPow2Div2((y[i] << headroom_y)) >> width_shift; } int exp_corr = (17 - headroom_x) + (17 - headroom_y) + width_shift + 1; int exp_ener = ((17 - headroom_y) << 1) + width_shift + 1; int temp_exp = 0; FIXP_DBL output = fDivNormSigned(corr, ener, &temp_exp); int output_exp = (exp_corr - exp_ener) + temp_exp; INT output_shift = 17 - output_exp; output_shift = fMin(output_shift, 31); output = scaleValue(output, -output_shift); return output; } void CBlock_FrequencyToTime( CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[], const SHORT frameLen, const int frameOk, FIXP_DBL *pWorkBuffer1, UINT elFlags, INT elCh) { int fr, fl, tl, nSpec; #if defined(FDK_ASSERT_ENABLE) LONG nSamples; #endif /* 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 BLOCK_LONG: fl = frameLen; fr = frameLen - getWindow2Nr(frameLen, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)); /* New startup needs differentiation between sine shape and low overlap shape. This is a special case for the LD-AAC transformation windows, because the slope length can be different while using the same window sequence. */ if (pAacDecoderStaticChannelInfo->IMdct.prev_tl == 0) { fl = fr; } break; case BLOCK_STOP: fl = frameLen >> 3; fr = frameLen; break; case BLOCK_START: /* or StopStartSequence */ fl = frameLen; fr = frameLen >> 3; break; case BLOCK_SHORT: fl = fr = frameLen >> 3; tl >>= 3; nSpec = 8; break; } { int last_frame_lost = pAacDecoderStaticChannelInfo->last_lpc_lost; if (pAacDecoderStaticChannelInfo->last_core_mode == LPD) { INT fac_FB = 1; if (elFlags & AC_EL_FULLBANDLPD) { fac_FB = 2; } FIXP_DBL *synth; /* Keep some free space at the beginning of the buffer. To be used for * past data */ if (!(elFlags & AC_EL_LPDSTEREOIDX)) { synth = pWorkBuffer1 + ((PIT_MAX_MAX - (1 * L_SUBFR)) * fac_FB); } else { synth = pWorkBuffer1 + PIT_MAX_MAX * fac_FB; } int fac_length = (pAacDecoderChannelInfo->icsInfo.WindowSequence == BLOCK_SHORT) ? (frameLen >> 4) : (frameLen >> 3); INT pitch[NB_SUBFR_SUPERFR + SYN_SFD]; FIXP_DBL pit_gain[NB_SUBFR_SUPERFR + SYN_SFD]; int nbDiv = (elFlags & AC_EL_FULLBANDLPD) ? 2 : 4; int lFrame = (elFlags & AC_EL_FULLBANDLPD) ? frameLen / 2 : frameLen; int nbSubfr = lFrame / (nbDiv * L_SUBFR); /* number of subframes per division */ int LpdSfd = (nbDiv * nbSubfr) >> 1; int SynSfd = LpdSfd - BPF_SFD; FDKmemclear( pitch, sizeof( pitch)); // added to prevent ferret errors in bass_pf_1sf_delay FDKmemclear(pit_gain, sizeof(pit_gain)); /* FAC case */ if (pAacDecoderStaticChannelInfo->last_lpd_mode == 0 || pAacDecoderStaticChannelInfo->last_lpd_mode == 4) { FIXP_DBL fac_buf[LFAC]; FIXP_LPC *A = pAacDecoderChannelInfo->data.usac.lp_coeff[0]; if (!frameOk || last_frame_lost || (pAacDecoderChannelInfo->data.usac.fac_data[0] == NULL)) { FDKmemclear(fac_buf, pAacDecoderChannelInfo->granuleLength * sizeof(FIXP_DBL)); pAacDecoderChannelInfo->data.usac.fac_data[0] = fac_buf; pAacDecoderChannelInfo->data.usac.fac_data_e[0] = 0; } INT A_exp; /* linear prediction coefficients exponent */ { for (int i = 0; i < M_LP_FILTER_ORDER; i++) { A[i] = FX_DBL2FX_LPC(fixp_cos( fMult(pAacDecoderStaticChannelInfo->lpc4_lsf[i], FL2FXCONST_SGL((1 << LSPARG_SCALE) * M_PI / 6400.0)), LSF_SCALE - LSPARG_SCALE)); } E_LPC_f_lsp_a_conversion(A, A, &A_exp); } #if defined(FDK_ASSERT_ENABLE) nSamples = #endif CLpd_FAC_Acelp2Mdct( &pAacDecoderStaticChannelInfo->IMdct, synth, SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient), pAacDecoderChannelInfo->specScale, nSpec, pAacDecoderChannelInfo->data.usac.fac_data[0], pAacDecoderChannelInfo->data.usac.fac_data_e[0], fac_length, frameLen, tl, FDKgetWindowSlope( fr, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)), fr, A, A_exp, &pAacDecoderStaticChannelInfo->acelp, (FIXP_DBL)0, /* FAC gain has already been applied. */ (last_frame_lost || !frameOk), 1, pAacDecoderStaticChannelInfo->last_lpd_mode, 0, pAacDecoderChannelInfo->currAliasingSymmetry); } else { #if defined(FDK_ASSERT_ENABLE) nSamples = #endif imlt_block( &pAacDecoderStaticChannelInfo->IMdct, synth, SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient), pAacDecoderChannelInfo->specScale, nSpec, frameLen, tl, FDKgetWindowSlope( fl, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)), fl, FDKgetWindowSlope( fr, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)), fr, (FIXP_DBL)0, pAacDecoderChannelInfo->currAliasingSymmetry ? MLT_FLAG_CURR_ALIAS_SYMMETRY : 0); } FDK_ASSERT(nSamples == frameLen); /* The "if" clause is entered both for fullbandLpd mono and * non-fullbandLpd*. The "else"-> just for fullbandLpd stereo*/ if (!(elFlags & AC_EL_LPDSTEREOIDX)) { FDKmemcpy(pitch, pAacDecoderStaticChannelInfo->old_T_pf, SynSfd * sizeof(INT)); FDKmemcpy(pit_gain, pAacDecoderStaticChannelInfo->old_gain_pf, SynSfd * sizeof(FIXP_DBL)); for (int i = SynSfd; i < LpdSfd + 3; i++) { pitch[i] = L_SUBFR; pit_gain[i] = (FIXP_DBL)0; } if (pAacDecoderStaticChannelInfo->last_lpd_mode == 0) { pitch[SynSfd] = pitch[SynSfd - 1]; pit_gain[SynSfd] = pit_gain[SynSfd - 1]; if (IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) { pitch[SynSfd + 1] = pitch[SynSfd]; pit_gain[SynSfd + 1] = pit_gain[SynSfd]; } } /* Copy old data to the beginning of the buffer */ { FDKmemcpy( pWorkBuffer1, pAacDecoderStaticChannelInfo->old_synth, ((PIT_MAX_MAX - (1 * L_SUBFR)) * fac_FB) * sizeof(FIXP_DBL)); } FIXP_DBL *p2_synth = pWorkBuffer1 + (PIT_MAX_MAX * fac_FB); /* recalculate pitch gain to allow postfilering on FAC area */ for (int i = 0; i < SynSfd + 2; i++) { int T = pitch[i]; FIXP_DBL gain = pit_gain[i]; if (gain > (FIXP_DBL)0) { gain = get_gain(&p2_synth[i * L_SUBFR * fac_FB], &p2_synth[(i * L_SUBFR * fac_FB) - fac_FB * T], L_SUBFR * fac_FB); pit_gain[i] = gain; } } bass_pf_1sf_delay(p2_synth, pitch, pit_gain, frameLen, (LpdSfd + 2) * L_SUBFR + BPF_SFD * L_SUBFR, frameLen - (LpdSfd + 4) * L_SUBFR, outSamples, pAacDecoderStaticChannelInfo->mem_bpf); } } else /* last_core_mode was not LPD */ { FIXP_DBL *tmp = pAacDecoderChannelInfo->pComStaticData->pWorkBufferCore1->mdctOutTemp; #if defined(FDK_ASSERT_ENABLE) nSamples = #endif imlt_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, pAacDecoderChannelInfo->currAliasingSymmetry ? MLT_FLAG_CURR_ALIAS_SYMMETRY : 0); scaleValuesSaturate(outSamples, tmp, frameLen, MDCT_OUT_HEADROOM); } } FDK_ASSERT(nSamples == frameLen); pAacDecoderStaticChannelInfo->last_core_mode = (pAacDecoderChannelInfo->icsInfo.WindowSequence == BLOCK_SHORT) ? FD_SHORT : FD_LONG; pAacDecoderStaticChannelInfo->last_lpd_mode = 255; } #include "ldfiltbank.h" void CBlock_FrequencyToTimeLowDelay( CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[], const short frameLen) { InvMdctTransformLowDelay_fdk( SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient), pAacDecoderChannelInfo->specScale[0], outSamples, pAacDecoderStaticChannelInfo->pOverlapBuffer, frameLen); }