From 022f1b86ef2f992c1c5623719e403b9b28e1becc Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 24 Jun 2019 16:26:20 +0200 Subject: Remove HCR, RVLC, error concealment --- Makefile.am | 7 - Makefile.vc | 7 - libAACdec/src/aac_ram.h | 3 - libAACdec/src/aac_rom.cpp | 96 -- libAACdec/src/aac_rom.h | 4 +- libAACdec/src/aacdec_hcr.cpp | 1498 --------------------------- libAACdec/src/aacdec_hcr.h | 128 --- libAACdec/src/aacdec_hcr_bit.cpp | 164 --- libAACdec/src/aacdec_hcr_bit.h | 114 --- libAACdec/src/aacdec_hcr_types.h | 432 -------- libAACdec/src/aacdec_hcrs.cpp | 1551 ---------------------------- libAACdec/src/aacdec_hcrs.h | 176 ---- libAACdec/src/aacdecoder.cpp | 91 +- libAACdec/src/aacdecoder.h | 3 - libAACdec/src/aacdecoder_lib.cpp | 73 +- libAACdec/src/block.cpp | 59 +- libAACdec/src/channel.cpp | 19 +- libAACdec/src/channelinfo.h | 22 - libAACdec/src/conceal.cpp | 2095 -------------------------------------- libAACdec/src/conceal.h | 152 --- libAACdec/src/conceal_types.h | 203 ---- libAACdec/src/rvlc.cpp | 1217 ---------------------- libAACdec/src/rvlc.h | 153 --- libAACdec/src/rvlc_info.h | 204 ---- libAACdec/src/rvlcbit.cpp | 148 --- libAACdec/src/rvlcbit.h | 111 -- libAACdec/src/rvlcconceal.cpp | 787 -------------- libAACdec/src/rvlcconceal.h | 127 --- libAACdec/src/usacdec_lpd.cpp | 20 +- 29 files changed, 21 insertions(+), 9643 deletions(-) delete mode 100644 libAACdec/src/aacdec_hcr.cpp delete mode 100644 libAACdec/src/aacdec_hcr.h delete mode 100644 libAACdec/src/aacdec_hcr_bit.cpp delete mode 100644 libAACdec/src/aacdec_hcr_bit.h delete mode 100644 libAACdec/src/aacdec_hcr_types.h delete mode 100644 libAACdec/src/aacdec_hcrs.cpp delete mode 100644 libAACdec/src/aacdec_hcrs.h delete mode 100644 libAACdec/src/conceal.cpp delete mode 100644 libAACdec/src/conceal.h delete mode 100644 libAACdec/src/conceal_types.h delete mode 100644 libAACdec/src/rvlc.cpp delete mode 100644 libAACdec/src/rvlc.h delete mode 100644 libAACdec/src/rvlc_info.h delete mode 100644 libAACdec/src/rvlcbit.cpp delete mode 100644 libAACdec/src/rvlcbit.h delete mode 100644 libAACdec/src/rvlcconceal.cpp delete mode 100644 libAACdec/src/rvlcconceal.h --- a/Makefile.am +++ b/Makefile.am @@ -50,9 +50,6 @@ AACDEC_SRC = \ libAACdec/src/aac_ram.cpp \ libAACdec/src/aac_rom.cpp \ libAACdec/src/aacdec_drc.cpp \ - libAACdec/src/aacdec_hcr.cpp \ - libAACdec/src/aacdec_hcr_bit.cpp \ - libAACdec/src/aacdec_hcrs.cpp \ libAACdec/src/aacdec_pns.cpp \ libAACdec/src/aacdec_tns.cpp \ libAACdec/src/aacdecoder.cpp \ @@ -60,12 +57,8 @@ AACDEC_SRC = \ libAACdec/src/block.cpp \ libAACdec/src/channel.cpp \ libAACdec/src/channelinfo.cpp \ - libAACdec/src/conceal.cpp \ libAACdec/src/ldfiltbank.cpp \ libAACdec/src/pulsedata.cpp \ - libAACdec/src/rvlc.cpp \ - libAACdec/src/rvlcbit.cpp \ - libAACdec/src/rvlcconceal.cpp \ libAACdec/src/stereo.cpp \ libAACdec/src/usacdec_ace_d4t64.cpp \ libAACdec/src/usacdec_ace_ltp.cpp \ --- a/Makefile.vc +++ b/Makefile.vc @@ -34,9 +34,6 @@ AACDEC_SRC = \ libAACdec/src/aac_ram.cpp \ libAACdec/src/aac_rom.cpp \ libAACdec/src/aacdec_drc.cpp \ - libAACdec/src/aacdec_hcr.cpp \ - libAACdec/src/aacdec_hcr_bit.cpp \ - libAACdec/src/aacdec_hcrs.cpp \ libAACdec/src/aacdec_pns.cpp \ libAACdec/src/aacdec_tns.cpp \ libAACdec/src/aacdecoder.cpp \ @@ -44,12 +41,8 @@ AACDEC_SRC = \ libAACdec/src/block.cpp \ libAACdec/src/channel.cpp \ libAACdec/src/channelinfo.cpp \ - libAACdec/src/conceal.cpp \ libAACdec/src/ldfiltbank.cpp \ libAACdec/src/pulsedata.cpp \ - libAACdec/src/rvlc.cpp \ - libAACdec/src/rvlcbit.cpp \ - libAACdec/src/rvlcconceal.cpp \ libAACdec/src/stereo.cpp \ libAACdec/src/usacdec_ace_d4t64.cpp \ libAACdec/src/usacdec_ace_ltp.cpp \ --- a/libAACdec/src/aac_ram.h +++ b/libAACdec/src/aac_ram.h @@ -111,9 +111,6 @@ amm-info@iis.fraunhofer.de #include "ac_arith_coder.h" -#include "aacdec_hcr_types.h" -#include "aacdec_hcr.h" - /* End of formal fix.h */ #define MAX_SYNCHS 10 --- a/libAACdec/src/aac_rom.cpp +++ b/libAACdec/src/aac_rom.cpp @@ -1583,102 +1583,6 @@ const SCHAR *aQuantTable[] = { aValTab24, /* 30 6 */ aValTab24}; /* 31 6 */ -/* arrays for HCR_TABLE_INFO structures */ -/* maximum length of codeword in each codebook */ -/* codebook: 0,1, 2,3, 4, 5, 6, 7, 8, 9, - * 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 */ -const UCHAR aMaxCwLen[MAX_CB] = {0, 11, 9, 20, 16, 13, 11, 14, 12, 17, 14, - 49, 0, 0, 0, 0, 14, 17, 21, 21, 25, 25, - 29, 29, 29, 29, 33, 33, 33, 37, 37, 41}; - -/* 11 13 15 17 19 - * 21 23 25 27 39 31 */ -/* CB: 0 1 2 3 4 5 6 7 8 9 10 12 14 16 18 20 - * 22 24 26 28 30 */ -const UCHAR aDimCb[MAX_CB] = { - 2, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; /* codebook dimension - - zero cb got a - dimension of 2 */ - -/* 11 13 15 17 19 - * 21 23 25 27 39 31 */ -/* CB: 0 1 2 3 4 5 6 7 8 9 10 12 14 16 18 20 - * 22 24 26 28 30 */ -const UCHAR aDimCbShift[MAX_CB] = { - 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; /* codebook dimension */ - -/* 1 -> decode sign bits */ -/* 0 -> decode no sign bits 11 13 15 17 19 21 - * 23 25 27 39 31 */ -/* CB: 0 1 2 3 4 5 6 7 8 9 10 12 14 16 18 20 22 - * 24 26 28 30 */ -const UCHAR aSignCb[MAX_CB] = {0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; - -/* arrays for HCR_CB_PAIRS structures */ -const UCHAR aMinOfCbPair[MAX_CB_PAIRS] = {0, 1, 3, 5, 7, 9, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 11}; -const UCHAR aMaxOfCbPair[MAX_CB_PAIRS] = {0, 2, 4, 6, 8, 10, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 11}; - -/* priorities of codebooks */ -const UCHAR aCbPriority[MAX_CB] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, - 22, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}; - -const SCHAR aCodebook2StartInt[] = {STOP_THIS_STATE, /* cb 0 */ - BODY_ONLY, /* cb 1 */ - BODY_ONLY, /* cb 2 */ - BODY_SIGN__BODY, /* cb 3 */ - BODY_SIGN__BODY, /* cb 4 */ - BODY_ONLY, /* cb 5 */ - BODY_ONLY, /* cb 6 */ - BODY_SIGN__BODY, /* cb 7 */ - BODY_SIGN__BODY, /* cb 8 */ - BODY_SIGN__BODY, /* cb 9 */ - BODY_SIGN__BODY, /* cb 10 */ - BODY_SIGN_ESC__BODY, /* cb 11 */ - STOP_THIS_STATE, /* cb 12 */ - STOP_THIS_STATE, /* cb 13 */ - STOP_THIS_STATE, /* cb 14 */ - STOP_THIS_STATE, /* cb 15 */ - BODY_SIGN_ESC__BODY, /* cb 16 */ - BODY_SIGN_ESC__BODY, /* cb 17 */ - BODY_SIGN_ESC__BODY, /* cb 18 */ - BODY_SIGN_ESC__BODY, /* cb 19 */ - BODY_SIGN_ESC__BODY, /* cb 20 */ - BODY_SIGN_ESC__BODY, /* cb 21 */ - BODY_SIGN_ESC__BODY, /* cb 22 */ - BODY_SIGN_ESC__BODY, /* cb 23 */ - BODY_SIGN_ESC__BODY, /* cb 24 */ - BODY_SIGN_ESC__BODY, /* cb 25 */ - BODY_SIGN_ESC__BODY, /* cb 26 */ - BODY_SIGN_ESC__BODY, /* cb 27 */ - BODY_SIGN_ESC__BODY, /* cb 28 */ - BODY_SIGN_ESC__BODY, /* cb 29 */ - BODY_SIGN_ESC__BODY, /* cb 30 */ - BODY_SIGN_ESC__BODY}; /* cb 31 */ - -const STATEFUNC aStateConstant2State[] = { - NULL, /* 0 = STOP_THIS_STATE */ - Hcr_State_BODY_ONLY, /* 1 = BODY_ONLY */ - Hcr_State_BODY_SIGN__BODY, /* 2 = BODY_SIGN__BODY */ - Hcr_State_BODY_SIGN__SIGN, /* 3 = BODY_SIGN__SIGN */ - Hcr_State_BODY_SIGN_ESC__BODY, /* 4 = BODY_SIGN_ESC__BODY */ - Hcr_State_BODY_SIGN_ESC__SIGN, /* 5 = BODY_SIGN_ESC__SIGN */ - Hcr_State_BODY_SIGN_ESC__ESC_PREFIX, /* 6 = BODY_SIGN_ESC__ESC_PREFIX */ - Hcr_State_BODY_SIGN_ESC__ESC_WORD}; /* 7 = BODY_SIGN_ESC__ESC_WORD */ - -/* CB: 0 1 2 3 4 5 6 7 8 9 10 12 - * 14 16 18 20 22 24 26 28 30 */ -const USHORT aLargestAbsoluteValue[MAX_CB] = { - 0, 1, 1, 2, 2, 4, 4, 7, 7, 12, 12, - 8191, 0, 0, 0, 0, 15, 31, 47, 63, 95, 127, - 159, 191, 223, 255, 319, 383, 511, 767, 1023, 2047}; /* lav */ /* CB: 11 13 * 15 17 19 21 23 25 27 39 31 */ --- a/libAACdec/src/aac_rom.h +++ b/libAACdec/src/aac_rom.h @@ -105,8 +105,6 @@ amm-info@iis.fraunhofer.de #include "common_fix.h" #include "FDK_audio.h" -#include "aacdec_hcr_types.h" -#include "aacdec_hcrs.h" #define PCM_DEC FIXP_DBL #define MAXVAL_PCM_DEC MAXVAL_DBL @@ -165,7 +163,7 @@ typedef struct { extern const CodeBookDescription AACcodeBookDescriptionTable[13]; extern const CodeBookDescription AACcodeBookDescriptionSCL; -extern const STATEFUNC aStateConstant2State[]; +#define MAX_CB 32 /* last used CB is cb #31 when VCB11 is used */ extern const SCHAR aCodebook2StartInt[]; --- a/libAACdec/src/aacdec_hcr.cpp +++ /dev/null @@ -1,1498 +0,0 @@ -/* ----------------------------------------------------------------------------- -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): Robert Weidner (DSP Solutions) - - Description: HCR Decoder: HCR initialization, preprocess HCR sideinfo, - decode priority codewords (PCWs) - -*******************************************************************************/ - -#include "aacdec_hcr.h" - -#include "aacdec_hcr_types.h" -#include "aacdec_hcr_bit.h" -#include "aacdec_hcrs.h" -#include "aac_ram.h" -#include "aac_rom.h" -#include "channel.h" -#include "block.h" - -#include "aacdecoder.h" /* for ID_CPE, ID_SCE ... */ -#include "FDK_bitstream.h" - -extern int mlFileChCurr; - -static void errDetectorInHcrSideinfoShrt(SCHAR cb, SHORT numLine, - UINT *errorWord); - -static void errDetectorInHcrLengths(SCHAR lengthOfLongestCodeword, - SHORT lengthOfReorderedSpectralData, - UINT *errorWord); - -static void HcrCalcNumCodeword(H_HCR_INFO pHcr); -static void HcrSortCodebookAndNumCodewordInSection(H_HCR_INFO pHcr); -static void HcrPrepareSegmentationGrid(H_HCR_INFO pHcr); -static void HcrExtendedSectionInfo(H_HCR_INFO pHcr); - -static void DeriveNumberOfExtendedSortedSectionsInSets( - UINT numSegment, USHORT *pNumExtendedSortedCodewordInSection, - int numExtendedSortedCodewordInSectionIdx, - USHORT *pNumExtendedSortedSectionsInSets, - int numExtendedSortedSectionsInSetsIdx); - -static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor, - INT quantSpecCoef, INT *pLeftStartOfSegment, - SCHAR *pRemainingBitsInSegment, - int *pNumDecodedBits); - -static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor, - UINT codebookDim, const SCHAR *pQuantVal, - FIXP_DBL *pQuantSpecCoef, int *quantSpecCoefIdx, - INT *pLeftStartOfSegment, - SCHAR *pRemainingBitsInSegment, int *pNumDecodedBits); - -static const SCHAR *DecodePCW_Body(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor, - const UINT *pCurrentTree, - const SCHAR *pQuantValBase, - INT *pLeftStartOfSegment, - SCHAR *pRemainingBitsInSegment, - int *pNumDecodedBits); - -static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr); - -static void HcrReorderQuantizedSpectralCoefficients( - H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo, - const SamplingRateInfo *pSamplingRateInfo); - -static UCHAR errDetectPcwSegmentation(SCHAR remainingBitsInSegment, - H_HCR_INFO pHcr, PCW_TYPE kind, - FIXP_DBL *qsc_base_of_cw, - UCHAR dimension); - -static void errDetectWithinSegmentationFinal(H_HCR_INFO pHcr); - -/*--------------------------------------------------------------------------------------------- - description: Check if codebook and numSect are within allowed range -(short only) --------------------------------------------------------------------------------------------- -*/ -static void errDetectorInHcrSideinfoShrt(SCHAR cb, SHORT numLine, - UINT *errorWord) { - if (cb < ZERO_HCB || cb >= MAX_CB_CHECK || cb == BOOKSCL) { - *errorWord |= CB_OUT_OF_RANGE_SHORT_BLOCK; - } - if (numLine < 0 || numLine > 1024) { - *errorWord |= LINE_IN_SECT_OUT_OF_RANGE_SHORT_BLOCK; - } -} - -/*--------------------------------------------------------------------------------------------- - description: Check both HCR lengths --------------------------------------------------------------------------------------------- -*/ -static void errDetectorInHcrLengths(SCHAR lengthOfLongestCodeword, - SHORT lengthOfReorderedSpectralData, - UINT *errorWord) { - if (lengthOfReorderedSpectralData < lengthOfLongestCodeword) { - *errorWord |= HCR_SI_LENGTHS_FAILURE; - } -} - -/*--------------------------------------------------------------------------------------------- - description: Decode (and adapt if necessary) the two HCR sideinfo -components: 'reordered_spectral_data_length' and 'longest_codeword_length' --------------------------------------------------------------------------------------------- -*/ - -void CHcr_Read(HANDLE_FDK_BITSTREAM bs, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - const MP4_ELEMENT_ID globalHcrType) { - SHORT lengOfReorderedSpectralData; - SCHAR lengOfLongestCodeword; - - pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfReorderedSpectralData = - 0; - pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword = 0; - - /* ------- SI-Value No 1 ------- */ - lengOfReorderedSpectralData = FDKreadBits(bs, 14) + ERROR_LORSD; - if (globalHcrType == ID_CPE) { - if ((lengOfReorderedSpectralData >= 0) && - (lengOfReorderedSpectralData <= CPE_TOP_LENGTH)) { - pAacDecoderChannelInfo->pDynData->specificTo.aac - .lenOfReorderedSpectralData = - lengOfReorderedSpectralData; /* the decoded value is within range */ - } else { - if (lengOfReorderedSpectralData > CPE_TOP_LENGTH) { - pAacDecoderChannelInfo->pDynData->specificTo.aac - .lenOfReorderedSpectralData = - CPE_TOP_LENGTH; /* use valid maximum */ - } - } - } else if (globalHcrType == ID_SCE || globalHcrType == ID_LFE || - globalHcrType == ID_CCE) { - if ((lengOfReorderedSpectralData >= 0) && - (lengOfReorderedSpectralData <= SCE_TOP_LENGTH)) { - pAacDecoderChannelInfo->pDynData->specificTo.aac - .lenOfReorderedSpectralData = - lengOfReorderedSpectralData; /* the decoded value is within range */ - } else { - if (lengOfReorderedSpectralData > SCE_TOP_LENGTH) { - pAacDecoderChannelInfo->pDynData->specificTo.aac - .lenOfReorderedSpectralData = - SCE_TOP_LENGTH; /* use valid maximum */ - } - } - } - - /* ------- SI-Value No 2 ------- */ - lengOfLongestCodeword = FDKreadBits(bs, 6) + ERROR_LOLC; - if ((lengOfLongestCodeword >= 0) && - (lengOfLongestCodeword <= LEN_OF_LONGEST_CW_TOP_LENGTH)) { - pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword = - lengOfLongestCodeword; /* the decoded value is within range */ - } else { - if (lengOfLongestCodeword > LEN_OF_LONGEST_CW_TOP_LENGTH) { - pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword = - LEN_OF_LONGEST_CW_TOP_LENGTH; /* use valid maximum */ - } - } -} - -/*--------------------------------------------------------------------------------------------- - description: Set up HCR - must be called before every call to -HcrDecoder(). For short block a sorting algorithm is applied to get the SI in -the order that HCR could assemble the qsc's as if it is a long block. ------------------------------------------------------------------------------------------------ - return: error log --------------------------------------------------------------------------------------------- -*/ - -UINT HcrInit(H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo, - const SamplingRateInfo *pSamplingRateInfo, - HANDLE_FDK_BITSTREAM bs) { - CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; - SHORT *pNumLinesInSec; - UCHAR *pCodeBk; - SHORT numSection; - SCHAR cb; - int numLine; - int i; - - pHcr->decInOut.lengthOfReorderedSpectralData = - pAacDecoderChannelInfo->pDynData->specificTo.aac - .lenOfReorderedSpectralData; - pHcr->decInOut.lengthOfLongestCodeword = - pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword; - pHcr->decInOut.pQuantizedSpectralCoefficientsBase = - pAacDecoderChannelInfo->pSpectralCoefficient; - pHcr->decInOut.quantizedSpectralCoefficientsIdx = 0; - pHcr->decInOut.pCodebook = - pAacDecoderChannelInfo->pDynData->specificTo.aac.aCodeBooks4Hcr; - pHcr->decInOut.pNumLineInSect = - pAacDecoderChannelInfo->pDynData->specificTo.aac.aNumLineInSec4Hcr; - pHcr->decInOut.numSection = - pAacDecoderChannelInfo->pDynData->specificTo.aac.numberSection; - pHcr->decInOut.errorLog = 0; - pHcr->nonPcwSideinfo.pResultBase = - SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); - - FDKsyncCache(bs); - pHcr->decInOut.bitstreamAnchor = (INT)FDKgetValidBits(bs); - - if (!IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) /* short block */ - { - SHORT band; - SHORT maxBand; - SCHAR group; - SCHAR winGroupLen; - SCHAR window; - SCHAR numUnitInBand; - SCHAR cntUnitInBand; - SCHAR groupWin; - SCHAR cb_prev; - - UCHAR *pCodeBook; - const SHORT *BandOffsets; - SCHAR numOfGroups; - - pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook; /* in */ - pNumLinesInSec = pHcr->decInOut.pNumLineInSect; /* out */ - pCodeBk = pHcr->decInOut.pCodebook; /* out */ - BandOffsets = - GetScaleFactorBandOffsets(pIcsInfo, pSamplingRateInfo); /* aux */ - numOfGroups = GetWindowGroups(pIcsInfo); - - numLine = 0; - numSection = 0; - cb = pCodeBook[0]; - cb_prev = pCodeBook[0]; - - /* convert HCR-sideinfo into a unitwise manner: When the cb changes, a new - * section starts */ - - *pCodeBk++ = cb_prev; - - maxBand = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo); - for (band = 0; band < maxBand; - band++) { /* from low to high sfbs i.e. from low to high frequencies */ - numUnitInBand = - ((BandOffsets[band + 1] - BandOffsets[band]) >> - FOUR_LOG_DIV_TWO_LOG); /* get the number of units in current sfb */ - for (cntUnitInBand = numUnitInBand; cntUnitInBand != 0; - cntUnitInBand--) { /* for every unit in the band */ - for (window = 0, group = 0; group < numOfGroups; group++) { - winGroupLen = (SCHAR)GetWindowGroupLength( - &pAacDecoderChannelInfo->icsInfo, group); - for (groupWin = winGroupLen; groupWin != 0; groupWin--, window++) { - cb = pCodeBook[group * 16 + band]; - if (cb != cb_prev) { - errDetectorInHcrSideinfoShrt(cb, numLine, - &pHcr->decInOut.errorLog); - if (pHcr->decInOut.errorLog != 0) { - return (pHcr->decInOut.errorLog); - } - *pCodeBk++ = cb; - *pNumLinesInSec++ = numLine; - numSection++; - - cb_prev = cb; - numLine = LINES_PER_UNIT; - } else { - numLine += LINES_PER_UNIT; - } - } - } - } - } - - numSection++; - - errDetectorInHcrSideinfoShrt(cb, numLine, &pHcr->decInOut.errorLog); - if (numSection <= 0 || numSection > 1024 / 2) { - pHcr->decInOut.errorLog |= NUM_SECT_OUT_OF_RANGE_SHORT_BLOCK; - } - errDetectorInHcrLengths(pHcr->decInOut.lengthOfLongestCodeword, - pHcr->decInOut.lengthOfReorderedSpectralData, - &pHcr->decInOut.errorLog); - if (pHcr->decInOut.errorLog != 0) { - return (pHcr->decInOut.errorLog); - } - - *pCodeBk = cb; - *pNumLinesInSec = numLine; - pHcr->decInOut.numSection = numSection; - - } else /* end short block prepare SI */ - { /* long block */ - errDetectorInHcrLengths(pHcr->decInOut.lengthOfLongestCodeword, - pHcr->decInOut.lengthOfReorderedSpectralData, - &pHcr->decInOut.errorLog); - numSection = pHcr->decInOut.numSection; - pNumLinesInSec = pHcr->decInOut.pNumLineInSect; - pCodeBk = pHcr->decInOut.pCodebook; - if (numSection <= 0 || numSection > 64) { - pHcr->decInOut.errorLog |= NUM_SECT_OUT_OF_RANGE_LONG_BLOCK; - numSection = 0; - } - - for (i = numSection; i != 0; i--) { - cb = *pCodeBk++; - - if (cb < ZERO_HCB || cb >= MAX_CB_CHECK || cb == BOOKSCL) { - pHcr->decInOut.errorLog |= CB_OUT_OF_RANGE_LONG_BLOCK; - } - - numLine = *pNumLinesInSec++; - /* FDK_ASSERT(numLine > 0); */ - - if ((numLine <= 0) || (numLine > 1024)) { - pHcr->decInOut.errorLog |= LINE_IN_SECT_OUT_OF_RANGE_LONG_BLOCK; - } - } - if (pHcr->decInOut.errorLog != 0) { - return (pHcr->decInOut.errorLog); - } - } - - pCodeBk = pHcr->decInOut.pCodebook; - for (i = 0; i < numSection; i++) { - if ((*pCodeBk == NOISE_HCB) || (*pCodeBk == INTENSITY_HCB2) || - (*pCodeBk == INTENSITY_HCB)) { - *pCodeBk = 0; - } - pCodeBk++; - } - - /* HCR-sideinfo-input is complete and seems to be valid */ - - return (pHcr->decInOut.errorLog); -} - -/*--------------------------------------------------------------------------------------------- - description: This function decodes the codewords of the spectral -coefficients from the bitstream according to the HCR algorithm and stores the -quantized spectral coefficients in correct order in the output buffer. --------------------------------------------------------------------------------------------- -*/ - -UINT HcrDecoder(H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo, - const SamplingRateInfo *pSamplingRateInfo, - HANDLE_FDK_BITSTREAM bs) { - int pTmp1, pTmp2, pTmp3, pTmp4; - int pTmp5; - - INT bitCntOffst; - INT saveBitCnt = (INT)FDKgetValidBits(bs); /* save bitstream position */ - - HcrCalcNumCodeword(pHcr); - - HcrSortCodebookAndNumCodewordInSection(pHcr); - - HcrPrepareSegmentationGrid(pHcr); - - HcrExtendedSectionInfo(pHcr); - - if ((pHcr->decInOut.errorLog & HCR_FATAL_PCW_ERROR_MASK) != 0) { - return (pHcr->decInOut.errorLog); /* sideinfo is massively corrupt, return - from HCR without having decoded - anything */ - } - - DeriveNumberOfExtendedSortedSectionsInSets( - pHcr->segmentInfo.numSegment, - pHcr->sectionInfo.pNumExtendedSortedCodewordInSection, - pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx, - pHcr->sectionInfo.pNumExtendedSortedSectionsInSets, - pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx); - - /* store */ - pTmp1 = pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx; - pTmp2 = pHcr->sectionInfo.extendedSortedCodebookIdx; - pTmp3 = pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx; - pTmp4 = pHcr->decInOut.quantizedSpectralCoefficientsIdx; - pTmp5 = pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx; - - /* ------- decode meaningful PCWs ------ */ - DecodePCWs(bs, pHcr); - - if ((pHcr->decInOut.errorLog & HCR_FATAL_PCW_ERROR_MASK) == 0) { - /* ------ decode the non-PCWs -------- */ - DecodeNonPCWs(bs, pHcr); - } - - errDetectWithinSegmentationFinal(pHcr); - - /* restore */ - pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx = pTmp1; - pHcr->sectionInfo.extendedSortedCodebookIdx = pTmp2; - pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx = pTmp3; - pHcr->decInOut.quantizedSpectralCoefficientsIdx = pTmp4; - pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx = pTmp5; - - HcrReorderQuantizedSpectralCoefficients(pHcr, pAacDecoderChannelInfo, - pSamplingRateInfo); - - /* restore bitstream position */ - bitCntOffst = (INT)FDKgetValidBits(bs) - saveBitCnt; - if (bitCntOffst) { - FDKpushBiDirectional(bs, bitCntOffst); - } - - return (pHcr->decInOut.errorLog); -} - -/*--------------------------------------------------------------------------------------------- - description: This function reorders the quantized spectral coefficients -sectionwise for long- and short-blocks and compares to the LAV (Largest Absolute -Value of the current codebook) -- a counter is incremented if there is an error - detected. - Additional for short-blocks a unit-based-deinterleaving is -applied. Moreover (for short blocks) the scaling is derived (compare plain -huffman decoder). --------------------------------------------------------------------------------------------- -*/ - -static void HcrReorderQuantizedSpectralCoefficients( - H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo, - const SamplingRateInfo *pSamplingRateInfo) { - INT qsc; - UINT abs_qsc; - UINT i, j; - USHORT numSpectralValuesInSection; - FIXP_DBL *pTeVa; - USHORT lavErrorCnt = 0; - - UINT numSection = pHcr->decInOut.numSection; - SPECTRAL_PTR pQuantizedSpectralCoefficientsBase = - pHcr->decInOut.pQuantizedSpectralCoefficientsBase; - FIXP_DBL *pQuantizedSpectralCoefficients = - SPEC_LONG(pHcr->decInOut.pQuantizedSpectralCoefficientsBase); - const UCHAR *pCbDimShift = aDimCbShift; - const USHORT *pLargestAbsVal = aLargestAbsoluteValue; - UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook; - USHORT *pNumSortedCodewordInSection = - pHcr->sectionInfo.pNumSortedCodewordInSection; - USHORT *pReorderOffset = pHcr->sectionInfo.pReorderOffset; - FIXP_DBL pTempValues[1024]; - FIXP_DBL *pBak = pTempValues; - - FDKmemclear(pTempValues, 1024 * sizeof(FIXP_DBL)); - - /* long and short: check if decoded huffman-values (quantized spectral - * coefficients) are within range */ - for (i = numSection; i != 0; i--) { - numSpectralValuesInSection = *pNumSortedCodewordInSection++ - << pCbDimShift[*pSortedCodebook]; - pTeVa = &pTempValues[*pReorderOffset++]; - for (j = numSpectralValuesInSection; j != 0; j--) { - qsc = *pQuantizedSpectralCoefficients++; - abs_qsc = fAbs(qsc); - if (abs_qsc <= pLargestAbsVal[*pSortedCodebook]) { - *pTeVa++ = (FIXP_DBL)qsc; /* the qsc value is within range */ - } else { /* line is too high .. */ - if (abs_qsc == - Q_VALUE_INVALID) { /* .. because of previous marking --> dont set - LAV flag (would be confusing), just copy out - the already marked value */ - *pTeVa++ = (FIXP_DBL)qsc; - } else { /* .. because a too high value was decoded for this cb --> set - LAV flag */ - *pTeVa++ = (FIXP_DBL)Q_VALUE_INVALID; - lavErrorCnt += 1; - } - } - } - pSortedCodebook++; - } - - if (!IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) { - FIXP_DBL *pOut; - FIXP_DBL locMax; - FIXP_DBL tmp; - SCHAR groupoffset; - SCHAR group; - SCHAR band; - SCHAR groupwin; - SCHAR window; - SCHAR numWinGroup; - SHORT interm; - SCHAR numSfbTransm; - SCHAR winGroupLen; - SHORT index; - INT msb; - INT lsb; - - SHORT *pScaleFacHcr = pAacDecoderChannelInfo->pDynData->aScaleFactor; - SHORT *pSfbSclHcr = pAacDecoderChannelInfo->pDynData->aSfbScale; - const SHORT *BandOffsets = GetScaleFactorBandOffsets( - &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo); - - pBak = pTempValues; - /* deinterleave unitwise for short blocks */ - for (window = 0; window < (8); window++) { - pOut = SPEC(pQuantizedSpectralCoefficientsBase, window, - pAacDecoderChannelInfo->granuleLength); - for (i = 0; i < (LINES_PER_UNIT_GROUP); i++) { - pTeVa = pBak + (window << FOUR_LOG_DIV_TWO_LOG) + - i * 32; /* distance of lines between unit groups has to be - constant for every framelength (32)! */ - for (j = (LINES_PER_UNIT); j != 0; j--) { - *pOut++ = *pTeVa++; - } - } - } - - /* short blocks only */ - /* derive global scaling-value for every sfb and every window (as it is done - * in plain-huffman-decoder at short blocks) */ - groupoffset = 0; - - numWinGroup = GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); - numSfbTransm = - GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo); - - for (group = 0; group < numWinGroup; group++) { - winGroupLen = - GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, group); - for (band = 0; band < numSfbTransm; band++) { - interm = group * 16 + band; - msb = pScaleFacHcr[interm] >> 2; - lsb = pScaleFacHcr[interm] & 3; - for (groupwin = 0; groupwin < winGroupLen; groupwin++) { - window = groupoffset + groupwin; - pBak = SPEC(pQuantizedSpectralCoefficientsBase, window, - pAacDecoderChannelInfo->granuleLength); - locMax = FL2FXCONST_DBL(0.0f); - for (index = BandOffsets[band]; index < BandOffsets[band + 1]; - index += LINES_PER_UNIT) { - pTeVa = &pBak[index]; - for (i = LINES_PER_UNIT; i != 0; i--) { - tmp = (*pTeVa < FL2FXCONST_DBL(0.0f)) ? -*pTeVa++ : *pTeVa++; - locMax = fixMax(tmp, locMax); - } - } - if (fixp_abs(locMax) > (FIXP_DBL)MAX_QUANTIZED_VALUE) { - locMax = (FIXP_DBL)MAX_QUANTIZED_VALUE; - } - pSfbSclHcr[window * 16 + band] = - msb - GetScaleFromValue( - locMax, lsb); /* save global scale maxima in this sfb */ - } - } - groupoffset += - GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, group); - } - } else { - /* copy straight for long-blocks */ - pQuantizedSpectralCoefficients = - SPEC_LONG(pQuantizedSpectralCoefficientsBase); - for (i = 1024; i != 0; i--) { - *pQuantizedSpectralCoefficients++ = *pBak++; - } - } - - if (lavErrorCnt != 0) { - pHcr->decInOut.errorLog |= LAV_VIOLATION; - } -} - -/*--------------------------------------------------------------------------------------------- - description: This function calculates the number of codewords - for each section (numCodewordInSection) and the number of -codewords for all sections (numCodeword). For zero and intensity codebooks a -entry is also done in the variable numCodewordInSection. It is assumed that the -codebook is a two tuples codebook. This is needed later for the calculation of -the base addresses for the reordering of the quantize spectral coefficients at -the end of the hcr tool. The variable numCodeword contain the number of -codewords which are really in the bitstream. Zero or intensity codebooks does -not increase the variable numCodewords. ------------------------------------------------------------------------------------------------ - return: - --------------------------------------------------------------------------------------------- -*/ - -static void HcrCalcNumCodeword(H_HCR_INFO pHcr) { - int hcrSection; - UINT numCodeword; - - UINT numSection = pHcr->decInOut.numSection; - UCHAR *pCodebook = pHcr->decInOut.pCodebook; - SHORT *pNumLineInSection = pHcr->decInOut.pNumLineInSect; - const UCHAR *pCbDimShift = aDimCbShift; - - USHORT *pNumCodewordInSection = pHcr->sectionInfo.pNumCodewordInSection; - - numCodeword = 0; - for (hcrSection = numSection; hcrSection != 0; hcrSection--) { - *pNumCodewordInSection = *pNumLineInSection++ >> pCbDimShift[*pCodebook]; - if (*pCodebook != 0) { - numCodeword += *pNumCodewordInSection; - } - pNumCodewordInSection++; - pCodebook++; - } - pHcr->sectionInfo.numCodeword = numCodeword; -} - -/*--------------------------------------------------------------------------------------------- - description: This function calculates the number - of sorted codebooks and sorts the codebooks and the -numCodewordInSection according to the priority. --------------------------------------------------------------------------------------------- -*/ - -static void HcrSortCodebookAndNumCodewordInSection(H_HCR_INFO pHcr) { - UINT i, j, k; - UCHAR temp; - UINT counter; - UINT startOffset; - UINT numZeroSection; - UCHAR *pDest; - UINT numSectionDec; - - UINT numSection = pHcr->decInOut.numSection; - UCHAR *pCodebook = pHcr->decInOut.pCodebook; - UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook; - USHORT *pNumCodewordInSection = pHcr->sectionInfo.pNumCodewordInSection; - USHORT *pNumSortedCodewordInSection = - pHcr->sectionInfo.pNumSortedCodewordInSection; - UCHAR *pCodebookSwitch = pHcr->sectionInfo.pCodebookSwitch; - USHORT *pReorderOffset = pHcr->sectionInfo.pReorderOffset; - const UCHAR *pCbPriority = aCbPriority; - const UCHAR *pMinOfCbPair = aMinOfCbPair; - const UCHAR *pMaxOfCbPair = aMaxOfCbPair; - const UCHAR *pCbDimShift = aDimCbShift; - - UINT searchStart = 0; - - /* calculate *pNumSortedSection and store the priorities in array - * pSortedCdebook */ - pDest = pSortedCodebook; - numZeroSection = 0; - for (i = numSection; i != 0; i--) { - if (pCbPriority[*pCodebook] == 0) { - numZeroSection += 1; - } - *pDest++ = pCbPriority[*pCodebook++]; - } - pHcr->sectionInfo.numSortedSection = - numSection - numZeroSection; /* numSortedSection contains no zero or - intensity section */ - pCodebook = pHcr->decInOut.pCodebook; - - /* sort priorities of the codebooks in array pSortedCdebook[] */ - numSectionDec = numSection - 1; - if (numSectionDec > 0) { - counter = numSectionDec; - for (j = numSectionDec; j != 0; j--) { - for (i = 0; i < counter; i++) { - /* swap priorities */ - if (pSortedCodebook[i + 1] > pSortedCodebook[i]) { - temp = pSortedCodebook[i]; - pSortedCodebook[i] = pSortedCodebook[i + 1]; - pSortedCodebook[i + 1] = temp; - } - } - counter -= 1; - } - } - - /* clear codebookSwitch array */ - for (i = numSection; i != 0; i--) { - *pCodebookSwitch++ = 0; - } - pCodebookSwitch = pHcr->sectionInfo.pCodebookSwitch; - - /* sort sectionCodebooks and numCodwordsInSection and calculate - * pReorderOffst[j] */ - for (j = 0; j < numSection; j++) { - for (i = searchStart; i < numSection; i++) { - if (pCodebookSwitch[i] == 0 && - (pMinOfCbPair[pSortedCodebook[j]] == pCodebook[i] || - pMaxOfCbPair[pSortedCodebook[j]] == pCodebook[i])) { - pCodebookSwitch[i] = 1; - pSortedCodebook[j] = pCodebook[i]; /* sort codebook */ - pNumSortedCodewordInSection[j] = - pNumCodewordInSection[i]; /* sort NumCodewordInSection */ - - startOffset = 0; - for (k = 0; k < i; k++) { /* make entry in pReorderOffst */ - startOffset += pNumCodewordInSection[k] << pCbDimShift[pCodebook[k]]; - } - pReorderOffset[j] = - startOffset; /* offset for reordering the codewords */ - - if (i == searchStart) { - k = i; - while (pCodebookSwitch[k++] == 1) searchStart++; - } - break; - } - } - } -} - -/*--------------------------------------------------------------------------------------------- - description: This function calculates the segmentation, which includes -numSegment, leftStartOfSegment, rightStartOfSegment and remainingBitsInSegment. - The segmentation could be visualized a as kind of -'overlay-grid' for the bitstream-block holding the HCR-encoded -quantized-spectral-coefficients. --------------------------------------------------------------------------------------------- -*/ - -static void HcrPrepareSegmentationGrid(H_HCR_INFO pHcr) { - USHORT i, j; - USHORT numSegment = 0; - INT segmentStart = 0; - UCHAR segmentWidth; - UCHAR lastSegmentWidth; - UCHAR sortedCodebook; - UCHAR endFlag = 0; - INT intermediateResult; - - SCHAR lengthOfLongestCodeword = pHcr->decInOut.lengthOfLongestCodeword; - SHORT lengthOfReorderedSpectralData = - pHcr->decInOut.lengthOfReorderedSpectralData; - UINT numSortedSection = pHcr->sectionInfo.numSortedSection; - UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook; - USHORT *pNumSortedCodewordInSection = - pHcr->sectionInfo.pNumSortedCodewordInSection; - INT *pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment; - INT *pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment; - SCHAR *pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment; - const UCHAR *pMaxCwLength = aMaxCwLen; - - for (i = numSortedSection; i != 0; i--) { - sortedCodebook = *pSortedCodebook++; - segmentWidth = - fMin((INT)pMaxCwLength[sortedCodebook], (INT)lengthOfLongestCodeword); - - for (j = *pNumSortedCodewordInSection; j != 0; j--) { - /* width allows a new segment */ - intermediateResult = segmentStart; - if ((segmentStart + segmentWidth) <= lengthOfReorderedSpectralData) { - /* store segment start, segment length and increment the number of - * segments */ - *pLeftStartOfSegment++ = intermediateResult; - *pRightStartOfSegment++ = intermediateResult + segmentWidth - 1; - *pRemainingBitsInSegment++ = segmentWidth; - segmentStart += segmentWidth; - numSegment += 1; - } - /* width does not allow a new segment */ - else { - /* correct the last segment length */ - pLeftStartOfSegment--; - pRightStartOfSegment--; - pRemainingBitsInSegment--; - segmentStart = *pLeftStartOfSegment; - - lastSegmentWidth = lengthOfReorderedSpectralData - segmentStart; - *pRemainingBitsInSegment = lastSegmentWidth; - *pRightStartOfSegment = segmentStart + lastSegmentWidth - 1; - endFlag = 1; - break; - } - } - pNumSortedCodewordInSection++; - if (endFlag != 0) { - break; - } - } - pHcr->segmentInfo.numSegment = numSegment; -} - -/*--------------------------------------------------------------------------------------------- - description: This function adapts the sorted section boundaries to the -boundaries of segmentation. If the section lengths does not fit completely into -the current segment, the section is spitted into two so called 'extended - sections'. The extended-section-info -(pNumExtendedSortedCodewordInSectin and pExtendedSortedCodebook) is updated in -this case. - --------------------------------------------------------------------------------------------- -*/ - -static void HcrExtendedSectionInfo(H_HCR_INFO pHcr) { - UINT srtSecCnt = 0; /* counter for sorted sections */ - UINT xSrtScCnt = 0; /* counter for extended sorted sections */ - UINT remainNumCwInSortSec; - UINT inSegmentRemainNumCW; - - UINT numSortedSection = pHcr->sectionInfo.numSortedSection; - UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook; - USHORT *pNumSortedCodewordInSection = - pHcr->sectionInfo.pNumSortedCodewordInSection; - UCHAR *pExtendedSortedCoBo = pHcr->sectionInfo.pExtendedSortedCodebook; - USHORT *pNumExtSortCwInSect = - pHcr->sectionInfo.pNumExtendedSortedCodewordInSection; - UINT numSegment = pHcr->segmentInfo.numSegment; - UCHAR *pMaxLenOfCbInExtSrtSec = pHcr->sectionInfo.pMaxLenOfCbInExtSrtSec; - SCHAR lengthOfLongestCodeword = pHcr->decInOut.lengthOfLongestCodeword; - const UCHAR *pMaxCwLength = aMaxCwLen; - - remainNumCwInSortSec = pNumSortedCodewordInSection[srtSecCnt]; - inSegmentRemainNumCW = numSegment; - - while (srtSecCnt < numSortedSection) { - if (inSegmentRemainNumCW < remainNumCwInSortSec) { - pNumExtSortCwInSect[xSrtScCnt] = inSegmentRemainNumCW; - pExtendedSortedCoBo[xSrtScCnt] = pSortedCodebook[srtSecCnt]; - - remainNumCwInSortSec -= inSegmentRemainNumCW; - inSegmentRemainNumCW = numSegment; - /* data of a sorted section was not integrated in extended sorted section - */ - } else if (inSegmentRemainNumCW == remainNumCwInSortSec) { - pNumExtSortCwInSect[xSrtScCnt] = inSegmentRemainNumCW; - pExtendedSortedCoBo[xSrtScCnt] = pSortedCodebook[srtSecCnt]; - - srtSecCnt++; - remainNumCwInSortSec = pNumSortedCodewordInSection[srtSecCnt]; - inSegmentRemainNumCW = numSegment; - /* data of a sorted section was integrated in extended sorted section */ - } else { /* inSegmentRemainNumCW > remainNumCwInSortSec */ - pNumExtSortCwInSect[xSrtScCnt] = remainNumCwInSortSec; - pExtendedSortedCoBo[xSrtScCnt] = pSortedCodebook[srtSecCnt]; - - inSegmentRemainNumCW -= remainNumCwInSortSec; - srtSecCnt++; - remainNumCwInSortSec = pNumSortedCodewordInSection[srtSecCnt]; - /* data of a sorted section was integrated in extended sorted section */ - } - pMaxLenOfCbInExtSrtSec[xSrtScCnt] = - fMin((INT)pMaxCwLength[pExtendedSortedCoBo[xSrtScCnt]], - (INT)lengthOfLongestCodeword); - - xSrtScCnt += 1; - - if (xSrtScCnt >= (MAX_SFB_HCR + MAX_HCR_SETS)) { - pHcr->decInOut.errorLog |= EXTENDED_SORTED_COUNTER_OVERFLOW; - return; - } - } - pNumExtSortCwInSect[xSrtScCnt] = 0; -} - -/*--------------------------------------------------------------------------------------------- - description: This function calculates the number of extended sorted -sections which belong to the sets. Each set from set 0 (one and only set for the -PCWs) till to the last set gets a entry in the array to which - 'pNumExtendedSortedSectinsInSets' points to. - - Calculation: The entrys in -pNumExtendedSortedCodewordInSectin are added untill the value numSegment is -reached. Then the sum_variable is cleared and the calculation starts from the -beginning. As much extended sorted Sections are summed up to reach the value -numSegment, as much is the current entry in *pNumExtendedSortedCodewordInSectin. --------------------------------------------------------------------------------------------- -*/ -static void DeriveNumberOfExtendedSortedSectionsInSets( - UINT numSegment, USHORT *pNumExtendedSortedCodewordInSection, - int numExtendedSortedCodewordInSectionIdx, - USHORT *pNumExtendedSortedSectionsInSets, - int numExtendedSortedSectionsInSetsIdx) { - USHORT counter = 0; - UINT cwSum = 0; - USHORT *pNumExSortCwInSec = pNumExtendedSortedCodewordInSection; - USHORT *pNumExSortSecInSets = pNumExtendedSortedSectionsInSets; - - while (pNumExSortCwInSec[numExtendedSortedCodewordInSectionIdx] != 0) { - cwSum += pNumExSortCwInSec[numExtendedSortedCodewordInSectionIdx]; - numExtendedSortedCodewordInSectionIdx++; - if (numExtendedSortedCodewordInSectionIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) { - return; - } - if (cwSum > numSegment) { - return; - } - counter++; - if (counter > 1024 / 4) { - return; - } - if (cwSum == numSegment) { - pNumExSortSecInSets[numExtendedSortedSectionsInSetsIdx] = counter; - numExtendedSortedSectionsInSetsIdx++; - if (numExtendedSortedSectionsInSetsIdx >= MAX_HCR_SETS) { - return; - } - counter = 0; - cwSum = 0; - } - } - pNumExSortSecInSets[numExtendedSortedSectionsInSetsIdx] = - counter; /* save last entry for the last - probably shorter - set */ -} - -/*--------------------------------------------------------------------------------------------- - description: This function decodes all priority codewords (PCWs) in a -spectrum (within set 0). The calculation of the PCWs is managed in two loops. -The loopcounter of the outer loop is set to the first value pointer - pNumExtendedSortedSectionsInSets points to. This value -represents the number of extended sorted sections within set 0. The loopcounter -of the inner loop is set to the first value pointer - pNumExtendedSortedCodewordInSectin points to. The value -represents the number of extended sorted codewords in sections (the original -sections have been splitted to go along with the borders of the sets). Each time -the number of the extended sorted codewords in sections are de- coded, the -pointer 'pNumExtendedSortedCodewordInSectin' is incremented by one. --------------------------------------------------------------------------------------------- -*/ -static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) { - UINT i; - USHORT extSortSec; - USHORT curExtSortCwInSec; - UCHAR codebook; - UCHAR dimension; - const UINT *pCurrentTree; - const SCHAR *pQuantValBase; - const SCHAR *pQuantVal; - - USHORT *pNumExtendedSortedCodewordInSection = - pHcr->sectionInfo.pNumExtendedSortedCodewordInSection; - int numExtendedSortedCodewordInSectionIdx = - pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx; - UCHAR *pExtendedSortedCodebook = pHcr->sectionInfo.pExtendedSortedCodebook; - int extendedSortedCodebookIdx = pHcr->sectionInfo.extendedSortedCodebookIdx; - USHORT *pNumExtendedSortedSectionsInSets = - pHcr->sectionInfo.pNumExtendedSortedSectionsInSets; - int numExtendedSortedSectionsInSetsIdx = - pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx; - FIXP_DBL *pQuantizedSpectralCoefficients = - SPEC_LONG(pHcr->decInOut.pQuantizedSpectralCoefficientsBase); - int quantizedSpectralCoefficientsIdx = - pHcr->decInOut.quantizedSpectralCoefficientsIdx; - INT *pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment; - SCHAR *pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment; - UCHAR *pMaxLenOfCbInExtSrtSec = pHcr->sectionInfo.pMaxLenOfCbInExtSrtSec; - int maxLenOfCbInExtSrtSecIdx = pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx; - UCHAR maxAllowedCwLen; - int numDecodedBits; - const UCHAR *pCbDimension = aDimCb; - const UCHAR *pCbSign = aSignCb; - - /* clear result array */ - FDKmemclear(pQuantizedSpectralCoefficients + quantizedSpectralCoefficientsIdx, - 1024 * sizeof(FIXP_DBL)); - - /* decode all PCWs in the extended sorted section(s) belonging to set 0 */ - for (extSortSec = - pNumExtendedSortedSectionsInSets[numExtendedSortedSectionsInSetsIdx]; - extSortSec != 0; extSortSec--) { - codebook = - pExtendedSortedCodebook[extendedSortedCodebookIdx]; /* get codebook for - this extended - sorted section - and increment ptr - to cb of next - ext. sort sec */ - extendedSortedCodebookIdx++; - if (extendedSortedCodebookIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) { - return; - } - dimension = pCbDimension[codebook]; /* get dimension of codebook of this - extended sort. sec. */ - pCurrentTree = - aHuffTable[codebook]; /* convert codebook to pointer to QSCs */ - pQuantValBase = - aQuantTable[codebook]; /* convert codebook to index to table of QSCs */ - maxAllowedCwLen = pMaxLenOfCbInExtSrtSec[maxLenOfCbInExtSrtSecIdx]; - maxLenOfCbInExtSrtSecIdx++; - if (maxLenOfCbInExtSrtSecIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) { - return; - } - - /* switch for decoding with different codebooks: */ - if (pCbSign[codebook] == - 0) { /* no sign bits follow after the codeword-body */ - /* PCW_BodyONLY */ - /*==============*/ - - for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection - [numExtendedSortedCodewordInSectionIdx]; - curExtSortCwInSec != 0; curExtSortCwInSec--) { - numDecodedBits = 0; - - /* decode PCW_BODY */ - pQuantVal = DecodePCW_Body( - bs, pHcr->decInOut.bitstreamAnchor, pCurrentTree, pQuantValBase, - pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits); - - /* result is written out here because NO sign bits follow the body */ - for (i = dimension; i != 0; i--) { - pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx] = - (FIXP_DBL)*pQuantVal++; /* write quant. spec. coef. into - spectrum; sign is already valid */ - quantizedSpectralCoefficientsIdx++; - if (quantizedSpectralCoefficientsIdx >= 1024) { - return; - } - } - - /* one more PCW should be decoded */ - - if (maxAllowedCwLen < (numDecodedBits + ERROR_PCW_BODY_ONLY_TOO_LONG)) { - pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_BITS_DECODED; - } - - if (1 == errDetectPcwSegmentation( - *pRemainingBitsInSegment - ERROR_PCW_BODY, pHcr, PCW_BODY, - pQuantizedSpectralCoefficients + - quantizedSpectralCoefficientsIdx - dimension, - dimension)) { - return; - } - pLeftStartOfSegment++; /* update pointer for decoding the next PCW */ - pRemainingBitsInSegment++; /* update pointer for decoding the next PCW - */ - } - } else if ((codebook < 11) && (pCbSign[codebook] == - 1)) { /* possibly there follow 1,2,3 or 4 - sign bits after the codeword-body */ - /* PCW_Body and PCW_Sign */ - /*=======================*/ - - for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection - [numExtendedSortedCodewordInSectionIdx]; - curExtSortCwInSec != 0; curExtSortCwInSec--) { - int err; - numDecodedBits = 0; - - pQuantVal = DecodePCW_Body( - bs, pHcr->decInOut.bitstreamAnchor, pCurrentTree, pQuantValBase, - pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits); - - err = DecodePCW_Sign( - bs, pHcr->decInOut.bitstreamAnchor, dimension, pQuantVal, - pQuantizedSpectralCoefficients, &quantizedSpectralCoefficientsIdx, - pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits); - if (err != 0) { - return; - } - /* one more PCW should be decoded */ - - if (maxAllowedCwLen < (numDecodedBits + ERROR_PCW_BODY_SIGN_TOO_LONG)) { - pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_SIGN_BITS_DECODED; - } - - if (1 == errDetectPcwSegmentation( - *pRemainingBitsInSegment - ERROR_PCW_BODY_SIGN, pHcr, - PCW_BODY_SIGN, - pQuantizedSpectralCoefficients + - quantizedSpectralCoefficientsIdx - dimension, - dimension)) { - return; - } - pLeftStartOfSegment++; - pRemainingBitsInSegment++; - } - } else if ((pCbSign[codebook] == 1) && - (codebook >= 11)) { /* possibly there follow some sign bits and - maybe one or two escape sequences after - the cw-body */ - /* PCW_Body, PCW_Sign and maybe PCW_Escape */ - /*=========================================*/ - - for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection - [numExtendedSortedCodewordInSectionIdx]; - curExtSortCwInSec != 0; curExtSortCwInSec--) { - int err; - numDecodedBits = 0; - - /* decode PCW_BODY */ - pQuantVal = DecodePCW_Body( - bs, pHcr->decInOut.bitstreamAnchor, pCurrentTree, pQuantValBase, - pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits); - - err = DecodePCW_Sign( - bs, pHcr->decInOut.bitstreamAnchor, dimension, pQuantVal, - pQuantizedSpectralCoefficients, &quantizedSpectralCoefficientsIdx, - pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits); - if (err != 0) { - return; - } - - /* decode PCW_ESCAPE if present */ - quantizedSpectralCoefficientsIdx -= DIMENSION_OF_ESCAPE_CODEBOOK; - - if (fixp_abs(pQuantizedSpectralCoefficients - [quantizedSpectralCoefficientsIdx]) == - (FIXP_DBL)ESCAPE_VALUE) { - pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx] = - (FIXP_DBL)DecodeEscapeSequence( - bs, pHcr->decInOut.bitstreamAnchor, - pQuantizedSpectralCoefficients - [quantizedSpectralCoefficientsIdx], - pLeftStartOfSegment, pRemainingBitsInSegment, - &numDecodedBits); - } - quantizedSpectralCoefficientsIdx++; - if (quantizedSpectralCoefficientsIdx >= 1024) { - return; - } - - if (fixp_abs(pQuantizedSpectralCoefficients - [quantizedSpectralCoefficientsIdx]) == - (FIXP_DBL)ESCAPE_VALUE) { - pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx] = - (FIXP_DBL)DecodeEscapeSequence( - bs, pHcr->decInOut.bitstreamAnchor, - pQuantizedSpectralCoefficients - [quantizedSpectralCoefficientsIdx], - pLeftStartOfSegment, pRemainingBitsInSegment, - &numDecodedBits); - } - quantizedSpectralCoefficientsIdx++; - if (quantizedSpectralCoefficientsIdx >= 1024) { - return; - } - - /* one more PCW should be decoded */ - - if (maxAllowedCwLen < - (numDecodedBits + ERROR_PCW_BODY_SIGN_ESC_TOO_LONG)) { - pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_SIGN_ESC_BITS_DECODED; - } - - if (1 == errDetectPcwSegmentation( - *pRemainingBitsInSegment - ERROR_PCW_BODY_SIGN_ESC, pHcr, - PCW_BODY_SIGN_ESC, - pQuantizedSpectralCoefficients + - quantizedSpectralCoefficientsIdx - - DIMENSION_OF_ESCAPE_CODEBOOK, - DIMENSION_OF_ESCAPE_CODEBOOK)) { - return; - } - pLeftStartOfSegment++; - pRemainingBitsInSegment++; - } - } - - /* all PCWs belonging to this extended section should be decoded */ - numExtendedSortedCodewordInSectionIdx++; - if (numExtendedSortedCodewordInSectionIdx >= MAX_SFB_HCR + MAX_HCR_SETS) { - return; - } - } - /* all PCWs should be decoded */ - - numExtendedSortedSectionsInSetsIdx++; - if (numExtendedSortedSectionsInSetsIdx >= MAX_HCR_SETS) { - return; - } - - /* Write back indexes into structure */ - pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx = - numExtendedSortedCodewordInSectionIdx; - pHcr->sectionInfo.extendedSortedCodebookIdx = extendedSortedCodebookIdx; - pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx = - numExtendedSortedSectionsInSetsIdx; - pHcr->decInOut.quantizedSpectralCoefficientsIdx = - quantizedSpectralCoefficientsIdx; - pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx = maxLenOfCbInExtSrtSecIdx; -} - -/*--------------------------------------------------------------------------------------------- - description: This function checks immediately after every decoded PCW, -whether out of the current segment too many bits have been read or not. If an -error occurrs, probably the sideinfo or the HCR-bitstream block holding the -huffman encoded quantized spectral coefficients is distorted. In this case the -two or four quantized spectral coefficients belonging to the current codeword - are marked (for being detected by concealment later). --------------------------------------------------------------------------------------------- -*/ -static UCHAR errDetectPcwSegmentation(SCHAR remainingBitsInSegment, - H_HCR_INFO pHcr, PCW_TYPE kind, - FIXP_DBL *qsc_base_of_cw, - UCHAR dimension) { - SCHAR i; - if (remainingBitsInSegment < 0) { - /* log the error */ - switch (kind) { - case PCW_BODY: - pHcr->decInOut.errorLog |= SEGMENT_OVERRIDE_ERR_PCW_BODY; - break; - case PCW_BODY_SIGN: - pHcr->decInOut.errorLog |= SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN; - break; - case PCW_BODY_SIGN_ESC: - pHcr->decInOut.errorLog |= SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN_ESC; - break; - } - /* mark the erred lines */ - for (i = dimension; i != 0; i--) { - *qsc_base_of_cw++ = (FIXP_DBL)Q_VALUE_INVALID; - } - return 1; - } - return 0; -} - -/*--------------------------------------------------------------------------------------------- - description: This function checks if all segments are empty after -decoding. There are _no lines markded_ as invalid because it could not be traced -back where from the remaining bits are. --------------------------------------------------------------------------------------------- -*/ -static void errDetectWithinSegmentationFinal(H_HCR_INFO pHcr) { - UCHAR segmentationErrorFlag = 0; - USHORT i; - SCHAR *pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment; - UINT numSegment = pHcr->segmentInfo.numSegment; - - for (i = numSegment; i != 0; i--) { - if (*pRemainingBitsInSegment++ != 0) { - segmentationErrorFlag = 1; - } - } - if (segmentationErrorFlag == 1) { - pHcr->decInOut.errorLog |= BIT_IN_SEGMENTATION_ERROR; - } -} - -/*--------------------------------------------------------------------------------------------- - description: This function walks one step within the decoding tree. Which -branch is taken depends on the decoded carryBit input parameter. --------------------------------------------------------------------------------------------- -*/ -void CarryBitToBranchValue(UCHAR carryBit, UINT treeNode, UINT *branchValue, - UINT *branchNode) { - if (carryBit == 0) { - *branchNode = - (treeNode & MASK_LEFT) >> LEFT_OFFSET; /* MASK_LEFT: 00FFF000 */ - } else { - *branchNode = treeNode & MASK_RIGHT; /* MASK_RIGHT: 00000FFF */ - } - - *branchValue = *branchNode & CLR_BIT_10; /* clear bit 10 (if set) */ -} - -/*--------------------------------------------------------------------------------------------- - description: Decodes the body of a priority codeword (PCW) ------------------------------------------------------------------------------------------------ - return: - return value is pointer to first of two or four quantized -spectral coefficients --------------------------------------------------------------------------------------------- -*/ -static const SCHAR *DecodePCW_Body(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor, - const UINT *pCurrentTree, - const SCHAR *pQuantValBase, - INT *pLeftStartOfSegment, - SCHAR *pRemainingBitsInSegment, - int *pNumDecodedBits) { - UCHAR carryBit; - UINT branchNode; - UINT treeNode; - UINT branchValue; - const SCHAR *pQuantVal; - - /* decode PCW_BODY */ - treeNode = *pCurrentTree; /* get first node of current tree belonging to - current codebook */ - - /* decode whole PCW-codeword-body */ - while (1) { - carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment, - pLeftStartOfSegment, /* dummy */ - FROM_LEFT_TO_RIGHT); - *pRemainingBitsInSegment -= 1; - *pNumDecodedBits += 1; - - CarryBitToBranchValue(carryBit, treeNode, &branchValue, &branchNode); - - if ((branchNode & TEST_BIT_10) == - TEST_BIT_10) { /* test bit 10 ; if set --> codeword-body is complete */ - break; /* end of branch in tree reached i.e. a whole PCW-Body is decoded - */ - } else { - treeNode = *( - pCurrentTree + - branchValue); /* update treeNode for further step in decoding tree */ - } - } - - pQuantVal = - pQuantValBase + branchValue; /* update pointer to valid first of 2 or 4 - quantized values */ - - return pQuantVal; -} - -/*--------------------------------------------------------------------------------------------- - description: This function decodes one escape sequence. In case of a -escape codebook and in case of the absolute value of the quantized spectral -value == 16, a escapeSequence is decoded in two steps: - 1. escape prefix - 2. escape word --------------------------------------------------------------------------------------------- -*/ - -static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor, - INT quantSpecCoef, INT *pLeftStartOfSegment, - SCHAR *pRemainingBitsInSegment, - int *pNumDecodedBits) { - UINT i; - INT sign; - UINT escapeOnesCounter = 0; - UINT carryBit; - INT escape_word = 0; - - /* decode escape prefix */ - while (1) { - carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment, - pLeftStartOfSegment, /* dummy */ - FROM_LEFT_TO_RIGHT); - *pRemainingBitsInSegment -= 1; - *pNumDecodedBits += 1; - - if (carryBit != 0) { - escapeOnesCounter += 1; - } else { - escapeOnesCounter += 4; - break; - } - } - - /* decode escape word */ - for (i = escapeOnesCounter; i != 0; i--) { - carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment, - pLeftStartOfSegment, /* dummy */ - FROM_LEFT_TO_RIGHT); - *pRemainingBitsInSegment -= 1; - *pNumDecodedBits += 1; - - escape_word <<= 1; - escape_word = escape_word | carryBit; - } - - sign = (quantSpecCoef >= 0) ? 1 : -1; - - quantSpecCoef = sign * (((INT)1 << escapeOnesCounter) + escape_word); - - return quantSpecCoef; -} - -/*--------------------------------------------------------------------------------------------- - description: Decodes the Signbits of a priority codeword (PCW) and writes -out the resulting quantized spectral values into unsorted sections ------------------------------------------------------------------------------------------------ - output: - two or four lines at position in corresponding section -(which are not located at the desired position, i.e. they must be reordered in -the last of eight function of HCR) ------------------------------------------------------------------------------------------------ - return: - updated pQuantSpecCoef pointer (to next empty storage for a -line) --------------------------------------------------------------------------------------------- -*/ -static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor, - UINT codebookDim, const SCHAR *pQuantVal, - FIXP_DBL *pQuantSpecCoef, int *quantSpecCoefIdx, - INT *pLeftStartOfSegment, - SCHAR *pRemainingBitsInSegment, - int *pNumDecodedBits) { - UINT i; - UINT carryBit; - INT quantSpecCoef; - - for (i = codebookDim; i != 0; i--) { - quantSpecCoef = *pQuantVal++; - if (quantSpecCoef != 0) { - carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment, - pLeftStartOfSegment, /* dummy */ - FROM_LEFT_TO_RIGHT); - *pRemainingBitsInSegment -= 1; - *pNumDecodedBits += 1; - if (*pRemainingBitsInSegment < 0 || *pNumDecodedBits >= (1024 >> 1)) { - return -1; - } - - /* adapt sign of values according to the decoded sign bit */ - if (carryBit != 0) { - pQuantSpecCoef[*quantSpecCoefIdx] = -(FIXP_DBL)quantSpecCoef; - } else { - pQuantSpecCoef[*quantSpecCoefIdx] = (FIXP_DBL)quantSpecCoef; - } - } else { - pQuantSpecCoef[*quantSpecCoefIdx] = FL2FXCONST_DBL(0.0f); - } - *quantSpecCoefIdx += 1; - if (*quantSpecCoefIdx >= 1024) { - return -1; - } - } - return 0; -} - -/*--------------------------------------------------------------------------------------------- - description: Mutes spectral lines which have been marked as erroneous -(Q_VALUE_INVALID) --------------------------------------------------------------------------------------------- -*/ -void HcrMuteErroneousLines(H_HCR_INFO hHcr) { - int c; - FIXP_DBL *RESTRICT pLong = - SPEC_LONG(hHcr->decInOut.pQuantizedSpectralCoefficientsBase); - - /* if there is a line with value Q_VALUE_INVALID mute it */ - for (c = 0; c < 1024; c++) { - if (pLong[c] == (FIXP_DBL)Q_VALUE_INVALID) { - pLong[c] = FL2FXCONST_DBL(0.0f); /* muting */ - } - } -} --- a/libAACdec/src/aacdec_hcr.h +++ /dev/null @@ -1,128 +0,0 @@ -/* ----------------------------------------------------------------------------- -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): Robert Weidner (DSP Solutions) - - Description: HCR Decoder: Interface function declaration; common defines - and structures; defines for switching error-generator, - -detector, and -concealment - -*******************************************************************************/ - -#ifndef AACDEC_HCR_H -#define AACDEC_HCR_H - -#include "channelinfo.h" -#include "FDK_bitstream.h" - -UINT HcrInit(H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo, - const SamplingRateInfo *pSamplingRateInfo, - HANDLE_FDK_BITSTREAM bs); -UINT HcrDecoder(H_HCR_INFO hHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo, - const SamplingRateInfo *pSamplingRateInfo, - HANDLE_FDK_BITSTREAM bs); -void CarryBitToBranchValue(UCHAR carryBit, UINT treeNode, UINT *branchValue, - UINT *branchNode); - -void CHcr_Read(HANDLE_FDK_BITSTREAM bs, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - const MP4_ELEMENT_ID globalHcrType); -void HcrMuteErroneousLines(H_HCR_INFO hHcr); - -void setHcrType(H_HCR_INFO hHcr, MP4_ELEMENT_ID type); -INT getHcrType(H_HCR_INFO hHcr); - -#endif /* AACDEC_HCR_H */ --- a/libAACdec/src/aacdec_hcr_bit.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* ----------------------------------------------------------------------------- -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): Robert Weidner (DSP Solutions) - - Description: HCR Decoder: Bitstream reading - -*******************************************************************************/ - -#include "aacdec_hcr_bit.h" - -/*--------------------------------------------------------------------------------------------- - description: This function toggles the read direction. ------------------------------------------------------------------------------------------------ - input: current read direction ------------------------------------------------------------------------------------------------ - return: new read direction --------------------------------------------------------------------------------------------- -*/ -UCHAR ToggleReadDirection(UCHAR readDirection) { - if (readDirection == FROM_LEFT_TO_RIGHT) { - return FROM_RIGHT_TO_LEFT; - } else { - return FROM_LEFT_TO_RIGHT; - } -} - -/*--------------------------------------------------------------------------------------------- - description: This function returns a bit from the bitstream according to -read direction. It is called very often, therefore it makes sense to inline it -(runtime). ------------------------------------------------------------------------------------------------ - input: - handle to FDK bitstream - - reference value marking start of bitfield - - pLeftStartOfSegment - - pRightStartOfSegment - - readDirection ------------------------------------------------------------------------------------------------ - return: - bit from bitstream --------------------------------------------------------------------------------------------- -*/ -UINT HcrGetABitFromBitstream(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor, - INT *pLeftStartOfSegment, - INT *pRightStartOfSegment, UCHAR readDirection) { - UINT bit; - INT readBitOffset; - - if (readDirection == FROM_LEFT_TO_RIGHT) { - readBitOffset = (INT)FDKgetValidBits(bs) - bsAnchor + *pLeftStartOfSegment; - if (readBitOffset) { - FDKpushBiDirectional(bs, readBitOffset); - } - - bit = FDKreadBits(bs, 1); - - *pLeftStartOfSegment += 1; - } else { - readBitOffset = (INT)FDKgetValidBits(bs) - bsAnchor + *pRightStartOfSegment; - if (readBitOffset) { - FDKpushBiDirectional(bs, readBitOffset); - } - - /* to be replaced with a brother function of FDKreadBits() */ - bit = FDKreadBits(bs, 1); - FDKpushBack(bs, 2); - - *pRightStartOfSegment -= 1; - } - - return (bit); -} --- a/libAACdec/src/aacdec_hcr_bit.h +++ /dev/null @@ -1,114 +0,0 @@ -/* ----------------------------------------------------------------------------- -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): Robert Weidner (DSP Solutions) - - Description: HCR Decoder: Bitstream reading prototypes - -*******************************************************************************/ - -#ifndef AACDEC_HCR_BIT_H -#define AACDEC_HCR_BIT_H - -#include "aacdec_hcr.h" - -UCHAR ToggleReadDirection(UCHAR readDirection); - -UINT HcrGetABitFromBitstream(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor, - INT *pLeftStartOfSegment, - INT *pRightStartOfSegment, UCHAR readDirection); - -#endif /* AACDEC_HCR_BIT_H */ --- a/libAACdec/src/aacdec_hcr_types.h +++ /dev/null @@ -1,432 +0,0 @@ -/* ----------------------------------------------------------------------------- -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): Robert Weidner (DSP Solutions) - - Description: HCR Decoder: Common defines and structures; defines for - switching error-generator, -detector, and -concealment; - -*******************************************************************************/ - -#ifndef AACDEC_HCR_TYPES_H -#define AACDEC_HCR_TYPES_H - -#include "FDK_bitstream.h" -#include "overlapadd.h" - -/* ------------------------------------------------ */ -/* ------------------------------------------------ */ - -#define LINES_PER_UNIT 4 - -/* ------------------------------------------------ */ -/* ------------------------------------------------ */ -/* ----------- basic HCR configuration ------------ */ - -#define MAX_SFB_HCR \ - (((1024 / 8) / LINES_PER_UNIT) * 8) /* (8 * 16) is not enough because sfbs \ - are split in units for blocktype \ - short */ -#define NUMBER_OF_UNIT_GROUPS (LINES_PER_UNIT * 8) -#define LINES_PER_UNIT_GROUP (1024 / NUMBER_OF_UNIT_GROUPS) /* 15 16 30 32 */ - -/* ------------------------------------------------ */ -/* ------------------------------------------------ */ -/* ------------------------------------------------ */ - -#define FROM_LEFT_TO_RIGHT 0 -#define FROM_RIGHT_TO_LEFT 1 - -#define MAX_CB_PAIRS 23 -#define MAX_HCR_SETS 14 - -#define ESCAPE_VALUE 16 -#define POSITION_OF_FLAG_A 21 -#define POSITION_OF_FLAG_B 20 - -#define MAX_CB 32 /* last used CB is cb #31 when VCB11 is used */ - -#define MAX_CB_CHECK \ - 32 /* support for VCB11 available -- is more general, could therefore used \ - in both cases */ - -#define NUMBER_OF_BIT_IN_WORD 32 - -/* log */ -#define THIRTYTWO_LOG_DIV_TWO_LOG 5 -#define EIGHT_LOG_DIV_TWO_LOG 3 -#define FOUR_LOG_DIV_TWO_LOG 2 - -/* borders */ -#define CPE_TOP_LENGTH 12288 -#define SCE_TOP_LENGTH 6144 -#define LEN_OF_LONGEST_CW_TOP_LENGTH 49 - -/* qsc's of high level */ -#define Q_VALUE_INVALID \ - 8192 /* mark a invalid line with this value (to be concealed later on) */ -#define HCR_DIRAC 500 /* a line of high level */ - -/* masks */ -#define MASK_LEFT 0xFFF000 -#define MASK_RIGHT 0xFFF -#define CLR_BIT_10 0x3FF -#define TEST_BIT_10 0x400 - -#define LEFT_OFFSET 12 - -/* when set HCR is replaced by a dummy-module which just fills the outputbuffer - * with a dirac sequence */ -/* use this if HCR is suspected to write in other modules -- if error is stell - * there, HCR is innocent */ - -/* ------------------------------ */ -/* - insert HCR errors - */ -/* ------------------------------ */ - -/* modify input lengths -- high protected */ -#define ERROR_LORSD 0 /* offset: error if different from zero */ -#define ERROR_LOLC 0 /* offset: error if different from zero */ - -/* segments are earlier empty as expected when decoding PCWs */ -#define ERROR_PCW_BODY \ - 0 /* set a positive values to trigger the error (make segments earlyer \ - appear to be empty) */ -#define ERROR_PCW_BODY_SIGN \ - 0 /* set a positive values to trigger the error (make segments earlyer \ - appear to be empty) */ -#define ERROR_PCW_BODY_SIGN_ESC \ - 0 /* set a positive values to trigger the error (make segments earlyer \ - appear to be empty) */ - -/* pretend there are too many bits decoded (enlarge length of codeword) at PCWs - * -- use a positive value */ -#define ERROR_PCW_BODY_ONLY_TOO_LONG \ - 0 /* set a positive values to trigger the error */ -#define ERROR_PCW_BODY_SIGN_TOO_LONG \ - 0 /* set a positive values to trigger the error */ -#define ERROR_PCW_BODY_SIGN_ESC_TOO_LONG \ - 0 /* set a positive values to trigger the error */ - -/* modify HCR bitstream block */ - -#define MODULO_DIVISOR_HCR 30 - -/* ------------------------------ */ -/* - detect HCR errors - */ -/* ------------------------------ */ -/* check input data */ - -/* during decoding */ - -/* all the segments are checked -- therefore -- if this check passes, its a kind - of evidence that the decoded PCWs and non-PCWs are fine */ - -/* if a codeword is decoded there exists a border for the number of bits, which - are allowed to read for this codeword. This border is the minimum of the - length of the longest codeword (for the currently used codebook) and the - separately transmitted 'lengthOfLongestCodeword' in this frame and channel. - The number of decoded bits is counted (for PCWs only -- there it makes really - sense in my opinion). If this number exceeds the border (derived as minimum - -- see above), a error is detected. */ - -/* ----------------------------------------------------------------------------------------------------- - This error check could be set to zero because due to a test within - RVLC-Escape-huffman-Decoder a too long codeword could not be detected -- it - seems that for RVLC-Escape-Codeword the coderoom is used to 100%. Therefore I - assume that the coderoom is used to 100% also for the codebooks 1..11 used at - HCR Therefore this test is deactivated pending further notice - ----------------------------------------------------------------------------------------------------- - */ - -/* test if the number of remaining bits in a segment is _below_ zero. If there - are no errors the lowest allowed value for remainingBitsInSegment is zero. - This check also could be set to zero (save runtime) */ - -/* other */ -/* when set to '1', avoid setting the LAV-Flag in errorLog due to a - previous-line-marking (at PCW decoder). A little more runtime is needed then - when writing values out into output-buffer. */ - -/* ------------------------------ */ -/* - conceal HCR errors - */ -/* ------------------------------ */ - -#define HCR_ERROR_CONCEALMENT \ - 1 /* if set to '1', HCR _mutes_ the erred quantized spectral coefficients */ - -// ------------------------------------------------------------------------------------------------------------------ -// errorLog: A word of 32 bits used for -// logging possible errors within HCR -// in case of distorted -// bitstreams. Table of all -// known errors: -// ------------------------------------------------------------------------------------------------------------------------ -// bit fatal location meaning -// ----+-----+-----------+-------------------------------------- -#define SEGMENT_OVERRIDE_ERR_PCW_BODY \ - 0x80000000 // 31 no PCW-Dec During PCW decoding it is checked after - // every PCW if there are too many bits decoded (immediate - // check). -#define SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN \ - 0x40000000 // 30 no PCW-Dec During PCW decoding it is checked after - // every PCW if there are too many bits decoded (immediate - // check). -#define SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN_ESC \ - 0x20000000 // 29 no PCW-Dec During PCW decoding it is checked after - // every PCW if there are too many bits decoded (immediate - // check). -#define EXTENDED_SORTED_COUNTER_OVERFLOW \ - 0x10000000 // 28 yes Init-Dec Error during extending sideinfo - // (neither a PCW nor a nonPCW was decoded so far) - // 0x08000000 // 27 reserved - // 0x04000000 // 26 reserved - // 0x02000000 // 25 reserved - // 0x01000000 // 24 reserved - // 0x00800000 // 23 reserved - // 0x00400000 // 22 reserved - // 0x00200000 // 21 reserved - // 0x00100000 // 20 reserved - -/* special errors */ -#define TOO_MANY_PCW_BODY_BITS_DECODED \ - 0x00080000 // 19 yes PCW-Dec During PCW-body-decoding too many bits - // have been read from bitstream -- advice: skip non-PCW decoding -#define TOO_MANY_PCW_BODY_SIGN_BITS_DECODED \ - 0x00040000 // 18 yes PCW-Dec During PCW-body-sign-decoding too many - // bits have been read from bitstream -- advice: skip non-PCW - // decoding -#define TOO_MANY_PCW_BODY_SIGN_ESC_BITS_DECODED \ - 0x00020000 // 17 yes PCW-Dec During PCW-body-sign-esc-decoding too - // many bits have been read from bitstream -- advice: skip - // non-PCW decoding - -// 0x00010000 // 16 reserved -#define STATE_ERROR_BODY_ONLY \ - 0x00008000 // 15 no NonPCW-Dec State machine returned with error -#define STATE_ERROR_BODY_SIGN__BODY \ - 0x00004000 // 14 no NonPCW-Dec State machine returned with error -#define STATE_ERROR_BODY_SIGN__SIGN \ - 0x00002000 // 13 no NonPCW-Dec State machine returned with error -#define STATE_ERROR_BODY_SIGN_ESC__BODY \ - 0x00001000 // 12 no NonPCW-Dec State machine returned with error -#define STATE_ERROR_BODY_SIGN_ESC__SIGN \ - 0x00000800 // 11 no NonPCW-Dec State machine returned with error -#define STATE_ERROR_BODY_SIGN_ESC__ESC_PREFIX \ - 0x00000400 // 10 no NonPCW-Dec State machine returned with error -#define STATE_ERROR_BODY_SIGN_ESC__ESC_WORD \ - 0x00000200 // 9 no NonPCW-Dec State machine returned with error -#define HCR_SI_LENGTHS_FAILURE \ - 0x00000100 // 8 yes Init-Dec LengthOfLongestCodeword must not be - // less than lenghtOfReorderedSpectralData -#define NUM_SECT_OUT_OF_RANGE_SHORT_BLOCK \ - 0x00000080 // 7 yes Init-Dec The number of sections is not within - // the allowed range (short block) -#define NUM_SECT_OUT_OF_RANGE_LONG_BLOCK \ - 0x00000040 // 6 yes Init-Dec The number of sections is not within - // the allowed range (long block) -#define LINE_IN_SECT_OUT_OF_RANGE_SHORT_BLOCK \ - 0x00000020 // 5 yes Init-Dec The number of lines per section is not - // within the allowed range (short block) -#define CB_OUT_OF_RANGE_SHORT_BLOCK \ - 0x00000010 // 4 yes Init-Dec The codebook is not within the allowed - // range (short block) -#define LINE_IN_SECT_OUT_OF_RANGE_LONG_BLOCK \ - 0x00000008 // 3 yes Init-Dec The number of lines per section is not - // within the allowed range (long block) -#define CB_OUT_OF_RANGE_LONG_BLOCK \ - 0x00000004 // 2 yes Init-Dec The codebook is not within the allowed - // range (long block) -#define LAV_VIOLATION \ - 0x00000002 // 1 no Final The absolute value of at least one - // decoded line was too high for the according codebook. -#define BIT_IN_SEGMENTATION_ERROR \ - 0x00000001 // 0 no Final After PCW and non-PWC-decoding at least - // one segment is not zero (global check). - -/*----------*/ -#define HCR_FATAL_PCW_ERROR_MASK 0x100E01FC - -typedef enum { PCW_BODY, PCW_BODY_SIGN, PCW_BODY_SIGN_ESC } PCW_TYPE; - -/* interface Decoder <---> HCR */ -typedef struct { - UINT errorLog; - SPECTRAL_PTR pQuantizedSpectralCoefficientsBase; - int quantizedSpectralCoefficientsIdx; - SHORT lengthOfReorderedSpectralData; - SHORT numSection; - SHORT *pNumLineInSect; - INT bitstreamAnchor; - SCHAR lengthOfLongestCodeword; - UCHAR *pCodebook; -} HCR_INPUT_OUTPUT; - -typedef struct { - const UCHAR *pMinOfCbPair; - const UCHAR *pMaxOfCbPair; -} HCR_CB_PAIRS; - -typedef struct { - const USHORT *pLargestAbsVal; - const UCHAR *pMaxCwLength; - const UCHAR *pCbDimension; - const UCHAR *pCbDimShift; - const UCHAR *pCbSign; - const UCHAR *pCbPriority; -} HCR_TABLE_INFO; - -typedef struct { - UINT numSegment; - UINT pSegmentBitfield[((1024 >> 1) / NUMBER_OF_BIT_IN_WORD + 1)]; - UINT pCodewordBitfield[((1024 >> 1) / NUMBER_OF_BIT_IN_WORD + 1)]; - UINT segmentOffset; - INT pLeftStartOfSegment[1024 >> 1]; - INT pRightStartOfSegment[1024 >> 1]; - SCHAR pRemainingBitsInSegment[1024 >> 1]; - UCHAR readDirection; - UCHAR numWordForBitfield; - USHORT pNumBitValidInLastWord; -} HCR_SEGMENT_INFO; - -typedef struct { - UINT numCodeword; - UINT numSortedSection; - USHORT pNumCodewordInSection[MAX_SFB_HCR]; - USHORT pNumSortedCodewordInSection[MAX_SFB_HCR]; - USHORT pNumExtendedSortedCodewordInSection[MAX_SFB_HCR + MAX_HCR_SETS]; - int numExtendedSortedCodewordInSectionIdx; - USHORT pNumExtendedSortedSectionsInSets[MAX_HCR_SETS]; - int numExtendedSortedSectionsInSetsIdx; - USHORT pReorderOffset[MAX_SFB_HCR]; - UCHAR pSortedCodebook[MAX_SFB_HCR]; - - UCHAR pExtendedSortedCodebook[MAX_SFB_HCR + MAX_HCR_SETS]; - int extendedSortedCodebookIdx; - UCHAR pMaxLenOfCbInExtSrtSec[MAX_SFB_HCR + MAX_HCR_SETS]; - int maxLenOfCbInExtSrtSecIdx; - UCHAR pCodebookSwitch[MAX_SFB_HCR]; -} HCR_SECTION_INFO; - -typedef UINT (*STATEFUNC)(HANDLE_FDK_BITSTREAM, void *); - -typedef struct { - /* worst-case and 1024/4 non-PCWs exist in worst-case */ - FIXP_DBL - *pResultBase; /* Base address for spectral data output target buffer */ - UINT iNode[1024 >> 2]; /* Helper indices for code books */ - USHORT - iResultPointer[1024 >> 2]; /* Helper indices for accessing pResultBase */ - UINT pEscapeSequenceInfo[1024 >> 2]; - UINT codewordOffset; - STATEFUNC pState; - UCHAR pCodebook[1024 >> 2]; - UCHAR pCntSign[1024 >> 2]; - /* this array holds the states coded as integer values within the range - * [0,1,..,7] */ - SCHAR pSta[1024 >> 2]; -} HCR_NON_PCW_SIDEINFO; - -typedef struct { - HCR_INPUT_OUTPUT decInOut; - HCR_SEGMENT_INFO segmentInfo; - HCR_SECTION_INFO sectionInfo; - HCR_NON_PCW_SIDEINFO nonPcwSideinfo; -} CErHcrInfo; - -typedef CErHcrInfo *H_HCR_INFO; - -#endif /* AACDEC_HCR_TYPES_H */ --- a/libAACdec/src/aacdec_hcrs.cpp +++ /dev/null @@ -1,1551 +0,0 @@ -/* ----------------------------------------------------------------------------- -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): Robert Weidner (DSP Solutions) - - Description: HCR Decoder: Prepare decoding of non-PCWs, segmentation- and - bitfield-handling, HCR-Statemachine - -*******************************************************************************/ - -#include "aacdec_hcrs.h" - -#include "aacdec_hcr.h" - -#include "aacdec_hcr_bit.h" -#include "aac_rom.h" -#include "aac_ram.h" - -static UINT InitSegmentBitfield(UINT *pNumSegment, - SCHAR *pRemainingBitsInSegment, - UINT *pSegmentBitfield, - UCHAR *pNumWordForBitfield, - USHORT *pNumBitValidInLastWord); - -static void InitNonPCWSideInformationForCurrentSet(H_HCR_INFO pHcr); - -static INT ModuloValue(INT input, INT bufferlength); - -static void ClearBitFromBitfield(STATEFUNC *ptrState, UINT offset, - UINT *pBitfield); - -/*--------------------------------------------------------------------------------------------- - description: This function decodes all non-priority codewords (non-PCWs) by -using a state-machine. --------------------------------------------------------------------------------------------- -*/ -void DecodeNonPCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) { - UINT numValidSegment; - INT segmentOffset; - INT codewordOffsetBase; - INT codewordOffset; - UINT trial; - - UINT *pNumSegment; - SCHAR *pRemainingBitsInSegment; - UINT *pSegmentBitfield; - UCHAR *pNumWordForBitfield; - USHORT *pNumBitValidInLastWord; - UINT *pCodewordBitfield; - INT bitfieldWord; - INT bitInWord; - UINT tempWord; - UINT interMediateWord; - INT tempBit; - INT carry; - - UINT numCodeword; - UCHAR numSet; - UCHAR currentSet; - UINT codewordInSet; - UINT remainingCodewordsInSet; - SCHAR *pSta; - UINT ret; - - pNumSegment = &(pHcr->segmentInfo.numSegment); - pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment; - pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield; - pNumWordForBitfield = &(pHcr->segmentInfo.numWordForBitfield); - pNumBitValidInLastWord = &(pHcr->segmentInfo.pNumBitValidInLastWord); - pSta = pHcr->nonPcwSideinfo.pSta; - - numValidSegment = InitSegmentBitfield(pNumSegment, pRemainingBitsInSegment, - pSegmentBitfield, pNumWordForBitfield, - pNumBitValidInLastWord); - - if (numValidSegment != 0) { - numCodeword = pHcr->sectionInfo.numCodeword; - numSet = ((numCodeword - 1) / *pNumSegment) + 1; - - pHcr->segmentInfo.readDirection = FROM_RIGHT_TO_LEFT; - - /* Process sets subsequently */ - for (currentSet = 1; currentSet < numSet; currentSet++) { - /* step 1 */ - numCodeword -= - *pNumSegment; /* number of remaining non PCWs [for all sets] */ - if (numCodeword < *pNumSegment) { - codewordInSet = numCodeword; /* for last set */ - } else { - codewordInSet = *pNumSegment; /* for all sets except last set */ - } - - /* step 2 */ - /* prepare array 'CodewordBitfield'; as much ones are written from left in - * all words, as much decodedCodewordInSetCounter nonPCWs exist in this - * set */ - tempWord = 0xFFFFFFFF; - pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield; - - for (bitfieldWord = *pNumWordForBitfield; bitfieldWord != 0; - bitfieldWord--) { /* loop over all used words */ - if (codewordInSet > NUMBER_OF_BIT_IN_WORD) { /* more codewords than - number of bits => fill - ones */ - /* fill a whole word with ones */ - *pCodewordBitfield++ = tempWord; - codewordInSet -= NUMBER_OF_BIT_IN_WORD; /* subtract number of bits */ - } else { - /* prepare last tempWord */ - for (remainingCodewordsInSet = codewordInSet; - remainingCodewordsInSet < NUMBER_OF_BIT_IN_WORD; - remainingCodewordsInSet++) { - tempWord = - tempWord & - ~(1 - << (NUMBER_OF_BIT_IN_WORD - 1 - - remainingCodewordsInSet)); /* set a zero at bit number - (NUMBER_OF_BIT_IN_WORD-1-i) - in tempWord */ - } - *pCodewordBitfield++ = tempWord; - tempWord = 0x00000000; - } - } - pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield; - - /* step 3 */ - /* build non-PCW sideinfo for each non-PCW of the current set */ - InitNonPCWSideInformationForCurrentSet(pHcr); - - /* step 4 */ - /* decode all non-PCWs belonging to this set */ - - /* loop over trials */ - codewordOffsetBase = 0; - for (trial = *pNumSegment; trial > 0; trial--) { - /* loop over number of words in bitfields */ - segmentOffset = 0; /* start at zero in every segment */ - pHcr->segmentInfo.segmentOffset = - segmentOffset; /* store in structure for states */ - codewordOffset = codewordOffsetBase; - pHcr->nonPcwSideinfo.codewordOffset = - codewordOffset; /* store in structure for states */ - - for (bitfieldWord = 0; bitfieldWord < *pNumWordForBitfield; - bitfieldWord++) { - /* derive tempWord with bitwise and */ - tempWord = - pSegmentBitfield[bitfieldWord] & pCodewordBitfield[bitfieldWord]; - - /* if tempWord is not zero, decode something */ - if (tempWord != 0) { - /* loop over all bits in tempWord; start state machine if & is true - */ - for (bitInWord = NUMBER_OF_BIT_IN_WORD; bitInWord > 0; - bitInWord--) { - interMediateWord = ((UINT)1 << (bitInWord - 1)); - if ((tempWord & interMediateWord) == interMediateWord) { - /* get state and start state machine */ - pHcr->nonPcwSideinfo.pState = - aStateConstant2State[pSta[codewordOffset]]; - - while (pHcr->nonPcwSideinfo.pState) { - ret = ((STATEFUNC)pHcr->nonPcwSideinfo.pState)(bs, pHcr); - if (ret != 0) { - return; - } - } - } - - /* update both offsets */ - segmentOffset += 1; /* add NUMBER_OF_BIT_IN_WORD times one */ - pHcr->segmentInfo.segmentOffset = segmentOffset; - codewordOffset += 1; /* add NUMBER_OF_BIT_IN_WORD times one */ - codewordOffset = - ModuloValue(codewordOffset, - *pNumSegment); /* index of the current codeword - lies within modulo range */ - pHcr->nonPcwSideinfo.codewordOffset = codewordOffset; - } - } else { - segmentOffset += - NUMBER_OF_BIT_IN_WORD; /* add NUMBER_OF_BIT_IN_WORD at once */ - pHcr->segmentInfo.segmentOffset = segmentOffset; - codewordOffset += - NUMBER_OF_BIT_IN_WORD; /* add NUMBER_OF_BIT_IN_WORD at once */ - codewordOffset = ModuloValue( - codewordOffset, - *pNumSegment); /* index of the current codeword lies within - modulo range */ - pHcr->nonPcwSideinfo.codewordOffset = codewordOffset; - } - } /* end of bitfield word loop */ - - /* decrement codeword - pointer */ - codewordOffsetBase -= 1; - codewordOffsetBase = - ModuloValue(codewordOffsetBase, *pNumSegment); /* index of the - current codeword - base lies within - modulo range */ - - /* rotate numSegment bits in codewordBitfield */ - /* rotation of *numSegment bits in bitfield of codewords - * (circle-rotation) */ - /* get last valid bit */ - tempBit = pCodewordBitfield[*pNumWordForBitfield - 1] & - (1 << (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord)); - tempBit = tempBit >> (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord); - - /* write zero into place where tempBit was fetched from */ - pCodewordBitfield[*pNumWordForBitfield - 1] = - pCodewordBitfield[*pNumWordForBitfield - 1] & - ~(1 << (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord)); - - /* rotate last valid word */ - pCodewordBitfield[*pNumWordForBitfield - 1] = - pCodewordBitfield[*pNumWordForBitfield - 1] >> 1; - - /* transfare carry bit 0 from current word into bitposition 31 from next - * word and rotate current word */ - for (bitfieldWord = *pNumWordForBitfield - 2; bitfieldWord > -1; - bitfieldWord--) { - /* get carry (=bit at position 0) from current word */ - carry = pCodewordBitfield[bitfieldWord] & 1; - - /* put the carry bit at position 31 into word right from current word - */ - pCodewordBitfield[bitfieldWord + 1] = - pCodewordBitfield[bitfieldWord + 1] | - (carry << (NUMBER_OF_BIT_IN_WORD - 1)); - - /* shift current word */ - pCodewordBitfield[bitfieldWord] = - pCodewordBitfield[bitfieldWord] >> 1; - } - - /* put tempBit into free bit-position 31 from first word */ - pCodewordBitfield[0] = - pCodewordBitfield[0] | (tempBit << (NUMBER_OF_BIT_IN_WORD - 1)); - - } /* end of trial loop */ - - /* toggle read direction */ - pHcr->segmentInfo.readDirection = - ToggleReadDirection(pHcr->segmentInfo.readDirection); - } - /* end of set loop */ - - /* all non-PCWs of this spectrum are decoded */ - } - - /* all PCWs and all non PCWs are decoded. They are unbacksorted in output - * buffer. Here is the Interface with comparing QSCs to asm decoding */ -} - -/*--------------------------------------------------------------------------------------------- - description: This function prepares the bitfield used for the - segments. The list is set up once to be used in all -following sets. If a segment is decoded empty, the according bit from the -Bitfield is removed. ------------------------------------------------------------------------------------------------ - return: numValidSegment = the number of valid segments --------------------------------------------------------------------------------------------- -*/ -static UINT InitSegmentBitfield(UINT *pNumSegment, - SCHAR *pRemainingBitsInSegment, - UINT *pSegmentBitfield, - UCHAR *pNumWordForBitfield, - USHORT *pNumBitValidInLastWord) { - SHORT i; - USHORT r; - UCHAR bitfieldWord; - UINT tempWord; - USHORT numValidSegment; - - *pNumWordForBitfield = - (*pNumSegment == 0) - ? 0 - : ((*pNumSegment - 1) >> THIRTYTWO_LOG_DIV_TWO_LOG) + 1; - - /* loop over all words, which are completely used or only partial */ - /* bit in pSegmentBitfield is zero if segment is empty; bit in - * pSegmentBitfield is one if segment is not empty */ - numValidSegment = 0; - *pNumBitValidInLastWord = *pNumSegment; - - /* loop over words */ - for (bitfieldWord = 0; bitfieldWord < *pNumWordForBitfield - 1; - bitfieldWord++) { - tempWord = 0xFFFFFFFF; /* set ones */ - r = bitfieldWord << THIRTYTWO_LOG_DIV_TWO_LOG; - for (i = 0; i < NUMBER_OF_BIT_IN_WORD; i++) { - if (pRemainingBitsInSegment[r + i] == 0) { - tempWord = tempWord & ~(1 << (NUMBER_OF_BIT_IN_WORD - 1 - - i)); /* set a zero at bit number - (NUMBER_OF_BIT_IN_WORD-1-i) in - tempWord */ - } else { - numValidSegment += 1; /* count segments which are not empty */ - } - } - pSegmentBitfield[bitfieldWord] = tempWord; /* store result */ - *pNumBitValidInLastWord -= NUMBER_OF_BIT_IN_WORD; /* calculate number of - zeros on LSB side in - the last word */ - } - - /* calculate last word: prepare special tempWord */ - tempWord = 0xFFFFFFFF; - for (i = 0; i < (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord); i++) { - tempWord = tempWord & ~(1 << i); /* clear bit i in tempWord */ - } - - /* calculate last word */ - r = bitfieldWord << THIRTYTWO_LOG_DIV_TWO_LOG; - for (i = 0; i < *pNumBitValidInLastWord; i++) { - if (pRemainingBitsInSegment[r + i] == 0) { - tempWord = tempWord & ~(1 << (NUMBER_OF_BIT_IN_WORD - 1 - - i)); /* set a zero at bit number - (NUMBER_OF_BIT_IN_WORD-1-i) in - tempWord */ - } else { - numValidSegment += 1; /* count segments which are not empty */ - } - } - pSegmentBitfield[bitfieldWord] = tempWord; /* store result */ - - return numValidSegment; -} - -/*--------------------------------------------------------------------------------------------- - description: This function sets up sideinfo for the non-PCW decoder (for the -current set). ----------------------------------------------------------------------------------------------*/ -static void InitNonPCWSideInformationForCurrentSet(H_HCR_INFO pHcr) { - USHORT i, k; - UCHAR codebookDim; - UINT startNode; - - UCHAR *pCodebook = pHcr->nonPcwSideinfo.pCodebook; - UINT *iNode = pHcr->nonPcwSideinfo.iNode; - UCHAR *pCntSign = pHcr->nonPcwSideinfo.pCntSign; - USHORT *iResultPointer = pHcr->nonPcwSideinfo.iResultPointer; - UINT *pEscapeSequenceInfo = pHcr->nonPcwSideinfo.pEscapeSequenceInfo; - SCHAR *pSta = pHcr->nonPcwSideinfo.pSta; - USHORT *pNumExtendedSortedCodewordInSection = - pHcr->sectionInfo.pNumExtendedSortedCodewordInSection; - int numExtendedSortedCodewordInSectionIdx = - pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx; - UCHAR *pExtendedSortedCodebook = pHcr->sectionInfo.pExtendedSortedCodebook; - int extendedSortedCodebookIdx = pHcr->sectionInfo.extendedSortedCodebookIdx; - USHORT *pNumExtendedSortedSectionsInSets = - pHcr->sectionInfo.pNumExtendedSortedSectionsInSets; - int numExtendedSortedSectionsInSetsIdx = - pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx; - int quantizedSpectralCoefficientsIdx = - pHcr->decInOut.quantizedSpectralCoefficientsIdx; - const UCHAR *pCbDimension = aDimCb; - int iterationCounter = 0; - - /* loop over number of extended sorted sections in the current set so all - * codewords sideinfo variables within this set can be prepared for decoding - */ - for (i = pNumExtendedSortedSectionsInSets[numExtendedSortedSectionsInSetsIdx]; - i != 0; i--) { - codebookDim = - pCbDimension[pExtendedSortedCodebook[extendedSortedCodebookIdx]]; - startNode = *aHuffTable[pExtendedSortedCodebook[extendedSortedCodebookIdx]]; - - for (k = pNumExtendedSortedCodewordInSection - [numExtendedSortedCodewordInSectionIdx]; - k != 0; k--) { - iterationCounter++; - if (iterationCounter > (1024 >> 2)) { - return; - } - *pSta++ = aCodebook2StartInt - [pExtendedSortedCodebook[extendedSortedCodebookIdx]]; - *pCodebook++ = pExtendedSortedCodebook[extendedSortedCodebookIdx]; - *iNode++ = startNode; - *pCntSign++ = 0; - *iResultPointer++ = quantizedSpectralCoefficientsIdx; - *pEscapeSequenceInfo++ = 0; - quantizedSpectralCoefficientsIdx += - codebookDim; /* update pointer by codebookDim --> point to next - starting value for writing out */ - if (quantizedSpectralCoefficientsIdx >= 1024) { - return; - } - } - numExtendedSortedCodewordInSectionIdx++; /* inc ptr for next ext sort sec in - current set */ - extendedSortedCodebookIdx++; /* inc ptr for next ext sort sec in current set - */ - if (numExtendedSortedCodewordInSectionIdx >= (MAX_SFB_HCR + MAX_HCR_SETS) || - extendedSortedCodebookIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) { - return; - } - } - numExtendedSortedSectionsInSetsIdx++; /* inc ptr for next set of non-PCWs */ - if (numExtendedSortedCodewordInSectionIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) { - return; - } - - /* Write back indexes */ - pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx = - numExtendedSortedCodewordInSectionIdx; - pHcr->sectionInfo.extendedSortedCodebookIdx = extendedSortedCodebookIdx; - pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx = - numExtendedSortedSectionsInSetsIdx; - pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx = - numExtendedSortedCodewordInSectionIdx; - pHcr->decInOut.quantizedSpectralCoefficientsIdx = - quantizedSpectralCoefficientsIdx; -} - -/*--------------------------------------------------------------------------------------------- - description: This function returns the input value if the value is in the - range of bufferlength. If is smaller, one bufferlength -is added, if is bigger one bufferlength is subtracted. ------------------------------------------------------------------------------------------------ - return: modulo result --------------------------------------------------------------------------------------------- -*/ -static INT ModuloValue(INT input, INT bufferlength) { - if (input > (bufferlength - 1)) { - return (input - bufferlength); - } - if (input < 0) { - return (input + bufferlength); - } - return input; -} - -/*--------------------------------------------------------------------------------------------- - description: This function clears a bit from current bitfield and - switches off the statemachine. - - A bit is cleared in two cases: - a) a codeword is decoded, then a bit is cleared in codeword -bitfield b) a segment is decoded empty, then a bit is cleared in segment -bitfield --------------------------------------------------------------------------------------------- -*/ -static void ClearBitFromBitfield(STATEFUNC *ptrState, UINT offset, - UINT *pBitfield) { - UINT numBitfieldWord; - UINT numBitfieldBit; - - /* get both values needed for clearing the bit */ - numBitfieldWord = offset >> THIRTYTWO_LOG_DIV_TWO_LOG; /* int = wordNr */ - numBitfieldBit = offset - (numBitfieldWord - << THIRTYTWO_LOG_DIV_TWO_LOG); /* fract = bitNr */ - - /* clear a bit in bitfield */ - pBitfield[numBitfieldWord] = - pBitfield[numBitfieldWord] & - ~(1 << (NUMBER_OF_BIT_IN_WORD - 1 - numBitfieldBit)); - - /* switch off state machine because codeword is decoded and/or because segment - * is empty */ - *ptrState = NULL; -} - -/* ========================================================================================= - the states of the statemachine - ========================================================================================= - */ - -/*--------------------------------------------------------------------------------------------- - description: Decodes the body of a codeword. This State is used for -codebooks 1,2,5 and 6. No sign bits are decoded, because the table of the -quantized spectral values has got a valid sign at the quantized spectral lines. ------------------------------------------------------------------------------------------------ - output: Two or four quantizes spectral values written at position -where pResultPointr points to ------------------------------------------------------------------------------------------------ - return: 0 --------------------------------------------------------------------------------------------- -*/ -UINT Hcr_State_BODY_ONLY(HANDLE_FDK_BITSTREAM bs, void *ptr) { - H_HCR_INFO pHcr = (H_HCR_INFO)ptr; - UINT *pSegmentBitfield; - UINT *pCodewordBitfield; - UINT segmentOffset; - FIXP_DBL *pResultBase; - UINT *iNode; - USHORT *iResultPointer; - UINT codewordOffset; - UINT branchNode; - UINT branchValue; - UINT iQSC; - UINT treeNode; - UCHAR carryBit; - INT *pLeftStartOfSegment; - INT *pRightStartOfSegment; - SCHAR *pRemainingBitsInSegment; - UCHAR readDirection; - UCHAR *pCodebook; - UCHAR dimCntr; - const UINT *pCurrentTree; - const UCHAR *pCbDimension; - const SCHAR *pQuantVal; - const SCHAR *pQuantValBase; - - pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment; - pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment; - pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment; - readDirection = pHcr->segmentInfo.readDirection; - pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield; - pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield; - segmentOffset = pHcr->segmentInfo.segmentOffset; - - pCodebook = pHcr->nonPcwSideinfo.pCodebook; - iNode = pHcr->nonPcwSideinfo.iNode; - pResultBase = pHcr->nonPcwSideinfo.pResultBase; - iResultPointer = pHcr->nonPcwSideinfo.iResultPointer; - codewordOffset = pHcr->nonPcwSideinfo.codewordOffset; - - pCbDimension = aDimCb; - - treeNode = iNode[codewordOffset]; - pCurrentTree = aHuffTable[pCodebook[codewordOffset]]; - - for (; pRemainingBitsInSegment[segmentOffset] > 0; - pRemainingBitsInSegment[segmentOffset] -= 1) { - carryBit = HcrGetABitFromBitstream( - bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset], - &pRightStartOfSegment[segmentOffset], readDirection); - - CarryBitToBranchValue(carryBit, /* make a step in decoding tree */ - treeNode, &branchValue, &branchNode); - - /* if end of branch reached write out lines and count bits needed for sign, - * otherwise store node in codeword sideinfo */ - if ((branchNode & TEST_BIT_10) == - TEST_BIT_10) { /* test bit 10 ; ==> body is complete */ - pQuantValBase = aQuantTable[pCodebook[codewordOffset]]; /* get base - address of - quantized - values - belonging to - current - codebook */ - pQuantVal = pQuantValBase + branchValue; /* set pointer to first valid - line [of 2 or 4 quantized - values] */ - - iQSC = iResultPointer[codewordOffset]; /* get position of first line for - writing out result */ - - for (dimCntr = pCbDimension[pCodebook[codewordOffset]]; dimCntr != 0; - dimCntr--) { - pResultBase[iQSC++] = - (FIXP_DBL)*pQuantVal++; /* write out 2 or 4 lines into - spectrum; no Sign bits - available in this state */ - } - - ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset, - pCodewordBitfield); /* clear a bit in bitfield and - switch off statemachine */ - pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of - for loop counter (see - above) is done here */ - break; /* end of branch in tree reached i.e. a whole nonPCW-Body is - decoded */ - } else { /* body is not decoded completely: */ - treeNode = *( - pCurrentTree + - branchValue); /* update treeNode for further step in decoding tree */ - } - } - iNode[codewordOffset] = treeNode; /* store updated treeNode because maybe - decoding of codeword body not finished - yet */ - - if (pRemainingBitsInSegment[segmentOffset] <= 0) { - ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset, - pSegmentBitfield); /* clear a bit in bitfield and - switch off statemachine */ - - if (pRemainingBitsInSegment[segmentOffset] < 0) { - pHcr->decInOut.errorLog |= STATE_ERROR_BODY_ONLY; - return BODY_ONLY; - } - } - - return STOP_THIS_STATE; -} - -/*--------------------------------------------------------------------------------------------- - description: Decodes the codeword body, writes out result and counts the -number of quantized spectral values, which are different form zero. For those -values sign bits are needed. - - If sign bit counter cntSign is different from zero, switch to -next state to decode sign Bits there. If sign bit counter cntSign is zero, no -sign bits are needed and codeword is decoded. ------------------------------------------------------------------------------------------------ - output: Two or four written quantizes spectral values written at -position where pResultPointr points to. The signs of those lines may be wrong. -If the signs [on just one signle sign] is wrong, the next state will correct it. ------------------------------------------------------------------------------------------------ - return: 0 --------------------------------------------------------------------------------------------- -*/ -UINT Hcr_State_BODY_SIGN__BODY(HANDLE_FDK_BITSTREAM bs, void *ptr) { - H_HCR_INFO pHcr = (H_HCR_INFO)ptr; - SCHAR *pRemainingBitsInSegment; - INT *pLeftStartOfSegment; - INT *pRightStartOfSegment; - UCHAR readDirection; - UINT *pSegmentBitfield; - UINT *pCodewordBitfield; - UINT segmentOffset; - - UCHAR *pCodebook; - UINT *iNode; - UCHAR *pCntSign; - FIXP_DBL *pResultBase; - USHORT *iResultPointer; - UINT codewordOffset; - - UINT iQSC; - UINT cntSign; - UCHAR dimCntr; - UCHAR carryBit; - SCHAR *pSta; - UINT treeNode; - UINT branchValue; - UINT branchNode; - const UCHAR *pCbDimension; - const UINT *pCurrentTree; - const SCHAR *pQuantValBase; - const SCHAR *pQuantVal; - - pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment; - pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment; - pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment; - readDirection = pHcr->segmentInfo.readDirection; - pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield; - pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield; - segmentOffset = pHcr->segmentInfo.segmentOffset; - - pCodebook = pHcr->nonPcwSideinfo.pCodebook; - iNode = pHcr->nonPcwSideinfo.iNode; - pCntSign = pHcr->nonPcwSideinfo.pCntSign; - pResultBase = pHcr->nonPcwSideinfo.pResultBase; - iResultPointer = pHcr->nonPcwSideinfo.iResultPointer; - codewordOffset = pHcr->nonPcwSideinfo.codewordOffset; - pSta = pHcr->nonPcwSideinfo.pSta; - - pCbDimension = aDimCb; - - treeNode = iNode[codewordOffset]; - pCurrentTree = aHuffTable[pCodebook[codewordOffset]]; - - for (; pRemainingBitsInSegment[segmentOffset] > 0; - pRemainingBitsInSegment[segmentOffset] -= 1) { - carryBit = HcrGetABitFromBitstream( - bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset], - &pRightStartOfSegment[segmentOffset], readDirection); - - CarryBitToBranchValue(carryBit, /* make a step in decoding tree */ - treeNode, &branchValue, &branchNode); - - /* if end of branch reached write out lines and count bits needed for sign, - * otherwise store node in codeword sideinfo */ - if ((branchNode & TEST_BIT_10) == - TEST_BIT_10) { /* test bit 10 ; if set body complete */ - /* body completely decoded; branchValue is valid, set pQuantVal to first - * (of two or four) quantized spectral coefficients */ - pQuantValBase = aQuantTable[pCodebook[codewordOffset]]; /* get base - address of - quantized - values - belonging to - current - codebook */ - pQuantVal = pQuantValBase + branchValue; /* set pointer to first valid - line [of 2 or 4 quantized - values] */ - - iQSC = iResultPointer[codewordOffset]; /* get position of first line for - writing result */ - - /* codeword decoding result is written out here: Write out 2 or 4 - * quantized spectral values with probably */ - /* wrong sign and count number of values which are different from zero for - * sign bit decoding [which happens in next state] */ - cntSign = 0; - for (dimCntr = pCbDimension[pCodebook[codewordOffset]]; dimCntr != 0; - dimCntr--) { - pResultBase[iQSC++] = - (FIXP_DBL)*pQuantVal; /* write quant. spec. coef. into spectrum */ - if (*pQuantVal++ != 0) { - cntSign += 1; - } - } - - if (cntSign == 0) { - ClearBitFromBitfield( - &(pHcr->nonPcwSideinfo.pState), segmentOffset, - pCodewordBitfield); /* clear a bit in bitfield and switch off - statemachine */ - } else { - pCntSign[codewordOffset] = cntSign; /* write sign count result into - codewordsideinfo of current - codeword */ - pSta[codewordOffset] = BODY_SIGN__SIGN; /* change state */ - pHcr->nonPcwSideinfo.pState = - aStateConstant2State[pSta[codewordOffset]]; /* get state from - separate array of - cw-sideinfo */ - } - pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of - for loop counter (see - above) is done here */ - break; /* end of branch in tree reached i.e. a whole nonPCW-Body is - decoded */ - } else { /* body is not decoded completely: */ - treeNode = *( - pCurrentTree + - branchValue); /* update treeNode for further step in decoding tree */ - } - } - iNode[codewordOffset] = treeNode; /* store updated treeNode because maybe - decoding of codeword body not finished - yet */ - - if (pRemainingBitsInSegment[segmentOffset] <= 0) { - ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset, - pSegmentBitfield); /* clear a bit in bitfield and - switch off statemachine */ - - if (pRemainingBitsInSegment[segmentOffset] < 0) { - pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN__BODY; - return BODY_SIGN__BODY; - } - } - - return STOP_THIS_STATE; -} - -/*--------------------------------------------------------------------------------------------- - description: This state decodes the sign bits belonging to a codeword. The -state is called as often in different "trials" until pCntSgn[codewordOffset] is -zero. ------------------------------------------------------------------------------------------------ - output: The two or four quantizes spectral values (written in previous -state) have now the correct sign. ------------------------------------------------------------------------------------------------ - return: 0 --------------------------------------------------------------------------------------------- -*/ -UINT Hcr_State_BODY_SIGN__SIGN(HANDLE_FDK_BITSTREAM bs, void *ptr) { - H_HCR_INFO pHcr = (H_HCR_INFO)ptr; - SCHAR *pRemainingBitsInSegment; - INT *pLeftStartOfSegment; - INT *pRightStartOfSegment; - UCHAR readDirection; - UINT *pSegmentBitfield; - UINT *pCodewordBitfield; - UINT segmentOffset; - - UCHAR *pCntSign; - FIXP_DBL *pResultBase; - USHORT *iResultPointer; - UINT codewordOffset; - - UCHAR carryBit; - UINT iQSC; - UCHAR cntSign; - - pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment; - pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment; - pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment; - readDirection = pHcr->segmentInfo.readDirection; - pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield; - pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield; - segmentOffset = pHcr->segmentInfo.segmentOffset; - - /*pCodebook = */ - pCntSign = pHcr->nonPcwSideinfo.pCntSign; - pResultBase = pHcr->nonPcwSideinfo.pResultBase; - iResultPointer = pHcr->nonPcwSideinfo.iResultPointer; - codewordOffset = pHcr->nonPcwSideinfo.codewordOffset; - - iQSC = iResultPointer[codewordOffset]; - cntSign = pCntSign[codewordOffset]; - - /* loop for sign bit decoding */ - for (; pRemainingBitsInSegment[segmentOffset] > 0; - pRemainingBitsInSegment[segmentOffset] -= 1) { - carryBit = HcrGetABitFromBitstream( - bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset], - &pRightStartOfSegment[segmentOffset], readDirection); - cntSign -= - 1; /* decrement sign counter because one sign bit has been read */ - - /* search for a line (which was decoded in previous state) which is not - * zero. [This value will get a sign] */ - while (pResultBase[iQSC] == (FIXP_DBL)0) { - if (++iQSC >= 1024) { /* points to current value different from zero */ - return BODY_SIGN__SIGN; - } - } - - /* put sign together with line; if carryBit is zero, the sign is ok already; - * no write operation necessary in this case */ - if (carryBit != 0) { - pResultBase[iQSC] = -pResultBase[iQSC]; /* carryBit = 1 --> minus */ - } - - iQSC++; /* update pointer to next (maybe valid) value */ - - if (cntSign == 0) { /* if (cntSign==0) ==> set state CODEWORD_DECODED */ - ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset, - pCodewordBitfield); /* clear a bit in bitfield and - switch off statemachine */ - pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of - for loop counter (see - above) is done here */ - break; /* whole nonPCW-Body and according sign bits are decoded */ - } - } - pCntSign[codewordOffset] = cntSign; - iResultPointer[codewordOffset] = iQSC; /* store updated pResultPointer */ - - if (pRemainingBitsInSegment[segmentOffset] <= 0) { - ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset, - pSegmentBitfield); /* clear a bit in bitfield and - switch off statemachine */ - - if (pRemainingBitsInSegment[segmentOffset] < 0) { - pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN__SIGN; - return BODY_SIGN__SIGN; - } - } - - return STOP_THIS_STATE; -} - -/*--------------------------------------------------------------------------------------------- - description: Decodes the codeword body in case of codebook is 11. Writes -out resulting two or four lines [with probably wrong sign] and counts the number -of lines, which are different form zero. This information is needed in next - state where sign bits will be decoded, if necessary. - If sign bit counter cntSign is zero, no sign bits are needed -and codeword is decoded completely. ------------------------------------------------------------------------------------------------ - output: Two lines (quantizes spectral coefficients) which are probably -wrong. The sign may be wrong and if one or two values is/are 16, the following -states will decode the escape sequence to correct the values which are wirtten -here. ------------------------------------------------------------------------------------------------ - return: 0 --------------------------------------------------------------------------------------------- -*/ -UINT Hcr_State_BODY_SIGN_ESC__BODY(HANDLE_FDK_BITSTREAM bs, void *ptr) { - H_HCR_INFO pHcr = (H_HCR_INFO)ptr; - SCHAR *pRemainingBitsInSegment; - INT *pLeftStartOfSegment; - INT *pRightStartOfSegment; - UCHAR readDirection; - UINT *pSegmentBitfield; - UINT *pCodewordBitfield; - UINT segmentOffset; - - UINT *iNode; - UCHAR *pCntSign; - FIXP_DBL *pResultBase; - USHORT *iResultPointer; - UINT codewordOffset; - - UCHAR carryBit; - UINT iQSC; - UINT cntSign; - UINT dimCntr; - UINT treeNode; - SCHAR *pSta; - UINT branchNode; - UINT branchValue; - const UINT *pCurrentTree; - const SCHAR *pQuantValBase; - const SCHAR *pQuantVal; - - pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment; - pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment; - pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment; - readDirection = pHcr->segmentInfo.readDirection; - pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield; - pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield; - segmentOffset = pHcr->segmentInfo.segmentOffset; - - iNode = pHcr->nonPcwSideinfo.iNode; - pCntSign = pHcr->nonPcwSideinfo.pCntSign; - pResultBase = pHcr->nonPcwSideinfo.pResultBase; - iResultPointer = pHcr->nonPcwSideinfo.iResultPointer; - codewordOffset = pHcr->nonPcwSideinfo.codewordOffset; - pSta = pHcr->nonPcwSideinfo.pSta; - - treeNode = iNode[codewordOffset]; - pCurrentTree = aHuffTable[ESCAPE_CODEBOOK]; - - for (; pRemainingBitsInSegment[segmentOffset] > 0; - pRemainingBitsInSegment[segmentOffset] -= 1) { - carryBit = HcrGetABitFromBitstream( - bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset], - &pRightStartOfSegment[segmentOffset], readDirection); - - /* make a step in tree */ - CarryBitToBranchValue(carryBit, treeNode, &branchValue, &branchNode); - - /* if end of branch reached write out lines and count bits needed for sign, - * otherwise store node in codeword sideinfo */ - if ((branchNode & TEST_BIT_10) == - TEST_BIT_10) { /* test bit 10 ; if set body complete */ - - /* body completely decoded; branchValue is valid */ - /* set pQuantVol to first (of two or four) quantized spectral coefficients - */ - pQuantValBase = aQuantTable[ESCAPE_CODEBOOK]; /* get base address of - quantized values - belonging to current - codebook */ - pQuantVal = pQuantValBase + branchValue; /* set pointer to first valid - line [of 2 or 4 quantized - values] */ - - /* make backup from original resultPointer in node storage for state - * BODY_SIGN_ESC__SIGN */ - iNode[codewordOffset] = iResultPointer[codewordOffset]; - - /* get position of first line for writing result */ - iQSC = iResultPointer[codewordOffset]; - - /* codeword decoding result is written out here: Write out 2 or 4 - * quantized spectral values with probably */ - /* wrong sign and count number of values which are different from zero for - * sign bit decoding [which happens in next state] */ - cntSign = 0; - - for (dimCntr = DIMENSION_OF_ESCAPE_CODEBOOK; dimCntr != 0; dimCntr--) { - pResultBase[iQSC++] = - (FIXP_DBL)*pQuantVal; /* write quant. spec. coef. into spectrum */ - if (*pQuantVal++ != 0) { - cntSign += 1; - } - } - - if (cntSign == 0) { - ClearBitFromBitfield( - &(pHcr->nonPcwSideinfo.pState), segmentOffset, - pCodewordBitfield); /* clear a bit in bitfield and switch off - statemachine */ - /* codeword decoded */ - } else { - /* write sign count result into codewordsideinfo of current codeword */ - pCntSign[codewordOffset] = cntSign; - pSta[codewordOffset] = BODY_SIGN_ESC__SIGN; /* change state */ - pHcr->nonPcwSideinfo.pState = - aStateConstant2State[pSta[codewordOffset]]; /* get state from - separate array of - cw-sideinfo */ - } - pRemainingBitsInSegment[segmentOffset] -= 1; /* the last reinitialzation - of for loop counter (see - above) is done here */ - break; /* end of branch in tree reached i.e. a whole nonPCW-Body is - decoded */ - } else { /* body is not decoded completely: */ - /* update treeNode for further step in decoding tree and store updated - * treeNode because maybe no more bits left in segment */ - treeNode = *(pCurrentTree + branchValue); - iNode[codewordOffset] = treeNode; - } - } - - if (pRemainingBitsInSegment[segmentOffset] <= 0) { - ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset, - pSegmentBitfield); /* clear a bit in bitfield and - switch off statemachine */ - - if (pRemainingBitsInSegment[segmentOffset] < 0) { - pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__BODY; - return BODY_SIGN_ESC__BODY; - } - } - - return STOP_THIS_STATE; -} - -/*--------------------------------------------------------------------------------------------- - description: This state decodes the sign bits, if a codeword of codebook 11 -needs some. A flag named 'flagB' in codeword sideinfo is set, if the second line -of quantized spectral values is 16. The 'flagB' is used in case of decoding of a -escape sequence is necessary as far as the second line is concerned. - - If only the first line needs an escape sequence, the flagB is -cleared. If only the second line needs an escape sequence, the flagB is not -used. - - For storing sideinfo in case of escape sequence decoding one -single word can be used for both escape sequences because they are decoded not -at the same time: - - - bit 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 -4 3 2 1 0 - ===== == == =========== =========== -=================================== ^ ^ ^ ^ ^ -^ | | | | | | res. flagA flagB -escapePrefixUp escapePrefixDown escapeWord - ------------------------------------------------------------------------------------------------ - output: Two lines with correct sign. If one or two values is/are 16, -the lines are not valid, otherwise they are. ------------------------------------------------------------------------------------------------ - return: 0 --------------------------------------------------------------------------------------------- -*/ -UINT Hcr_State_BODY_SIGN_ESC__SIGN(HANDLE_FDK_BITSTREAM bs, void *ptr) { - H_HCR_INFO pHcr = (H_HCR_INFO)ptr; - SCHAR *pRemainingBitsInSegment; - INT *pLeftStartOfSegment; - INT *pRightStartOfSegment; - UCHAR readDirection; - UINT *pSegmentBitfield; - UINT *pCodewordBitfield; - UINT segmentOffset; - - UINT *iNode; - UCHAR *pCntSign; - FIXP_DBL *pResultBase; - USHORT *iResultPointer; - UINT *pEscapeSequenceInfo; - UINT codewordOffset; - - UINT iQSC; - UCHAR cntSign; - UINT flagA; - UINT flagB; - UINT flags; - UCHAR carryBit; - SCHAR *pSta; - - pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment; - pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment; - pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment; - readDirection = pHcr->segmentInfo.readDirection; - pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield; - pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield; - segmentOffset = pHcr->segmentInfo.segmentOffset; - - iNode = pHcr->nonPcwSideinfo.iNode; - pCntSign = pHcr->nonPcwSideinfo.pCntSign; - pResultBase = pHcr->nonPcwSideinfo.pResultBase; - iResultPointer = pHcr->nonPcwSideinfo.iResultPointer; - pEscapeSequenceInfo = pHcr->nonPcwSideinfo.pEscapeSequenceInfo; - codewordOffset = pHcr->nonPcwSideinfo.codewordOffset; - pSta = pHcr->nonPcwSideinfo.pSta; - - iQSC = iResultPointer[codewordOffset]; - cntSign = pCntSign[codewordOffset]; - - /* loop for sign bit decoding */ - for (; pRemainingBitsInSegment[segmentOffset] > 0; - pRemainingBitsInSegment[segmentOffset] -= 1) { - carryBit = HcrGetABitFromBitstream( - bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset], - &pRightStartOfSegment[segmentOffset], readDirection); - - /* decrement sign counter because one sign bit has been read */ - cntSign -= 1; - pCntSign[codewordOffset] = cntSign; - - /* get a quantized spectral value (which was decoded in previous state) - * which is not zero. [This value will get a sign] */ - while (pResultBase[iQSC] == (FIXP_DBL)0) { - if (++iQSC >= 1024) { - return BODY_SIGN_ESC__SIGN; - } - } - iResultPointer[codewordOffset] = iQSC; - - /* put negative sign together with quantized spectral value; if carryBit is - * zero, the sign is ok already; no write operation necessary in this case - */ - if (carryBit != 0) { - pResultBase[iQSC] = -pResultBase[iQSC]; /* carryBit = 1 --> minus */ - } - iQSC++; /* update index to next (maybe valid) value */ - iResultPointer[codewordOffset] = iQSC; - - if (cntSign == 0) { - /* all sign bits are decoded now */ - pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of - for loop counter (see - above) is done here */ - - /* check decoded values if codeword is decoded: Check if one or two escape - * sequences 16 follow */ - - /* step 0 */ - /* restore pointer to first decoded quantized value [ = original - * pResultPointr] from index iNode prepared in State_BODY_SIGN_ESC__BODY - */ - iQSC = iNode[codewordOffset]; - - /* step 1 */ - /* test first value if escape sequence follows */ - flagA = 0; /* for first possible escape sequence */ - if (fixp_abs(pResultBase[iQSC++]) == (FIXP_DBL)ESCAPE_VALUE) { - flagA = 1; - } - - /* step 2 */ - /* test second value if escape sequence follows */ - flagB = 0; /* for second possible escape sequence */ - if (fixp_abs(pResultBase[iQSC]) == (FIXP_DBL)ESCAPE_VALUE) { - flagB = 1; - } - - /* step 3 */ - /* evaluate flag result and go on if necessary */ - if (!flagA && !flagB) { - ClearBitFromBitfield( - &(pHcr->nonPcwSideinfo.pState), segmentOffset, - pCodewordBitfield); /* clear a bit in bitfield and switch off - statemachine */ - } else { - /* at least one of two lines is 16 */ - /* store both flags at correct positions in non PCW codeword sideinfo - * pEscapeSequenceInfo[codewordOffset] */ - flags = flagA << POSITION_OF_FLAG_A; - flags |= (flagB << POSITION_OF_FLAG_B); - pEscapeSequenceInfo[codewordOffset] = flags; - - /* set next state */ - pSta[codewordOffset] = BODY_SIGN_ESC__ESC_PREFIX; - pHcr->nonPcwSideinfo.pState = - aStateConstant2State[pSta[codewordOffset]]; /* get state from - separate array of - cw-sideinfo */ - - /* set result pointer to the first line of the two decoded lines */ - iResultPointer[codewordOffset] = iNode[codewordOffset]; - - if (!flagA && flagB) { - /* update pResultPointr ==> state Stat_BODY_SIGN_ESC__ESC_WORD writes - * to correct position. Second value is the one and only escape value - */ - iQSC = iResultPointer[codewordOffset]; - iQSC++; - iResultPointer[codewordOffset] = iQSC; - } - - } /* at least one of two lines is 16 */ - break; /* nonPCW-Body at cb 11 and according sign bits are decoded */ - - } /* if ( cntSign == 0 ) */ - } /* loop over remaining Bits in segment */ - - if (pRemainingBitsInSegment[segmentOffset] <= 0) { - ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset, - pSegmentBitfield); /* clear a bit in bitfield and - switch off statemachine */ - - if (pRemainingBitsInSegment[segmentOffset] < 0) { - pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__SIGN; - return BODY_SIGN_ESC__SIGN; - } - } - return STOP_THIS_STATE; -} - -/*--------------------------------------------------------------------------------------------- - description: Decode escape prefix of first or second escape sequence. The -escape prefix consists of ones. The following zero is also decoded here. ------------------------------------------------------------------------------------------------ - output: If the single separator-zero which follows the -escape-prefix-ones is not yet decoded: The value 'escapePrefixUp' in word -pEscapeSequenceInfo[codewordOffset] is updated. - - If the single separator-zero which follows the -escape-prefix-ones is decoded: Two updated values 'escapePrefixUp' and -'escapePrefixDown' in word pEscapeSequenceInfo[codewordOffset]. This State is -finished. Switch to next state. ------------------------------------------------------------------------------------------------ - return: 0 --------------------------------------------------------------------------------------------- -*/ -UINT Hcr_State_BODY_SIGN_ESC__ESC_PREFIX(HANDLE_FDK_BITSTREAM bs, void *ptr) { - H_HCR_INFO pHcr = (H_HCR_INFO)ptr; - SCHAR *pRemainingBitsInSegment; - INT *pLeftStartOfSegment; - INT *pRightStartOfSegment; - UCHAR readDirection; - UINT *pSegmentBitfield; - UINT segmentOffset; - UINT *pEscapeSequenceInfo; - UINT codewordOffset; - UCHAR carryBit; - UINT escapePrefixUp; - SCHAR *pSta; - - pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment; - pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment; - pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment; - readDirection = pHcr->segmentInfo.readDirection; - pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield; - segmentOffset = pHcr->segmentInfo.segmentOffset; - pEscapeSequenceInfo = pHcr->nonPcwSideinfo.pEscapeSequenceInfo; - codewordOffset = pHcr->nonPcwSideinfo.codewordOffset; - pSta = pHcr->nonPcwSideinfo.pSta; - - escapePrefixUp = - (pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_PREFIX_UP) >> - LSB_ESCAPE_PREFIX_UP; - - /* decode escape prefix */ - for (; pRemainingBitsInSegment[segmentOffset] > 0; - pRemainingBitsInSegment[segmentOffset] -= 1) { - carryBit = HcrGetABitFromBitstream( - bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset], - &pRightStartOfSegment[segmentOffset], readDirection); - - /* count ones and store sum in escapePrefixUp */ - if (carryBit == 1) { - escapePrefixUp += 1; /* update conter for ones */ - - /* store updated counter in sideinfo of current codeword */ - pEscapeSequenceInfo[codewordOffset] &= - ~MASK_ESCAPE_PREFIX_UP; /* delete old escapePrefixUp */ - escapePrefixUp <<= LSB_ESCAPE_PREFIX_UP; /* shift to correct position */ - pEscapeSequenceInfo[codewordOffset] |= - escapePrefixUp; /* insert new escapePrefixUp */ - escapePrefixUp >>= LSB_ESCAPE_PREFIX_UP; /* shift back down */ - } else { /* separator [zero] reached */ - pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of - for loop counter (see - above) is done here */ - escapePrefixUp += - 4; /* if escape_separator '0' appears, add 4 and ==> break */ - - /* store escapePrefixUp in pEscapeSequenceInfo[codewordOffset] at bit - * position escapePrefixUp */ - pEscapeSequenceInfo[codewordOffset] &= - ~MASK_ESCAPE_PREFIX_UP; /* delete old escapePrefixUp */ - escapePrefixUp <<= LSB_ESCAPE_PREFIX_UP; /* shift to correct position */ - pEscapeSequenceInfo[codewordOffset] |= - escapePrefixUp; /* insert new escapePrefixUp */ - escapePrefixUp >>= LSB_ESCAPE_PREFIX_UP; /* shift back down */ - - /* store escapePrefixUp in pEscapeSequenceInfo[codewordOffset] at bit - * position escapePrefixDown */ - pEscapeSequenceInfo[codewordOffset] &= - ~MASK_ESCAPE_PREFIX_DOWN; /* delete old escapePrefixDown */ - escapePrefixUp <<= LSB_ESCAPE_PREFIX_DOWN; /* shift to correct position */ - pEscapeSequenceInfo[codewordOffset] |= - escapePrefixUp; /* insert new escapePrefixDown */ - - pSta[codewordOffset] = BODY_SIGN_ESC__ESC_WORD; /* set next state */ - pHcr->nonPcwSideinfo.pState = - aStateConstant2State[pSta[codewordOffset]]; /* get state from separate - array of cw-sideinfo */ - break; - } - } - - if (pRemainingBitsInSegment[segmentOffset] <= 0) { - ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset, - pSegmentBitfield); /* clear a bit in bitfield and - switch off statemachine */ - - if (pRemainingBitsInSegment[segmentOffset] < 0) { - pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__ESC_PREFIX; - return BODY_SIGN_ESC__ESC_PREFIX; - } - } - - return STOP_THIS_STATE; -} - -/*--------------------------------------------------------------------------------------------- - description: Decode escapeWord of escape sequence. If the escape sequence -is decoded completely, assemble quantized-spectral-escape-coefficient and -replace the previous decoded 16 by the new value. Test flagB. If flagB is set, -the second escape sequence must be decoded. If flagB is not set, the codeword is -decoded and the state machine is switched off. ------------------------------------------------------------------------------------------------ - output: Two lines with valid sign. At least one of both lines has got -the correct value. ------------------------------------------------------------------------------------------------ - return: 0 --------------------------------------------------------------------------------------------- -*/ -UINT Hcr_State_BODY_SIGN_ESC__ESC_WORD(HANDLE_FDK_BITSTREAM bs, void *ptr) { - H_HCR_INFO pHcr = (H_HCR_INFO)ptr; - SCHAR *pRemainingBitsInSegment; - INT *pLeftStartOfSegment; - INT *pRightStartOfSegment; - UCHAR readDirection; - UINT *pSegmentBitfield; - UINT *pCodewordBitfield; - UINT segmentOffset; - - FIXP_DBL *pResultBase; - USHORT *iResultPointer; - UINT *pEscapeSequenceInfo; - UINT codewordOffset; - - UINT escapeWord; - UINT escapePrefixDown; - UINT escapePrefixUp; - UCHAR carryBit; - UINT iQSC; - INT sign; - UINT flagA; - UINT flagB; - SCHAR *pSta; - - pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment; - pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment; - pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment; - readDirection = pHcr->segmentInfo.readDirection; - pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield; - pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield; - segmentOffset = pHcr->segmentInfo.segmentOffset; - - pResultBase = pHcr->nonPcwSideinfo.pResultBase; - iResultPointer = pHcr->nonPcwSideinfo.iResultPointer; - pEscapeSequenceInfo = pHcr->nonPcwSideinfo.pEscapeSequenceInfo; - codewordOffset = pHcr->nonPcwSideinfo.codewordOffset; - pSta = pHcr->nonPcwSideinfo.pSta; - - escapeWord = pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_WORD; - escapePrefixDown = - (pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_PREFIX_DOWN) >> - LSB_ESCAPE_PREFIX_DOWN; - - /* decode escape word */ - for (; pRemainingBitsInSegment[segmentOffset] > 0; - pRemainingBitsInSegment[segmentOffset] -= 1) { - carryBit = HcrGetABitFromBitstream( - bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset], - &pRightStartOfSegment[segmentOffset], readDirection); - - /* build escape word */ - escapeWord <<= - 1; /* left shift previous decoded part of escapeWord by on bit */ - escapeWord = escapeWord | carryBit; /* assemble escape word by bitwise or */ - - /* decrement counter for length of escape word because one more bit was - * decoded */ - escapePrefixDown -= 1; - - /* store updated escapePrefixDown */ - pEscapeSequenceInfo[codewordOffset] &= - ~MASK_ESCAPE_PREFIX_DOWN; /* delete old escapePrefixDown */ - escapePrefixDown <<= LSB_ESCAPE_PREFIX_DOWN; /* shift to correct position */ - pEscapeSequenceInfo[codewordOffset] |= - escapePrefixDown; /* insert new escapePrefixDown */ - escapePrefixDown >>= LSB_ESCAPE_PREFIX_DOWN; /* shift back */ - - /* store updated escapeWord */ - pEscapeSequenceInfo[codewordOffset] &= - ~MASK_ESCAPE_WORD; /* delete old escapeWord */ - pEscapeSequenceInfo[codewordOffset] |= - escapeWord; /* insert new escapeWord */ - - if (escapePrefixDown == 0) { - pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of - for loop counter (see - above) is done here */ - - /* escape sequence decoded. Assemble escape-line and replace original line - */ - - /* step 0 */ - /* derive sign */ - iQSC = iResultPointer[codewordOffset]; - sign = (pResultBase[iQSC] >= (FIXP_DBL)0) - ? 1 - : -1; /* get sign of escape value 16 */ - - /* step 1 */ - /* get escapePrefixUp */ - escapePrefixUp = - (pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_PREFIX_UP) >> - LSB_ESCAPE_PREFIX_UP; - - /* step 2 */ - /* calculate escape value */ - pResultBase[iQSC] = - (FIXP_DBL)(sign * (((INT)1 << escapePrefixUp) + (INT)escapeWord)); - - /* get both flags from sideinfo (flags are not shifted to the - * lsb-position) */ - flagA = pEscapeSequenceInfo[codewordOffset] & MASK_FLAG_A; - flagB = pEscapeSequenceInfo[codewordOffset] & MASK_FLAG_B; - - /* step 3 */ - /* clear the whole escape sideinfo word */ - pEscapeSequenceInfo[codewordOffset] = 0; - - /* change state in dependence of flag flagB */ - if (flagA != 0) { - /* first escape sequence decoded; previous decoded 16 has been replaced - * by valid line */ - - /* clear flagA in sideinfo word because this escape sequence has already - * beed decoded */ - pEscapeSequenceInfo[codewordOffset] &= ~MASK_FLAG_A; - - if (flagB == 0) { - ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset, - pCodewordBitfield); /* clear a bit in bitfield - and switch off - statemachine */ - } else { - /* updated pointer to next and last 16 */ - iQSC++; - iResultPointer[codewordOffset] = iQSC; - - /* change state */ - pSta[codewordOffset] = BODY_SIGN_ESC__ESC_PREFIX; - pHcr->nonPcwSideinfo.pState = - aStateConstant2State[pSta[codewordOffset]]; /* get state from - separate array of - cw-sideinfo */ - } - } else { - ClearBitFromBitfield( - &(pHcr->nonPcwSideinfo.pState), segmentOffset, - pCodewordBitfield); /* clear a bit in bitfield and switch off - statemachine */ - } - break; - } - } - - if (pRemainingBitsInSegment[segmentOffset] <= 0) { - ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset, - pSegmentBitfield); /* clear a bit in bitfield and - switch off statemachine */ - - if (pRemainingBitsInSegment[segmentOffset] < 0) { - pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__ESC_WORD; - return BODY_SIGN_ESC__ESC_WORD; - } - } - - return STOP_THIS_STATE; -} --- a/libAACdec/src/aacdec_hcrs.h +++ /dev/null @@ -1,176 +0,0 @@ -/* ----------------------------------------------------------------------------- -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): Robert Weidner (DSP Solutions) - - Description: HCR Decoder: Defines of state-constants, masks and - state-prototypes - -*******************************************************************************/ - -#ifndef AACDEC_HCRS_H -#define AACDEC_HCRS_H - -#include "FDK_bitstream.h" -#include "aacdec_hcr_types.h" -/* The four different kinds of types of states are: */ -/* different states are defined as constants */ /* start middle=self next - stop */ -#define STOP_THIS_STATE \ - 0 /* */ -#define BODY_ONLY \ - 1 /* X X X */ -#define BODY_SIGN__BODY \ - 2 /* X X X X [stop if no sign] */ -#define BODY_SIGN__SIGN \ - 3 /* X X [stop if sign bits decoded] */ -#define BODY_SIGN_ESC__BODY \ - 4 /* X X X X [stop if no sign] */ -#define BODY_SIGN_ESC__SIGN \ - 5 /* X X X [stop if no escape sequence] */ -#define BODY_SIGN_ESC__ESC_PREFIX \ - 6 /* X X */ -#define BODY_SIGN_ESC__ESC_WORD \ - 7 /* X X X [stop if abs(second qsc) != 16] */ - -/* examples: */ - -/* BODY_ONLY means only the codeword body will be decoded; no - * sign bits will follow and no escapesequence will follow */ - -/* BODY_SIGN__BODY means that the codeword consists of two parts; - * body and sign part. The part '__BODY' after the two underscores shows */ -/* that the bits which are currently decoded belong - * to the '__BODY' of the codeword and not to the sign part. */ - -/* BODY_SIGN_ESC__ESC_PB means that the codeword consists of three parts; - * body, sign and (here: two) escape sequences; */ -/* P = Prefix = ones */ -/* W = Escape Word */ -/* A = first possible (of two) Escape sequeces */ -/* B = second possible (of two) Escape sequeces */ -/* The part after the two underscores shows that - * the current bits which are decoded belong to the '__ESC_PB' - part of the */ -/* codeword. That means the body and the sign bits - * are decoded completely and the bits which are decoded now belong to */ -/* the escape sequence [P = prefix; B=second - * possible escape sequence] */ - -#define MSB_31_MASK 0x80000000 /* masks MSB (= Bit 31) in a 32 bit word */ -#define DIMENSION_OF_ESCAPE_CODEBOOK 2 /* for cb >= 11 is dimension 2 */ -#define ESCAPE_CODEBOOK 11 - -#define MASK_ESCAPE_PREFIX_UP 0x000F0000 -#define LSB_ESCAPE_PREFIX_UP 16 - -#define MASK_ESCAPE_PREFIX_DOWN 0x0000F000 -#define LSB_ESCAPE_PREFIX_DOWN 12 - -#define MASK_ESCAPE_WORD 0x00000FFF -#define MASK_FLAG_A 0x00200000 -#define MASK_FLAG_B 0x00100000 - -extern void DecodeNonPCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO hHcr); - -UINT Hcr_State_BODY_ONLY(HANDLE_FDK_BITSTREAM, void*); -UINT Hcr_State_BODY_SIGN__BODY(HANDLE_FDK_BITSTREAM, void*); -UINT Hcr_State_BODY_SIGN__SIGN(HANDLE_FDK_BITSTREAM, void*); -UINT Hcr_State_BODY_SIGN_ESC__BODY(HANDLE_FDK_BITSTREAM, void*); -UINT Hcr_State_BODY_SIGN_ESC__SIGN(HANDLE_FDK_BITSTREAM, void*); -UINT Hcr_State_BODY_SIGN_ESC__ESC_PREFIX(HANDLE_FDK_BITSTREAM, void*); -UINT Hcr_State_BODY_SIGN_ESC__ESC_WORD(HANDLE_FDK_BITSTREAM, void*); - -#endif /* AACDEC_HCRS_H */ --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -163,17 +163,12 @@ amm-info@iis.fraunhofer.de #include "sac_dec_lib.h" -#include "aacdec_hcr.h" -#include "rvlc.h" - #include "usacdec_lpd.h" #include "ac_arith_coder.h" #include "tpdec_lib.h" -#include "conceal.h" - #include "FDK_crc.h" #define PS_IS_EXPLICITLY_DISABLED(aot, flags) \ (((aot) == AOT_DRM_AAC) && !(flags & AC_PS_PRESENT)) @@ -1191,10 +1186,6 @@ LINKSPEC_CPP HANDLE_AACDECODER CAacDecod /* initialize progam config */ CProgramConfig_Init(&self->pce); - /* initialize error concealment common data */ - CConcealment_InitCommonData(&self->concealCommonData); - self->concealMethodUser = ConcealMethodNone; /* undefined -> auto mode */ - self->hDrcInfo = GetDrcInfo(); if (self->hDrcInfo == NULL) { goto bail; @@ -1202,8 +1193,7 @@ LINKSPEC_CPP HANDLE_AACDECODER CAacDecod /* Init common DRC structure */ aacDecoder_drcInit(self->hDrcInfo); /* Set default frame delay */ - aacDecoder_drcSetParam(self->hDrcInfo, DRC_BS_DELAY, - CConcealment_GetDelay(&self->concealCommonData)); + aacDecoder_drcSetParam(self->hDrcInfo, DRC_BS_DELAY, 0); self->workBufferCore2 = GetWorkBufferCore2(); if (self->workBufferCore2 == NULL) goto bail; @@ -2085,15 +2075,6 @@ CAacDecoder_Init(HANDLE_AACDECODER self, if (self->pAacDecoderStaticChannelInfo[ch]->pCpeStaticData != NULL) { self->pAacDecoderStaticChannelInfo[ch] - ->pCpeStaticData->jointStereoPersistentData - .spectralCoeffs[ch2] = - self->pAacDecoderStaticChannelInfo[ch] - ->concealmentInfo.spectralCoefficient; - self->pAacDecoderStaticChannelInfo[ch] - ->pCpeStaticData->jointStereoPersistentData.specScale[ch2] = - self->pAacDecoderStaticChannelInfo[ch] - ->concealmentInfo.specScale; - self->pAacDecoderStaticChannelInfo[ch] ->pCpeStaticData->jointStereoPersistentData.scratchBuffer = (FIXP_DBL *)self->pTimeData2; } @@ -2193,12 +2174,6 @@ CAacDecoder_Init(HANDLE_AACDECODER self, /* Delete mixdown metadata from the past */ pcmDmx_Reset(self->hPcmUtils, PCMDMX_RESET_BS_DATA); - /* Reset concealment only if ASC changed. Otherwise it will be done with - any config callback. E.g. every time the LATM SMC is present. */ - CConcealment_InitChannelData( - &self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo, - &self->concealCommonData, initRenderMode, - self->streamInfo.aacSamplesPerFrame); ch++; chIdx++; } @@ -2336,12 +2311,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecod int ch; /* Clear history */ for (ch = 0; ch < self->aacChannels; ch++) { - /* Reset concealment */ - CConcealment_InitChannelData( - &self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo, - &self->concealCommonData, - self->pAacDecoderChannelInfo[0]->renderMode, - self->streamInfo.aacSamplesPerFrame); /* Clear overlap-add buffers to avoid clicks. */ FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer, OverlapBufferSize * sizeof(FIXP_DBL)); @@ -2403,15 +2372,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecod if (ch >= self->aacChannels) { return AAC_DEC_UNKNOWN; } - - /* if last frame was broken and this frame is no independent frame, - * correct decoding is impossible we need to trigger concealment */ - if ((CConcealment_GetLastFrameOk( - &self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo, - 1) == 0) && - !(self->flags[streamIndex] & AC_INDEP)) { - self->frameOK = 0; - } ch++; } } @@ -3081,13 +3041,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecod * following concealment method, mark the frame as erroneous */ { CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; - CConcealmentInfo *hConcealmentInfo = - &pAacDecoderStaticChannelInfo->concealmentInfo; const int mute_release_active = - (self->frameOK && !(flags & AACDEC_CONCEAL)) && - ((hConcealmentInfo->concealState >= ConcealState_Mute) && - (hConcealmentInfo->cntValidFrames + 1 <= - hConcealmentInfo->pConcealParams->numMuteReleaseFrames)); + (self->frameOK && !(flags & AACDEC_CONCEAL)); const int icsIsInvalid = (GetScaleFactorBandsTransmitted(pIcsInfo) > GetScaleFactorBandsTotal(pIcsInfo)); const int icsInfoUsedinFadeOut = @@ -3098,29 +3053,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecod } } - /* - Conceal defective spectral data - */ - { - CAacDecoderChannelInfo **ppAacDecoderChannelInfo = - &pAacDecoderChannelInfo; - CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo = - &pAacDecoderStaticChannelInfo; - { - concealApplyReturnCode = CConcealment_Apply( - &(*ppAacDecoderStaticChannelInfo)->concealmentInfo, - *ppAacDecoderChannelInfo, *ppAacDecoderStaticChannelInfo, - &self->samplingRateInfo[streamIndex], - self->streamInfo.aacSamplesPerFrame, - pAacDecoderStaticChannelInfo->last_lpd_mode, - (self->frameOK && !(flags & AACDEC_CONCEAL)), - self->flags[streamIndex]); - } - } - if (concealApplyReturnCode == -1) { - frameOk_butConceal = 1; - } - if (flags & (AACDEC_INTR)) { /* Reset DRC control data for this channel */ aacDecoder_drcInitChannelData(&pAacDecoderStaticChannelInfo->drcData); @@ -3191,20 +3123,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecod ErrorStatus = AAC_DEC_UNKNOWN; break; } - /* TimeDomainFading */ - if (!CConceal_TDFading_Applied[c]) { - CConceal_TDFading_Applied[c] = CConcealment_TDFading( - self->streamInfo.aacSamplesPerFrame, - &self->pAacDecoderStaticChannelInfo[c], pTimeData + offset, 0); - if (c + 1 < (8) && c < aacChannels - 1) { - /* update next TDNoise Seed to avoid muting in case of Parametric - * Stereo */ - self->pAacDecoderStaticChannelInfo[c + 1] - ->concealmentInfo.TDNoiseSeed = - self->pAacDecoderStaticChannelInfo[c] - ->concealmentInfo.TDNoiseSeed; - } - } } } @@ -3249,11 +3167,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecod } } - /* Add additional concealment delay */ - self->streamInfo.outputDelay += - CConcealment_GetDelay(&self->concealCommonData) * - self->streamInfo.aacSamplesPerFrame; - /* Map DRC data to StreamInfo structure */ aacDecoder_drcGetInfo(self->hDrcInfo, &self->streamInfo.drcPresMode, &self->streamInfo.drcProgRefLev); --- a/libAACdec/src/aacdecoder.h +++ b/libAACdec/src/aacdecoder.h @@ -236,9 +236,6 @@ struct AAC_DECODER_INSTANCE { 1)]; /*!< Pointer to persistent data shared by both channels of a CPE. This structure is allocated once for each CPE. */ - CConcealParams concealCommonData; - CConcealmentMethod concealMethodUser; - CUsacCoreExtensions usacCoreExt; /*!< Data and handles to extend USAC FD/LPD core decoder (SBR, MPS, ...) */ UINT numUsacElements[(1 * 1)]; --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -107,8 +107,6 @@ amm-info@iis.fraunhofer.de #include "tpdec_lib.h" #include "FDK_core.h" /* FDK_tools version info */ -#include "conceal.h" - #include "aacdec_drc.h" #include "sac_dec_lib.h" @@ -280,26 +278,6 @@ static INT aacDecoder_ConfigCallback(voi { err = aacDecoder_Config(self, pAscStruct, configMode, configChanged); } } if (err == AAC_DEC_OK) { - /* - revert concealment method if either - - Interpolation concealment might not be meaningful - - Interpolation concealment is not implemented - */ - if ((self->flags[0] & (AC_LD | AC_ELD) && - (self->concealMethodUser == ConcealMethodNone) && - CConcealment_GetDelay(&self->concealCommonData) > - 0) /* might not be meaningful but allow if user has set it - expicitly */ - || (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA) && - CConcealment_GetDelay(&self->concealCommonData) > - 0) /* not implemented */ - ) { - /* Revert to error concealment method Noise Substitution. - Because interpolation is not implemented for USAC or - the additional delay is unwanted for low delay codecs. */ - setConcealMethod(self, 1); - } - aacDecoder_setMetadataExpiry(self, self->metadataExpiry); errTp = TRANSPORTDEC_OK; } else { if (err == AAC_DEC_NEED_TO_RESTART) { @@ -529,17 +507,12 @@ static AAC_DECODER_ERROR setConcealMetho const HANDLE_AACDECODER self, /*!< Handle of the decoder instance */ const INT method) { AAC_DECODER_ERROR errorStatus = AAC_DEC_OK; - CConcealParams *pConcealData = NULL; int method_revert = 0; HANDLE_AAC_DRC hDrcInfo = NULL; HANDLE_PCM_DOWNMIX hPcmDmx = NULL; - CConcealmentMethod backupMethod = ConcealMethodNone; - int backupDelay = 0; - int bsDelay = 0; /* check decoder handle */ if (self != NULL) { - pConcealData = &self->concealCommonData; hDrcInfo = self->hDrcInfo; hPcmDmx = self->hPcmUtils; if (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA) && method >= 2) { @@ -555,33 +528,13 @@ static AAC_DECODER_ERROR setConcealMetho } } - /* Get current method/delay */ - backupMethod = CConcealment_GetMethod(pConcealData); - backupDelay = CConcealment_GetDelay(pConcealData); - - /* Be sure to set AAC and SBR concealment method simultaneously! */ - errorStatus = CConcealment_SetParams( - pConcealData, - (method_revert == 0) ? (int)method : (int)1, // concealMethod - AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, // concealFadeOutSlope - AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, // concealFadeInSlope - AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, // concealMuteRelease - AACDEC_CONCEAL_PARAM_NOT_SPECIFIED // concealComfNoiseLevel - ); - if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) { - goto bail; - } - - /* Get new delay */ - bsDelay = CConcealment_GetDelay(pConcealData); - - errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, bsDelay); + errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, 0); if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) { goto bail; } if (errorStatus == AAC_DEC_OK) { - PCMDMX_ERROR err = pcmDmx_SetParam(hPcmDmx, DMX_BS_DATA_DELAY, bsDelay); + PCMDMX_ERROR err = pcmDmx_SetParam(hPcmDmx, DMX_BS_DATA_DELAY, 0); switch (err) { case PCMDMX_INVALID_HANDLE: errorStatus = AAC_DEC_INVALID_HANDLE; @@ -596,15 +549,10 @@ static AAC_DECODER_ERROR setConcealMetho bail: if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) { - /* Revert to the initial state */ - CConcealment_SetParams( - pConcealData, (int)backupMethod, AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, - AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, - AACDEC_CONCEAL_PARAM_NOT_SPECIFIED); /* Revert DRC bitstream delay */ - aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, backupDelay); + aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, 0); /* Revert PCM mixdown bitstream delay */ - pcmDmx_SetParam(hPcmDmx, DMX_BS_DATA_DELAY, backupDelay); + pcmDmx_SetParam(hPcmDmx, DMX_BS_DATA_DELAY, 0); } return errorStatus; @@ -834,9 +782,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecode packed into a helper function which keeps all modules and libs in a consistent state even in the case an error occures. */ errorStatus = setConcealMethod(self, value); - if (errorStatus == AAC_DEC_OK) { - self->concealMethodUser = (CConcealmentMethod)value; - } break; default: @@ -966,8 +911,7 @@ LINKSPEC_CPP HANDLE_AACDECODER aacDecode aacDec->limiterEnableCurr = 0; /* Assure that all modules have same delay */ - if (setConcealMethod(aacDec, - CConcealment_GetMethod(&aacDec->concealCommonData))) { + if (setConcealMethod(aacDec, 0)) { err = -1; goto bail; } @@ -1359,9 +1303,7 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER break; } - if ((ErrorStatus != AAC_DEC_OK) || (flags & AACDEC_CONCEAL) || - self->pAacDecoderStaticChannelInfo[0]->concealmentInfo.concealState > - ConcealState_FadeIn) { + if ((ErrorStatus != AAC_DEC_OK) || (flags & AACDEC_CONCEAL)) { self->frameOK = 0; /* if an error has occured do concealment in the SBR decoder too */ } @@ -1457,9 +1399,6 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER domain signal before the QMF synthesis. Therefore the DRC gains need to be delayed by the QMF synthesis delay. */ if (self->mpsEnableCurr) drcDelay = 257; - /* Take into account concealment delay */ - drcDelay += CConcealment_GetDelay(&self->concealCommonData) * - self->streamInfo.frameSize; for (ch = 0; ch < self->streamInfo.numChannels; ch++) { UCHAR mapValue = FDK_chMapDescr_getMapValue( --- a/libAACdec/src/block.cpp +++ b/libAACdec/src/block.cpp @@ -114,9 +114,6 @@ amm-info@iis.fraunhofer.de #include "ac_arith_coder.h" -#include "aacdec_hcr.h" -#include "rvlc.h" - #if defined(__arm__) #include "arm/block_arm.cpp" #endif @@ -331,12 +328,7 @@ AAC_DECODER_ERROR CBlock_ReadSectionData 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; @@ -376,22 +368,8 @@ AAC_DECODER_ERROR CBlock_ReadSectionData 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++; + /* HCR disabled */ + return AAC_DEC_PARSE_ERROR; } /* Check spectral line limits */ @@ -718,41 +696,12 @@ AAC_DECODER_ERROR CBlock_ReadSpectralDat /* 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 disabled */ + return AAC_DEC_DECODE_FRAME_ERROR; } - /* HCR - Huffman Codeword Reordering short finished */ if (IsLongBlock(&pAacDecoderChannelInfo->icsInfo) && !(flags & (AC_ELD | AC_SCALABLE))) { --- a/libAACdec/src/channel.cpp +++ b/libAACdec/src/channel.cpp @@ -106,12 +106,6 @@ amm-info@iis.fraunhofer.de #include "aacdec_tns.h" #include "FDK_bitstream.h" -#include "conceal.h" - -#include "rvlc.h" - -#include "aacdec_hcr.h" - #include "usacdec_lpd.h" #include "usacdec_fac.h" @@ -376,9 +370,6 @@ void CChannelElement_Decode( ->pCpeStaticData->jointStereoPersistentData.clearSpectralCoeffs = 0; } } - - CRvlc_ElementCheck(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo, - flags, el_channels); } void CChannel_CodebookTableInit( @@ -596,8 +587,8 @@ AAC_DECODER_ERROR CChannelElement_Read( case scale_factor_data: if (flags & AC_ER_RVLC) { - /* read RVLC data from bitstream (error sens. cat. 1) */ - CRvlc_Read(pAacDecoderChannelInfo[ch], hBs); + /* RVLC not supported */ + error = AAC_DEC_DECODE_FRAME_ERROR; } else { error = CBlock_ReadScaleFactorData(pAacDecoderChannelInfo[ch], hBs, flags); @@ -730,15 +721,13 @@ AAC_DECODER_ERROR CChannelElement_Read( } break; case esc2_rvlc: if (flags & AC_ER_RVLC) { - CRvlc_Decode(pAacDecoderChannelInfo[ch], - pAacDecoderStaticChannelInfo[ch], hBs); + error = AAC_DEC_UNSUPPORTED_FORMAT; } break; case esc1_hcr: if (flags & AC_ER_HCR) { - CHcr_Read(hBs, pAacDecoderChannelInfo[ch], - numberOfChannels == 2 ? ID_CPE : ID_SCE); + error = AAC_DEC_UNSUPPORTED_FORMAT; } break; --- a/libAACdec/src/channelinfo.h +++ b/libAACdec/src/channelinfo.h @@ -117,17 +117,12 @@ amm-info@iis.fraunhofer.de #include "aacdec_pns.h" -#include "aacdec_hcr_types.h" -#include "rvlc_info.h" - #include "usacdec_acelp.h" #include "usacdec_const.h" #include "usacdec_rom.h" #include "ac_arith_coder.h" -#include "conceal_types.h" - #include "aacdec_drc_types.h" #define WB_SECTION_SIZE (1024 * 2) @@ -257,7 +252,6 @@ typedef struct { ULONG nfRandomSeed; /* seed value for USAC noise filling random generator */ CDrcChannelData drcData; - CConcealmentInfo concealmentInfo; CpePersistentData *pCpeStaticData; @@ -280,11 +274,6 @@ typedef struct { shouldBeUnion { struct { CPulseData PulseData; - SHORT aNumLineInSec4Hcr[MAX_SFB_HCR]; /* needed once for all channels - except for Drm syntax */ - UCHAR - aCodeBooks4Hcr[MAX_SFB_HCR]; /* needed once for all channels except for - Drm syntax. Same as "aCodeBook" ? */ SHORT lenOfReorderedSpectralData; SCHAR lenOfLongestCodeword; SCHAR numberSection; @@ -325,17 +314,6 @@ typedef struct { CJointStereoData jointStereoData; /* One for one element */ - shouldBeUnion { - struct { - CErHcrInfo erHcrInfo; - CErRvlcInfo erRvlcInfo; - SHORT aRvlcScfEsc[RVLC_MAX_SFB]; /* needed once for all channels */ - SHORT aRvlcScfFwd[RVLC_MAX_SFB]; /* needed once for all channels */ - SHORT aRvlcScfBwd[RVLC_MAX_SFB]; /* needed once for all channels */ - } aac; - } - overlay; - } CAacDecoderCommonData; typedef struct { --- a/libAACdec/src/conceal.cpp +++ /dev/null @@ -1,2095 +0,0 @@ -/* ----------------------------------------------------------------------------- -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: independent channel concealment - -*******************************************************************************/ - -/*! - \page concealment AAC core concealment - - This AAC core implementation includes a concealment function, which can be - enabled using the several defines during compilation. - - There are various tests inside the core, starting with simple CRC tests and - ending in a variety of plausibility checks. If such a check indicates an - invalid bitstream, then concealment is applied. - - Concealment is also applied when the calling main program indicates a - distorted or missing data frame using the frameOK flag. This is used for error - detection on the transport layer. (See below) - - There are three concealment-modes: - - 1) Muting: The spectral data is simply set to zero in case of an detected - error. - - 2) Noise substitution: In case of an detected error, concealment copies the - last frame and adds attenuates the spectral data. For this mode you have to - set the #CONCEAL_NOISE define. Noise substitution adds no additional delay. - - 3) Interpolation: The interpolation routine swaps the spectral data from the - previous and the current frame just before the final frequency to time - conversion. In case a single frame is corrupted, concealmant interpolates - between the last good and the first good frame to create the spectral data for - the missing frame. If multiple frames are corrupted, concealment implements - first a fade out based on slightly modified spectral values from the last good - frame. As soon as good frames are available, concealmant fades in the new - spectral data. For this mode you have to set the #CONCEAL_INTER define. Note - that in this case, you also need to set #SBR_BS_DELAY_ENABLE, which basically - adds approriate delay in the SBR decoder. Note that the - Interpolating-Concealment increases the delay of your decoder by one frame and - that it does require additional resources such as memory and computational - complexity. - -

How concealment can be used with errors on the transport layer

- - Many errors can or have to be detected on the transport layer. For example in - IP based systems packet loss can occur. The transport protocol used should - indicate such packet loss by inserting an empty frame with frameOK=0. -*/ - -#include "conceal.h" - -#include "aac_rom.h" -#include "genericStds.h" - -/* PNS (of block) */ -#include "aacdec_pns.h" -#include "block.h" - -#define CONCEAL_DFLT_COMF_NOISE_LEVEL (0x100000) - -#define CONCEAL_NOT_DEFINED ((UCHAR)-1) - -/* default settings */ -#define CONCEAL_DFLT_FADEOUT_FRAMES (6) -#define CONCEAL_DFLT_FADEIN_FRAMES (5) -#define CONCEAL_DFLT_MUTE_RELEASE_FRAMES (0) - -#define CONCEAL_DFLT_FADE_FACTOR (0.707106781186548f) /* 1/sqrt(2) */ - -/* some often used constants: */ -#define FIXP_ZERO FL2FXCONST_DBL(0.0f) -#define FIXP_ONE FL2FXCONST_DBL(1.0f) -#define FIXP_FL_CORRECTION FL2FXCONST_DBL(0.53333333333333333f) - -/* For parameter conversion */ -#define CONCEAL_PARAMETER_BITS (8) -#define CONCEAL_MAX_QUANT_FACTOR ((1 << CONCEAL_PARAMETER_BITS) - 1) -/*#define CONCEAL_MIN_ATTENUATION_FACTOR_025 ( FL2FXCONST_DBL(0.971627951577106174) )*/ /* -0.25 dB */ -#define CONCEAL_MIN_ATTENUATION_FACTOR_025_LD \ - FL2FXCONST_DBL(-0.041524101186092029596853445212299) -/*#define CONCEAL_MIN_ATTENUATION_FACTOR_050 ( FL2FXCONST_DBL(0.944060876285923380) )*/ /* -0.50 dB */ -#define CONCEAL_MIN_ATTENUATION_FACTOR_050_LD \ - FL2FXCONST_DBL(-0.083048202372184059253597008145293) - -typedef enum { - CConcealment_NoExpand, - CConcealment_Expand, - CConcealment_Compress -} CConcealmentExpandType; - -static const FIXP_SGL facMod4Table[4] = { - FL2FXCONST_SGL(0.500000000f), /* FIXP_SGL(0x4000), 2^-(1-0,00) */ - FL2FXCONST_SGL(0.594603558f), /* FIXP_SGL(0x4c1b), 2^-(1-0,25) */ - FL2FXCONST_SGL(0.707106781f), /* FIXP_SGL(0x5a82), 2^-(1-0,50) */ - FL2FXCONST_SGL(0.840896415f) /* FIXP_SGL(0x6ba2) 2^-(1-0,75) */ -}; - -static void CConcealment_CalcBandEnergy( - FIXP_DBL *spectrum, const SamplingRateInfo *pSamplingRateInfo, - const int blockType, CConcealmentExpandType ex, int *sfbEnergy); - -static void CConcealment_InterpolateBuffer(FIXP_DBL *spectrum, - SHORT *pSpecScalePrev, - SHORT *pSpecScaleAct, - SHORT *pSpecScaleOut, int *enPrv, - int *enAct, int sfbCnt, - const SHORT *pSfbOffset); - -static int CConcealment_ApplyInter( - CConcealmentInfo *pConcealmentInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame, - const int improveTonal, const int frameOk, const int mute_release_active); - -static int CConcealment_ApplyNoise( - CConcealmentInfo *pConcealmentInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame, - const UINT flags); - -static void CConcealment_UpdateState( - CConcealmentInfo *pConcealmentInfo, int frameOk, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo); - -static void CConcealment_ApplyRandomSign(int iRandomPhase, FIXP_DBL *spec, - int samplesPerFrame); - -/* TimeDomainFading */ -static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart, - FIXP_DBL fadeStop, FIXP_PCM *pcmdata); -static void CConcealment_TDFadeFillFadingStations(FIXP_DBL *fadingStations, - int *fadingSteps, - FIXP_DBL fadeStop, - FIXP_DBL fadeStart, - TDfadingType fadingType); -static void CConcealment_TDFading_doLinearFadingSteps(int *fadingSteps); - -/* Streamline the state machine */ -static int CConcealment_ApplyFadeOut( - int mode, CConcealmentInfo *pConcealmentInfo, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo); - -static int CConcealment_TDNoise_Random(ULONG *seed); -static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo, - const int len, FIXP_PCM *const pcmdata); - -static BLOCK_TYPE CConcealment_GetWinSeq(int prevWinSeq) { - BLOCK_TYPE newWinSeq = BLOCK_LONG; - - /* Try to have only long blocks */ - if (prevWinSeq == BLOCK_START || prevWinSeq == BLOCK_SHORT) { - newWinSeq = BLOCK_STOP; - } - - return (newWinSeq); -} - -/*! - \brief Init common concealment information data - - \param pConcealCommonData Pointer to the concealment common data structure. -*/ -void CConcealment_InitCommonData(CConcealParams *pConcealCommonData) { - if (pConcealCommonData != NULL) { - int i; - - /* Set default error concealment technique */ - pConcealCommonData->method = ConcealMethodInter; - - pConcealCommonData->numFadeOutFrames = CONCEAL_DFLT_FADEOUT_FRAMES; - pConcealCommonData->numFadeInFrames = CONCEAL_DFLT_FADEIN_FRAMES; - pConcealCommonData->numMuteReleaseFrames = CONCEAL_DFLT_MUTE_RELEASE_FRAMES; - - pConcealCommonData->comfortNoiseLevel = - (FIXP_DBL)CONCEAL_DFLT_COMF_NOISE_LEVEL; - - /* Init fade factors (symetric) */ - pConcealCommonData->fadeOutFactor[0] = - FL2FXCONST_SGL(CONCEAL_DFLT_FADE_FACTOR); - pConcealCommonData->fadeInFactor[0] = pConcealCommonData->fadeOutFactor[0]; - - for (i = 1; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) { - pConcealCommonData->fadeOutFactor[i] = - FX_DBL2FX_SGL(fMult(pConcealCommonData->fadeOutFactor[i - 1], - FL2FXCONST_SGL(CONCEAL_DFLT_FADE_FACTOR))); - pConcealCommonData->fadeInFactor[i] = - pConcealCommonData->fadeOutFactor[i]; - } - } -} - -/*! - \brief Get current concealment method. - - \param pConcealCommonData Pointer to common concealment data (for all - channels) -*/ -CConcealmentMethod CConcealment_GetMethod(CConcealParams *pConcealCommonData) { - CConcealmentMethod method = ConcealMethodNone; - - if (pConcealCommonData != NULL) { - method = pConcealCommonData->method; - } - - return (method); -} - -/*! - \brief Init concealment information for each channel - - \param pConcealChannelInfo Pointer to the channel related concealment info - structure to be initialized. \param pConcealCommonData Pointer to common - concealment data (for all channels) \param initRenderMode Initial render - mode to be set for the current channel. \param samplesPerFrame The number - of samples per frame. -*/ -void CConcealment_InitChannelData(CConcealmentInfo *pConcealChannelInfo, - CConcealParams *pConcealCommonData, - AACDEC_RENDER_MODE initRenderMode, - int samplesPerFrame) { - int i; - pConcealChannelInfo->TDNoiseSeed = 0; - FDKmemclear(pConcealChannelInfo->TDNoiseStates, - sizeof(pConcealChannelInfo->TDNoiseStates)); - pConcealChannelInfo->TDNoiseCoef[0] = FL2FXCONST_SGL(0.05f); - pConcealChannelInfo->TDNoiseCoef[1] = FL2FXCONST_SGL(0.5f); - pConcealChannelInfo->TDNoiseCoef[2] = FL2FXCONST_SGL(0.45f); - - pConcealChannelInfo->pConcealParams = pConcealCommonData; - - pConcealChannelInfo->lastRenderMode = initRenderMode; - - pConcealChannelInfo->windowShape = CONCEAL_NOT_DEFINED; - pConcealChannelInfo->windowSequence = BLOCK_LONG; /* default type */ - pConcealChannelInfo->lastWinGrpLen = 1; - - pConcealChannelInfo->concealState = ConcealState_Ok; - - FDKmemclear(pConcealChannelInfo->spectralCoefficient, - 1024 * sizeof(FIXP_CNCL)); - - for (i = 0; i < 8; i++) { - pConcealChannelInfo->specScale[i] = 0; - } - - pConcealChannelInfo->iRandomPhase = 0; - - pConcealChannelInfo->prevFrameOk[0] = 1; - pConcealChannelInfo->prevFrameOk[1] = 1; - - pConcealChannelInfo->cntFadeFrames = 0; - pConcealChannelInfo->cntValidFrames = 0; - pConcealChannelInfo->fade_old = (FIXP_DBL)MAXVAL_DBL; - pConcealChannelInfo->winGrpOffset[0] = 0; - pConcealChannelInfo->winGrpOffset[1] = 0; - pConcealChannelInfo->attGrpOffset[0] = 0; - pConcealChannelInfo->attGrpOffset[1] = 0; -} - -/*! - \brief Set error concealment parameters - - \param concealParams - \param method - \param fadeOutSlope - \param fadeInSlope - \param muteRelease - \param comfNoiseLevel -*/ -AAC_DECODER_ERROR -CConcealment_SetParams(CConcealParams *concealParams, int method, - int fadeOutSlope, int fadeInSlope, int muteRelease, - FIXP_DBL comfNoiseLevel) { - /* set concealment technique */ - if (method != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) { - switch ((CConcealmentMethod)method) { - case ConcealMethodMute: - case ConcealMethodNoise: - case ConcealMethodInter: - /* Be sure to enable delay adjustment of SBR decoder! */ - if (concealParams == NULL) { - return AAC_DEC_INVALID_HANDLE; - } else { - /* set param */ - concealParams->method = (CConcealmentMethod)method; - } - break; - - default: - return AAC_DEC_SET_PARAM_FAIL; - } - } - - /* set number of frames for fade-out slope */ - if (fadeOutSlope != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) { - if ((fadeOutSlope < CONCEAL_MAX_NUM_FADE_FACTORS) && (fadeOutSlope >= 0)) { - if (concealParams == NULL) { - return AAC_DEC_INVALID_HANDLE; - } else { - /* set param */ - concealParams->numFadeOutFrames = fadeOutSlope; - } - } else { - return AAC_DEC_SET_PARAM_FAIL; - } - } - - /* set number of frames for fade-in slope */ - if (fadeInSlope != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) { - if ((fadeInSlope < CONCEAL_MAX_NUM_FADE_FACTORS) && (fadeInSlope >= 0)) { - if (concealParams == NULL) { - return AAC_DEC_INVALID_HANDLE; - } else { - /* set param */ - concealParams->numFadeInFrames = fadeInSlope; - } - } else { - return AAC_DEC_SET_PARAM_FAIL; - } - } - - /* set number of error-free frames after which the muting will be released */ - if (muteRelease != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) { - if ((muteRelease < (CONCEAL_MAX_NUM_FADE_FACTORS << 1)) && - (muteRelease >= 0)) { - if (concealParams == NULL) { - return AAC_DEC_INVALID_HANDLE; - } else { - /* set param */ - concealParams->numMuteReleaseFrames = muteRelease; - } - } else { - return AAC_DEC_SET_PARAM_FAIL; - } - } - - /* set confort noise level which will be inserted while in state 'muting' */ - if (comfNoiseLevel != (FIXP_DBL)AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) { - if ((comfNoiseLevel < (FIXP_DBL)0) || - (comfNoiseLevel > (FIXP_DBL)MAXVAL_DBL)) { - return AAC_DEC_SET_PARAM_FAIL; - } - if (concealParams == NULL) { - return AAC_DEC_INVALID_HANDLE; - } else { - concealParams->comfortNoiseLevel = (FIXP_DBL)comfNoiseLevel; - } - } - - return (AAC_DEC_OK); -} - -/*! - \brief Set fade-out/in attenuation factor vectors - - \param concealParams - \param fadeOutAttenuationVector - \param fadeInAttenuationVector - - \return 0 if OK all other values indicate errors -*/ -AAC_DECODER_ERROR -CConcealment_SetAttenuation(CConcealParams *concealParams, - const SHORT *fadeOutAttenuationVector, - const SHORT *fadeInAttenuationVector) { - if ((fadeOutAttenuationVector == NULL) && (fadeInAttenuationVector == NULL)) { - return AAC_DEC_SET_PARAM_FAIL; - } - - /* Fade-out factors */ - if (fadeOutAttenuationVector != NULL) { - int i; - - /* check quantized factors first */ - for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) { - if ((fadeOutAttenuationVector[i] < 0) || - (fadeOutAttenuationVector[i] > CONCEAL_MAX_QUANT_FACTOR)) { - return AAC_DEC_SET_PARAM_FAIL; - } - } - if (concealParams == NULL) { - return AAC_DEC_INVALID_HANDLE; - } - - /* now dequantize factors */ - for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) { - concealParams->fadeOutFactor[i] = - FX_DBL2FX_SGL(fLdPow(CONCEAL_MIN_ATTENUATION_FACTOR_025_LD, 0, - (FIXP_DBL)((INT)(FL2FXCONST_DBL(1.0 / 2.0) >> - (CONCEAL_PARAMETER_BITS - 1)) * - (INT)fadeOutAttenuationVector[i]), - CONCEAL_PARAMETER_BITS)); - } - } - - /* Fade-in factors */ - if (fadeInAttenuationVector != NULL) { - int i; - - /* check quantized factors first */ - for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) { - if ((fadeInAttenuationVector[i] < 0) || - (fadeInAttenuationVector[i] > CONCEAL_MAX_QUANT_FACTOR)) { - return AAC_DEC_SET_PARAM_FAIL; - } - } - if (concealParams == NULL) { - return AAC_DEC_INVALID_HANDLE; - } - - /* now dequantize factors */ - for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) { - concealParams->fadeInFactor[i] = FX_DBL2FX_SGL( - fLdPow(CONCEAL_MIN_ATTENUATION_FACTOR_025_LD, 0, - (FIXP_DBL)((INT)(FIXP_ONE >> CONCEAL_PARAMETER_BITS) * - (INT)fadeInAttenuationVector[i]), - CONCEAL_PARAMETER_BITS)); - } - } - - return (AAC_DEC_OK); -} - -/*! - \brief Get state of concealment module. - - \param pConcealChannelInfo - - \return Concealment state. -*/ -CConcealmentState CConcealment_GetState(CConcealmentInfo *pConcealChannelInfo) { - CConcealmentState state = ConcealState_Ok; - - if (pConcealChannelInfo != NULL) { - state = pConcealChannelInfo->concealState; - } - - return (state); -} - -/*! - \brief Store data for concealment techniques applied later - - Interface function to store data for different concealment strategies - */ -void CConcealment_Store( - CConcealmentInfo *hConcealmentInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) { - UCHAR nbDiv = NB_DIV; - - if (!(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD && - pAacDecoderChannelInfo->data.usac.mod[nbDiv - 1] == 0)) - - { - FIXP_DBL *pSpectralCoefficient = - SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); - SHORT *pSpecScale = pAacDecoderChannelInfo->specScale; - CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; - - SHORT tSpecScale[8]; - UCHAR tWindowShape; - BLOCK_TYPE tWindowSequence; - - /* store old window infos for swapping */ - tWindowSequence = hConcealmentInfo->windowSequence; - tWindowShape = hConcealmentInfo->windowShape; - - /* store old scale factors for swapping */ - FDKmemcpy(tSpecScale, hConcealmentInfo->specScale, 8 * sizeof(SHORT)); - - /* store new window infos */ - hConcealmentInfo->windowSequence = GetWindowSequence(pIcsInfo); - hConcealmentInfo->windowShape = GetWindowShape(pIcsInfo); - hConcealmentInfo->lastWinGrpLen = - *(GetWindowGroupLengthTable(pIcsInfo) + GetWindowGroups(pIcsInfo) - 1); - - /* store new scale factors */ - FDKmemcpy(hConcealmentInfo->specScale, pSpecScale, 8 * sizeof(SHORT)); - - if (hConcealmentInfo->pConcealParams->method < ConcealMethodInter) { - /* store new spectral bins */ -#if (CNCL_FRACT_BITS == DFRACT_BITS) - FDKmemcpy(hConcealmentInfo->spectralCoefficient, pSpectralCoefficient, - 1024 * sizeof(FIXP_CNCL)); -#else - FIXP_CNCL *RESTRICT pCncl = - &hConcealmentInfo->spectralCoefficient[1024 - 1]; - FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024 - 1]; - int i; - for (i = 1024; i != 0; i--) { - *pCncl-- = FX_DBL2FX_CNCL(*pSpec--); - } -#endif - } else { - /* swap spectral data */ -#if (FIXP_CNCL == FIXP_DBL) - C_ALLOC_SCRATCH_START(pSpecTmp, FIXP_DBL, 1024); - FDKmemcpy(pSpecTmp, pSpectralCoefficient, 1024 * sizeof(FIXP_DBL)); - FDKmemcpy(pSpectralCoefficient, hConcealmentInfo->spectralCoefficient, - 1024 * sizeof(FIXP_DBL)); - FDKmemcpy(hConcealmentInfo->spectralCoefficient, pSpecTmp, - 1024 * sizeof(FIXP_DBL)); - C_ALLOC_SCRATCH_END(pSpecTmp, FIXP_DBL, 1024); -#else - FIXP_CNCL *RESTRICT pCncl = - &hConcealmentInfo->spectralCoefficient[1024 - 1]; - FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024 - 1]; - FIXP_DBL tSpec; - - for (int i = 1024; i != 0; i--) { - tSpec = *pSpec; - *pSpec-- = FX_CNCL2FX_DBL(*pCncl); - *pCncl-- = FX_DBL2FX_CNCL(tSpec); - } -#endif - - /* complete swapping of window infos */ - pIcsInfo->WindowSequence = tWindowSequence; - pIcsInfo->WindowShape = tWindowShape; - - /* complete swapping of scale factors */ - FDKmemcpy(pSpecScale, tSpecScale, 8 * sizeof(SHORT)); - } - } - - if (pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD) { - /* Store LSF4 */ - FDKmemcpy(hConcealmentInfo->lsf4, pAacDecoderStaticChannelInfo->lpc4_lsf, - sizeof(hConcealmentInfo->lsf4)); - /* Store TCX gain */ - hConcealmentInfo->last_tcx_gain = - pAacDecoderStaticChannelInfo->last_tcx_gain; - hConcealmentInfo->last_tcx_gain_e = - pAacDecoderStaticChannelInfo->last_tcx_gain_e; - } -} - -/*! - \brief Apply concealment - - Interface function to different concealment strategies - */ -int CConcealment_Apply( - CConcealmentInfo *hConcealmentInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame, - const UCHAR lastLpdMode, const int frameOk, const UINT flags) { - int appliedProcessing = 0; - const int mute_release_active = - frameOk && (hConcealmentInfo->concealState >= ConcealState_Mute) && - (hConcealmentInfo->cntValidFrames + 1 <= - hConcealmentInfo->pConcealParams->numMuteReleaseFrames); - - if (hConcealmentInfo->windowShape == CONCEAL_NOT_DEFINED) { - /* Initialize window_shape with same value as in the current (parsed) frame. - Because section 4.6.11.3.2 (Windowing and block switching) of ISO/IEC - 14496-3:2009 says: For the first raw_data_block() to be decoded the - window_shape of the left and right half of the window are identical. */ - hConcealmentInfo->windowShape = pAacDecoderChannelInfo->icsInfo.WindowShape; - } - - if (frameOk && !mute_release_active) { - /* Update render mode if frameOk except for ongoing mute release state. */ - hConcealmentInfo->lastRenderMode = - (SCHAR)pAacDecoderChannelInfo->renderMode; - - /* Rescue current data for concealment in future frames */ - CConcealment_Store(hConcealmentInfo, pAacDecoderChannelInfo, - pAacDecoderStaticChannelInfo); - /* Reset index to random sign vector to make sign calculation frame agnostic - (only depends on number of subsequently concealed spectral blocks) */ - hConcealmentInfo->iRandomPhase = 0; - } else { - if (hConcealmentInfo->lastRenderMode == AACDEC_RENDER_INVALID) { - hConcealmentInfo->lastRenderMode = AACDEC_RENDER_IMDCT; - } - pAacDecoderChannelInfo->renderMode = - (AACDEC_RENDER_MODE)hConcealmentInfo->lastRenderMode; - } - - /* hand current frame status to the state machine */ - CConcealment_UpdateState(hConcealmentInfo, frameOk, - pAacDecoderStaticChannelInfo, samplesPerFrame, - pAacDecoderChannelInfo); - - { - if (!frameOk && pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_IMDCT) { - /* LPC extrapolation */ - CLpc_Conceal(pAacDecoderChannelInfo->data.usac.lsp_coeff, - pAacDecoderStaticChannelInfo->lpc4_lsf, - pAacDecoderStaticChannelInfo->lsf_adaptive_mean, - hConcealmentInfo->lastRenderMode == AACDEC_RENDER_IMDCT); - FDKmemcpy(hConcealmentInfo->lsf4, pAacDecoderStaticChannelInfo->lpc4_lsf, - sizeof(pAacDecoderStaticChannelInfo->lpc4_lsf)); - } - - /* Create data for signal rendering according to the selected concealment - * method and decoder operating mode. */ - - if ((!frameOk || mute_release_active) && - (pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD)) { - /* Restore old LSF4 */ - FDKmemcpy(pAacDecoderStaticChannelInfo->lpc4_lsf, hConcealmentInfo->lsf4, - sizeof(pAacDecoderStaticChannelInfo->lpc4_lsf)); - /* Restore old TCX gain */ - pAacDecoderStaticChannelInfo->last_tcx_gain = - hConcealmentInfo->last_tcx_gain; - pAacDecoderStaticChannelInfo->last_tcx_gain_e = - hConcealmentInfo->last_tcx_gain_e; - } - - if (!(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD && - pAacDecoderStaticChannelInfo->last_lpd_mode == 0)) { - switch (hConcealmentInfo->pConcealParams->method) { - default: - case ConcealMethodMute: - if (!frameOk) { - /* Mute spectral data in case of errors */ - FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient, - samplesPerFrame * sizeof(FIXP_DBL)); - /* Set last window shape */ - pAacDecoderChannelInfo->icsInfo.WindowShape = - hConcealmentInfo->windowShape; - appliedProcessing = 1; - } - break; - - case ConcealMethodNoise: - /* Noise substitution error concealment technique */ - appliedProcessing = CConcealment_ApplyNoise( - hConcealmentInfo, pAacDecoderChannelInfo, - pAacDecoderStaticChannelInfo, pSamplingRateInfo, samplesPerFrame, - flags); - break; - - case ConcealMethodInter: - /* Energy interpolation concealment based on 3GPP */ - appliedProcessing = CConcealment_ApplyInter( - hConcealmentInfo, pAacDecoderChannelInfo, pSamplingRateInfo, - samplesPerFrame, 0, /* don't use tonal improvement */ - frameOk, mute_release_active); - break; - } - } else if (!frameOk || mute_release_active) { - /* simply restore the buffer */ - FIXP_DBL *pSpectralCoefficient = - SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); - SHORT *pSpecScale = pAacDecoderChannelInfo->specScale; - CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; -#if (CNCL_FRACT_BITS != DFRACT_BITS) - FIXP_CNCL *RESTRICT pCncl = - &hConcealmentInfo->spectralCoefficient[1024 - 1]; - FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024 - 1]; - int i; -#endif - - /* restore window infos (gri) do we need that? */ - pIcsInfo->WindowSequence = hConcealmentInfo->windowSequence; - pIcsInfo->WindowShape = hConcealmentInfo->windowShape; - - if (hConcealmentInfo->concealState != ConcealState_Mute) { - /* restore scale factors */ - FDKmemcpy(pSpecScale, hConcealmentInfo->specScale, 8 * sizeof(SHORT)); - - /* restore spectral bins */ -#if (CNCL_FRACT_BITS == DFRACT_BITS) - FDKmemcpy(pSpectralCoefficient, hConcealmentInfo->spectralCoefficient, - 1024 * sizeof(FIXP_DBL)); -#else - for (i = 1024; i != 0; i--) { - *pSpec-- = FX_CNCL2FX_DBL(*pCncl--); - } -#endif - } else { - /* clear scale factors */ - FDKmemclear(pSpecScale, 8 * sizeof(SHORT)); - - /* clear buffer */ - FDKmemclear(pSpectralCoefficient, 1024 * sizeof(FIXP_CNCL)); - } - } - } - /* update history */ - hConcealmentInfo->prevFrameOk[0] = hConcealmentInfo->prevFrameOk[1]; - hConcealmentInfo->prevFrameOk[1] = frameOk; - - return mute_release_active ? -1 : appliedProcessing; -} - -/*! -\brief Apply concealment noise substitution - - In case of frame lost this function produces a noisy frame with respect to the - energies values of past frame. - */ -static int CConcealment_ApplyNoise( - CConcealmentInfo *pConcealmentInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame, - const UINT flags) { - FIXP_DBL *pSpectralCoefficient = - SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); - CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; - - int appliedProcessing = 0; - - FDK_ASSERT(pConcealmentInfo != NULL); - FDK_ASSERT((samplesPerFrame >= 120) && (samplesPerFrame <= 1024)); - - switch (pConcealmentInfo->concealState) { - case ConcealState_Ok: - /* Nothing to do here! */ - break; - - case ConcealState_Single: - case ConcealState_FadeOut: - appliedProcessing = CConcealment_ApplyFadeOut( - /*mode =*/1, pConcealmentInfo, pAacDecoderStaticChannelInfo, - samplesPerFrame, pAacDecoderChannelInfo); - break; - - case ConcealState_Mute: { - /* set dummy window parameters */ - pIcsInfo->Valid = 0; /* Trigger the generation of a consitent IcsInfo */ - pIcsInfo->WindowShape = - pConcealmentInfo->windowShape; /* Prevent an invalid WindowShape - (required for F/T transform) */ - pIcsInfo->WindowSequence = - CConcealment_GetWinSeq(pConcealmentInfo->windowSequence); - pConcealmentInfo->windowSequence = - pIcsInfo->WindowSequence; /* Store for next frame - (spectrum in concealment - buffer can't be used at - all) */ - - /* mute spectral data */ - FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL)); - FDKmemclear(pConcealmentInfo->spectralCoefficient, - samplesPerFrame * sizeof(FIXP_DBL)); - - appliedProcessing = 1; - } break; - - case ConcealState_FadeIn: { - /* TimeDomainFading: */ - /* Attenuation of signal is done in CConcealment_TDFading() */ - - appliedProcessing = 1; - } break; - - default: - /* we shouldn't come here anyway */ - FDK_ASSERT(0); - break; - } - - return appliedProcessing; -} - -/*! - \brief Apply concealment interpolation - - The function swaps the data from the current and the previous frame. If an - error has occured, frame interpolation is performed to restore the missing - frame. In case of multiple faulty frames, fade-in and fade-out is applied. -*/ -static int CConcealment_ApplyInter( - CConcealmentInfo *pConcealmentInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame, - const int improveTonal, const int frameOk, const int mute_release_active) { -#if defined(FDK_ASSERT_ENABLE) - CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams; -#endif - - FIXP_DBL *pSpectralCoefficient = - SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); - CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; - SHORT *pSpecScale = pAacDecoderChannelInfo->specScale; - - int sfbEnergyPrev[64]; - int sfbEnergyAct[64]; - - int i, appliedProcessing = 0; - - /* clear/init */ - FDKmemclear(sfbEnergyPrev, 64 * sizeof(int)); - FDKmemclear(sfbEnergyAct, 64 * sizeof(int)); - - if (!frameOk || mute_release_active) { - /* Restore last frame from concealment buffer */ - pIcsInfo->WindowShape = pConcealmentInfo->windowShape; - pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence; - - /* Restore spectral data */ - for (i = 0; i < samplesPerFrame; i++) { - pSpectralCoefficient[i] = - FX_CNCL2FX_DBL(pConcealmentInfo->spectralCoefficient[i]); - } - - /* Restore scale factors */ - FDKmemcpy(pSpecScale, pConcealmentInfo->specScale, 8 * sizeof(SHORT)); - } - - /* if previous frame was not ok */ - if (!pConcealmentInfo->prevFrameOk[1] || mute_release_active) { - /* if current frame (f_n) is ok and the last but one frame (f_(n-2)) - was ok, too, then interpolate both frames in order to generate - the current output frame (f_(n-1)). Otherwise, use the last stored - frame (f_(n-2) or f_(n-3) or ...). */ - if (frameOk && pConcealmentInfo->prevFrameOk[0] && !mute_release_active) { - appliedProcessing = 1; - - /* Interpolate both frames in order to generate the current output frame - * (f_(n-1)). */ - if (pIcsInfo->WindowSequence == BLOCK_SHORT) { - /* f_(n-2) == BLOCK_SHORT */ - /* short--??????--short, short--??????--long interpolation */ - /* short--short---short, short---long---long interpolation */ - - int wnd; - - if (pConcealmentInfo->windowSequence == - BLOCK_SHORT) { /* f_n == BLOCK_SHORT */ - /* short--short---short interpolation */ - - int scaleFactorBandsTotal = - pSamplingRateInfo->NumberOfScaleFactorBands_Short; - const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short; - pIcsInfo->WindowShape = (samplesPerFrame <= 512) ? 2 : 1; - pIcsInfo->WindowSequence = BLOCK_SHORT; - - for (wnd = 0; wnd < 8; wnd++) { - CConcealment_CalcBandEnergy( - &pSpectralCoefficient[wnd * - (samplesPerFrame / 8)], /* spec_(n-2) */ - pSamplingRateInfo, BLOCK_SHORT, CConcealment_NoExpand, - sfbEnergyPrev); - - CConcealment_CalcBandEnergy( - &pConcealmentInfo->spectralCoefficient[wnd * (samplesPerFrame / - 8)], /* spec_n */ - pSamplingRateInfo, BLOCK_SHORT, CConcealment_NoExpand, - sfbEnergyAct); - - CConcealment_InterpolateBuffer( - &pSpectralCoefficient[wnd * - (samplesPerFrame / 8)], /* spec_(n-1) */ - &pSpecScale[wnd], &pConcealmentInfo->specScale[wnd], - &pSpecScale[wnd], sfbEnergyPrev, sfbEnergyAct, - scaleFactorBandsTotal, pSfbOffset); - } - } else { /* f_n != BLOCK_SHORT */ - /* short---long---long interpolation */ - - int scaleFactorBandsTotal = - pSamplingRateInfo->NumberOfScaleFactorBands_Long; - const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long; - SHORT specScaleOut; - - CConcealment_CalcBandEnergy( - &pSpectralCoefficient[samplesPerFrame - - (samplesPerFrame / - 8)], /* [wnd] spec_(n-2) */ - pSamplingRateInfo, BLOCK_SHORT, CConcealment_Expand, - sfbEnergyAct); - - CConcealment_CalcBandEnergy( - pConcealmentInfo->spectralCoefficient, /* spec_n */ - pSamplingRateInfo, BLOCK_LONG, CConcealment_NoExpand, - sfbEnergyPrev); - - pIcsInfo->WindowShape = 0; - pIcsInfo->WindowSequence = BLOCK_STOP; - - for (i = 0; i < samplesPerFrame; i++) { - pSpectralCoefficient[i] = - pConcealmentInfo->spectralCoefficient[i]; /* spec_n */ - } - - for (i = 0; i < 8; i++) { /* search for max(specScale) */ - if (pSpecScale[i] > pSpecScale[0]) { - pSpecScale[0] = pSpecScale[i]; - } - } - - CConcealment_InterpolateBuffer( - pSpectralCoefficient, /* spec_(n-1) */ - &pConcealmentInfo->specScale[0], &pSpecScale[0], &specScaleOut, - sfbEnergyPrev, sfbEnergyAct, scaleFactorBandsTotal, pSfbOffset); - - pSpecScale[0] = specScaleOut; - } - } else { - /* long--??????--short, long--??????--long interpolation */ - /* long---long---short, long---long---long interpolation */ - - int scaleFactorBandsTotal = - pSamplingRateInfo->NumberOfScaleFactorBands_Long; - const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long; - SHORT specScaleAct = pConcealmentInfo->specScale[0]; - - CConcealment_CalcBandEnergy(pSpectralCoefficient, /* spec_(n-2) */ - pSamplingRateInfo, BLOCK_LONG, - CConcealment_NoExpand, sfbEnergyPrev); - - if (pConcealmentInfo->windowSequence == - BLOCK_SHORT) { /* f_n == BLOCK_SHORT */ - /* long---long---short interpolation */ - - pIcsInfo->WindowShape = (samplesPerFrame <= 512) ? 2 : 1; - pIcsInfo->WindowSequence = BLOCK_START; - - for (i = 1; i < 8; i++) { /* search for max(specScale) */ - if (pConcealmentInfo->specScale[i] > specScaleAct) { - specScaleAct = pConcealmentInfo->specScale[i]; - } - } - - /* Expand first short spectrum */ - CConcealment_CalcBandEnergy( - pConcealmentInfo->spectralCoefficient, /* spec_n */ - pSamplingRateInfo, BLOCK_SHORT, CConcealment_Expand, /* !!! */ - sfbEnergyAct); - } else { - /* long---long---long interpolation */ - - pIcsInfo->WindowShape = 0; - pIcsInfo->WindowSequence = BLOCK_LONG; - - CConcealment_CalcBandEnergy( - pConcealmentInfo->spectralCoefficient, /* spec_n */ - pSamplingRateInfo, BLOCK_LONG, CConcealment_NoExpand, - sfbEnergyAct); - } - - CConcealment_InterpolateBuffer( - pSpectralCoefficient, /* spec_(n-1) */ - &pSpecScale[0], &specScaleAct, &pSpecScale[0], sfbEnergyPrev, - sfbEnergyAct, scaleFactorBandsTotal, pSfbOffset); - } - } - - /* Noise substitution of sign of the output spectral coefficients */ - CConcealment_ApplyRandomSign(pConcealmentInfo->iRandomPhase, - pSpectralCoefficient, samplesPerFrame); - /* Increment random phase index to avoid repetition artifacts. */ - pConcealmentInfo->iRandomPhase = - (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1); - } - - /* scale spectrum according to concealment state */ - switch (pConcealmentInfo->concealState) { - case ConcealState_Single: - appliedProcessing = 1; - break; - - case ConcealState_FadeOut: { - FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0); - FDK_ASSERT(pConcealmentInfo->cntFadeFrames < - CONCEAL_MAX_NUM_FADE_FACTORS); - FDK_ASSERT(pConcealmentInfo->cntFadeFrames < - pConcealCommonData->numFadeOutFrames); - - /* TimeDomainFading: */ - /* Attenuation of signal is done in CConcealment_TDFading() */ - - appliedProcessing = 1; - } break; - - case ConcealState_FadeIn: { - FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0); - FDK_ASSERT(pConcealmentInfo->cntFadeFrames < - CONCEAL_MAX_NUM_FADE_FACTORS); - FDK_ASSERT(pConcealmentInfo->cntFadeFrames < - pConcealCommonData->numFadeInFrames); - - /* TimeDomainFading: */ - /* Attenuation of signal is done in CConcealment_TDFading() */ - - appliedProcessing = 1; - } break; - - case ConcealState_Mute: { - /* set dummy window parameters */ - pIcsInfo->Valid = 0; /* Trigger the generation of a consitent IcsInfo */ - pIcsInfo->WindowShape = - pConcealmentInfo->windowShape; /* Prevent an invalid WindowShape - (required for F/T transform) */ - pIcsInfo->WindowSequence = - CConcealment_GetWinSeq(pConcealmentInfo->windowSequence); - pConcealmentInfo->windowSequence = - pIcsInfo->WindowSequence; /* Store for next frame - (spectrum in concealment - buffer can't be used at - all) */ - - /* mute spectral data */ - FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL)); - - appliedProcessing = 1; - } break; - - default: - /* nothing to do here */ - break; - } - - return appliedProcessing; -} - -/*! - \brief Calculate the spectral energy - - The function calculates band-wise the spectral energy. This is used for - frame interpolation. -*/ -static void CConcealment_CalcBandEnergy( - FIXP_DBL *spectrum, const SamplingRateInfo *pSamplingRateInfo, - const int blockType, CConcealmentExpandType expandType, int *sfbEnergy) { - const SHORT *pSfbOffset; - int line, sfb, scaleFactorBandsTotal = 0; - - /* In the following calculations, enAccu is initialized with LSB-value in - * order to avoid zero energy-level */ - - line = 0; - - switch (blockType) { - case BLOCK_LONG: - case BLOCK_START: - case BLOCK_STOP: - - if (expandType == CConcealment_NoExpand) { - /* standard long calculation */ - scaleFactorBandsTotal = - pSamplingRateInfo->NumberOfScaleFactorBands_Long; - pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long; - - for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) { - FIXP_DBL enAccu = (FIXP_DBL)(LONG)1; - int sfbScale = - (sizeof(LONG) << 3) - - CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1; - /* scaling depends on sfb width. */ - for (; line < pSfbOffset[sfb + 1]; line++) { - enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale; - } - *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1; - } - } else { - /* compress long to short */ - scaleFactorBandsTotal = - pSamplingRateInfo->NumberOfScaleFactorBands_Short; - pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short; - - for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) { - FIXP_DBL enAccu = (FIXP_DBL)(LONG)1; - int sfbScale = - (sizeof(LONG) << 3) - - CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1; - /* scaling depends on sfb width. */ - for (; line < pSfbOffset[sfb + 1] << 3; line++) { - enAccu += - (enAccu + (fPow2Div2(*(spectrum + line)) >> sfbScale)) >> 3; - } - *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1; - } - } - break; - - case BLOCK_SHORT: - - if (expandType == CConcealment_NoExpand) { - /* standard short calculation */ - scaleFactorBandsTotal = - pSamplingRateInfo->NumberOfScaleFactorBands_Short; - pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short; - - for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) { - FIXP_DBL enAccu = (FIXP_DBL)(LONG)1; - int sfbScale = - (sizeof(LONG) << 3) - - CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1; - /* scaling depends on sfb width. */ - for (; line < pSfbOffset[sfb + 1]; line++) { - enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale; - } - *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1; - } - } else { - /* expand short to long spectrum */ - scaleFactorBandsTotal = - pSamplingRateInfo->NumberOfScaleFactorBands_Long; - pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long; - - for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) { - FIXP_DBL enAccu = (FIXP_DBL)(LONG)1; - int sfbScale = - (sizeof(LONG) << 3) - - CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1; - /* scaling depends on sfb width. */ - for (; line < pSfbOffset[sfb + 1]; line++) { - enAccu += fPow2Div2(*(spectrum + (line >> 3))) >> sfbScale; - } - *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1; - } - } - break; - } -} - -/*! - \brief Interpolate buffer - - The function creates the interpolated spectral data according to the - energy of the last good frame and the current (good) frame. -*/ -static void CConcealment_InterpolateBuffer(FIXP_DBL *spectrum, - SHORT *pSpecScalePrv, - SHORT *pSpecScaleAct, - SHORT *pSpecScaleOut, int *enPrv, - int *enAct, int sfbCnt, - const SHORT *pSfbOffset) { - int sfb, line = 0; - int fac_shift; - int fac_mod; - FIXP_DBL accu; - - for (sfb = 0; sfb < sfbCnt; sfb++) { - fac_shift = - enPrv[sfb] - enAct[sfb] + ((*pSpecScaleAct - *pSpecScalePrv) << 1); - fac_mod = fac_shift & 3; - fac_shift = (fac_shift >> 2) + 1; - fac_shift += *pSpecScalePrv - fixMax(*pSpecScalePrv, *pSpecScaleAct); - - for (; line < pSfbOffset[sfb + 1]; line++) { - accu = fMult(*(spectrum + line), facMod4Table[fac_mod]); - if (fac_shift < 0) { - accu >>= -fac_shift; - } else { - accu <<= fac_shift; - } - *(spectrum + line) = accu; - } - } - *pSpecScaleOut = fixMax(*pSpecScalePrv, *pSpecScaleAct); -} - -/*! - \brief Find next fading frame in case of changing fading direction - - \param pConcealCommonData Pointer to the concealment common data structure. - \param actFadeIndex Last index used for fading - \param direction Direction of change: 0 : change from FADE-OUT to FADE-IN, 1 - : change from FADE-IN to FADE-OUT - - This function determines the next fading index to be used for the fading - direction to be changed to. -*/ - -static INT findEquiFadeFrame(CConcealParams *pConcealCommonData, - INT actFadeIndex, int direction) { - FIXP_SGL *pFactor; - FIXP_SGL referenceVal; - FIXP_SGL minDiff = (FIXP_SGL)MAXVAL_SGL; - - INT nextFadeIndex = 0; - - int i; - - /* init depending on direction */ - if (direction == 0) { /* FADE-OUT => FADE-IN */ - if (actFadeIndex < 0) { - referenceVal = (FIXP_SGL)MAXVAL_SGL; - } else { - referenceVal = pConcealCommonData->fadeOutFactor[actFadeIndex] >> 1; - } - pFactor = pConcealCommonData->fadeInFactor; - } else { /* FADE-IN => FADE-OUT */ - if (actFadeIndex < 0) { - referenceVal = (FIXP_SGL)MAXVAL_SGL; - } else { - referenceVal = pConcealCommonData->fadeInFactor[actFadeIndex] >> 1; - } - pFactor = pConcealCommonData->fadeOutFactor; - } - - /* search for minimum difference */ - for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) { - FIXP_SGL diff = fixp_abs((pFactor[i] >> 1) - referenceVal); - if (diff < minDiff) { - minDiff = diff; - nextFadeIndex = i; - } - } - - /* check and adjust depending on direction */ - if (direction == 0) { /* FADE-OUT => FADE-IN */ - if (nextFadeIndex > pConcealCommonData->numFadeInFrames) { - nextFadeIndex = fMax(pConcealCommonData->numFadeInFrames - 1, 0); - } - if (((pFactor[nextFadeIndex] >> 1) <= referenceVal) && - (nextFadeIndex > 0)) { - nextFadeIndex -= 1; - } - } else { /* FADE-IN => FADE-OUT */ - if (((pFactor[nextFadeIndex] >> 1) >= referenceVal) && - (nextFadeIndex < CONCEAL_MAX_NUM_FADE_FACTORS - 1)) { - nextFadeIndex += 1; - } - } - - return (nextFadeIndex); -} - -/*! - \brief Update the concealment state - - The function updates the state of the concealment state-machine. The - states are: mute, fade-in, fade-out, interpolate and frame-ok. -*/ -static void CConcealment_UpdateState( - CConcealmentInfo *pConcealmentInfo, int frameOk, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo) { - CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams; - - switch (pConcealCommonData->method) { - case ConcealMethodNoise: { - if (pConcealmentInfo->concealState != ConcealState_Ok) { - /* count the valid frames during concealment process */ - if (frameOk) { - pConcealmentInfo->cntValidFrames += 1; - } else { - pConcealmentInfo->cntValidFrames = 0; - } - } - - /* -- STATE MACHINE for Noise Substitution -- */ - switch (pConcealmentInfo->concealState) { - case ConcealState_Ok: - if (!frameOk) { - pConcealmentInfo->cntFadeFrames = 0; - pConcealmentInfo->cntValidFrames = 0; - pConcealmentInfo->attGrpOffset[0] = 0; - pConcealmentInfo->attGrpOffset[1] = 0; - pConcealmentInfo->winGrpOffset[0] = 0; - pConcealmentInfo->winGrpOffset[1] = 0; - if (pConcealCommonData->numFadeOutFrames > 0) { - /* change to state SINGLE-FRAME-LOSS */ - pConcealmentInfo->concealState = ConcealState_Single; - /* mode 0 just updates the Fading counter */ - CConcealment_ApplyFadeOut( - /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo, - samplesPerFrame, pAacDecoderChannelInfo); - - } else { - /* change to state MUTE */ - pConcealmentInfo->concealState = ConcealState_Mute; - } - } - break; - - case ConcealState_Single: /* Just a pre-stage before fade-out begins. - Stay here only one frame! */ - if (frameOk) { - /* change to state OK */ - pConcealmentInfo->concealState = ConcealState_Ok; - } else { - if (pConcealmentInfo->cntFadeFrames >= - pConcealCommonData->numFadeOutFrames) { - /* change to state MUTE */ - pConcealmentInfo->concealState = ConcealState_Mute; - } else { - /* change to state FADE-OUT */ - pConcealmentInfo->concealState = ConcealState_FadeOut; - /* mode 0 just updates the Fading counter */ - CConcealment_ApplyFadeOut( - /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo, - samplesPerFrame, pAacDecoderChannelInfo); - } - } - break; - - case ConcealState_FadeOut: - if (pConcealmentInfo->cntValidFrames > - pConcealCommonData->numMuteReleaseFrames) { - if (pConcealCommonData->numFadeInFrames > 0) { - /* change to state FADE-IN */ - pConcealmentInfo->concealState = ConcealState_FadeIn; - pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( - pConcealCommonData, pConcealmentInfo->cntFadeFrames, - 0 /* FadeOut -> FadeIn */); - } else { - /* change to state OK */ - pConcealmentInfo->concealState = ConcealState_Ok; - } - } else { - if (frameOk) { - /* we have good frame information but stay fully in concealment - - * reset winGrpOffset/attGrpOffset */ - pConcealmentInfo->winGrpOffset[0] = 0; - pConcealmentInfo->winGrpOffset[1] = 0; - pConcealmentInfo->attGrpOffset[0] = 0; - pConcealmentInfo->attGrpOffset[1] = 0; - } - if (pConcealmentInfo->cntFadeFrames >= - pConcealCommonData->numFadeOutFrames) { - /* change to state MUTE */ - pConcealmentInfo->concealState = ConcealState_Mute; - } else /* Stay in FADE-OUT */ - { - /* mode 0 just updates the Fading counter */ - CConcealment_ApplyFadeOut( - /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo, - samplesPerFrame, pAacDecoderChannelInfo); - } - } - break; - - case ConcealState_Mute: - if (pConcealmentInfo->cntValidFrames > - pConcealCommonData->numMuteReleaseFrames) { - if (pConcealCommonData->numFadeInFrames > 0) { - /* change to state FADE-IN */ - pConcealmentInfo->concealState = ConcealState_FadeIn; - pConcealmentInfo->cntFadeFrames = - pConcealCommonData->numFadeInFrames - 1; - } else { - /* change to state OK */ - pConcealmentInfo->concealState = ConcealState_Ok; - } - } else { - if (frameOk) { - /* we have good frame information but stay fully in concealment - - * reset winGrpOffset/attGrpOffset */ - pConcealmentInfo->winGrpOffset[0] = 0; - pConcealmentInfo->winGrpOffset[1] = 0; - pConcealmentInfo->attGrpOffset[0] = 0; - pConcealmentInfo->attGrpOffset[1] = 0; - } - } - break; - - case ConcealState_FadeIn: - pConcealmentInfo->cntFadeFrames -= 1; - if (frameOk) { - if (pConcealmentInfo->cntFadeFrames < 0) { - /* change to state OK */ - pConcealmentInfo->concealState = ConcealState_Ok; - } - } else { - if (pConcealCommonData->numFadeOutFrames > 0) { - /* change to state FADE-OUT */ - pConcealmentInfo->concealState = ConcealState_FadeOut; - pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( - pConcealCommonData, pConcealmentInfo->cntFadeFrames + 1, - 1 /* FadeIn -> FadeOut */); - pConcealmentInfo->winGrpOffset[0] = 0; - pConcealmentInfo->winGrpOffset[1] = 0; - pConcealmentInfo->attGrpOffset[0] = 0; - pConcealmentInfo->attGrpOffset[1] = 0; - - pConcealmentInfo - ->cntFadeFrames--; /* decrease because - CConcealment_ApplyFadeOut() will - increase, accordingly */ - /* mode 0 just updates the Fading counter */ - CConcealment_ApplyFadeOut( - /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo, - samplesPerFrame, pAacDecoderChannelInfo); - } else { - /* change to state MUTE */ - pConcealmentInfo->concealState = ConcealState_Mute; - } - } - break; - - default: - FDK_ASSERT(0); - break; - } - } break; - - case ConcealMethodInter: - case ConcealMethodTonal: { - if (pConcealmentInfo->concealState != ConcealState_Ok) { - /* count the valid frames during concealment process */ - if (pConcealmentInfo->prevFrameOk[1] || - (pConcealmentInfo->prevFrameOk[0] && - !pConcealmentInfo->prevFrameOk[1] && frameOk)) { - /* The frame is OK even if it can be estimated by the energy - * interpolation algorithm */ - pConcealmentInfo->cntValidFrames += 1; - } else { - pConcealmentInfo->cntValidFrames = 0; - } - } - - /* -- STATE MACHINE for energy interpolation -- */ - switch (pConcealmentInfo->concealState) { - case ConcealState_Ok: - if (!(pConcealmentInfo->prevFrameOk[1] || - (pConcealmentInfo->prevFrameOk[0] && - !pConcealmentInfo->prevFrameOk[1] && frameOk))) { - if (pConcealCommonData->numFadeOutFrames > 0) { - /* Fade out only if the energy interpolation algorithm can not be - * applied! */ - pConcealmentInfo->concealState = ConcealState_FadeOut; - } else { - /* change to state MUTE */ - pConcealmentInfo->concealState = ConcealState_Mute; - } - pConcealmentInfo->cntFadeFrames = 0; - pConcealmentInfo->cntValidFrames = 0; - } - break; - - case ConcealState_Single: - pConcealmentInfo->concealState = ConcealState_Ok; - break; - - case ConcealState_FadeOut: - pConcealmentInfo->cntFadeFrames += 1; - - if (pConcealmentInfo->cntValidFrames > - pConcealCommonData->numMuteReleaseFrames) { - if (pConcealCommonData->numFadeInFrames > 0) { - /* change to state FADE-IN */ - pConcealmentInfo->concealState = ConcealState_FadeIn; - pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( - pConcealCommonData, pConcealmentInfo->cntFadeFrames - 1, - 0 /* FadeOut -> FadeIn */); - } else { - /* change to state OK */ - pConcealmentInfo->concealState = ConcealState_Ok; - } - } else { - if (pConcealmentInfo->cntFadeFrames >= - pConcealCommonData->numFadeOutFrames) { - /* change to state MUTE */ - pConcealmentInfo->concealState = ConcealState_Mute; - } - } - break; - - case ConcealState_Mute: - if (pConcealmentInfo->cntValidFrames > - pConcealCommonData->numMuteReleaseFrames) { - if (pConcealCommonData->numFadeInFrames > 0) { - /* change to state FADE-IN */ - pConcealmentInfo->concealState = ConcealState_FadeIn; - pConcealmentInfo->cntFadeFrames = - pConcealCommonData->numFadeInFrames - 1; - } else { - /* change to state OK */ - pConcealmentInfo->concealState = ConcealState_Ok; - } - } - break; - - case ConcealState_FadeIn: - pConcealmentInfo->cntFadeFrames -= - 1; /* used to address the fade-in factors */ - - if (frameOk || pConcealmentInfo->prevFrameOk[1]) { - if (pConcealmentInfo->cntFadeFrames < 0) { - /* change to state OK */ - pConcealmentInfo->concealState = ConcealState_Ok; - } - } else { - if (pConcealCommonData->numFadeOutFrames > 0) { - /* change to state FADE-OUT */ - pConcealmentInfo->concealState = ConcealState_FadeOut; - pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( - pConcealCommonData, pConcealmentInfo->cntFadeFrames + 1, - 1 /* FadeIn -> FadeOut */); - } else { - /* change to state MUTE */ - pConcealmentInfo->concealState = ConcealState_Mute; - } - } - break; - } /* End switch(pConcealmentInfo->concealState) */ - } break; - - default: - /* Don't need a state machine for other concealment methods. */ - break; - } -} - -/*! -\brief Randomizes the sign of the spectral data - - The function toggles the sign of the spectral data randomly. This is - useful to ensure the quality of the concealed frames. - */ -static void CConcealment_ApplyRandomSign(int randomPhase, FIXP_DBL *spec, - int samplesPerFrame) { - int i; - USHORT packedSign = 0; - - /* random table 512x16bit has been reduced to 512 packed sign bits = 32x16 bit - */ - - /* read current packed sign word */ - packedSign = AacDec_randomSign[randomPhase >> 4]; - packedSign >>= (randomPhase & 0xf); - - for (i = 0; i < samplesPerFrame; i++) { - if ((randomPhase & 0xf) == 0) { - packedSign = AacDec_randomSign[randomPhase >> 4]; - } - - if (packedSign & 0x1) { - spec[i] = -spec[i]; - } - packedSign >>= 1; - - randomPhase = (randomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1); - } -} - -/*! - \brief Get fadeing factor for current concealment state. - - The function returns the state (ok or not) of the previous frame. - If called before the function CConcealment_Apply() set the fBeforeApply - flag to get the correct value. - - \return Frame OK flag of previous frame. - */ -int CConcealment_GetLastFrameOk(CConcealmentInfo *hConcealmentInfo, - const int fBeforeApply) { - int prevFrameOk = 1; - - if (hConcealmentInfo != NULL) { - prevFrameOk = hConcealmentInfo->prevFrameOk[fBeforeApply & 0x1]; - } - - return prevFrameOk; -} - -/*! - \brief Get the number of delay frames introduced by concealment technique. - - \return Number of delay frames. - */ -UINT CConcealment_GetDelay(CConcealParams *pConcealCommonData) { - UINT frameDelay = 0; - - if (pConcealCommonData != NULL) { - switch (pConcealCommonData->method) { - case ConcealMethodTonal: - case ConcealMethodInter: - frameDelay = 1; - break; - default: - break; - } - } - - return frameDelay; -} - -static int CConcealment_ApplyFadeOut( - int mode, CConcealmentInfo *pConcealmentInfo, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo) { - /* mode 1 = apply RandomSign and mute spectral coefficients if necessary, * - * mode 0 = Update cntFadeFrames */ - - /* restore frequency coefficients from buffer with a specific muting */ - int srcWin, dstWin, numWindows = 1; - int windowLen = samplesPerFrame; - int srcGrpStart = 0; - int winIdxStride = 1; - int numWinGrpPerFac, attIdx, attIdxStride; - int i; - int appliedProcessing = 0; - - CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; - FIXP_DBL *pSpectralCoefficient = - SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); - SHORT *pSpecScale = pAacDecoderChannelInfo->specScale; - - /* set old window parameters */ - if (pConcealmentInfo->lastRenderMode == AACDEC_RENDER_LPD) { - switch (pAacDecoderStaticChannelInfo->last_lpd_mode) { - case 1: - numWindows = 4; - srcGrpStart = 3; - windowLen = samplesPerFrame >> 2; - break; - case 2: - numWindows = 2; - srcGrpStart = 1; - windowLen = samplesPerFrame >> 1; - winIdxStride = 2; - break; - case 3: - numWindows = 1; - srcGrpStart = 0; - windowLen = samplesPerFrame; - winIdxStride = 4; - break; - } - pConcealmentInfo->lastWinGrpLen = 1; - } else { - pIcsInfo->WindowShape = pConcealmentInfo->windowShape; - pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence; - - if (pConcealmentInfo->windowSequence == BLOCK_SHORT) { - /* short block handling */ - numWindows = 8; - windowLen = samplesPerFrame >> 3; - srcGrpStart = numWindows - pConcealmentInfo->lastWinGrpLen; - } - } - - attIdxStride = - fMax(1, (int)(numWindows / (pConcealmentInfo->lastWinGrpLen + 1))); - - /* load last state */ - attIdx = pConcealmentInfo->cntFadeFrames; - numWinGrpPerFac = pConcealmentInfo->attGrpOffset[mode]; - srcWin = srcGrpStart + pConcealmentInfo->winGrpOffset[mode]; - - FDK_ASSERT((srcGrpStart * windowLen + windowLen) <= samplesPerFrame); - FDK_ASSERT((srcWin * windowLen + windowLen) <= 1024); - - for (dstWin = 0; dstWin < numWindows; dstWin += 1) { - FIXP_CNCL *pCncl = - pConcealmentInfo->spectralCoefficient + (srcWin * windowLen); - FIXP_DBL *pOut = pSpectralCoefficient + (dstWin * windowLen); - - if (mode == 1) { - /* mute if attIdx gets large enaugh */ - if (attIdx > pConcealmentInfo->pConcealParams->numFadeOutFrames) { - FDKmemclear(pCncl, sizeof(FIXP_DBL) * windowLen); - } - - /* restore frequency coefficients from buffer - attenuation is done later - */ - for (i = 0; i < windowLen; i++) { - pOut[i] = pCncl[i]; - } - - /* apply random change of sign for spectral coefficients */ - CConcealment_ApplyRandomSign(pConcealmentInfo->iRandomPhase, pOut, - windowLen); - - /* Increment random phase index to avoid repetition artifacts. */ - pConcealmentInfo->iRandomPhase = - (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1); - - /* set old scale factors */ - pSpecScale[dstWin * winIdxStride] = - pConcealmentInfo->specScale[srcWin * winIdxStride]; - } - - srcWin += 1; - - if (srcWin >= numWindows) { - /* end of sequence -> rewind to first window of group */ - srcWin = srcGrpStart; - numWinGrpPerFac += 1; - if (numWinGrpPerFac >= attIdxStride) { - numWinGrpPerFac = 0; - attIdx += 1; - } - } - } - - /* store current state */ - - pConcealmentInfo->winGrpOffset[mode] = srcWin - srcGrpStart; - FDK_ASSERT((pConcealmentInfo->winGrpOffset[mode] >= 0) && - (pConcealmentInfo->winGrpOffset[mode] < 8)); - pConcealmentInfo->attGrpOffset[mode] = numWinGrpPerFac; - FDK_ASSERT((pConcealmentInfo->attGrpOffset[mode] >= 0) && - (pConcealmentInfo->attGrpOffset[mode] < attIdxStride)); - - if (mode == 0) { - pConcealmentInfo->cntFadeFrames = attIdx; - } - - appliedProcessing = 1; - - return appliedProcessing; -} - -/*! - \brief Do Time domain fading (TDFading) in concealment case - - In case of concealment, this function takes care of the fading, after time -domain signal has been rendered by the respective signal rendering functions. - The fading out in case of ACELP decoding is not done by this function but by -the ACELP decoder for the first concealed frame if CONCEAL_CORE_IGNORANT_FADE is -not set. - - TimeDomain fading never creates jumps in energy / discontinuities, it always -does a continuous fading. To achieve this, fading is always done from a starting -point to a target point, while the starting point is always determined to be the -last target point. By varying the target point of a fading, the fading slope can -be controlled. - - This principle is applied to the fading within a frame and the fading from -frame to frame. - - One frame is divided into 8 subframes to obtain 8 parts of fading slopes -within a frame, each maybe with its own gradient. - - Workflow: - 1.) Determine Fading behavior and end-of-frame target fading level, based on -concealmentState (determined by CConcealment_UpdateState()) and the core mode. - - By _DEFAULT_, - The target fading level is determined by fadeOutFactor[cntFadeFrames] -in case of fadeOut, or fadeInFactor[cntFadeFrames] in case of fadeIn. - --> fading type is FADE_TIMEDOMAIN in this case. Target fading level -is determined by fading index cntFadeFrames. - - - If concealmentState is signalling a _MUTED SIGNAL_, - TDFading decays to 0 within 1/8th of a frame if numFadeOutFrames == 0. - --> fading type is FADE_TIMEDOMAIN_TOSPECTRALMUTE in this case. - - - If concealmentState is signalling the _END OF MUTING_, - TDFading fades to target fading level within 1/8th of a frame if -numFadeInFrames == 0. - --> fading type is FADE_TIMEDOMAIN_FROMSPECTRALMUTE in this case. -Target fading level is determined by fading index cntFadeFrames. - -#ifndef CONCEAL_CORE_IGNORANT_FADE - - In case of an _ACELP FADEOUT_, - TDFading leaves fading control to ACELP decoder for 1/2 frame. - --> fading type is FADE_ACELPDOMAIN in this case. -#endif - - 2.) Render fading levels within current frame and do the final fading: - Map Fading slopes to fading levels and apply to time domain signal. - - -*/ - -INT CConcealment_TDFading( - int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo, - FIXP_PCM *pcmdata, FIXP_PCM *pcmdata_1) { - /* - Do the fading in Time domain based on concealment states and core mode - */ - FIXP_DBL fadeStop, attMute = (FIXP_DBL)0; - int idx = 0, ii; - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo = - *ppAacDecoderStaticChannelInfo; - CConcealmentInfo *pConcealmentInfo = - &pAacDecoderStaticChannelInfo->concealmentInfo; - CConcealParams *pConcealParams = pConcealmentInfo->pConcealParams; - const CConcealmentState concealState = pConcealmentInfo->concealState; - TDfadingType fadingType; - FIXP_DBL fadingStations[9] = {0}; - int fadingSteps[8] = {0}; - const FIXP_DBL fadeStart = - pConcealmentInfo - ->fade_old; /* start fading at last end-of-frame attenuation */ - FIXP_SGL *fadeFactor = pConcealParams->fadeOutFactor; - const INT cntFadeFrames = pConcealmentInfo->cntFadeFrames; - int TDFadeOutStopBeforeMute = 1; - int TDFadeInStopBeforeFullLevel = 1; - - /* - determine Fading behaviour (end-of-frame attenuation and fading type) (1.) - */ - - switch (concealState) { - case ConcealState_Single: - case ConcealState_Mute: - case ConcealState_FadeOut: - idx = (pConcealParams->method == ConcealMethodNoise) ? cntFadeFrames - 1 - : cntFadeFrames; - fadingType = FADE_TIMEDOMAIN; - - if (concealState == ConcealState_Mute || - (cntFadeFrames + TDFadeOutStopBeforeMute) > - pConcealmentInfo->pConcealParams->numFadeOutFrames) { - fadingType = FADE_TIMEDOMAIN_TOSPECTRALMUTE; - } - - break; - case ConcealState_FadeIn: - idx = cntFadeFrames; - idx -= TDFadeInStopBeforeFullLevel; - FDK_FALLTHROUGH; - case ConcealState_Ok: - fadeFactor = pConcealParams->fadeInFactor; - idx = (concealState == ConcealState_Ok) ? -1 : idx; - fadingType = (pConcealmentInfo->concealState_old == ConcealState_Mute) - ? FADE_TIMEDOMAIN_FROMSPECTRALMUTE - : FADE_TIMEDOMAIN; - break; - default: - FDK_ASSERT(0); - fadingType = FADE_TIMEDOMAIN_TOSPECTRALMUTE; - break; - } - - /* determine Target end-of-frame fading level and fading slope */ - switch (fadingType) { - case FADE_TIMEDOMAIN_FROMSPECTRALMUTE: - fadeStop = - (idx < 0) ? (FIXP_DBL)MAXVAL_DBL : FX_SGL2FX_DBL(fadeFactor[idx]); - if (pConcealmentInfo->pConcealParams->numFadeInFrames == 0) { - /* do step as fast as possible */ - fadingSteps[0] = 1; - break; - } - CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]); - break; - case FADE_TIMEDOMAIN: - fadeStop = - (idx < 0) ? (FIXP_DBL)MAXVAL_DBL : FX_SGL2FX_DBL(fadeFactor[idx]); - CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]); - break; - case FADE_TIMEDOMAIN_TOSPECTRALMUTE: - fadeStop = attMute; - if (pConcealmentInfo->pConcealParams->numFadeOutFrames == 0) { - /* do step as fast as possible */ - fadingSteps[0] = 1; - break; - } - CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]); - break; - } - - /* - Render fading levels within current frame and do the final fading (2.) - */ - - len >>= 3; - CConcealment_TDFadeFillFadingStations(fadingStations, fadingSteps, fadeStop, - fadeStart, fadingType); - - if ((fadingStations[8] != (FIXP_DBL)MAXVAL_DBL) || - (fadingStations[7] != (FIXP_DBL)MAXVAL_DBL) || - (fadingStations[6] != (FIXP_DBL)MAXVAL_DBL) || - (fadingStations[5] != (FIXP_DBL)MAXVAL_DBL) || - (fadingStations[4] != (FIXP_DBL)MAXVAL_DBL) || - (fadingStations[3] != (FIXP_DBL)MAXVAL_DBL) || - (fadingStations[2] != (FIXP_DBL)MAXVAL_DBL) || - (fadingStations[1] != (FIXP_DBL)MAXVAL_DBL) || - (fadingStations[0] != - (FIXP_DBL)MAXVAL_DBL)) /* if there's something to fade */ - { - int start = 0; - for (ii = 0; ii < 8; ii++) { - CConcealment_TDFadePcmAtt(start, len, fadingStations[ii], - fadingStations[ii + 1], pcmdata); - start += len; - } - } - CConcealment_TDNoise_Apply(pConcealmentInfo, len, pcmdata); - - /* Save end-of-frame attenuation and fading type */ - pConcealmentInfo->lastFadingType = fadingType; - pConcealmentInfo->fade_old = fadeStop; - pConcealmentInfo->concealState_old = concealState; - - return 1; -} - -/* attenuate pcmdata in Time Domain Fading process */ -static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart, - FIXP_DBL fadeStop, FIXP_PCM *pcmdata) { - int i; - FIXP_DBL dStep; - FIXP_DBL dGain; - FIXP_DBL dGain_apply; - int bitshift = (DFRACT_BITS - SAMPLE_BITS); - - /* set start energy */ - dGain = fadeStart; - /* determine energy steps from sample to sample */ - dStep = (FIXP_DBL)((int)((fadeStart >> 1) - (fadeStop >> 1)) / len) << 1; - - for (i = start; i < (start + len); i++) { - dGain -= dStep; - /* prevent gain from getting negative due to possible fixpoint inaccuracies - */ - dGain_apply = fMax((FIXP_DBL)0, dGain); - /* finally, attenuate samples */ - pcmdata[i] = (FIXP_PCM)((fMult(pcmdata[i], (dGain_apply))) >> bitshift); - } -} - -/* -\brief Fill FadingStations - -The fadingstations are the attenuation factors, being applied to its dedicated -portions of pcm data. They are calculated using the fadingsteps. One fadingstep -is the weighted contribution to the fading slope within its dedicated portion of -pcm data. - -*Fadingsteps : 0 0 0 1 0 1 2 0 - - |<- 1 Frame pcm data ->| - fadeStart-->|__________ | - ^ ^ ^ ^ \____ | - Attenuation : | | | | ^ ^\__ | - | | | | | | ^\ | - | | | | | | | \___|<-- fadeStop - | | | | | | | ^ ^ - | | | | | | | | | -Fadingstations: [0][1][2][3][4][5][6][7][8] - -(Fadingstations "[0]" is "[8] from previous frame", therefore its not meaningful -to be edited) - -*/ -static void CConcealment_TDFadeFillFadingStations(FIXP_DBL *fadingStations, - int *fadingSteps, - FIXP_DBL fadeStop, - FIXP_DBL fadeStart, - TDfadingType fadingType) { - int i; - INT fadingSteps_sum = 0; - INT fadeDiff; - - fadingSteps_sum = fadingSteps[0] + fadingSteps[1] + fadingSteps[2] + - fadingSteps[3] + fadingSteps[4] + fadingSteps[5] + - fadingSteps[6] + fadingSteps[7]; - fadeDiff = ((INT)(fadeStop - fadeStart) / fMax(fadingSteps_sum, (INT)1)); - fadingStations[0] = fadeStart; - for (i = 1; i < 8; i++) { - fadingStations[i] = - fadingStations[i - 1] + (FIXP_DBL)(fadeDiff * fadingSteps[i - 1]); - } - fadingStations[8] = fadeStop; -} - -static void CConcealment_TDFading_doLinearFadingSteps(int *fadingSteps) { - fadingSteps[0] = fadingSteps[1] = fadingSteps[2] = fadingSteps[3] = - fadingSteps[4] = fadingSteps[5] = fadingSteps[6] = fadingSteps[7] = 1; -} - -/* end of TimeDomainFading functions */ - -/* derived from int UsacRandomSign() */ -static int CConcealment_TDNoise_Random(ULONG *seed) { - *seed = (ULONG)(((UINT64)(*seed) * 69069) + 5); - return (int)(*seed); -} - -static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo, - const int len, FIXP_PCM *const pcmdata) { - FIXP_PCM *states = pConcealmentInfo->TDNoiseStates; - FIXP_PCM noiseVal; - FIXP_DBL noiseValLong; - FIXP_SGL *coef = pConcealmentInfo->TDNoiseCoef; - FIXP_DBL TDNoiseAtt; - ULONG seed = pConcealmentInfo->TDNoiseSeed = - (ULONG)CConcealment_TDNoise_Random(&pConcealmentInfo->TDNoiseSeed) + 1; - - TDNoiseAtt = pConcealmentInfo->pConcealParams->comfortNoiseLevel; - - int ii; - - if ((pConcealmentInfo->concealState != ConcealState_Ok || - pConcealmentInfo->concealState_old != ConcealState_Ok) && - TDNoiseAtt != (FIXP_DBL)0) { - for (ii = 0; ii < (len << 3); ii++) { - /* create filtered noise */ - states[2] = states[1]; - states[1] = states[0]; - states[0] = ((FIXP_PCM)CConcealment_TDNoise_Random(&seed)); - noiseValLong = fMult(states[0], coef[0]) + fMult(states[1], coef[1]) + - fMult(states[2], coef[2]); - noiseVal = FX_DBL2FX_PCM(fMult(noiseValLong, TDNoiseAtt)); - - /* add filtered noise - check for clipping, before */ - if (noiseVal > (FIXP_PCM)0 && - pcmdata[ii] > (FIXP_PCM)MAXVAL_FIXP_PCM - noiseVal) { - noiseVal = noiseVal * (FIXP_PCM)-1; - } else if (noiseVal < (FIXP_PCM)0 && - pcmdata[ii] < (FIXP_PCM)MINVAL_FIXP_PCM - noiseVal) { - noiseVal = noiseVal * (FIXP_PCM)-1; - } - - pcmdata[ii] += noiseVal; - } - } -} --- a/libAACdec/src/conceal.h +++ /dev/null @@ -1,152 +0,0 @@ -/* ----------------------------------------------------------------------------- -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: independent channel concealment - -*******************************************************************************/ - -#ifndef CONCEAL_H -#define CONCEAL_H - -#include "channelinfo.h" - -#define AACDEC_CONCEAL_PARAM_NOT_SPECIFIED (0xFFFE) - -void CConcealment_InitCommonData(CConcealParams *pConcealCommonData); - -void CConcealment_InitChannelData(CConcealmentInfo *hConcealmentInfo, - CConcealParams *pConcealCommonData, - AACDEC_RENDER_MODE initRenderMode, - int samplesPerFrame); - -CConcealmentMethod CConcealment_GetMethod(CConcealParams *pConcealCommonData); - -UINT CConcealment_GetDelay(CConcealParams *pConcealCommonData); - -AAC_DECODER_ERROR -CConcealment_SetParams(CConcealParams *concealParams, int method, - int fadeOutSlope, int fadeInSlope, int muteRelease, - FIXP_DBL comfNoiseLevel); - -CConcealmentState CConcealment_GetState(CConcealmentInfo *hConcealmentInfo); - -AAC_DECODER_ERROR -CConcealment_SetAttenuation(CConcealParams *concealParams, - const SHORT *fadeOutAttenuationVector, - const SHORT *fadeInAttenuationVector); - -void CConcealment_Store( - CConcealmentInfo *hConcealmentInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo); - -int CConcealment_Apply( - CConcealmentInfo *hConcealmentInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame, - const UCHAR lastLpdMode, const int FrameOk, const UINT flags); - -int CConcealment_GetLastFrameOk(CConcealmentInfo *hConcealmentInfo, - const int fBeforeApply); - -INT CConcealment_TDFading( - int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo, - FIXP_PCM *pcmdata, FIXP_PCM *pcmdata_1); - -#endif /* #ifndef CONCEAL_H */ --- a/libAACdec/src/conceal_types.h +++ /dev/null @@ -1,203 +0,0 @@ -/* ----------------------------------------------------------------------------- -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): Christian Griebel - - Description: Error concealment structs and types - -*******************************************************************************/ - -#ifndef CONCEAL_TYPES_H -#define CONCEAL_TYPES_H - -#include "machine_type.h" -#include "common_fix.h" - -#include "rvlc_info.h" - -#include "usacdec_lpc.h" - -#define CONCEAL_MAX_NUM_FADE_FACTORS (32) - -#define FIXP_CNCL FIXP_DBL -#define FL2FXCONST_CNCL FL2FXCONST_DBL -#define FX_DBL2FX_CNCL -#define FX_CNCL2FX_DBL -#define CNCL_FRACT_BITS DFRACT_BITS - -/* Warning: Do not ever change these values. */ -typedef enum { - ConcealMethodNone = -1, - ConcealMethodMute = 0, - ConcealMethodNoise = 1, - ConcealMethodInter = 2, - ConcealMethodTonal = 3 - -} CConcealmentMethod; - -typedef enum { - ConcealState_Ok, - ConcealState_Single, - ConcealState_FadeIn, - ConcealState_Mute, - ConcealState_FadeOut - -} CConcealmentState; - -typedef struct { - FIXP_SGL fadeOutFactor[CONCEAL_MAX_NUM_FADE_FACTORS]; - FIXP_SGL fadeInFactor[CONCEAL_MAX_NUM_FADE_FACTORS]; - - CConcealmentMethod method; - - int numFadeOutFrames; - int numFadeInFrames; - int numMuteReleaseFrames; - FIXP_DBL comfortNoiseLevel; - -} CConcealParams; - -typedef enum { - FADE_TIMEDOMAIN_TOSPECTRALMUTE = 1, - FADE_TIMEDOMAIN_FROMSPECTRALMUTE, - FADE_TIMEDOMAIN -} TDfadingType; - -typedef struct { - CConcealParams *pConcealParams; - - FIXP_CNCL spectralCoefficient[1024]; - SHORT specScale[8]; - - INT iRandomPhase; - INT prevFrameOk[2]; - INT cntValidFrames; - INT cntFadeFrames; /* State for signal fade-in/out */ - /* States for signal fade-out of frames with more than one window/subframe - - [0] used by Update CntFadeFrames mode of CConcealment_ApplyFadeOut, [1] used - by FadeOut mode */ - int winGrpOffset[2]; /* State for signal fade-out of frames with more than one - window/subframe */ - int attGrpOffset[2]; /* State for faster signal fade-out of frames with - transient signal parts */ - - SCHAR lastRenderMode; - - UCHAR windowShape; - BLOCK_TYPE windowSequence; - UCHAR lastWinGrpLen; - - CConcealmentState concealState; - CConcealmentState concealState_old; - FIXP_DBL fade_old; /* last fading factor */ - TDfadingType lastFadingType; /* last fading type */ - - SHORT aRvlcPreviousScaleFactor[RVLC_MAX_SFB]; /* needed once per channel */ - UCHAR aRvlcPreviousCodebook[RVLC_MAX_SFB]; /* needed once per channel */ - SCHAR rvlcPreviousScaleFactorOK; - SCHAR rvlcPreviousBlockType; - - FIXP_LPC lsf4[M_LP_FILTER_ORDER]; - FIXP_DBL last_tcx_gain; - INT last_tcx_gain_e; - ULONG TDNoiseSeed; - FIXP_PCM TDNoiseStates[3]; - FIXP_SGL TDNoiseCoef[3]; - FIXP_SGL TDNoiseAtt; - -} CConcealmentInfo; - -#endif /* #ifndef CONCEAL_TYPES_H */ --- a/libAACdec/src/rvlc.cpp +++ /dev/null @@ -1,1217 +0,0 @@ -/* ----------------------------------------------------------------------------- -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): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief RVLC Decoder - \author Robert Weidner -*/ - -#include "rvlc.h" - -#include "block.h" - -#include "aac_rom.h" -#include "rvlcbit.h" -#include "rvlcconceal.h" -#include "aacdec_hcr.h" - -/*--------------------------------------------------------------------------------------------- - function: rvlcInit - - description: init RVLC by data from channelinfo, which was decoded -previously and set up pointers ------------------------------------------------------------------------------------------------ - input: - pointer rvlc structure - - pointer channel info structure - - pointer bitstream structure ------------------------------------------------------------------------------------------------ - return: - --------------------------------------------------------------------------------------------- -*/ - -static void rvlcInit(CErRvlcInfo *pRvlc, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - HANDLE_FDK_BITSTREAM bs) { - /* RVLC common initialization part 2 of 2 */ - SHORT *pScfEsc = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc; - SHORT *pScfFwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd; - SHORT *pScfBwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd; - SHORT *pScaleFactor = pAacDecoderChannelInfo->pDynData->aScaleFactor; - int bnds; - - pAacDecoderChannelInfo->pDynData->specificTo.aac.rvlcIntensityUsed = 0; - - pRvlc->numDecodedEscapeWordsEsc = 0; - pRvlc->numDecodedEscapeWordsFwd = 0; - pRvlc->numDecodedEscapeWordsBwd = 0; - - pRvlc->intensity_used = 0; - pRvlc->errorLogRvlc = 0; - - pRvlc->conceal_max = CONCEAL_MAX_INIT; - pRvlc->conceal_min = CONCEAL_MIN_INIT; - - pRvlc->conceal_max_esc = CONCEAL_MAX_INIT; - pRvlc->conceal_min_esc = CONCEAL_MIN_INIT; - - pRvlc->pHuffTreeRvlcEscape = aHuffTreeRvlcEscape; - pRvlc->pHuffTreeRvlCodewds = aHuffTreeRvlCodewds; - - /* init scf arrays (for savety (in case of there are only zero codebooks)) */ - for (bnds = 0; bnds < RVLC_MAX_SFB; bnds++) { - pScfFwd[bnds] = 0; - pScfBwd[bnds] = 0; - pScfEsc[bnds] = 0; - pScaleFactor[bnds] = 0; - } - - /* set base bitstream ptr to the RVL-coded part (start of RVLC data (ESC 2)) - */ - FDKsyncCache(bs); - pRvlc->bsAnchor = (INT)FDKgetValidBits(bs); - - pRvlc->bitstreamIndexRvlFwd = - 0; /* first bit within RVL coded block as start address for forward - decoding */ - pRvlc->bitstreamIndexRvlBwd = - pRvlc->length_of_rvlc_sf - 1; /* last bit within RVL coded block as start - address for backward decoding */ - - /* skip RVLC-bitstream-part -- pointing now to escapes (if present) or to TNS - * data (if present) */ - FDKpushFor(bs, pRvlc->length_of_rvlc_sf); - - if (pRvlc->sf_escapes_present != 0) { - /* locate internal bitstream ptr at escapes (which is the second part) */ - FDKsyncCache(bs); - pRvlc->bitstreamIndexEsc = pRvlc->bsAnchor - (INT)FDKgetValidBits(bs); - - /* skip escapeRVLC-bitstream-part -- pointing to TNS data (if present) to - * make decoder continue */ - /* decoding of RVLC should work despite this second pushFor during - * initialization because */ - /* bitstream initialization is valid for both ESC2 data parts (RVL-coded - * values and ESC-coded values) */ - FDKpushFor(bs, pRvlc->length_of_rvlc_escapes); - } -} - -/*--------------------------------------------------------------------------------------------- - function: rvlcCheckIntensityCb - - description: Check if a intensity codebook is used in the current channel. ------------------------------------------------------------------------------------------------ - input: - pointer rvlc structure - - pointer channel info structure ------------------------------------------------------------------------------------------------ - output: - intensity_used: 0 no intensity codebook is used - 1 intensity codebook is used ------------------------------------------------------------------------------------------------ - return: - --------------------------------------------------------------------------------------------- -*/ - -static void rvlcCheckIntensityCb( - CErRvlcInfo *pRvlc, CAacDecoderChannelInfo *pAacDecoderChannelInfo) { - int group, band, bnds; - - pRvlc->intensity_used = 0; - - for (group = 0; group < pRvlc->numWindowGroups; group++) { - for (band = 0; band < pRvlc->maxSfbTransmitted; band++) { - bnds = 16 * group + band; - if ((pAacDecoderChannelInfo->pDynData->aCodeBook[bnds] == - INTENSITY_HCB) || - (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds] == - INTENSITY_HCB2)) { - pRvlc->intensity_used = 1; - break; - } - } - } -} - -/*--------------------------------------------------------------------------------------------- - function: rvlcDecodeEscapeWord - - description: Decode a huffman coded RVLC Escape-word. This value is part -of a DPCM coded scalefactor. ------------------------------------------------------------------------------------------------ - input: - pointer rvlc structure ------------------------------------------------------------------------------------------------ - return: - a single RVLC-Escape value which had to be applied to a -DPCM value (which has a absolute value of 7) --------------------------------------------------------------------------------------------- -*/ - -static SCHAR rvlcDecodeEscapeWord(CErRvlcInfo *pRvlc, HANDLE_FDK_BITSTREAM bs) { - int i; - SCHAR value; - UCHAR carryBit; - UINT treeNode; - UINT branchValue; - UINT branchNode; - - INT *pBitstreamIndexEsc; - const UINT *pEscTree; - - pEscTree = pRvlc->pHuffTreeRvlcEscape; - pBitstreamIndexEsc = &(pRvlc->bitstreamIndexEsc); - treeNode = *pEscTree; /* init at starting node */ - - for (i = MAX_LEN_RVLC_ESCAPE_WORD - 1; i >= 0; i--) { - carryBit = - rvlcReadBitFromBitstream(bs, /* get next bit */ - pRvlc->bsAnchor, pBitstreamIndexEsc, FWD); - - CarryBitToBranchValue(carryBit, /* huffman decoding, do a single step in - huffman decoding tree */ - treeNode, &branchValue, &branchNode); - - if ((branchNode & TEST_BIT_10) == - TEST_BIT_10) { /* test bit 10 ; if set --> a RVLC-escape-word is - completely decoded */ - value = (SCHAR)branchNode & CLR_BIT_10; - pRvlc->length_of_rvlc_escapes -= (MAX_LEN_RVLC_ESCAPE_WORD - i); - - if (pRvlc->length_of_rvlc_escapes < 0) { - pRvlc->errorLogRvlc |= RVLC_ERROR_ALL_ESCAPE_WORDS_INVALID; - value = -1; - } - - return value; - } else { - treeNode = *( - pEscTree + - branchValue); /* update treeNode for further step in decoding tree */ - } - } - - pRvlc->errorLogRvlc |= RVLC_ERROR_ALL_ESCAPE_WORDS_INVALID; - - return -1; /* should not be reached */ -} - -/*--------------------------------------------------------------------------------------------- - function: rvlcDecodeEscapes - - description: Decodes all huffman coded RVLC Escape Words. - Here a difference to the pseudo-code-implementation from -standard can be found. A while loop (and not two nested for loops) is used for -two reasons: - - 1. The plain huffman encoded escapes are decoded before the -RVL-coded scalefactors. Therefore the escapes are present in the second step - when decoding the RVL-coded-scalefactor values in forward -and backward direction. - - When the RVL-coded scalefactors are decoded and there a -escape is needed, then it is just taken out of the array in ascending order. - - 2. It's faster. ------------------------------------------------------------------------------------------------ - input: - pointer rvlc structure - - handle to FDK bitstream ------------------------------------------------------------------------------------------------ - return: - 0 ok the decoded escapes seem to be valid - - 1 error there was a error detected during decoding escapes - --> all escapes are invalid --------------------------------------------------------------------------------------------- -*/ - -static void rvlcDecodeEscapes(CErRvlcInfo *pRvlc, SHORT *pEsc, - HANDLE_FDK_BITSTREAM bs) { - SCHAR escWord; - SCHAR escCnt = 0; - SHORT *pEscBitCntSum; - - pEscBitCntSum = &(pRvlc->length_of_rvlc_escapes); - - /* Decode all RVLC-Escape words with a plain Huffman-Decoder */ - while (*pEscBitCntSum > 0) { - escWord = rvlcDecodeEscapeWord(pRvlc, bs); - - if (escWord >= 0) { - pEsc[escCnt] = escWord; - escCnt++; - } else { - pRvlc->errorLogRvlc |= RVLC_ERROR_ALL_ESCAPE_WORDS_INVALID; - pRvlc->numDecodedEscapeWordsEsc = escCnt; - - return; - } - } /* all RVLC escapes decoded */ - - pRvlc->numDecodedEscapeWordsEsc = escCnt; -} - -/*--------------------------------------------------------------------------------------------- - function: decodeRVLCodeword - - description: Decodes a RVL-coded dpcm-word (-part). ------------------------------------------------------------------------------------------------ - input: - FDK bitstream handle - - pointer rvlc structure ------------------------------------------------------------------------------------------------ - return: - a dpcm value which is within range [0,1,..,14] in case of -no errors. The offset of 7 must be subtracted to get a valid dpcm scalefactor -value. In case of errors a forbidden codeword is detected --> returning -1 --------------------------------------------------------------------------------------------- -*/ - -SCHAR decodeRVLCodeword(HANDLE_FDK_BITSTREAM bs, CErRvlcInfo *pRvlc) { - int i; - SCHAR value; - UCHAR carryBit; - UINT branchValue; - UINT branchNode; - - const UINT *pRvlCodeTree = pRvlc->pHuffTreeRvlCodewds; - UCHAR direction = pRvlc->direction; - INT *pBitstrIndxRvl = pRvlc->pBitstrIndxRvl_RVL; - UINT treeNode = *pRvlCodeTree; - - for (i = MAX_LEN_RVLC_CODE_WORD - 1; i >= 0; i--) { - carryBit = - rvlcReadBitFromBitstream(bs, /* get next bit */ - pRvlc->bsAnchor, pBitstrIndxRvl, direction); - - CarryBitToBranchValue(carryBit, /* huffman decoding, do a single step in - huffman decoding tree */ - treeNode, &branchValue, &branchNode); - - if ((branchNode & TEST_BIT_10) == - TEST_BIT_10) { /* test bit 10 ; if set --> a - RVLC-codeword is completely decoded - */ - value = (SCHAR)(branchNode & CLR_BIT_10); - *pRvlc->pRvlBitCnt_RVL -= (MAX_LEN_RVLC_CODE_WORD - i); - - /* check available bits for decoding */ - if (*pRvlc->pRvlBitCnt_RVL < 0) { - if (direction == FWD) { - pRvlc->errorLogRvlc |= RVLC_ERROR_RVL_SUM_BIT_COUNTER_BELOW_ZERO_FWD; - } else { - pRvlc->errorLogRvlc |= RVLC_ERROR_RVL_SUM_BIT_COUNTER_BELOW_ZERO_BWD; - } - value = -1; /* signalize an error in return value, because too many bits - was decoded */ - } - - /* check max value of dpcm value */ - if (value > MAX_ALLOWED_DPCM_INDEX) { - if (direction == FWD) { - pRvlc->errorLogRvlc |= RVLC_ERROR_FORBIDDEN_CW_DETECTED_FWD; - } else { - pRvlc->errorLogRvlc |= RVLC_ERROR_FORBIDDEN_CW_DETECTED_BWD; - } - value = -1; /* signalize an error in return value, because a forbidden - cw was detected*/ - } - - return value; /* return a dpcm value with offset +7 or an error status */ - } else { - treeNode = *( - pRvlCodeTree + - branchValue); /* update treeNode for further step in decoding tree */ - } - } - - return -1; -} - -/*--------------------------------------------------------------------------------------------- - function: rvlcDecodeForward - - description: Decode RVL-coded codewords in forward direction. ------------------------------------------------------------------------------------------------ - input: - pointer rvlc structure - - pointer channel info structure - - handle to FDK bitstream ------------------------------------------------------------------------------------------------ - return: - --------------------------------------------------------------------------------------------- -*/ - -static void rvlcDecodeForward(CErRvlcInfo *pRvlc, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - HANDLE_FDK_BITSTREAM bs) { - int band = 0; - int group = 0; - int bnds = 0; - - SHORT dpcm; - - SHORT factor = - pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - SF_OFFSET; - SHORT position = -SF_OFFSET; - SHORT noisenrg = pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - - SF_OFFSET - 90 - 256; - - SHORT *pScfFwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd; - SHORT *pScfEsc = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc; - UCHAR *pEscFwdCnt = &(pRvlc->numDecodedEscapeWordsFwd); - - pRvlc->pRvlBitCnt_RVL = &(pRvlc->length_of_rvlc_sf_fwd); - pRvlc->pBitstrIndxRvl_RVL = &(pRvlc->bitstreamIndexRvlFwd); - - *pEscFwdCnt = 0; - pRvlc->direction = FWD; - pRvlc->noise_used = 0; - pRvlc->sf_used = 0; - pRvlc->lastScf = 0; - pRvlc->lastNrg = 0; - pRvlc->lastIs = 0; - - rvlcCheckIntensityCb(pRvlc, pAacDecoderChannelInfo); - - /* main loop fwd long */ - for (group = 0; group < pRvlc->numWindowGroups; group++) { - for (band = 0; band < pRvlc->maxSfbTransmitted; band++) { - bnds = 16 * group + band; - - switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) { - case ZERO_HCB: - pScfFwd[bnds] = 0; - break; - - case INTENSITY_HCB2: - case INTENSITY_HCB: - /* store dpcm_is_position */ - dpcm = decodeRVLCodeword(bs, pRvlc); - if (dpcm < 0) { - pRvlc->conceal_max = bnds; - return; - } - dpcm -= TABLE_OFFSET; - if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) { - if (pRvlc->length_of_rvlc_escapes) { - pRvlc->conceal_max = bnds; - return; - } else { - if (dpcm == MIN_RVL) { - dpcm -= *pScfEsc++; - } else { - dpcm += *pScfEsc++; - } - (*pEscFwdCnt)++; - if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) { - pRvlc->conceal_max_esc = bnds; - } - } - } - position += dpcm; - pScfFwd[bnds] = position; - pRvlc->lastIs = position; - break; - - case NOISE_HCB: - if (pRvlc->noise_used == 0) { - pRvlc->noise_used = 1; - pRvlc->first_noise_band = bnds; - noisenrg += pRvlc->dpcm_noise_nrg; - pScfFwd[bnds] = 100 + noisenrg; - pRvlc->lastNrg = noisenrg; - } else { - dpcm = decodeRVLCodeword(bs, pRvlc); - if (dpcm < 0) { - pRvlc->conceal_max = bnds; - return; - } - dpcm -= TABLE_OFFSET; - if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) { - if (pRvlc->length_of_rvlc_escapes) { - pRvlc->conceal_max = bnds; - return; - } else { - if (dpcm == MIN_RVL) { - dpcm -= *pScfEsc++; - } else { - dpcm += *pScfEsc++; - } - (*pEscFwdCnt)++; - if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) { - pRvlc->conceal_max_esc = bnds; - } - } - } - noisenrg += dpcm; - pScfFwd[bnds] = 100 + noisenrg; - pRvlc->lastNrg = noisenrg; - } - pAacDecoderChannelInfo->data.aac.PnsData.pnsUsed[bnds] = 1; - break; - - default: - pRvlc->sf_used = 1; - dpcm = decodeRVLCodeword(bs, pRvlc); - if (dpcm < 0) { - pRvlc->conceal_max = bnds; - return; - } - dpcm -= TABLE_OFFSET; - if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) { - if (pRvlc->length_of_rvlc_escapes) { - pRvlc->conceal_max = bnds; - return; - } else { - if (dpcm == MIN_RVL) { - dpcm -= *pScfEsc++; - } else { - dpcm += *pScfEsc++; - } - (*pEscFwdCnt)++; - if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) { - pRvlc->conceal_max_esc = bnds; - } - } - } - factor += dpcm; - pScfFwd[bnds] = factor; - pRvlc->lastScf = factor; - break; - } - } - } - - /* postfetch fwd long */ - if (pRvlc->intensity_used) { - dpcm = decodeRVLCodeword(bs, pRvlc); /* dpcm_is_last_position */ - if (dpcm < 0) { - pRvlc->conceal_max = bnds; - return; - } - dpcm -= TABLE_OFFSET; - if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) { - if (pRvlc->length_of_rvlc_escapes) { - pRvlc->conceal_max = bnds; - return; - } else { - if (dpcm == MIN_RVL) { - dpcm -= *pScfEsc++; - } else { - dpcm += *pScfEsc++; - } - (*pEscFwdCnt)++; - if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) { - pRvlc->conceal_max_esc = bnds; - } - } - } - pRvlc->dpcm_is_last_position = dpcm; - } -} - -/*--------------------------------------------------------------------------------------------- - function: rvlcDecodeBackward - - description: Decode RVL-coded codewords in backward direction. ------------------------------------------------------------------------------------------------ - input: - pointer rvlc structure - - pointer channel info structure - - handle FDK bitstream ------------------------------------------------------------------------------------------------ - return: - --------------------------------------------------------------------------------------------- -*/ - -static void rvlcDecodeBackward(CErRvlcInfo *pRvlc, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - HANDLE_FDK_BITSTREAM bs) { - SHORT band, group, dpcm, offset; - SHORT bnds = pRvlc->maxSfbTransmitted - 1; - - SHORT factor = pRvlc->rev_global_gain - SF_OFFSET; - SHORT position = pRvlc->dpcm_is_last_position - SF_OFFSET; - SHORT noisenrg = pRvlc->rev_global_gain + pRvlc->dpcm_noise_last_position - - SF_OFFSET - 90 - 256; - - SHORT *pScfBwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd; - SHORT *pScfEsc = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc; - UCHAR *pEscEscCnt = &(pRvlc->numDecodedEscapeWordsEsc); - UCHAR *pEscBwdCnt = &(pRvlc->numDecodedEscapeWordsBwd); - - pRvlc->pRvlBitCnt_RVL = &(pRvlc->length_of_rvlc_sf_bwd); - pRvlc->pBitstrIndxRvl_RVL = &(pRvlc->bitstreamIndexRvlBwd); - - *pEscBwdCnt = 0; - pRvlc->direction = BWD; - pScfEsc += *pEscEscCnt - 1; /* set pScfEsc to last entry */ - pRvlc->firstScf = 0; - pRvlc->firstNrg = 0; - pRvlc->firstIs = 0; - - /* prefetch long BWD */ - if (pRvlc->intensity_used) { - dpcm = decodeRVLCodeword(bs, pRvlc); /* dpcm_is_last_position */ - if (dpcm < 0) { - pRvlc->dpcm_is_last_position = 0; - pRvlc->conceal_min = bnds; - return; - } - dpcm -= TABLE_OFFSET; - if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) { - if (pRvlc->length_of_rvlc_escapes) { - pRvlc->conceal_min = bnds; - return; - } else { - if (dpcm == MIN_RVL) { - dpcm -= *pScfEsc--; - } else { - dpcm += *pScfEsc--; - } - (*pEscBwdCnt)++; - if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) { - pRvlc->conceal_min_esc = bnds; - } - } - } - pRvlc->dpcm_is_last_position = dpcm; - } - - /* main loop long BWD */ - for (group = pRvlc->numWindowGroups - 1; group >= 0; group--) { - for (band = pRvlc->maxSfbTransmitted - 1; band >= 0; band--) { - bnds = 16 * group + band; - if ((band == 0) && (pRvlc->numWindowGroups != 1)) - offset = 16 - pRvlc->maxSfbTransmitted + 1; - else - offset = 1; - - switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) { - case ZERO_HCB: - pScfBwd[bnds] = 0; - break; - - case INTENSITY_HCB2: - case INTENSITY_HCB: - /* store dpcm_is_position */ - dpcm = decodeRVLCodeword(bs, pRvlc); - if (dpcm < 0) { - pScfBwd[bnds] = position; - pRvlc->conceal_min = fMax(0, bnds - offset); - return; - } - dpcm -= TABLE_OFFSET; - if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) { - if (pRvlc->length_of_rvlc_escapes) { - pScfBwd[bnds] = position; - pRvlc->conceal_min = fMax(0, bnds - offset); - return; - } else { - if (dpcm == MIN_RVL) { - dpcm -= *pScfEsc--; - } else { - dpcm += *pScfEsc--; - } - (*pEscBwdCnt)++; - if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) { - pRvlc->conceal_min_esc = fMax(0, bnds - offset); - } - } - } - pScfBwd[bnds] = position; - position -= dpcm; - pRvlc->firstIs = position; - break; - - case NOISE_HCB: - if (bnds == pRvlc->first_noise_band) { - pScfBwd[bnds] = - pRvlc->dpcm_noise_nrg + - pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - - SF_OFFSET - 90 - 256; - pRvlc->firstNrg = pScfBwd[bnds]; - } else { - dpcm = decodeRVLCodeword(bs, pRvlc); - if (dpcm < 0) { - pScfBwd[bnds] = noisenrg; - pRvlc->conceal_min = fMax(0, bnds - offset); - return; - } - dpcm -= TABLE_OFFSET; - if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) { - if (pRvlc->length_of_rvlc_escapes) { - pScfBwd[bnds] = noisenrg; - pRvlc->conceal_min = fMax(0, bnds - offset); - return; - } else { - if (dpcm == MIN_RVL) { - dpcm -= *pScfEsc--; - } else { - dpcm += *pScfEsc--; - } - (*pEscBwdCnt)++; - if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) { - pRvlc->conceal_min_esc = fMax(0, bnds - offset); - } - } - } - pScfBwd[bnds] = noisenrg; - noisenrg -= dpcm; - pRvlc->firstNrg = noisenrg; - } - break; - - default: - dpcm = decodeRVLCodeword(bs, pRvlc); - if (dpcm < 0) { - pScfBwd[bnds] = factor; - pRvlc->conceal_min = fMax(0, bnds - offset); - return; - } - dpcm -= TABLE_OFFSET; - if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) { - if (pRvlc->length_of_rvlc_escapes) { - pScfBwd[bnds] = factor; - pRvlc->conceal_min = fMax(0, bnds - offset); - return; - } else { - if (dpcm == MIN_RVL) { - dpcm -= *pScfEsc--; - } else { - dpcm += *pScfEsc--; - } - (*pEscBwdCnt)++; - if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) { - pRvlc->conceal_min_esc = fMax(0, bnds - offset); - } - } - } - pScfBwd[bnds] = factor; - factor -= dpcm; - pRvlc->firstScf = factor; - break; - } - } - } -} - -/*--------------------------------------------------------------------------------------------- - function: rvlcFinalErrorDetection - - description: Call RVLC concealment if error was detected in decoding -process ------------------------------------------------------------------------------------------------ - input: - pointer rvlc structure - - pointer channel info structure ------------------------------------------------------------------------------------------------ - return: - --------------------------------------------------------------------------------------------- -*/ - -static void rvlcFinalErrorDetection( - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) { - CErRvlcInfo *pRvlc = - &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo; - UCHAR ErrorStatusComplete = 0; - UCHAR ErrorStatusLengthFwd = 0; - UCHAR ErrorStatusLengthBwd = 0; - UCHAR ErrorStatusLengthEscapes = 0; - UCHAR ErrorStatusFirstScf = 0; - UCHAR ErrorStatusLastScf = 0; - UCHAR ErrorStatusFirstNrg = 0; - UCHAR ErrorStatusLastNrg = 0; - UCHAR ErrorStatusFirstIs = 0; - UCHAR ErrorStatusLastIs = 0; - UCHAR ErrorStatusForbiddenCwFwd = 0; - UCHAR ErrorStatusForbiddenCwBwd = 0; - UCHAR ErrorStatusNumEscapesFwd = 0; - UCHAR ErrorStatusNumEscapesBwd = 0; - UCHAR ConcealStatus = 1; - UCHAR currentBlockType; /* short: 0, not short: 1*/ - - pAacDecoderChannelInfo->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK = 1; - - /* invalid escape words, bit counter unequal zero, forbidden codeword detected - */ - if (pRvlc->errorLogRvlc & RVLC_ERROR_FORBIDDEN_CW_DETECTED_FWD) - ErrorStatusForbiddenCwFwd = 1; - - if (pRvlc->errorLogRvlc & RVLC_ERROR_FORBIDDEN_CW_DETECTED_BWD) - ErrorStatusForbiddenCwBwd = 1; - - /* bit counter forward unequal zero */ - if (pRvlc->length_of_rvlc_sf_fwd) ErrorStatusLengthFwd = 1; - - /* bit counter backward unequal zero */ - if (pRvlc->length_of_rvlc_sf_bwd) ErrorStatusLengthBwd = 1; - - /* bit counter escape sequences unequal zero */ - if (pRvlc->sf_escapes_present) - if (pRvlc->length_of_rvlc_escapes) ErrorStatusLengthEscapes = 1; - - if (pRvlc->sf_used) { - /* first decoded scf does not match to global gain in backward direction */ - if (pRvlc->firstScf != - (pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - SF_OFFSET)) - ErrorStatusFirstScf = 1; - - /* last decoded scf does not match to rev global gain in forward direction - */ - if (pRvlc->lastScf != (pRvlc->rev_global_gain - SF_OFFSET)) - ErrorStatusLastScf = 1; - } - - if (pRvlc->noise_used) { - /* first decoded nrg does not match to dpcm_noise_nrg in backward direction - */ - if (pRvlc->firstNrg != - (pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain + - pRvlc->dpcm_noise_nrg - SF_OFFSET - 90 - 256)) - ErrorStatusFirstNrg = 1; - - /* last decoded nrg does not match to dpcm_noise_last_position in forward - * direction */ - if (pRvlc->lastNrg != - (pRvlc->rev_global_gain + pRvlc->dpcm_noise_last_position - SF_OFFSET - - 90 - 256)) - ErrorStatusLastNrg = 1; - } - - if (pRvlc->intensity_used) { - /* first decoded is position does not match in backward direction */ - if (pRvlc->firstIs != (-SF_OFFSET)) ErrorStatusFirstIs = 1; - - /* last decoded is position does not match in forward direction */ - if (pRvlc->lastIs != (pRvlc->dpcm_is_last_position - SF_OFFSET)) - ErrorStatusLastIs = 1; - } - - /* decoded escapes and used escapes in forward direction do not fit */ - if ((pRvlc->numDecodedEscapeWordsFwd != pRvlc->numDecodedEscapeWordsEsc) && - (pRvlc->conceal_max == CONCEAL_MAX_INIT)) { - ErrorStatusNumEscapesFwd = 1; - } - - /* decoded escapes and used escapes in backward direction do not fit */ - if ((pRvlc->numDecodedEscapeWordsBwd != pRvlc->numDecodedEscapeWordsEsc) && - (pRvlc->conceal_min == CONCEAL_MIN_INIT)) { - ErrorStatusNumEscapesBwd = 1; - } - - if (ErrorStatusLengthEscapes || - (((pRvlc->conceal_max == CONCEAL_MAX_INIT) && - (pRvlc->numDecodedEscapeWordsFwd != pRvlc->numDecodedEscapeWordsEsc) && - (ErrorStatusLastScf || ErrorStatusLastNrg || ErrorStatusLastIs)) - - && - - ((pRvlc->conceal_min == CONCEAL_MIN_INIT) && - (pRvlc->numDecodedEscapeWordsBwd != pRvlc->numDecodedEscapeWordsEsc) && - (ErrorStatusFirstScf || ErrorStatusFirstNrg || ErrorStatusFirstIs))) || - ((pRvlc->conceal_max == CONCEAL_MAX_INIT) && - ((pRvlc->rev_global_gain - SF_OFFSET - pRvlc->lastScf) < -15)) || - ((pRvlc->conceal_min == CONCEAL_MIN_INIT) && - ((pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - SF_OFFSET - - pRvlc->firstScf) < -15))) { - if ((pRvlc->conceal_max == CONCEAL_MAX_INIT) || - (pRvlc->conceal_min == CONCEAL_MIN_INIT)) { - pRvlc->conceal_max = 0; - pRvlc->conceal_min = fMax( - 0, (pRvlc->numWindowGroups - 1) * 16 + pRvlc->maxSfbTransmitted - 1); - } else { - pRvlc->conceal_max = fMin(pRvlc->conceal_max, pRvlc->conceal_max_esc); - pRvlc->conceal_min = fMax(pRvlc->conceal_min, pRvlc->conceal_min_esc); - } - } - - ErrorStatusComplete = ErrorStatusLastScf || ErrorStatusFirstScf || - ErrorStatusLastNrg || ErrorStatusFirstNrg || - ErrorStatusLastIs || ErrorStatusFirstIs || - ErrorStatusForbiddenCwFwd || - ErrorStatusForbiddenCwBwd || ErrorStatusLengthFwd || - ErrorStatusLengthBwd || ErrorStatusLengthEscapes || - ErrorStatusNumEscapesFwd || ErrorStatusNumEscapesBwd; - - currentBlockType = - (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) ? 0 - : 1; - - if (!ErrorStatusComplete) { - int band; - int group; - int bnds; - int lastSfbIndex; - - lastSfbIndex = (pRvlc->numWindowGroups > 1) ? 16 : 64; - - for (group = 0; group < pRvlc->numWindowGroups; group++) { - for (band = 0; band < pRvlc->maxSfbTransmitted; band++) { - bnds = 16 * group + band; - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = - pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousScaleFactor[bnds] = - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; - } - } - - for (group = 0; group < pRvlc->numWindowGroups; group++) { - for (band = 0; band < pRvlc->maxSfbTransmitted; band++) { - bnds = 16 * group + band; - pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousCodebook[bnds] = - pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]; - } - for (; band < lastSfbIndex; band++) { - bnds = 16 * group + band; - FDK_ASSERT(bnds >= 0 && bnds < RVLC_MAX_SFB); - pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousCodebook[bnds] = ZERO_HCB; - } - } - } else { - int band; - int group; - - /* A single bit error was detected in decoding of dpcm values. It also could - be an error with more bits in decoding of escapes and dpcm values whereby - an illegal codeword followed not directly after the corrupted bits but - just after decoding some more (wrong) scalefactors. Use the smaller - scalefactor from forward decoding, backward decoding and previous frame. - */ - if (((pRvlc->conceal_min != CONCEAL_MIN_INIT) || - (pRvlc->conceal_max != CONCEAL_MAX_INIT)) && - (pRvlc->conceal_min <= pRvlc->conceal_max) && - (pAacDecoderStaticChannelInfo->concealmentInfo.rvlcPreviousBlockType == - currentBlockType) && - pAacDecoderStaticChannelInfo->concealmentInfo - .rvlcPreviousScaleFactorOK && - pRvlc->sf_concealment && ConcealStatus) { - BidirectionalEstimation_UseScfOfPrevFrameAsReference( - pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo); - ConcealStatus = 0; - } - - /* A single bit error was detected in decoding of dpcm values. It also could - be an error with more bits in decoding of escapes and dpcm values whereby - an illegal codeword followed not directly after the corrupted bits but - just after decoding some more (wrong) scalefactors. Use the smaller - scalefactor from forward and backward decoding. */ - if ((pRvlc->conceal_min <= pRvlc->conceal_max) && - ((pRvlc->conceal_min != CONCEAL_MIN_INIT) || - (pRvlc->conceal_max != CONCEAL_MAX_INIT)) && - !(pAacDecoderStaticChannelInfo->concealmentInfo - .rvlcPreviousScaleFactorOK && - pRvlc->sf_concealment && - (pAacDecoderStaticChannelInfo->concealmentInfo - .rvlcPreviousBlockType == currentBlockType)) && - ConcealStatus) { - BidirectionalEstimation_UseLowerScfOfCurrentFrame(pAacDecoderChannelInfo); - ConcealStatus = 0; - } - - /* No errors were detected in decoding of escapes and dpcm values however - the first and last value of a group (is,nrg,sf) is incorrect */ - if ((pRvlc->conceal_min <= pRvlc->conceal_max) && - ((ErrorStatusLastScf && ErrorStatusFirstScf) || - (ErrorStatusLastNrg && ErrorStatusFirstNrg) || - (ErrorStatusLastIs && ErrorStatusFirstIs)) && - !(ErrorStatusForbiddenCwFwd || ErrorStatusForbiddenCwBwd || - ErrorStatusLengthEscapes) && - ConcealStatus) { - StatisticalEstimation(pAacDecoderChannelInfo); - ConcealStatus = 0; - } - - /* A error with more bits in decoding of escapes and dpcm values was - detected. Use the smaller scalefactor from forward decoding, backward - decoding and previous frame. */ - if ((pRvlc->conceal_min <= pRvlc->conceal_max) && - pAacDecoderStaticChannelInfo->concealmentInfo - .rvlcPreviousScaleFactorOK && - pRvlc->sf_concealment && - (pAacDecoderStaticChannelInfo->concealmentInfo.rvlcPreviousBlockType == - currentBlockType) && - ConcealStatus) { - PredictiveInterpolation(pAacDecoderChannelInfo, - pAacDecoderStaticChannelInfo); - ConcealStatus = 0; - } - - /* Call frame concealment, because no better strategy was found. Setting the - scalefactors to zero is done for debugging purposes */ - if (ConcealStatus) { - for (group = 0; group < pRvlc->numWindowGroups; group++) { - for (band = 0; band < pRvlc->maxSfbTransmitted; band++) { - pAacDecoderChannelInfo->pDynData->aScaleFactor[16 * group + band] = 0; - } - } - pAacDecoderChannelInfo->pDynData->specificTo.aac - .rvlcCurrentScaleFactorOK = 0; - } - } -} - -/*--------------------------------------------------------------------------------------------- - function: CRvlc_Read - - description: Read RVLC ESC1 data (side info) from bitstream. ------------------------------------------------------------------------------------------------ - input: - pointer rvlc structure - - pointer channel info structure - - pointer bitstream structure ------------------------------------------------------------------------------------------------ - return: - --------------------------------------------------------------------------------------------- -*/ - -void CRvlc_Read(CAacDecoderChannelInfo *pAacDecoderChannelInfo, - HANDLE_FDK_BITSTREAM bs) { - CErRvlcInfo *pRvlc = - &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo; - - int group, band; - - /* RVLC long specific initialization Init part 1 of 2 */ - pRvlc->numWindowGroups = GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); - pRvlc->maxSfbTransmitted = - GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo); - pRvlc->noise_used = 0; /* noise detection */ - pRvlc->dpcm_noise_nrg = 0; /* only for debugging */ - pRvlc->dpcm_noise_last_position = 0; /* only for debugging */ - pRvlc->length_of_rvlc_escapes = - -1; /* default value is used for error detection and concealment */ - - /* read only error sensitivity class 1 data (ESC 1 - data) */ - pRvlc->sf_concealment = FDKreadBits(bs, 1); /* #1 */ - pRvlc->rev_global_gain = FDKreadBits(bs, 8); /* #2 */ - - if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) { - pRvlc->length_of_rvlc_sf = FDKreadBits(bs, 11); /* #3 */ - } else { - pRvlc->length_of_rvlc_sf = FDKreadBits(bs, 9); /* #3 */ - } - - /* check if noise codebook is used */ - for (group = 0; group < pRvlc->numWindowGroups; group++) { - for (band = 0; band < pRvlc->maxSfbTransmitted; band++) { - if (pAacDecoderChannelInfo->pDynData->aCodeBook[16 * group + band] == - NOISE_HCB) { - pRvlc->noise_used = 1; - break; - } - } - } - - if (pRvlc->noise_used) - pRvlc->dpcm_noise_nrg = FDKreadBits(bs, 9); /* #4 PNS */ - - pRvlc->sf_escapes_present = FDKreadBits(bs, 1); /* #5 */ - - if (pRvlc->sf_escapes_present) { - pRvlc->length_of_rvlc_escapes = FDKreadBits(bs, 8); /* #6 */ - } - - if (pRvlc->noise_used) { - pRvlc->dpcm_noise_last_position = FDKreadBits(bs, 9); /* #7 PNS */ - pRvlc->length_of_rvlc_sf -= 9; - } - - pRvlc->length_of_rvlc_sf_fwd = pRvlc->length_of_rvlc_sf; - pRvlc->length_of_rvlc_sf_bwd = pRvlc->length_of_rvlc_sf; -} - -/*--------------------------------------------------------------------------------------------- - function: CRvlc_Decode - - description: Decode rvlc data - The function reads both the escape sequences and the -scalefactors in forward and backward direction. If an error occured during -decoding process which can not be concealed with the rvlc concealment frame -concealment will be initiated. Then the element "rvlcCurrentScaleFactorOK" in -the decoder channel info is set to 0 otherwise it is set to 1. ------------------------------------------------------------------------------------------------ - input: - pointer rvlc structure - - pointer channel info structure - - pointer to persistent channel info structure - - pointer bitstream structure ------------------------------------------------------------------------------------------------ - return: ErrorStatus = AAC_DEC_OK --------------------------------------------------------------------------------------------- -*/ - -void CRvlc_Decode(CAacDecoderChannelInfo *pAacDecoderChannelInfo, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - HANDLE_FDK_BITSTREAM bs) { - CErRvlcInfo *pRvlc = - &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo; - INT bitCntOffst; - INT saveBitCnt; - - rvlcInit(pRvlc, pAacDecoderChannelInfo, bs); - - /* save bitstream position */ - saveBitCnt = (INT)FDKgetValidBits(bs); - - if (pRvlc->sf_escapes_present) - rvlcDecodeEscapes( - pRvlc, pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc, bs); - - rvlcDecodeForward(pRvlc, pAacDecoderChannelInfo, bs); - rvlcDecodeBackward(pRvlc, pAacDecoderChannelInfo, bs); - rvlcFinalErrorDetection(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo); - - pAacDecoderChannelInfo->pDynData->specificTo.aac.rvlcIntensityUsed = - pRvlc->intensity_used; - pAacDecoderChannelInfo->data.aac.PnsData.PnsActive = pRvlc->noise_used; - - /* restore bitstream position */ - bitCntOffst = (INT)FDKgetValidBits(bs) - saveBitCnt; - if (bitCntOffst) { - FDKpushBiDirectional(bs, bitCntOffst); - } -} - -void CRvlc_ElementCheck( - CAacDecoderChannelInfo *pAacDecoderChannelInfo[], - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[], - const UINT flags, const INT elChannels) { - int ch; - - /* Required for MPS residuals. */ - if (pAacDecoderStaticChannelInfo == NULL) { - return; - } - - /* RVLC specific sanity checks */ - if ((flags & AC_ER_RVLC) && (elChannels == 2)) { /* to be reviewed */ - if (((pAacDecoderChannelInfo[0] - ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK == 0) || - (pAacDecoderChannelInfo[1] - ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK == 0)) && - pAacDecoderChannelInfo[0]->pComData->jointStereoData.MsMaskPresent) { - pAacDecoderChannelInfo[0] - ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK = 0; - pAacDecoderChannelInfo[1] - ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK = 0; - } - - if ((pAacDecoderChannelInfo[0] - ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK == 0) && - (pAacDecoderChannelInfo[1] - ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK == 1) && - (pAacDecoderChannelInfo[1] - ->pDynData->specificTo.aac.rvlcIntensityUsed == 1)) { - pAacDecoderChannelInfo[1] - ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK = 0; - } - } - - for (ch = 0; ch < elChannels; ch++) { - pAacDecoderStaticChannelInfo[ch]->concealmentInfo.rvlcPreviousBlockType = - (GetWindowSequence(&pAacDecoderChannelInfo[ch]->icsInfo) == BLOCK_SHORT) - ? 0 - : 1; - if (flags & AC_ER_RVLC) { - pAacDecoderStaticChannelInfo[ch] - ->concealmentInfo.rvlcPreviousScaleFactorOK = - pAacDecoderChannelInfo[ch] - ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK; - } else { - pAacDecoderStaticChannelInfo[ch] - ->concealmentInfo.rvlcPreviousScaleFactorOK = 0; - } - } -} --- a/libAACdec/src/rvlc.h +++ /dev/null @@ -1,153 +0,0 @@ -/* ----------------------------------------------------------------------------- -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): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Defines structures and prototypes for RVLC - \author Robert Weidner -*/ - -#ifndef RVLC_H -#define RVLC_H - -#include "aacdecoder.h" -#include "channel.h" -#include "rvlc_info.h" - -/* ------------------------------------------------------------------- */ -/* errorLogRvlc: A word of 32 bits used for logging possible errors */ -/* within RVLC in case of distorted bitstreams. */ -/* ------------------------------------------------------------------- */ -#define RVLC_ERROR_ALL_ESCAPE_WORDS_INVALID \ - 0x80000000 /* ESC-Dec During RVLC-Escape-decoding there have been more \ - bits decoded as there are available */ -#define RVLC_ERROR_RVL_SUM_BIT_COUNTER_BELOW_ZERO_FWD \ - 0x40000000 /* RVL-Dec negative sum-bitcounter during RVL-fwd-decoding \ - (long+shrt) */ -#define RVLC_ERROR_RVL_SUM_BIT_COUNTER_BELOW_ZERO_BWD \ - 0x20000000 /* RVL-Dec negative sum-bitcounter during RVL-fwd-decoding \ - (long+shrt) */ -#define RVLC_ERROR_FORBIDDEN_CW_DETECTED_FWD \ - 0x08000000 /* RVL-Dec forbidden codeword detected fwd (long+shrt) */ -#define RVLC_ERROR_FORBIDDEN_CW_DETECTED_BWD \ - 0x04000000 /* RVL-Dec forbidden codeword detected bwd (long+shrt) */ - -void CRvlc_Read(CAacDecoderChannelInfo *pAacDecoderChannelInfo, - HANDLE_FDK_BITSTREAM bs); - -void CRvlc_Decode(CAacDecoderChannelInfo *pAacDecoderChannelInfo, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - HANDLE_FDK_BITSTREAM bs); - -/** - * \brief performe sanity checks to the channel data corresponding to one - * channel element. - * \param pAacDecoderChannelInfo - * \param pAacDecoderStaticChannelInfo - * \param elChannels amount of channels of the channel element. - */ -void CRvlc_ElementCheck( - CAacDecoderChannelInfo *pAacDecoderChannelInfo[], - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[], - const UINT flags, const INT elChannels); - -#endif /* RVLC_H */ --- a/libAACdec/src/rvlc_info.h +++ /dev/null @@ -1,204 +0,0 @@ -/* ----------------------------------------------------------------------------- -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): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Defines structures for RVLC - \author Robert Weidner -*/ -#ifndef RVLC_INFO_H -#define RVLC_INFO_H - -#define FWD 0 /* bitstream decoding direction forward (RVL coded part) */ -#define BWD 1 /* bitstream decoding direction backward (RVL coded part) */ - -#define MAX_RVL 7 /* positive RVLC escape */ -#define MIN_RVL -7 /* negative RVLC escape */ -#define MAX_ALLOWED_DPCM_INDEX \ - 14 /* the maximum allowed index of a decoded dpcm value (offset \ - 'TABLE_OFFSET' incl --> must be subtracted) */ -#define TABLE_OFFSET \ - 7 /* dpcm offset of valid output values of rvl table decoding, the rvl table \ - ouly returns positive values, therefore the offset */ -#define MAX_LEN_RVLC_CODE_WORD 9 /* max length of a RVL codeword in bits */ -#define MAX_LEN_RVLC_ESCAPE_WORD \ - 20 /* max length of huffman coded RVLC escape word in bits */ - -#define DPCM_NOISE_NRG_BITS 9 -#define SF_OFFSET 100 /* offset for correcting scf value */ - -#define CONCEAL_MAX_INIT 1311 /* arbitrary value */ -#define CONCEAL_MIN_INIT -1311 /* arbitrary value */ - -#define RVLC_MAX_SFB ((8) * (16)) - -/* sideinfo of RVLC */ -typedef struct { - /* ------- ESC 1 Data: --------- */ /* order of RVLC-bitstream components in - bitstream (RVLC-initialization), every - component appears only once in - bitstream */ - INT sf_concealment; /* 1 */ - INT rev_global_gain; /* 2 */ - SHORT length_of_rvlc_sf; /* 3 */ /* original value, gets modified - (subtract 9) in case of noise - (PNS); is kept for later use */ - INT dpcm_noise_nrg; /* 4 optional */ - INT sf_escapes_present; /* 5 */ - SHORT length_of_rvlc_escapes; /* 6 optional */ - INT dpcm_noise_last_position; /* 7 optional */ - - INT dpcm_is_last_position; - - SHORT length_of_rvlc_sf_fwd; /* length_of_rvlc_sf used for forward decoding */ - SHORT - length_of_rvlc_sf_bwd; /* length_of_rvlc_sf used for backward decoding */ - - /* for RVL-Codeword decoder to distinguish between fwd and bwd decoding */ - SHORT *pRvlBitCnt_RVL; - INT *pBitstrIndxRvl_RVL; - - UCHAR numWindowGroups; - UCHAR maxSfbTransmitted; - UCHAR first_noise_group; - UCHAR first_noise_band; - UCHAR direction; - - /* bitstream indices */ - INT bsAnchor; /* hcr bit buffer reference index */ - INT bitstreamIndexRvlFwd; /* base address of RVL-coded-scalefactor data (ESC - 2) for forward decoding */ - INT bitstreamIndexRvlBwd; /* base address of RVL-coded-scalefactor data (ESC - 2) for backward decoding */ - INT bitstreamIndexEsc; /* base address where RVLC-escapes start (ESC 2) */ - - /* decoding trees */ - const UINT *pHuffTreeRvlCodewds; - const UINT *pHuffTreeRvlcEscape; - - /* escape counters */ - UCHAR numDecodedEscapeWordsFwd; /* when decoding RVL-codes forward */ - UCHAR numDecodedEscapeWordsBwd; /* when decoding RVL-codes backward */ - UCHAR numDecodedEscapeWordsEsc; /* when decoding the escape-Words */ - - SCHAR noise_used; - SCHAR intensity_used; - SCHAR sf_used; - - SHORT firstScf; - SHORT lastScf; - SHORT firstNrg; - SHORT lastNrg; - SHORT firstIs; - SHORT lastIs; - - /* ------ RVLC error detection ------ */ - UINT errorLogRvlc; /* store RVLC errors */ - SHORT conceal_min; /* is set at backward decoding */ - SHORT conceal_max; /* is set at forward decoding */ - SHORT conceal_min_esc; /* is set at backward decoding */ - SHORT conceal_max_esc; /* is set at forward decoding */ -} CErRvlcInfo; - -typedef CErRvlcInfo RVLC_INFO; /* temp */ - -#endif /* RVLC_INFO_H */ --- a/libAACdec/src/rvlcbit.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* ----------------------------------------------------------------------------- -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): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief RVLC bitstream reading - \author Robert Weidner -*/ - -#include "rvlcbit.h" - -/*--------------------------------------------------------------------------------------------- - function: rvlcReadBitFromBitstream - - description: This function returns a bit from the bitstream according to -read direction. It is called very often, therefore it makes sense to inline it -(runtime). ------------------------------------------------------------------------------------------------ - input: - bitstream - - pPosition - - readDirection ------------------------------------------------------------------------------------------------ - return: - bit from bitstream --------------------------------------------------------------------------------------------- -*/ - -UCHAR rvlcReadBitFromBitstream(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor, - INT *pPosition, UCHAR readDirection) { - UINT bit; - INT readBitOffset = (INT)FDKgetValidBits(bs) - bsAnchor + *pPosition; - - if (readBitOffset) { - FDKpushBiDirectional(bs, readBitOffset); - } - - if (readDirection == FWD) { - bit = FDKreadBits(bs, 1); - - *pPosition += 1; - } else { - /* to be replaced with a brother function of FDKreadBits() */ - bit = FDKreadBits(bs, 1); - FDKpushBack(bs, 2); - - *pPosition -= 1; - } - - return (bit); -} --- a/libAACdec/src/rvlcbit.h +++ /dev/null @@ -1,111 +0,0 @@ -/* ----------------------------------------------------------------------------- -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): Robert Weidner (DSP Solutions) - - Description: RVLC Decoder: Bitstream reading - -*******************************************************************************/ - -#ifndef RVLCBIT_H -#define RVLCBIT_H - -#include "rvlc.h" - -UCHAR rvlcReadBitFromBitstream(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor, - INT *pPosition, UCHAR readDirection); - -#endif /* RVLCBIT_H */ --- a/libAACdec/src/rvlcconceal.cpp +++ /dev/null @@ -1,787 +0,0 @@ -/* ----------------------------------------------------------------------------- -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): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief rvlc concealment - \author Josef Hoepfl -*/ - -#include "rvlcconceal.h" - -#include "block.h" -#include "rvlc.h" - -/*--------------------------------------------------------------------------------------------- - function: calcRefValFwd - - description: The function determines the scalefactor which is closed to the -scalefactorband conceal_min. The same is done for intensity data and noise -energies. ------------------------------------------------------------------------------------------------ - output: - reference value scf - - reference value internsity data - - reference value noise energy ------------------------------------------------------------------------------------------------ - return: - --------------------------------------------------------------------------------------------- -*/ - -static void calcRefValFwd(CErRvlcInfo *pRvlc, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - int *refIsFwd, int *refNrgFwd, int *refScfFwd) { - int band, bnds, group, startBand; - int idIs, idNrg, idScf; - int conceal_min, conceal_group_min; - int MaximumScaleFactorBands; - - if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) - MaximumScaleFactorBands = 16; - else - MaximumScaleFactorBands = 64; - - conceal_min = pRvlc->conceal_min % MaximumScaleFactorBands; - conceal_group_min = pRvlc->conceal_min / MaximumScaleFactorBands; - - /* calculate first reference value for approach in forward direction */ - idIs = idNrg = idScf = 1; - - /* set reference values */ - *refIsFwd = -SF_OFFSET; - *refNrgFwd = pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - - SF_OFFSET - 90 - 256; - *refScfFwd = - pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - SF_OFFSET; - - startBand = conceal_min - 1; - for (group = conceal_group_min; group >= 0; group--) { - for (band = startBand; band >= 0; band--) { - bnds = 16 * group + band; - switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) { - case ZERO_HCB: - break; - case INTENSITY_HCB: - case INTENSITY_HCB2: - if (idIs) { - *refIsFwd = - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; - idIs = 0; /* reference value has been set */ - } - break; - case NOISE_HCB: - if (idNrg) { - *refNrgFwd = - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; - idNrg = 0; /* reference value has been set */ - } - break; - default: - if (idScf) { - *refScfFwd = - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; - idScf = 0; /* reference value has been set */ - } - break; - } - } - startBand = pRvlc->maxSfbTransmitted - 1; - } -} - -/*--------------------------------------------------------------------------------------------- - function: calcRefValBwd - - description: The function determines the scalefactor which is closed to the -scalefactorband conceal_max. The same is done for intensity data and noise -energies. ------------------------------------------------------------------------------------------------ - output: - reference value scf - - reference value internsity data - - reference value noise energy ------------------------------------------------------------------------------------------------ - return: - --------------------------------------------------------------------------------------------- -*/ - -static void calcRefValBwd(CErRvlcInfo *pRvlc, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - int *refIsBwd, int *refNrgBwd, int *refScfBwd) { - int band, bnds, group, startBand; - int idIs, idNrg, idScf; - int conceal_max, conceal_group_max; - int MaximumScaleFactorBands; - - if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) - MaximumScaleFactorBands = 16; - else - MaximumScaleFactorBands = 64; - - conceal_max = pRvlc->conceal_max % MaximumScaleFactorBands; - conceal_group_max = pRvlc->conceal_max / MaximumScaleFactorBands; - - /* calculate first reference value for approach in backward direction */ - idIs = idNrg = idScf = 1; - - /* set reference values */ - *refIsBwd = pRvlc->dpcm_is_last_position - SF_OFFSET; - *refNrgBwd = pRvlc->rev_global_gain + pRvlc->dpcm_noise_last_position - - SF_OFFSET - 90 - 256 + pRvlc->dpcm_noise_nrg; - *refScfBwd = pRvlc->rev_global_gain - SF_OFFSET; - - startBand = conceal_max + 1; - - /* if needed, re-set reference values */ - for (group = conceal_group_max; group < pRvlc->numWindowGroups; group++) { - for (band = startBand; band < pRvlc->maxSfbTransmitted; band++) { - bnds = 16 * group + band; - switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) { - case ZERO_HCB: - break; - case INTENSITY_HCB: - case INTENSITY_HCB2: - if (idIs) { - *refIsBwd = - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]; - idIs = 0; /* reference value has been set */ - } - break; - case NOISE_HCB: - if (idNrg) { - *refNrgBwd = - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]; - idNrg = 0; /* reference value has been set */ - } - break; - default: - if (idScf) { - *refScfBwd = - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]; - idScf = 0; /* reference value has been set */ - } - break; - } - } - startBand = 0; - } -} - -/*--------------------------------------------------------------------------------------------- - function: BidirectionalEstimation_UseLowerScfOfCurrentFrame - - description: This approach by means of bidirectional estimation is generally -performed when a single bit error has been detected, the bit error can be -isolated between 'conceal_min' and 'conceal_max' and the 'sf_concealment' flag -is not set. The sets of scalefactors decoded in forward and backward direction -are compared with each other. The smaller scalefactor will be considered as the -correct one respectively. The reconstruction of the scalefactors with this -approach archieve good results in audio quality. The strategy must be applied to -scalefactors, intensity data and noise energy seperately. ------------------------------------------------------------------------------------------------ - output: Concealed scalefactor, noise energy and intensity data between -conceal_min and conceal_max ------------------------------------------------------------------------------------------------ - return: - --------------------------------------------------------------------------------------------- -*/ - -void BidirectionalEstimation_UseLowerScfOfCurrentFrame( - CAacDecoderChannelInfo *pAacDecoderChannelInfo) { - CErRvlcInfo *pRvlc = - &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo; - int band, bnds, startBand, endBand, group; - int conceal_min, conceal_max; - int conceal_group_min, conceal_group_max; - int MaximumScaleFactorBands; - - if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) { - MaximumScaleFactorBands = 16; - } else { - MaximumScaleFactorBands = 64; - } - - /* If an error was detected just in forward or backward direction, set the - corresponding border for concealment to a appropriate scalefactor band. The - border is set to first or last sfb respectively, because the error will - possibly not follow directly after the corrupt bit but just after decoding - some more (wrong) scalefactors. */ - if (pRvlc->conceal_min == CONCEAL_MIN_INIT) pRvlc->conceal_min = 0; - - if (pRvlc->conceal_max == CONCEAL_MAX_INIT) - pRvlc->conceal_max = - (pRvlc->numWindowGroups - 1) * 16 + pRvlc->maxSfbTransmitted - 1; - - conceal_min = pRvlc->conceal_min % MaximumScaleFactorBands; - conceal_group_min = pRvlc->conceal_min / MaximumScaleFactorBands; - conceal_max = pRvlc->conceal_max % MaximumScaleFactorBands; - conceal_group_max = pRvlc->conceal_max / MaximumScaleFactorBands; - - if (pRvlc->conceal_min == pRvlc->conceal_max) { - int refIsFwd, refNrgFwd, refScfFwd; - int refIsBwd, refNrgBwd, refScfBwd; - - bnds = pRvlc->conceal_min; - calcRefValFwd(pRvlc, pAacDecoderChannelInfo, &refIsFwd, &refNrgFwd, - &refScfFwd); - calcRefValBwd(pRvlc, pAacDecoderChannelInfo, &refIsBwd, &refNrgBwd, - &refScfBwd); - - switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) { - case ZERO_HCB: - break; - case INTENSITY_HCB: - case INTENSITY_HCB2: - if (refIsFwd < refIsBwd) - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refIsFwd; - else - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refIsBwd; - break; - case NOISE_HCB: - if (refNrgFwd < refNrgBwd) - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refNrgFwd; - else - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refNrgBwd; - break; - default: - if (refScfFwd < refScfBwd) - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refScfFwd; - else - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refScfBwd; - break; - } - } else { - pAacDecoderChannelInfo->pComData->overlay.aac - .aRvlcScfFwd[pRvlc->conceal_max] = - pAacDecoderChannelInfo->pComData->overlay.aac - .aRvlcScfBwd[pRvlc->conceal_max]; - pAacDecoderChannelInfo->pComData->overlay.aac - .aRvlcScfBwd[pRvlc->conceal_min] = - pAacDecoderChannelInfo->pComData->overlay.aac - .aRvlcScfFwd[pRvlc->conceal_min]; - - /* consider the smaller of the forward and backward decoded value as the - * correct one */ - startBand = conceal_min; - if (conceal_group_min == conceal_group_max) - endBand = conceal_max; - else - endBand = pRvlc->maxSfbTransmitted - 1; - - for (group = conceal_group_min; group <= conceal_group_max; group++) { - for (band = startBand; band <= endBand; band++) { - bnds = 16 * group + band; - if (pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds] < - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]) - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; - else - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]; - } - startBand = 0; - if ((group + 1) == conceal_group_max) endBand = conceal_max; - } - } - - /* now copy all data to the output buffer which needs not to be concealed */ - if (conceal_group_min == 0) - endBand = conceal_min; - else - endBand = pRvlc->maxSfbTransmitted; - for (group = 0; group <= conceal_group_min; group++) { - for (band = 0; band < endBand; band++) { - bnds = 16 * group + band; - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; - } - if ((group + 1) == conceal_group_min) endBand = conceal_min; - } - - startBand = conceal_max + 1; - for (group = conceal_group_max; group < pRvlc->numWindowGroups; group++) { - for (band = startBand; band < pRvlc->maxSfbTransmitted; band++) { - bnds = 16 * group + band; - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]; - } - startBand = 0; - } -} - -/*--------------------------------------------------------------------------------------------- - function: BidirectionalEstimation_UseScfOfPrevFrameAsReference - - description: This approach by means of bidirectional estimation is generally -performed when a single bit error has been detected, the bit error can be -isolated between 'conceal_min' and 'conceal_max', the 'sf_concealment' flag is -set and the previous frame has the same block type as the current frame. The -scalefactor decoded in forward and backward direction and the scalefactor of the -previous frame are compared with each other. The smaller scalefactor will be -considered as the correct one. At this the codebook of the previous and current -frame must be of the same set (scf, nrg, is) in each scalefactorband. Otherwise -the scalefactor of the previous frame is not considered in the minimum -calculation. The reconstruction of the scalefactors with this approach archieve -good results in audio quality. The strategy must be applied to scalefactors, -intensity data and noise energy seperately. ------------------------------------------------------------------------------------------------ - output: Concealed scalefactor, noise energy and intensity data between -conceal_min and conceal_max ------------------------------------------------------------------------------------------------ - return: - --------------------------------------------------------------------------------------------- -*/ - -void BidirectionalEstimation_UseScfOfPrevFrameAsReference( - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) { - CErRvlcInfo *pRvlc = - &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo; - int band, bnds, startBand, endBand, group; - int conceal_min, conceal_max; - int conceal_group_min, conceal_group_max; - int MaximumScaleFactorBands; - SHORT commonMin; - - if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) { - MaximumScaleFactorBands = 16; - } else { - MaximumScaleFactorBands = 64; - } - - /* If an error was detected just in forward or backward direction, set the - corresponding border for concealment to a appropriate scalefactor band. The - border is set to first or last sfb respectively, because the error will - possibly not follow directly after the corrupt bit but just after decoding - some more (wrong) scalefactors. */ - if (pRvlc->conceal_min == CONCEAL_MIN_INIT) pRvlc->conceal_min = 0; - - if (pRvlc->conceal_max == CONCEAL_MAX_INIT) - pRvlc->conceal_max = - (pRvlc->numWindowGroups - 1) * 16 + pRvlc->maxSfbTransmitted - 1; - - conceal_min = pRvlc->conceal_min % MaximumScaleFactorBands; - conceal_group_min = pRvlc->conceal_min / MaximumScaleFactorBands; - conceal_max = pRvlc->conceal_max % MaximumScaleFactorBands; - conceal_group_max = pRvlc->conceal_max / MaximumScaleFactorBands; - - pAacDecoderChannelInfo->pComData->overlay.aac - .aRvlcScfFwd[pRvlc->conceal_max] = - pAacDecoderChannelInfo->pComData->overlay.aac - .aRvlcScfBwd[pRvlc->conceal_max]; - pAacDecoderChannelInfo->pComData->overlay.aac - .aRvlcScfBwd[pRvlc->conceal_min] = - pAacDecoderChannelInfo->pComData->overlay.aac - .aRvlcScfFwd[pRvlc->conceal_min]; - - /* consider the smaller of the forward and backward decoded value as the - * correct one */ - startBand = conceal_min; - if (conceal_group_min == conceal_group_max) - endBand = conceal_max; - else - endBand = pRvlc->maxSfbTransmitted - 1; - - for (group = conceal_group_min; group <= conceal_group_max; group++) { - for (band = startBand; band <= endBand; band++) { - bnds = 16 * group + band; - switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) { - case ZERO_HCB: - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = 0; - break; - - case INTENSITY_HCB: - case INTENSITY_HCB2: - if ((pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousCodebook[bnds] == INTENSITY_HCB) || - (pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousCodebook[bnds] == INTENSITY_HCB2)) { - commonMin = fMin( - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds], - pAacDecoderChannelInfo->pComData->overlay.aac - .aRvlcScfBwd[bnds]); - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = - fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousScaleFactor[bnds]); - } else { - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = fMin( - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds], - pAacDecoderChannelInfo->pComData->overlay.aac - .aRvlcScfBwd[bnds]); - } - break; - - case NOISE_HCB: - if (pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousCodebook[bnds] == NOISE_HCB) { - commonMin = fMin( - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds], - pAacDecoderChannelInfo->pComData->overlay.aac - .aRvlcScfBwd[bnds]); - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = - fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousScaleFactor[bnds]); - } else { - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = fMin( - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds], - pAacDecoderChannelInfo->pComData->overlay.aac - .aRvlcScfBwd[bnds]); - } - break; - - default: - if ((pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousCodebook[bnds] != ZERO_HCB) && - (pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousCodebook[bnds] != NOISE_HCB) && - (pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousCodebook[bnds] != INTENSITY_HCB) && - (pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousCodebook[bnds] != INTENSITY_HCB2)) { - commonMin = fMin( - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds], - pAacDecoderChannelInfo->pComData->overlay.aac - .aRvlcScfBwd[bnds]); - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = - fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousScaleFactor[bnds]); - } else { - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = fMin( - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds], - pAacDecoderChannelInfo->pComData->overlay.aac - .aRvlcScfBwd[bnds]); - } - break; - } - } - startBand = 0; - if ((group + 1) == conceal_group_max) endBand = conceal_max; - } - - /* now copy all data to the output buffer which needs not to be concealed */ - if (conceal_group_min == 0) - endBand = conceal_min; - else - endBand = pRvlc->maxSfbTransmitted; - for (group = 0; group <= conceal_group_min; group++) { - for (band = 0; band < endBand; band++) { - bnds = 16 * group + band; - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; - } - if ((group + 1) == conceal_group_min) endBand = conceal_min; - } - - startBand = conceal_max + 1; - for (group = conceal_group_max; group < pRvlc->numWindowGroups; group++) { - for (band = startBand; band < pRvlc->maxSfbTransmitted; band++) { - bnds = 16 * group + band; - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]; - } - startBand = 0; - } -} - -/*--------------------------------------------------------------------------------------------- - function: StatisticalEstimation - - description: This approach by means of statistical estimation is generally -performed when both the start value and the end value are different and no -further errors have been detected. Considering the forward and backward decoded -scalefactors, the set with the lower scalefactors in sum will be considered as -the correct one. The scalefactors are differentially encoded. Normally it would -reach to compare one pair of the forward and backward decoded scalefactors to -specify the lower set. But having detected no further errors does not -necessarily mean the absence of errors. Therefore all scalefactors decoded in -forward and backward direction are summed up seperately. The set with the lower -sum will be used. The strategy must be applied to scalefactors, intensity data -and noise energy seperately. ------------------------------------------------------------------------------------------------ - output: Concealed scalefactor, noise energy and intensity data ------------------------------------------------------------------------------------------------ - return: - --------------------------------------------------------------------------------------------- -*/ - -void StatisticalEstimation(CAacDecoderChannelInfo *pAacDecoderChannelInfo) { - CErRvlcInfo *pRvlc = - &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo; - int band, bnds, group; - int sumIsFwd, sumIsBwd; /* sum of intensity data forward/backward */ - int sumNrgFwd, sumNrgBwd; /* sum of noise energy data forward/backward */ - int sumScfFwd, sumScfBwd; /* sum of scalefactor data forward/backward */ - int useIsFwd, useNrgFwd, useScfFwd; /* the flags signals the elements which - are used for the final result */ - - sumIsFwd = sumIsBwd = sumNrgFwd = sumNrgBwd = sumScfFwd = sumScfBwd = 0; - useIsFwd = useNrgFwd = useScfFwd = 0; - - /* calculate sum of each group (scf,nrg,is) of forward and backward direction - */ - for (group = 0; group < pRvlc->numWindowGroups; group++) { - for (band = 0; band < pRvlc->maxSfbTransmitted; band++) { - bnds = 16 * group + band; - switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) { - case ZERO_HCB: - break; - - case INTENSITY_HCB: - case INTENSITY_HCB2: - sumIsFwd += - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; - sumIsBwd += - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]; - break; - - case NOISE_HCB: - sumNrgFwd += - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; - sumNrgBwd += - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]; - break; - - default: - sumScfFwd += - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; - sumScfBwd += - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]; - break; - } - } - } - - /* find for each group (scf,nrg,is) the correct direction */ - if (sumIsFwd < sumIsBwd) useIsFwd = 1; - - if (sumNrgFwd < sumNrgBwd) useNrgFwd = 1; - - if (sumScfFwd < sumScfBwd) useScfFwd = 1; - - /* conceal each group (scf,nrg,is) */ - for (group = 0; group < pRvlc->numWindowGroups; group++) { - for (band = 0; band < pRvlc->maxSfbTransmitted; band++) { - bnds = 16 * group + band; - switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) { - case ZERO_HCB: - break; - - case INTENSITY_HCB: - case INTENSITY_HCB2: - if (useIsFwd) - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; - else - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]; - break; - - case NOISE_HCB: - if (useNrgFwd) - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; - else - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]; - break; - - default: - if (useScfFwd) - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; - else - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]; - break; - } - } - } -} - -/*--------------------------------------------------------------------------------------------- - description: Approach by means of predictive interpolation - This approach by means of predictive estimation is generally -performed when the error cannot be isolated between 'conceal_min' and -'conceal_max', the 'sf_concealment' flag is set and the previous frame has the -same block type as the current frame. Check for each scalefactorband if the same -type of data (scalefactor, internsity data, noise energies) is transmitted. If -so use the scalefactor (intensity data, noise energy) in the current frame. -Otherwise set the scalefactor (intensity data, noise energy) for this -scalefactorband to zero. ------------------------------------------------------------------------------------------------ - output: Concealed scalefactor, noise energy and intensity data ------------------------------------------------------------------------------------------------ - return: - --------------------------------------------------------------------------------------------- -*/ - -void PredictiveInterpolation( - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) { - CErRvlcInfo *pRvlc = - &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo; - int band, bnds, group; - SHORT commonMin; - - for (group = 0; group < pRvlc->numWindowGroups; group++) { - for (band = 0; band < pRvlc->maxSfbTransmitted; band++) { - bnds = 16 * group + band; - switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) { - case ZERO_HCB: - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = 0; - break; - - case INTENSITY_HCB: - case INTENSITY_HCB2: - if ((pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousCodebook[bnds] == INTENSITY_HCB) || - (pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousCodebook[bnds] == INTENSITY_HCB2)) { - commonMin = fMin( - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds], - pAacDecoderChannelInfo->pComData->overlay.aac - .aRvlcScfBwd[bnds]); - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = - fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousScaleFactor[bnds]); - } else { - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = -110; - } - break; - - case NOISE_HCB: - if (pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousCodebook[bnds] == NOISE_HCB) { - commonMin = fMin( - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds], - pAacDecoderChannelInfo->pComData->overlay.aac - .aRvlcScfBwd[bnds]); - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = - fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousScaleFactor[bnds]); - } else { - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = -110; - } - break; - - default: - if ((pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousCodebook[bnds] != ZERO_HCB) && - (pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousCodebook[bnds] != NOISE_HCB) && - (pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousCodebook[bnds] != INTENSITY_HCB) && - (pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousCodebook[bnds] != INTENSITY_HCB2)) { - commonMin = fMin( - pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds], - pAacDecoderChannelInfo->pComData->overlay.aac - .aRvlcScfBwd[bnds]); - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = - fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo - .aRvlcPreviousScaleFactor[bnds]); - } else { - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = 0; - } - break; - } - } - } -} --- a/libAACdec/src/rvlcconceal.h +++ /dev/null @@ -1,127 +0,0 @@ -/* ----------------------------------------------------------------------------- -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): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief rvlc concealment - \author Josef Hoepfl -*/ - -#ifndef RVLCCONCEAL_H -#define RVLCCONCEAL_H - -#include "rvlc.h" - -void BidirectionalEstimation_UseLowerScfOfCurrentFrame( - CAacDecoderChannelInfo *pAacDecoderChannelInfo); - -void BidirectionalEstimation_UseScfOfPrevFrameAsReference( - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo); - -void StatisticalEstimation(CAacDecoderChannelInfo *pAacDecoderChannelInfo); - -void PredictiveInterpolation( - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo); - -#endif /* RVLCCONCEAL_H */ --- a/libAACdec/src/usacdec_lpd.cpp +++ b/libAACdec/src/usacdec_lpd.cpp @@ -111,8 +111,6 @@ amm-info@iis.fraunhofer.de #include "usacdec_acelp.h" #include "overlapadd.h" -#include "conceal.h" - #include "block.h" #define SF_PITCH_TRACK 6 @@ -1210,8 +1208,7 @@ AAC_DECODER_ERROR CLpdChannelStream_Read : &lg_table_ccfl[1][lg_table_offset]; int last_lpc_lost = pAacDecoderStaticChannelInfo->last_lpc_lost; - int last_frame_ok = CConcealment_GetLastFrameOk( - &pAacDecoderStaticChannelInfo->concealmentInfo, 1); + int last_frame_ok = 1; INT i_offset; UINT samplingRate; @@ -1392,13 +1389,7 @@ AAC_DECODER_ERROR CLpdChannelStream_Read } } - if (!CConcealment_GetLastFrameOk( - &pAacDecoderStaticChannelInfo->concealmentInfo, 1)) { - E_LPC_f_lsp_a_conversion( - pAacDecoderChannelInfo->data.usac.lsp_coeff[0], - pAacDecoderChannelInfo->data.usac.lp_coeff[0], - &pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0]); - } else if (pAacDecoderStaticChannelInfo->last_lpd_mode != 0) { + if (pAacDecoderStaticChannelInfo->last_lpd_mode != 0) { if (pAacDecoderStaticChannelInfo->last_lpd_mode == 255) { /* We need it for TCX decoding or ACELP excitation update */ E_LPC_f_lsp_a_conversion( @@ -1426,9 +1417,7 @@ AAC_DECODER_ERROR CLpdChannelStream_Read FD_SHORT; pAacDecoderChannelInfo->data.usac.lpd_mode_last = 255; - if ((pAacDecoderStaticChannelInfo->last_core_mode != FD_SHORT) && - CConcealment_GetLastFrameOk( - &pAacDecoderStaticChannelInfo->concealmentInfo, 1)) { + if ((pAacDecoderStaticChannelInfo->last_core_mode != FD_SHORT)) { /* USAC Conformance document: short_fac_flag shall be encoded with a value of 1 if the window_sequence of the previous frame was 2 (EIGHT_SHORT_SEQUENCE). @@ -1604,8 +1593,7 @@ AAC_DECODER_ERROR CLpd_RenderTimeSignal( return AAC_DEC_UNKNOWN; } - last_frame_lost = !CConcealment_GetLastFrameOk( - &pAacDecoderStaticChannelInfo->concealmentInfo, 0); + last_frame_lost = 0; /* Maintain LPD mode from previous frame */ if ((pAacDecoderStaticChannelInfo->last_core_mode == FD_LONG) ||