summaryrefslogtreecommitdiffstats
path: root/fdk-aac/libAACdec/src/aacdec_tns.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fdk-aac/libAACdec/src/aacdec_tns.cpp')
-rw-r--r--fdk-aac/libAACdec/src/aacdec_tns.cpp361
1 files changed, 361 insertions, 0 deletions
diff --git a/fdk-aac/libAACdec/src/aacdec_tns.cpp b/fdk-aac/libAACdec/src/aacdec_tns.cpp
new file mode 100644
index 0000000..fb3fe33
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_tns.cpp
@@ -0,0 +1,361 @@
+/* -----------------------------------------------------------------------------
+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: temporal noise shaping tool
+
+*******************************************************************************/
+
+#include "aacdec_tns.h"
+#include "aac_rom.h"
+#include "FDK_bitstream.h"
+#include "channelinfo.h"
+
+#include "FDK_lpc.h"
+
+#define TNS_MAXIMUM_ORDER_AAC 12
+
+/*!
+ \brief Reset tns data
+
+ The function resets the tns data
+
+ \return none
+*/
+void CTns_Reset(CTnsData *pTnsData) {
+ /* Note: the following FDKmemclear should not be required. */
+ FDKmemclear(pTnsData->Filter,
+ TNS_MAX_WINDOWS * TNS_MAXIMUM_FILTERS * sizeof(CFilter));
+ FDKmemclear(pTnsData->NumberOfFilters, TNS_MAX_WINDOWS * sizeof(UCHAR));
+ pTnsData->DataPresent = 0;
+ pTnsData->Active = 0;
+}
+
+void CTns_ReadDataPresentFlag(
+ HANDLE_FDK_BITSTREAM bs, /*!< pointer to bitstream */
+ CTnsData *pTnsData) /*!< pointer to aac decoder channel info */
+{
+ pTnsData->DataPresent = (UCHAR)FDKreadBits(bs, 1);
+}
+
+/*!
+ \brief Read tns data from bitstream
+
+ The function reads the elements for tns from
+ the bitstream.
+
+ \return none
+*/
+AAC_DECODER_ERROR CTns_Read(HANDLE_FDK_BITSTREAM bs, CTnsData *pTnsData,
+ const CIcsInfo *pIcsInfo, const UINT flags) {
+ UCHAR n_filt, order;
+ UCHAR length, coef_res, coef_compress;
+ UCHAR window;
+ UCHAR wins_per_frame;
+ UCHAR isLongFlag;
+ UCHAR start_window;
+ AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
+
+ if (!pTnsData->DataPresent) {
+ return ErrorStatus;
+ }
+
+ {
+ start_window = 0;
+ wins_per_frame = GetWindowsPerFrame(pIcsInfo);
+ isLongFlag = IsLongBlock(pIcsInfo);
+ }
+
+ pTnsData->GainLd = 0;
+
+ for (window = start_window; window < wins_per_frame; window++) {
+ pTnsData->NumberOfFilters[window] = n_filt =
+ (UCHAR)FDKreadBits(bs, isLongFlag ? 2 : 1);
+
+ if (n_filt) {
+ int index;
+ UCHAR nextstopband;
+
+ coef_res = (UCHAR)FDKreadBits(bs, 1);
+
+ nextstopband = GetScaleFactorBandsTotal(pIcsInfo);
+
+ for (index = 0; index < n_filt; index++) {
+ CFilter *filter = &pTnsData->Filter[window][index];
+
+ length = (UCHAR)FDKreadBits(bs, isLongFlag ? 6 : 4);
+
+ if (length > nextstopband) {
+ length = nextstopband;
+ }
+
+ filter->StartBand = nextstopband - length;
+ filter->StopBand = nextstopband;
+ nextstopband = filter->StartBand;
+
+ if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) {
+ /* max(Order) = 15 (long), 7 (short) */
+ filter->Order = order = (UCHAR)FDKreadBits(bs, isLongFlag ? 4 : 3);
+ } else {
+ filter->Order = order = (UCHAR)FDKreadBits(bs, isLongFlag ? 5 : 3);
+
+ if (filter->Order > TNS_MAXIMUM_ORDER) {
+ ErrorStatus = AAC_DEC_TNS_READ_ERROR;
+ return ErrorStatus;
+ }
+ }
+
+ FDK_ASSERT(order <=
+ TNS_MAXIMUM_ORDER); /* avoid illegal memory access */
+ if (order) {
+ UCHAR coef, s_mask;
+ UCHAR i;
+ SCHAR n_mask;
+
+ static const UCHAR sgn_mask[] = {0x2, 0x4, 0x8};
+ static const SCHAR neg_mask[] = {~0x3, ~0x7, ~0xF};
+
+ filter->Direction = FDKreadBits(bs, 1) ? -1 : 1;
+
+ coef_compress = (UCHAR)FDKreadBits(bs, 1);
+
+ filter->Resolution = coef_res + 3;
+
+ s_mask = sgn_mask[coef_res + 1 - coef_compress];
+ n_mask = neg_mask[coef_res + 1 - coef_compress];
+
+ for (i = 0; i < order; i++) {
+ coef = (UCHAR)FDKreadBits(bs, filter->Resolution - coef_compress);
+ filter->Coeff[i] = (coef & s_mask) ? (coef | n_mask) : coef;
+ }
+ pTnsData->GainLd = 4;
+ }
+ }
+ }
+ }
+
+ pTnsData->Active = 1;
+
+ return ErrorStatus;
+}
+
+void CTns_ReadDataPresentUsac(HANDLE_FDK_BITSTREAM hBs, CTnsData *pTnsData0,
+ CTnsData *pTnsData1, UCHAR *ptns_on_lr,
+ const CIcsInfo *pIcsInfo, const UINT flags,
+ const UINT elFlags, const int fCommonWindow) {
+ int common_tns = 0;
+
+ if (fCommonWindow) {
+ common_tns = FDKreadBit(hBs);
+ }
+ { *ptns_on_lr = FDKreadBit(hBs); }
+ if (common_tns) {
+ pTnsData0->DataPresent = 1;
+ CTns_Read(hBs, pTnsData0, pIcsInfo, flags);
+
+ pTnsData0->DataPresent = 0;
+ pTnsData0->Active = 1;
+ *pTnsData1 = *pTnsData0;
+ } else {
+ int tns_present_both;
+
+ tns_present_both = FDKreadBit(hBs);
+ if (tns_present_both) {
+ pTnsData0->DataPresent = 1;
+ pTnsData1->DataPresent = 1;
+ } else {
+ pTnsData1->DataPresent = FDKreadBit(hBs);
+ pTnsData0->DataPresent = !pTnsData1->DataPresent;
+ }
+ }
+}
+
+/*!
+ \brief Apply tns to spectral lines
+
+ The function applies the tns to the spectrum,
+
+ \return none
+*/
+void CTns_Apply(CTnsData *RESTRICT pTnsData, /*!< pointer to aac decoder info */
+ const CIcsInfo *pIcsInfo, SPECTRAL_PTR pSpectralCoefficient,
+ const SamplingRateInfo *pSamplingRateInfo,
+ const INT granuleLength, const UCHAR nbands,
+ const UCHAR igf_active, const UINT flags) {
+ int window, index, start, stop, size, start_window, wins_per_frame;
+
+ if (pTnsData->Active) {
+ C_AALLOC_SCRATCH_START(coeff, FIXP_TCC, TNS_MAXIMUM_ORDER)
+
+ {
+ start_window = 0;
+ wins_per_frame = GetWindowsPerFrame(pIcsInfo);
+ }
+
+ for (window = start_window; window < wins_per_frame; window++) {
+ FIXP_DBL *pSpectrum;
+
+ { pSpectrum = SPEC(pSpectralCoefficient, window, granuleLength); }
+
+ for (index = 0; index < pTnsData->NumberOfFilters[window]; index++) {
+ CFilter *filter = &pTnsData->Filter[window][index];
+
+ if (filter->Order > 0) {
+ FIXP_TCC *pCoeff;
+ UCHAR tns_max_bands;
+
+ pCoeff = coeff;
+ if (filter->Resolution == 3) {
+ int i;
+ for (i = 0; i < filter->Order; i++)
+ *pCoeff++ = FDKaacDec_tnsCoeff3[filter->Coeff[i] + 4];
+ } else {
+ int i;
+ for (i = 0; i < filter->Order; i++)
+ *pCoeff++ = FDKaacDec_tnsCoeff4[filter->Coeff[i] + 8];
+ }
+
+ switch (granuleLength) {
+ case 480:
+ tns_max_bands =
+ tns_max_bands_tbl_480[pSamplingRateInfo->samplingRateIndex];
+ break;
+ case 512:
+ tns_max_bands =
+ tns_max_bands_tbl_512[pSamplingRateInfo->samplingRateIndex];
+ break;
+ default:
+ tns_max_bands = GetMaximumTnsBands(
+ pIcsInfo, pSamplingRateInfo->samplingRateIndex);
+ /* See redefinition of TNS_MAX_BANDS table */
+ if ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
+ (pSamplingRateInfo->samplingRateIndex > 5)) {
+ tns_max_bands += 1;
+ }
+ break;
+ }
+
+ start = fixMin(fixMin(filter->StartBand, tns_max_bands), nbands);
+
+ start = GetScaleFactorBandOffsets(pIcsInfo, pSamplingRateInfo)[start];
+
+ if (igf_active) {
+ stop = fixMin(filter->StopBand, nbands);
+ } else {
+ stop = fixMin(fixMin(filter->StopBand, tns_max_bands), nbands);
+ }
+
+ stop = GetScaleFactorBandOffsets(pIcsInfo, pSamplingRateInfo)[stop];
+
+ size = stop - start;
+
+ if (size) {
+ C_ALLOC_SCRATCH_START(state, FIXP_DBL, TNS_MAXIMUM_ORDER)
+
+ FDKmemclear(state, TNS_MAXIMUM_ORDER * sizeof(FIXP_DBL));
+ CLpc_SynthesisLattice(pSpectrum + start, size, 0, 0,
+ filter->Direction, coeff, filter->Order,
+ state);
+
+ C_ALLOC_SCRATCH_END(state, FIXP_DBL, TNS_MAXIMUM_ORDER)
+ }
+ }
+ }
+ }
+ C_AALLOC_SCRATCH_END(coeff, FIXP_TCC, TNS_MAXIMUM_ORDER)
+ }
+}