aboutsummaryrefslogtreecommitdiffstats
path: root/libAACdec/src/block.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libAACdec/src/block.cpp')
-rw-r--r--libAACdec/src/block.cpp1372
1 files changed, 936 insertions, 436 deletions
diff --git a/libAACdec/src/block.cpp b/libAACdec/src/block.cpp
index a19284e..7d2a4b9 100644
--- a/libAACdec/src/block.cpp
+++ b/libAACdec/src/block.cpp
@@ -1,74 +1,85 @@
-
-/* -----------------------------------------------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
- All rights reserved.
+© 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.
+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:
+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 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
+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.
+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.
+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."
+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.
+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.
+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.
+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
@@ -79,28 +90,33 @@ Am Wolfsmantel 33
www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------------------------------------ */
+----------------------------------------------------------------------------- */
-/***************************** MPEG-4 AAC Decoder **************************
+/**************************** 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
@@ -111,135 +127,169 @@ amm-info@iis.fraunhofer.de
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 */
+ const LONG q) /*!< quantized coefficient */
{
- LONG i, off, neg ;
+ if (fAbs(q) != 16) return (q);
- if (q < 0)
- {
- if (q != -16) return q;
- neg = 1;
- }
- else
- {
- if (q != +16) return q;
- neg = 0;
+ LONG i, off;
+ for (i = 4; i < 32; i++) {
+ if (FDKreadBit(bs) == 0) break;
}
- 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);
- }
+ if (i == 32) return (MAX_QUANTIZED_VALUE + 1);
+ off = FDKreadBits(bs, i);
i = off + (1 << i);
- if (neg) i = -i;
+ if (q < 0) i = -i;
return i;
}
AAC_DECODER_ERROR CBlock_ReadScaleFactorData(
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
- HANDLE_FDK_BITSTREAM bs,
- UINT flags
- )
-{
+ 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 */
+ 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;
+ 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, SamplingRateInfo *pSamplingRateInfo)
-{
+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));
-
- 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++)
- {
+ 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);
+ 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]);
+ for (band = 0; band < maxSfbs; band++) {
+ SpecScale_window =
+ fMax(SpecScale_window, (int)pSfbScale[window * 16 + band]);
}
- if (pAacDecoderChannelInfo->pDynData->TnsData.Active) {
- SpecScale_window += TNS_SCALE;
+ 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 */
@@ -247,79 +297,80 @@ void CBlock_ScaleSpectralData(CAacDecoderChannelInfo *pAacDecoderChannelInfo, Sa
#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++)
- {
+ 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 */
+#endif /* FUNCTION_CBlock_ScaleSpectralData_func1 */
}
}
-
}
-AAC_DECODER_ERROR CBlock_ReadSectionData(HANDLE_FDK_BITSTREAM bs,
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
- const SamplingRateInfo *pSamplingRateInfo,
- const UINT flags)
-{
+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);
+ 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));
+ FDKmemclear(pCodeBook, sizeof(UCHAR) * (8 * 16));
- const int nbits = (IsLongBlock(&pAacDecoderChannelInfo->icsInfo) == 1) ? 5 : 3;
+ const int nbits =
+ (IsLongBlock(&pAacDecoderChannelInfo->icsInfo) == 1) ? 5 : 3;
- int sect_esc_val = (1 << nbits) - 1 ;
+ 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; )
- {
+ 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) {
+ 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)) ) {
+ 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)
- {
+ while (sect_len_incr == sect_esc_val) {
sect_len += sect_esc_val;
sect_len_incr = FDKreadBits(bs, nbits);
}
- }
- else {
+ } else {
sect_len_incr = 1;
}
sect_len += sect_len_incr;
-
top = band + sect_len;
if (flags & AC_ER_HCR) {
@@ -327,10 +378,13 @@ AAC_DECODER_ERROR CBlock_ReadSectionData(HANDLE_FDK_BITSTREAM bs,
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)
- {
+ if (sect_cb == BOOKSCL) {
return AAC_DEC_INVALID_CODE_BOOK;
} else {
*pHcrCodeBook++ = sect_cb;
@@ -339,259 +393,340 @@ AAC_DECODER_ERROR CBlock_ReadSectionData(HANDLE_FDK_BITSTREAM bs,
}
/* Check spectral line limits */
- if (IsLongBlock( &(pAacDecoderChannelInfo->icsInfo) ))
- {
+ if (IsLongBlock(&(pAacDecoderChannelInfo->icsInfo))) {
if (top > 64) {
return AAC_DEC_DECODE_FRAME_ERROR;
}
} else { /* short block */
- if (top + group*16 > (8 * 16)) {
+ 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)
- )
- {
+ 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;
+ 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).
+ * \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];
+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 *ptr = spectrum;
- FIXP_DBL signedValue;
+ FIXP_DBL *RESTRICT 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;
+ 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 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);
+ 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]);
+ value = fMultDiv2((FIXP_DBL)temp, MantissaTabler[exponent]);
- /* + 1 compensates fMultDiv2() */
- scaleValueInPlace(&value, scale + ExponentTabler[exponent] + 1);
+ /* + 1 compensates fMultDiv2() */
+ scaleValueInPlace(&value, scale + ExponentTabler[exponent]);
- signedValue = (signedValue < (FIXP_DBL)0) ? -value : value;
- ptr[-1] = signedValue;
- }
+ signedValue = (signedValue < (FIXP_DBL)0) ? -value : value;
+ ptr[-1] = signedValue;
}
+ }
}
-AAC_DECODER_ERROR CBlock_InverseQuantizeSpectralData(CAacDecoderChannelInfo *pAacDecoderChannelInfo, SamplingRateInfo *pSamplingRateInfo)
-{
+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);
+ 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++)
- {
+ 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];
-
- 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)
- )
+ 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 ;
+ 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;
+ locMax = maxabs_D(pSpectralCoefficient, noLines);
- for (i = noLines; i-- ; ) {
- /* Expensive memory access */
- locMax = fMax(fixp_abs(pSpectralCoefficient[i]), locMax);
+ 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_DECODE_FRAME_ERROR;
+ return AAC_DEC_PARSE_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
+ /* 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 ;
- int lsb = pScaleFactor [bnds] & 0x03 ;
- int scale = GetScaleFromValue(locMax, lsb);
+ int msb = pScaleFactor[bnds] >> 2;
- pSfbScale[window*16+band] = msb - scale;
- InverseQuantizeBand(pSpectralCoefficient, noLines, lsb, scale);
+ /* 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++) */
- return AAC_DEC_OK;
-}
+ /* 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++)*/
-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);
+ return AAC_DEC_OK;
+}
- SPECTRAL_PTR pSpectralCoefficient = pAacDecoderChannelInfo->pSpectralCoefficient;
- FIXP_DBL locMax;
+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);
- int ScaleFactorBandsTransmitted = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+ SPECTRAL_PTR pSpectralCoefficient =
+ pAacDecoderChannelInfo->pSpectralCoefficient;
FDK_ASSERT(BandOffsets != NULL);
FDKmemclear(pSpectralCoefficient, sizeof(SPECTRUM));
- if ( (flags & AC_ER_HCR) == 0 )
- {
+ 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 */
- for (group=0; group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++)
- {
- for (band=0; band < ScaleFactorBandsTransmitted; band++)
- {
- int bnds = group*16+band;
+ 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) */
+ /* 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];
+ 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;
+ 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 (offset == 0) {
- if (tmp != FIXP_DBL(0))
- tmp = (FDKreadBits(bs,1))? -tmp : tmp;
+ if (currentCB == ESCBOOK) {
+ for (int j = 0; j < 2; j++)
+ mdctSpectrum[index + j] = (FIXP_DBL)CBlock_GetEscape(
+ bs, (LONG)mdctSpectrum[index + j]);
}
- 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]);
-
+ 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 += GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo,group);
+ groupoffset += max_groupwin;
}
/* plain huffman decoding (short) finished */
}
+
/* HCR - Huffman Codeword Reordering short */
- else /* if ( flags & AC_ER_HCR ) */
+ 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 ) {
-
+ if (pAacDecoderChannelInfo->pDynData->specificTo.aac
+ .lenOfReorderedSpectralData != 0) {
/* HCR initialization short */
hcrStatus = HcrInit(hHcr, pAacDecoderChannelInfo, pSamplingRateInfo, bs);
@@ -600,7 +735,8 @@ AAC_DECODER_ERROR CBlock_ReadSpectralData(HANDLE_FDK_BITSTREAM bs,
}
/* HCR decoding short */
- hcrStatus = HcrDecoder(hHcr, pAacDecoderChannelInfo, pSamplingRateInfo, bs);
+ hcrStatus =
+ HcrDecoder(hHcr, pAacDecoderChannelInfo, pSamplingRateInfo, bs);
if (hcrStatus != 0) {
#if HCR_ERROR_CONCEALMENT
@@ -610,100 +746,314 @@ AAC_DECODER_ERROR CBlock_ReadSpectralData(HANDLE_FDK_BITSTREAM bs,
#endif /* HCR_ERROR_CONCEALMENT */
}
- FDKpushFor (bs, pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfReorderedSpectralData);
+ 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;
+}
- 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));
+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;
- return AAC_DEC_OK;
+ /* 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;
+ }
-void ApplyTools ( CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
- const SamplingRateInfo *pSamplingRateInfo,
- const UINT flags,
- const int channel )
-{
+ return errorAAC;
+}
- 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
- );
+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);
}
- CTns_Apply (
- &pAacDecoderChannelInfo[channel]->pDynData->TnsData,
- &pAacDecoderChannelInfo[channel]->icsInfo,
- pAacDecoderChannelInfo[channel]->pSpectralCoefficient,
- pSamplingRateInfo,
- pAacDecoderChannelInfo[channel]->granuleLength
- );
+ 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)
-{
+static int getWindow2Nr(int length, int shape) {
int nr = 0;
if (shape == 2) {
/* Low Overlap, 3/4 zeroed */
- nr = (length * 3)>>2;
+ 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;
+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;
- /* 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.
+#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 ) {
+ switch (pAacDecoderChannelInfo->icsInfo.WindowSequence) {
default:
- case OnlyLongSequence:
+ case BLOCK_LONG:
fl = frameLen;
- fr = frameLen - getWindow2Nr(frameLen, GetWindowShape(&pAacDecoderChannelInfo->icsInfo));
+ 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 LongStopSequence:
+ case BLOCK_STOP:
fl = frameLen >> 3;
fr = frameLen;
break;
- case LongStartSequence: /* or StopStartSequence */
+ case BLOCK_START: /* or StopStartSequence */
fl = frameLen;
fr = frameLen >> 3;
break;
- case EightShortSequence:
+ case BLOCK_SHORT:
fl = fr = frameLen >> 3;
tl >>= 3;
nSpec = 8;
@@ -711,48 +1061,198 @@ void CBlock_FrequencyToTime(CAacDecoderStaticChannelInfo *pAacDecoderStaticChann
}
{
- int i;
+ int last_frame_lost = pAacDecoderStaticChannelInfo->last_lpc_lost;
- {
- 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]);
+ 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,
- INT_PCM outSamples[],
- const short frameLen,
- const char stride )
-{
- InvMdctTransformLowDelay_fdk (
- SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
- pAacDecoderChannelInfo->specScale[0],
- outSamples,
- pAacDecoderStaticChannelInfo->pOverlapBuffer,
- stride,
- frameLen
- );
+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);
}