From b1b306443a1cc0308fa563b40a281bae53346d01 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 9 Aug 2019 17:08:22 +0200 Subject: Replace obsolete SBR CRC with superior FDK CRC implementation. Fixes ELD SBR CRC decoding and prevents negative shift exponents in calcCRC(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I0c40609975de5854560643f3ce2c9fecf5973f73 --- libSBRdec/src/sbr_crc.cpp | 192 ------------------------------------------- libSBRdec/src/sbr_crc.h | 138 ------------------------------- libSBRdec/src/sbrdecoder.cpp | 87 ++++++++------------ 3 files changed, 35 insertions(+), 382 deletions(-) delete mode 100644 libSBRdec/src/sbr_crc.cpp delete mode 100644 libSBRdec/src/sbr_crc.h (limited to 'libSBRdec') diff --git a/libSBRdec/src/sbr_crc.cpp b/libSBRdec/src/sbr_crc.cpp deleted file mode 100644 index ba0fd05..0000000 --- a/libSBRdec/src/sbr_crc.cpp +++ /dev/null @@ -1,192 +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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief CRC check coutines -*/ - -#include "sbr_crc.h" - -#include "FDK_bitstream.h" -#include "transcendent.h" - -#define MAXCRCSTEP 16 -#define MAXCRCSTEP_LD 4 - -/*! - \brief crc calculation -*/ -static ULONG calcCRC(HANDLE_CRC hCrcBuf, ULONG bValue, int nBits) { - int i; - ULONG bMask = (1UL << (nBits - 1)); - - for (i = 0; i < nBits; i++, bMask >>= 1) { - USHORT flag = (hCrcBuf->crcState & hCrcBuf->crcMask) ? 1 : 0; - USHORT flag1 = (bMask & bValue) ? 1 : 0; - - flag ^= flag1; - hCrcBuf->crcState <<= 1; - if (flag) hCrcBuf->crcState ^= hCrcBuf->crcPoly; - } - - return (hCrcBuf->crcState); -} - -/*! - \brief crc -*/ -static int getCrc(HANDLE_FDK_BITSTREAM hBs, ULONG NrBits) { - int i; - CRC_BUFFER CrcBuf; - - CrcBuf.crcState = SBR_CRC_START; - CrcBuf.crcPoly = SBR_CRC_POLY; - CrcBuf.crcMask = SBR_CRC_MASK; - - int CrcStep = NrBits >> MAXCRCSTEP_LD; - - int CrcNrBitsRest = (NrBits - CrcStep * MAXCRCSTEP); - ULONG bValue; - - for (i = 0; i < CrcStep; i++) { - bValue = FDKreadBits(hBs, MAXCRCSTEP); - calcCRC(&CrcBuf, bValue, MAXCRCSTEP); - } - - bValue = FDKreadBits(hBs, CrcNrBitsRest); - calcCRC(&CrcBuf, bValue, CrcNrBitsRest); - - return (CrcBuf.crcState & SBR_CRC_RANGE); -} - -/*! - \brief crc interface - \return 1: CRC OK, 0: CRC check failure -*/ -int SbrCrcCheck(HANDLE_FDK_BITSTREAM hBs, /*!< handle to bit-buffer */ - LONG NrBits) /*!< max. CRC length */ -{ - int crcResult = 1; - ULONG NrCrcBits; - ULONG crcCheckResult; - LONG NrBitsAvailable; - ULONG crcCheckSum; - - crcCheckSum = FDKreadBits(hBs, 10); - - NrBitsAvailable = FDKgetValidBits(hBs); - if (NrBitsAvailable <= 0) { - return 0; - } - - NrCrcBits = fixMin((INT)NrBits, (INT)NrBitsAvailable); - - crcCheckResult = getCrc(hBs, NrCrcBits); - FDKpushBack(hBs, (NrBitsAvailable - FDKgetValidBits(hBs))); - - if (crcCheckResult != crcCheckSum) { - crcResult = 0; - } - - return (crcResult); -} diff --git a/libSBRdec/src/sbr_crc.h b/libSBRdec/src/sbr_crc.h deleted file mode 100644 index 9633717..0000000 --- a/libSBRdec/src/sbr_crc.h +++ /dev/null @@ -1,138 +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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief CRC checking routines -*/ -#ifndef SBR_CRC_H -#define SBR_CRC_H - -#include "sbrdecoder.h" - -#include "FDK_bitstream.h" - -/* some useful crc polynoms: - -crc5: x^5+x^4+x^2+x^1+1 -crc6: x^6+x^5+x^3+x^2+x+1 -crc7: x^7+x^6+x^2+1 -crc8: x^8+x^2+x+x+1 -*/ - -/* default SBR CRC */ /* G(x) = x^10 + x^9 + x^5 + x^4 + x + 1 */ -#define SBR_CRC_POLY 0x0233 -#define SBR_CRC_MASK 0x0200 -#define SBR_CRC_START 0x0000 -#define SBR_CRC_RANGE 0x03FF - -typedef struct { - USHORT crcState; - USHORT crcMask; - USHORT crcPoly; -} CRC_BUFFER; - -typedef CRC_BUFFER *HANDLE_CRC; - -int SbrCrcCheck(HANDLE_FDK_BITSTREAM hBitBuf, LONG NrCrcBits); - -#endif diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp index c827ced..52403f6 100644 --- a/libSBRdec/src/sbrdecoder.cpp +++ b/libSBRdec/src/sbrdecoder.cpp @@ -143,14 +143,12 @@ amm-info@iis.fraunhofer.de #include "env_extr.h" #include "sbr_dec.h" #include "env_dec.h" -#include "sbr_crc.h" +#include "FDK_crc.h" #include "sbr_ram.h" #include "sbr_rom.h" #include "lpp_tran.h" #include "transcendent.h" -#include "FDK_crc.h" - #include "sbrdec_drc.h" #include "psbitdec.h" @@ -1134,18 +1132,22 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs, SBR_HEADER_STATUS headerStatus = HEADER_NOT_PRESENT; INT startPos = FDKgetValidBits(hBs); - INT CRCLen = 0; + FDK_CRCINFO crcInfo; + INT crcReg = 0; + USHORT sbrCrc = 0; + UINT crcPoly; + UINT crcStartValue = 0; + UINT crcLen; + HANDLE_FDK_BITSTREAM hBsOriginal = hBs; FDK_BITSTREAM bsBwd; - FDK_CRCINFO crcInfo; - INT crcReg = 0; - USHORT drmSbrCrc = 0; const int fGlobalIndependencyFlag = acFlags & AC_INDEP; const int bs_pvc = acElFlags[elementIndex] & AC_EL_USAC_PVC; const int bs_interTes = acElFlags[elementIndex] & AC_EL_USAC_ITES; int stereo; int fDoDecodeSbrData = 1; + int alignBits = 0; int lastSlot, lastHdrSlot = 0, thisHdrSlot = 0; @@ -1277,27 +1279,23 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs, if (fDoDecodeSbrData) { if (crcFlag) { switch (self->coreCodec) { - case AOT_ER_AAC_ELD: - FDKpushFor(hBs, 10); - /* check sbrcrc later: we don't know the payload length now */ - break; case AOT_DRM_AAC: case AOT_DRM_SURROUND: - drmSbrCrc = (USHORT)FDKreadBits(hBs, 8); - /* Setup CRC decoder */ - FDKcrcInit(&crcInfo, 0x001d, 0xFFFF, 8); - /* Start CRC region */ - crcReg = FDKcrcStartReg(&crcInfo, hBs, 0); + crcPoly = 0x001d; + crcLen = 8; + crcStartValue = 0x000000ff; break; default: - CRCLen = bsPayLen - 10; /* change: 0 => i */ - if (CRCLen < 0) { - fDoDecodeSbrData = 0; - } else { - fDoDecodeSbrData = SbrCrcCheck(hBs, CRCLen); - } + crcPoly = 0x0633; + crcLen = 10; + crcStartValue = 0x00000000; break; } + sbrCrc = (USHORT)FDKreadBits(hBs, crcLen); + /* Setup CRC decoder */ + FDKcrcInit(&crcInfo, crcPoly, crcStartValue, crcLen); + /* Start CRC region */ + crcReg = FDKcrcStartReg(&crcInfo, hBs, 0); } } /* if (fDoDecodeSbrData) */ @@ -1450,35 +1448,6 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs, valBits = (INT)FDKgetValidBits(hBs); } - if (crcFlag) { - switch (self->coreCodec) { - case AOT_ER_AAC_ELD: { - /* late crc check for eld */ - INT payloadbits = - (INT)startPos - (INT)FDKgetValidBits(hBs) - startPos; - INT crcLen = payloadbits - 10; - FDKpushBack(hBs, payloadbits); - fDoDecodeSbrData = SbrCrcCheck(hBs, crcLen); - FDKpushFor(hBs, crcLen); - } break; - case AOT_DRM_AAC: - case AOT_DRM_SURROUND: - /* End CRC region */ - FDKcrcEndReg(&crcInfo, hBs, crcReg); - /* Check CRC */ - if ((FDKcrcGetCRC(&crcInfo) ^ 0xFF) != drmSbrCrc) { - fDoDecodeSbrData = 0; - if (headerStatus != HEADER_NOT_PRESENT) { - headerStatus = HEADER_ERROR; - hSbrHeader->syncState = SBR_NOT_INITIALIZED; - } - } - break; - default: - break; - } - } - /* sanity check of remaining bits */ if (valBits < 0) { fDoDecodeSbrData = 0; @@ -1489,7 +1458,7 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs, case AOT_AAC_LC: { /* This sanity check is only meaningful with General Audio * bitstreams */ - int alignBits = valBits & 0x7; + alignBits = valBits & 0x7; if (valBits > alignBits) { fDoDecodeSbrData = 0; @@ -1508,6 +1477,20 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs, errorStatus = SBRDEC_PARSE_ERROR; } + if (crcFlag && (hSbrHeader->syncState >= SBR_HEADER) && fDoDecodeSbrData) { + FDKpushFor(hBs, alignBits); + FDKcrcEndReg(&crcInfo, hBs, crcReg); /* End CRC region */ + FDKpushBack(hBs, alignBits); + /* Check CRC */ + if ((FDKcrcGetCRC(&crcInfo) ^ crcStartValue) != sbrCrc) { + fDoDecodeSbrData = 0; + if (headerStatus != HEADER_NOT_PRESENT) { + headerStatus = HEADER_ERROR; + hSbrHeader->syncState = SBR_NOT_INITIALIZED; + } + } + } + if (!fDoDecodeSbrData) { /* Set error flag for this slot to trigger concealment */ setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_ERROR); -- cgit v1.2.3 From bedfd82356dafa1f51f360af29f302a672d6866c Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 9 Aug 2019 17:09:00 +0200 Subject: Fix shift value assignment in addHighBandPart(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I69457c1b551e33e3ee9ef39b457b0f83de2e370e --- libSBRdec/src/hbe.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libSBRdec') diff --git a/libSBRdec/src/hbe.cpp b/libSBRdec/src/hbe.cpp index 1141e9c..2284c42 100644 --- a/libSBRdec/src/hbe.cpp +++ b/libSBRdec/src/hbe.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -1339,7 +1339,7 @@ static void addHighBandPart(FIXP_DBL g_r_m, FIXP_DBL g_i_m, INT g_e, g_r_m = fMultDiv2(tmp_r, factor_m) << shift; g_i_m = fMultDiv2(tmp_i, factor_m) << shift; g_e = scale_factor_hbe - (g_e + factor_e + gammaCenter_e + add); - fMax((INT)0, g_e); + g_e = fMax((INT)0, g_e); *qmfHBEBufReal_F += g_r_m >> g_e; *qmfHBEBufImag_F += g_i_m >> g_e; } -- cgit v1.2.3 From a65911cd2ef6a16878e88cd91818ef962950ceec Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 9 Aug 2019 17:09:18 +0200 Subject: Limit shift exponent in adjustTimeSlot_EldGrid(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I4000972d63d74e871d47f2db031308cd7ea285d6 --- libSBRdec/src/env_calc.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'libSBRdec') diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp index 1242833..eaf739d 100644 --- a/libSBRdec/src/env_calc.cpp +++ b/libSBRdec/src/env_calc.cpp @@ -1576,12 +1576,13 @@ void calculateSbrEnvelope( FDK_ASSERT(!iTES_enable); /* not supported */ if (flags & SBRDEC_ELD_GRID) { /* FDKmemset(analysBufferReal[j], 0, 64 * sizeof(FIXP_DBL)); */ - adjustTimeSlot_EldGrid(&analysBufferReal[j][lowSubband], pNrgs, - &h_sbr_cal_env->harmIndex, lowSubband, - noSubbands, - fMin(scale_change, DFRACT_BITS - 1), - noNoiseFlag, &h_sbr_cal_env->phaseIndex, - EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale); + adjustTimeSlot_EldGrid( + &analysBufferReal[j][lowSubband], pNrgs, + &h_sbr_cal_env->harmIndex, lowSubband, noSubbands, + fMin(scale_change, DFRACT_BITS - 1), noNoiseFlag, + &h_sbr_cal_env->phaseIndex, + fMax(EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale, + -(DFRACT_BITS - 1))); } else { adjustTimeSlotLC(&analysBufferReal[j][lowSubband], pNrgs, &h_sbr_cal_env->harmIndex, lowSubband, noSubbands, -- cgit v1.2.3 From 6f98eab35095f5fd7bcfb9df585ff0b0c6f1460d Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 9 Aug 2019 17:09:36 +0200 Subject: Saturate shift value in calculateSbrEnvelope(). Prevents too large shift values. Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I3331ac9bc267cd3fa4c1178bc445998869f0d99b --- libSBRdec/src/env_calc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libSBRdec') diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp index eaf739d..c34ce96 100644 --- a/libSBRdec/src/env_calc.cpp +++ b/libSBRdec/src/env_calc.cpp @@ -1477,7 +1477,7 @@ void calculateSbrEnvelope( for (k = 0; k < noSubbands; k++) { int sc = scale_change - pNrgs->nrgGain_e[k] + (sc_change - 1); - pNrgs->nrgGain[k] >>= sc; + pNrgs->nrgGain[k] >>= fixMin(sc, DFRACT_BITS - 1); pNrgs->nrgGain_e[k] += sc; } @@ -1485,7 +1485,7 @@ void calculateSbrEnvelope( for (k = 0; k < noSubbands; k++) { int sc = scale_change - h_sbr_cal_env->filtBuffer_e[k] + (sc_change - 1); - h_sbr_cal_env->filtBuffer[k] >>= sc; + h_sbr_cal_env->filtBuffer[k] >>= fixMin(sc, DFRACT_BITS - 1); } } -- cgit v1.2.3 From a7029823f4836a4e8564b636d43e4ebd202f3ec0 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 18 Oct 2019 14:02:38 +0200 Subject: Prevent integer overflow in sbrDecoder_calculateGainVec(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I359f7f976a5ad5459be7d7b786145988a175e305 --- libSBRdec/src/HFgen_preFlat.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'libSBRdec') diff --git a/libSBRdec/src/HFgen_preFlat.cpp b/libSBRdec/src/HFgen_preFlat.cpp index 96adbb9..268011e 100644 --- a/libSBRdec/src/HFgen_preFlat.cpp +++ b/libSBRdec/src/HFgen_preFlat.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -904,23 +904,24 @@ void sbrDecoder_calculateGainVec(FIXP_DBL **sourceBufferReal, } if (maxVal != FL2FX_DBL(0.0f)) { - reserve = fixMax(0, CntLeadingZeros(maxVal) - 2); + reserve = CntLeadingZeros(maxVal) - 2; } nrg_ov = nrg = (FIXP_DBL)0; if (scale_nrg_ov > -31) { for (i = startSample; i < overlap; i++) { - nrg_ov += (fPow2Div2(sourceBufferReal[i][loBand] << reserve) + - fPow2Div2(sourceBufferImag[i][loBand] << reserve)) >> - sum_scale_ov; + nrg_ov += + (fPow2Div2(scaleValue(sourceBufferReal[i][loBand], reserve)) + + fPow2Div2(scaleValue(sourceBufferImag[i][loBand], reserve))) >> + sum_scale_ov; } } else { scale_nrg_ov = 0; } if (scale_nrg > -31) { for (i = overlap; i < stopSample; i++) { - nrg += (fPow2Div2(sourceBufferReal[i][loBand] << reserve) + - fPow2Div2(sourceBufferImag[i][loBand] << reserve)) >> + nrg += (fPow2Div2(scaleValue(sourceBufferReal[i][loBand], reserve)) + + fPow2Div2(scaleValue(sourceBufferImag[i][loBand], reserve))) >> sum_scale; } } else { -- cgit v1.2.3 From 9ba6f8b6a21cca4a4f89d0202af501fd3a67e144 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 18 Oct 2019 14:02:58 +0200 Subject: Fix signed integer overflow in calcFactorPerBand() calculation. Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I9f18f675112651be8dec5c0474601ca6531fbf15 --- libSBRdec/src/sbrdec_freq_sca.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'libSBRdec') diff --git a/libSBRdec/src/sbrdec_freq_sca.cpp b/libSBRdec/src/sbrdec_freq_sca.cpp index 165f94b..e187656 100644 --- a/libSBRdec/src/sbrdec_freq_sca.cpp +++ b/libSBRdec/src/sbrdec_freq_sca.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -230,6 +230,8 @@ static UCHAR getStopBand( } } + stopMin = fMin(stopMin, 64); + /* Choose a stop band between k1 and 64 depending on stopFreq (0..13), based on a logarithmic scale. @@ -523,7 +525,8 @@ static FIXP_SGL calcFactorPerBand(int k_start, int k_stop, int num_bands) { step = FL2FXCONST_DBL(0.0f); } } - return FX_DBL2FX_SGL(bandfactor << 1); + return (bandfactor >= FL2FXCONST_DBL(0.5)) ? (FIXP_SGL)MAXVAL_SGL + : FX_DBL2FX_SGL(bandfactor << 1); } /*! -- cgit v1.2.3 From 54cd15bd807a69a7d68cbb414b8a3ea4b280748f Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 18 Oct 2019 14:05:11 +0200 Subject: Fix nrgGain_e update in equalizeFiltBufferExp(). Prevents negative shift exponents in calculateSbrEnvelope(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I66ad54dae0fa1d414d8b2b9a9e0b6145cce4042d --- libSBRdec/src/env_calc.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'libSBRdec') diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp index c34ce96..5cfd56c 100644 --- a/libSBRdec/src/env_calc.cpp +++ b/libSBRdec/src/env_calc.cpp @@ -1831,7 +1831,8 @@ static void equalizeFiltBufferExp( diff = (int)(nrgGain_e[band] - filtBuffer_e[band]); if (diff > 0) { filtBuffer[band] >>= - diff; /* Compensate for the scale change by shifting the mantissa. */ + fMin(diff, DFRACT_BITS - 1); /* Compensate for the scale change by + shifting the mantissa. */ filtBuffer_e[band] += diff; /* New gain is bigger, use its exponent */ } else if (diff < 0) { /* The buffered gains seem to be larger, but maybe there @@ -1851,8 +1852,8 @@ static void equalizeFiltBufferExp( filtBuffer_e[band] -= reserve; /* Compensate in the exponent: */ /* For the remaining difference, change the new gain value */ - diff = fixMin(-(reserve + diff), DFRACT_BITS - 1); - nrgGain[band] >>= diff; + diff = -(reserve + diff); + nrgGain[band] >>= fMin(diff, DFRACT_BITS - 1); nrgGain_e[band] += diff; } } -- cgit v1.2.3 From b2f2a109d3546a1f412fda3a3f41abc6bdb4f949 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 18 Oct 2019 14:05:33 +0200 Subject: Limit too large shift value in apply_inter_tes(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I38cc7053e671f6e20a1a9ba4f1645d1cf8be77e2 --- libSBRdec/src/env_calc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'libSBRdec') diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp index 5cfd56c..41c9e88 100644 --- a/libSBRdec/src/env_calc.cpp +++ b/libSBRdec/src/env_calc.cpp @@ -739,7 +739,8 @@ static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag, fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_after_sf); total_power_high_after_sf = new_summand_sf; } else if (new_summand_sf < total_power_high_after_sf) { - subsample_power_high[i] >>= total_power_high_after_sf - new_summand_sf; + subsample_power_high[i] >>= + fMin(DFRACT_BITS - 1, total_power_high_after_sf - new_summand_sf); } total_power_high_after += subsample_power_high[i] >> preShift2; } -- cgit v1.2.3 From 5838a313ae49b81dfc377d4c4ef45c34239d3495 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:05:18 +0100 Subject: Fix signed integer overflow in pvcDecodeTimeSlot(). Bug: 145668022 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I0a165330cf174f24310f8d705523d310a3522e7a --- libSBRdec/src/pvc_dec.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'libSBRdec') diff --git a/libSBRdec/src/pvc_dec.cpp b/libSBRdec/src/pvc_dec.cpp index b477122..e1e3c2c 100644 --- a/libSBRdec/src/pvc_dec.cpp +++ b/libSBRdec/src/pvc_dec.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -534,7 +534,8 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData, for (ksg = ksg_start; ksg < PVC_NBLOW; ksg++) { for (band = sg_borders[ksg]; band < sg_borders[ksg + 1]; band++) { /* The division by 8 == (RATE*lbw) is required algorithmically */ - E[ksg] += (fPow2Div2(qmfR[band]) + fPow2Div2(qmfI[band])) >> 2; + E[ksg] += + ((fPow2Div2(qmfR[band]) >> 1) + (fPow2Div2(qmfI[band]) >> 1)) >> 3; } } } @@ -542,7 +543,7 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData, if (E[ksg] > (FIXP_DBL)0) { /* 10/log2(10) = 0.752574989159953 * 2^2 */ int exp_log; - FIXP_DBL nrg = CalcLog2(E[ksg], 2 * qmfExponent, &exp_log); + FIXP_DBL nrg = CalcLog2(E[ksg], 2 * qmfExponent + 2, &exp_log); nrg = fMult(nrg, FL2FXCONST_SGL(LOG10FAC)); nrg = scaleValue(nrg, exp_log - PVC_ESG_EXP + 2); pEsg[ksg] = fMax(nrg, FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP))); @@ -603,22 +604,22 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData, E_high_exp[ksg] = 0; /* residual part */ - accu = ((LONG)(SCHAR)*pTab2++) << (DFRACT_BITS - 8 - PVC_ESG_EXP + + accu = ((LONG)(SCHAR)*pTab2++) << (DFRACT_BITS - 8 - PVC_ESG_EXP - 2 + pPvcDynamicData->pScalingCoef[3]); /* linear combination of lower grouped energies part */ for (kb = 0; kb < PVC_NBLOW; kb++) { predCoeff = (FIXP_SGL)( (SHORT)(SCHAR)pTab1[kb * pPvcDynamicData->nbHigh + ksg] << 8); - predCoeff_exp = pPvcDynamicData->pScalingCoef[kb] + - 1; /* +1 to compensate for Div2 */ - accu += fMultDiv2(E[kb], predCoeff) << predCoeff_exp; + predCoeff_exp = -(pPvcDynamicData->pScalingCoef[kb] + 1 - + 2); /* +1 to compensate for Div2; -2 for accu */ + accu += fMultDiv2(E[kb], predCoeff) >> predCoeff_exp; } /* convert back to linear domain */ accu = fMult(accu, FL2FXCONST_SGL(LOG10FAC_INV)); - accu = f2Pow( - accu, PVC_ESG_EXP - 1, - &predCoeff_exp); /* -1 compensates for exponent of LOG10FAC_INV */ + accu = f2Pow(accu, PVC_ESG_EXP - 1 + 2, + &predCoeff_exp); /* -1 compensates for exponent of + LOG10FAC_INV; +2 for accu */ predictedEsgSlot[ksg] = accu; E_high_exp[ksg] = predCoeff_exp; if (predCoeff_exp > E_high_exp_max) { @@ -628,8 +629,8 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData, /* rescale output vector according to largest exponent */ for (ksg = 0; ksg < pPvcDynamicData->nbHigh; ksg++) { - int scale = E_high_exp[ksg] - E_high_exp_max; - predictedEsgSlot[ksg] = scaleValue(predictedEsgSlot[ksg], scale); + int scale = fMin(E_high_exp_max - E_high_exp[ksg], DFRACT_BITS - 1); + predictedEsgSlot[ksg] = predictedEsgSlot[ksg] >> scale; } *predictedEsg_exp = E_high_exp_max; } -- cgit v1.2.3 From 2ce3e76d0fd843e1cede9c747392b716039db596 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:05:40 +0100 Subject: Improve robustness of limiter band table calculation in ResetLimiterBands(). Bug: 145668973 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Ic076cf5b44c0618734064b670de61f9da532a13e --- libSBRdec/src/env_calc.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'libSBRdec') diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp index 41c9e88..23ad509 100644 --- a/libSBRdec/src/env_calc.cpp +++ b/libSBRdec/src/env_calc.cpp @@ -3144,6 +3144,11 @@ ResetLimiterBands( return SBRDEC_UNSUPPORTED_CONFIG; } + /* Restrict maximum value of limiter band table */ + if (workLimiterBandTable[tempNoLim] > highSubband) { + return SBRDEC_UNSUPPORTED_CONFIG; + } + /* Copy limiterbands from working buffer into final destination */ for (k = 0; k <= nBands; k++) { limiterBandTable[k] = workLimiterBandTable[k]; -- cgit v1.2.3 From 68cdcfc6b82f88ed1f616b7e3a0133b0072f4bf4 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:06:00 +0100 Subject: Avoid signed integer overflows in multiple adjustTimeSlot*() functions. Bug: 145669628 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Id0f3ee9d3413e534505c0c7eea379ce42880ca79 --- libSBRdec/src/env_calc.cpp | 97 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 25 deletions(-) (limited to 'libSBRdec') diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp index 23ad509..81f03f3 100644 --- a/libSBRdec/src/env_calc.cpp +++ b/libSBRdec/src/env_calc.cpp @@ -151,6 +151,9 @@ amm-info@iis.fraunhofer.de #include "genericStds.h" /* need FDKpow() for debug outputs */ +#define MAX_SFB_NRG_HEADROOM (1) +#define MAX_VAL_NRG_HEADROOM ((((FIXP_DBL)MAXVAL_DBL) >> MAX_SFB_NRG_HEADROOM)) + typedef struct { FIXP_DBL nrgRef[MAX_FREQ_COEFFS]; FIXP_DBL nrgEst[MAX_FREQ_COEFFS]; @@ -986,7 +989,8 @@ void calculateSbrEnvelope( */ if (!useLP) adj_e = h_sbr_cal_env->filtBufferNoise_e - - getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands); + getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands) + + (INT)MAX_SFB_NRG_HEADROOM; /* Scan for maximum reference energy to be able @@ -1006,7 +1010,7 @@ void calculateSbrEnvelope( - Smoothing can smear high gains of the previous envelope into the current */ - maxSfbNrg_e += 6; + maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM); adj_e = maxSfbNrg_e; // final_e should not exist for PVC fixfix framing @@ -1032,7 +1036,7 @@ void calculateSbrEnvelope( - Smoothing can smear high gains of the previous envelope into the current */ - maxSfbNrg_e += 6; + maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM); if (borders[i] < hHeaderData->numberTimeSlots) /* This envelope affects timeslots that belong to the output frame */ @@ -2426,6 +2430,9 @@ static void adjustTimeSlot_EldGrid( const FIXP_DBL *p_harmonicPhaseX = &harmonicPhaseX[harmIndex][0]; const INT *p_harmonicPhase = &harmonicPhase[harmIndex][0]; + const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change; + const FIXP_DBL min_val = -max_val; + *(ptrReal - 1) = fAddSaturate( *(ptrReal - 1), SATURATE_SHIFT(fMultDiv2(p_harmonicPhaseX[lowSubband & 1], pSineLevel[0]), @@ -2438,7 +2445,8 @@ static void adjustTimeSlot_EldGrid( FIXP_DBL sineLevel_curr = *pSineLevel++; phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1); - signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change); + signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val) + << scale_change; sbNoise = *pNoiseLevel++; if (((INT)sineLevel_curr | noNoiseFlag) == 0) { signalReal += @@ -2472,7 +2480,8 @@ static void adjustTimeSlot_EldGrid( FIXP_DBL sineLevel_curr = *pSineLevel++; phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1); - signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change); + signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val) + << scale_change; sbNoise = *pNoiseLevel++; if (((INT)sineLevel_curr | noNoiseFlag) == 0) { signalReal += @@ -2512,6 +2521,8 @@ static void adjustTimeSlotLC( FIXP_DBL signalReal, sineLevel, sineLevelNext, sineLevelPrev; int tone_count = 0; int sineSign = 1; + const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change; + const FIXP_DBL min_val = -max_val; #define C1 ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.00815f)) #define C1_CLDFB ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.16773f)) @@ -2527,7 +2538,8 @@ static void adjustTimeSlotLC( of the signal and should be carried out with full accuracy (supplying #FRACT_BITS valid bits). */ - signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change); + signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val) + << scale_change; sineLevel = *pSineLevel++; sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f); @@ -2555,10 +2567,10 @@ static void adjustTimeSlotLC( /* save switch and compare operations and reduce to XOR statement */ if (((harmIndex >> 1) & 0x1) ^ freqInvFlag) { - *(ptrReal - 1) += tmp1; + *(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), tmp1); signalReal -= tmp2; } else { - *(ptrReal - 1) -= tmp1; + *(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), -tmp1); signalReal += tmp2; } *ptrReal++ = signalReal; @@ -2589,7 +2601,9 @@ static void adjustTimeSlotLC( /* The next multiplication constitutes the actual envelope adjustment of * the signal. */ - signalReal += fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change); + signalReal += + fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val) + << scale_change; pNoiseLevel++; *ptrReal++ = signalReal; @@ -2602,7 +2616,8 @@ static void adjustTimeSlotLC( index++; /* The next multiplication constitutes the actual envelope adjustment of * the signal. */ - signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change); + signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val) + << scale_change; if (*pSineLevel++ != FL2FXCONST_DBL(0.0f)) tone_count++; @@ -2630,7 +2645,8 @@ static void adjustTimeSlotLC( index++; /* The next multiplication constitutes the actual envelope adjustment of the * signal. */ - signalReal = fMultDiv2(*ptrReal, *pGain) << ((int)scale_change); + signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain), max_val), min_val) + << scale_change; sineLevelPrev = fMultDiv2(pSineLevel[-1], FL2FX_SGL(0.0163f)); sineLevel = pSineLevel[0]; @@ -2699,6 +2715,9 @@ static void adjustTimeSlotHQ_GainAndNoise( /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio; int index = *ptrPhaseIndex; int shift; + FIXP_DBL max_val_noise = 0, min_val_noise = 0; + const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change; + const FIXP_DBL min_val = -max_val; *ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1); @@ -2708,6 +2727,8 @@ static void adjustTimeSlotHQ_GainAndNoise( shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift); } else { shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift); + max_val_noise = MAX_VAL_NRG_HEADROOM >> shift; + min_val_noise = -max_val_noise; } if (smooth_ratio > FL2FXCONST_SGL(0.0f)) { @@ -2723,8 +2744,10 @@ static void adjustTimeSlotHQ_GainAndNoise( smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) + fMult(direct_ratio, noiseLevel[k]); } else { - smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) << shift) + - fMult(direct_ratio, noiseLevel[k]); + smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]); + smoothedNoise = + (fMax(fMin(smoothedNoise, max_val_noise), min_val_noise) << shift) + + fMult(direct_ratio, noiseLevel[k]); } /* @@ -2732,8 +2755,12 @@ static void adjustTimeSlotHQ_GainAndNoise( of the signal and should be carried out with full accuracy (supplying #DFRACT_BITS valid bits). */ - signalReal = fMultDiv2(*ptrReal, smoothedGain) << ((int)scale_change); - signalImag = fMultDiv2(*ptrImag, smoothedGain) << ((int)scale_change); + signalReal = + fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val) + << scale_change; + signalImag = + fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val) + << scale_change; index++; @@ -2755,8 +2782,12 @@ static void adjustTimeSlotHQ_GainAndNoise( } else { for (k = 0; k < noSubbands; k++) { smoothedGain = gain[k]; - signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change; - signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change; + signalReal = + fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val) + << scale_change; + signalImag = + fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val) + << scale_change; index++; @@ -2862,6 +2893,9 @@ static void adjustTimeSlotHQ( int freqInvFlag = (lowSubband & 1); FIXP_DBL sineLevel; int shift; + FIXP_DBL max_val_noise = 0, min_val_noise = 0; + const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change; + const FIXP_DBL min_val = -max_val; *ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1); *ptrHarmIndex = (harmIndex + 1) & 3; @@ -2877,10 +2911,13 @@ static void adjustTimeSlotHQ( filtBufferNoiseShift += 1; /* due to later use of fMultDiv2 instead of fMult */ - if (filtBufferNoiseShift < 0) + if (filtBufferNoiseShift < 0) { shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift); - else + } else { shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift); + max_val_noise = MAX_VAL_NRG_HEADROOM >> shift; + min_val_noise = -max_val_noise; + } if (smooth_ratio > FL2FXCONST_SGL(0.0f)) { for (k = 0; k < noSubbands; k++) { @@ -2896,8 +2933,10 @@ static void adjustTimeSlotHQ( smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) + fMult(direct_ratio, noiseLevel[k]); } else { - smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) << shift) + - fMult(direct_ratio, noiseLevel[k]); + smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]); + smoothedNoise = + (fMax(fMin(smoothedNoise, max_val_noise), min_val_noise) << shift) + + fMult(direct_ratio, noiseLevel[k]); } /* @@ -2905,8 +2944,12 @@ static void adjustTimeSlotHQ( of the signal and should be carried out with full accuracy (supplying #DFRACT_BITS valid bits). */ - signalReal = fMultDiv2(*ptrReal, smoothedGain) << ((int)scale_change); - signalImag = fMultDiv2(*ptrImag, smoothedGain) << ((int)scale_change); + signalReal = + fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val) + << scale_change; + signalImag = + fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val) + << scale_change; index++; @@ -2959,8 +3002,12 @@ static void adjustTimeSlotHQ( } else { for (k = 0; k < noSubbands; k++) { smoothedGain = gain[k]; - signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change; - signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change; + signalReal = + fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val) + << scale_change; + signalImag = + fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val) + << scale_change; index++; -- cgit v1.2.3 From 801b45ffab8c3ac50c620fd5c6a5818782d2f889 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:09:09 +0100 Subject: Adjust scaling in lppTransposerHBE() to prevent signed integer overflow in autocorrelation. Bug: 145669291 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Ia32b081b982d6886f51642a7ed1ca73acb40dac9 --- libSBRdec/src/lpp_tran.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'libSBRdec') diff --git a/libSBRdec/src/lpp_tran.cpp b/libSBRdec/src/lpp_tran.cpp index 6acb626..93e1158 100644 --- a/libSBRdec/src/lpp_tran.cpp +++ b/libSBRdec/src/lpp_tran.cpp @@ -1014,8 +1014,8 @@ void lppTransposerHBE( pSettings->nCols) + lowBandShift); - dynamicScale = fixMax( - 0, dynamicScale - 1); /* one additional bit headroom to prevent -1.0 */ + dynamicScale = + dynamicScale - 1; /* one additional bit headroom to prevent -1.0 */ /* Scale temporal QMF buffer. @@ -1194,6 +1194,9 @@ void lppTransposerHBE( } else { /* bw <= 0 */ int descale = fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale)); + dynamicScale += + 1; /* prevent negativ scale factor due to 'one additional bit + headroom' */ for (i = startSample; i < stopSample; i++) { FIXP_DBL accu1, accu2; @@ -1210,9 +1213,9 @@ void lppTransposerHBE( dynamicScale; qmfBufferReal[i][loBand] = - (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << 1); + (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << (1 + 1)); qmfBufferImag[i][loBand] = - (lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << 1); + (lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << (1 + 1)); } } /* bw <= 0 */ -- cgit v1.2.3 From 5d095631969aa7136ac2cb7e0e13664516054097 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:08:57 +0100 Subject: Avoid too large shift exponent in apply_inter_tes() by using fIsLessThan. Bug: 146936613 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I8414072929ec8f786e0c003f18ab453dbacb9e5e --- libSBRdec/src/env_calc.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'libSBRdec') diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp index 81f03f3..0b2f651 100644 --- a/libSBRdec/src/env_calc.cpp +++ b/libSBRdec/src/env_calc.cpp @@ -702,20 +702,11 @@ static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag, gain_sf[i] += gamma_sf + 1; /* +1 because of fMultDiv2() */ /* set gain to at least 0.2f */ - FIXP_DBL point_two = FL2FXCONST_DBL(0.8f); /* scaled up by 2 */ - int point_two_sf = -2; - - FIXP_DBL tmp = gain[i]; - if (point_two_sf < gain_sf[i]) { - point_two >>= gain_sf[i] - point_two_sf; - } else { - tmp >>= point_two_sf - gain_sf[i]; - } - /* limit and calculate gain[i]^2 too */ FIXP_DBL gain_pow2; int gain_pow2_sf; - if (tmp < point_two) { + + if (fIsLessThan(gain[i], gain_sf[i], FL2FXCONST_DBL(0.2f), 0)) { gain[i] = FL2FXCONST_DBL(0.8f); gain_sf[i] = -2; gain_pow2 = FL2FXCONST_DBL(0.64f); -- cgit v1.2.3 From 90c29e0808d2221ae747bad7385036c20b5662b0 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 19 Dec 2019 17:27:40 +0100 Subject: Revise memory overlay usage and remove deprecated buffers and overlay tags. Bug: 149514474 Test: atest DecoderTestXheAac DecoderTestAacDrc Change-Id: I7aea2898a3c49e06209fae89d734939c100e1184 --- libAACdec/src/aac_ram.cpp | 10 +--------- libAACdec/src/aac_ram.h | 7 +------ libFDK/include/FDK_qmf_domain.h | 3 +-- libFDK/src/FDK_qmf_domain.cpp | 14 +++++--------- libSBRdec/src/sbr_ram.cpp | 5 +---- 5 files changed, 9 insertions(+), 30 deletions(-) (limited to 'libSBRdec') diff --git a/libAACdec/src/aac_ram.cpp b/libAACdec/src/aac_ram.cpp index e13167d..aa8f6a6 100644 --- a/libAACdec/src/aac_ram.cpp +++ b/libAACdec/src/aac_ram.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -105,12 +105,7 @@ amm-info@iis.fraunhofer.de #define WORKBUFFER1_TAG 0 #define WORKBUFFER2_TAG 1 - -#define WORKBUFFER3_TAG 4 -#define WORKBUFFER4_TAG 5 - #define WORKBUFFER5_TAG 6 - #define WORKBUFFER6_TAG 7 /*! The structure AAC_DECODER_INSTANCE is the top level structure holding all @@ -169,9 +164,6 @@ C_ALLOC_MEM2(TimeDataFlush, INT_PCM, TIME_DATA_FLUSH_SIZE, (8)) C_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL, ((8) * 1024), SECT_DATA_L2, WORKBUFFER2_TAG) -C_ALLOC_MEM_OVERLAY(WorkBufferCore3, FIXP_DBL, WB_SECTION_SIZE, SECT_DATA_L2, - WORKBUFFER3_TAG) -C_AALLOC_MEM(WorkBufferCore4, FIXP_DBL, WB_SECTION_SIZE) C_ALLOC_MEM_OVERLAY(WorkBufferCore6, SCHAR, fMax((INT)(sizeof(FIXP_DBL) * WB_SECTION_SIZE), (INT)sizeof(CAacDecoderCommonData)), diff --git a/libAACdec/src/aac_ram.h b/libAACdec/src/aac_ram.h index a861e25..b9b95b7 100644 --- a/libAACdec/src/aac_ram.h +++ b/libAACdec/src/aac_ram.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -136,12 +136,7 @@ H_ALLOC_MEM(TimeDataFlush, INT_PCM) H_ALLOC_MEM_OVERLAY(WorkBufferCore1, CWorkBufferCore1) H_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL) - -H_ALLOC_MEM_OVERLAY(WorkBufferCore3, FIXP_DBL) -H_ALLOC_MEM(WorkBufferCore4, FIXP_DBL) - H_ALLOC_MEM_OVERLAY(WorkBufferCore5, PCM_DEC) - H_ALLOC_MEM_OVERLAY(WorkBufferCore6, SCHAR) #endif /* #ifndef AAC_RAM_H */ diff --git a/libFDK/include/FDK_qmf_domain.h b/libFDK/include/FDK_qmf_domain.h index d8bc8ce..aa247e9 100644 --- a/libFDK/include/FDK_qmf_domain.h +++ b/libFDK/include/FDK_qmf_domain.h @@ -123,11 +123,10 @@ typedef enum { #define QMF_WB_SECTION_SIZE (1024 * 2) H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore1, FIXP_DBL) -H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore2, FIXP_DBL) H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore3, FIXP_DBL) H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore4, FIXP_DBL) -H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore5, FIXP_DBL) H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL) +H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore7, FIXP_DBL) #define QMF_DOMAIN_MAX_ANALYSIS_QMF_BANDS (64) #define QMF_DOMAIN_MAX_SYNTHESIS_QMF_BANDS (QMF_MAX_SYNTHESIS_BANDS) diff --git a/libFDK/src/FDK_qmf_domain.cpp b/libFDK/src/FDK_qmf_domain.cpp index 5e1d35f..71e2ef5 100644 --- a/libFDK/src/FDK_qmf_domain.cpp +++ b/libFDK/src/FDK_qmf_domain.cpp @@ -106,25 +106,21 @@ amm-info@iis.fraunhofer.de #include "common_fix.h" #define WORKBUFFER1_TAG 0 -#define WORKBUFFER2_TAG 1 - #define WORKBUFFER3_TAG 4 #define WORKBUFFER4_TAG 5 -#define WORKBUFFER5_TAG 6 #define WORKBUFFER6_TAG 7 +#define WORKBUFFER7_TAG 8 C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore1, FIXP_DBL, QMF_WB_SECTION_SIZE, SECT_DATA_L1, WORKBUFFER1_TAG) -C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore2, FIXP_DBL, QMF_WB_SECTION_SIZE, - SECT_DATA_L2, WORKBUFFER2_TAG) C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore3, FIXP_DBL, QMF_WB_SECTION_SIZE, SECT_DATA_L2, WORKBUFFER3_TAG) C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore4, FIXP_DBL, QMF_WB_SECTION_SIZE, SECT_DATA_L2, WORKBUFFER4_TAG) -C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore5, FIXP_DBL, QMF_WB_SECTION_SIZE, - SECT_DATA_L2, WORKBUFFER5_TAG) C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL, QMF_WB_SECTION_SIZE, SECT_DATA_L2, WORKBUFFER6_TAG) +C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore7, FIXP_DBL, QMF_WB_SECTION_SIZE, + SECT_DATA_L2, WORKBUFFER7_TAG) /*! Analysis states buffer.
Dimension: #((8) + (1)) */ @@ -949,7 +945,7 @@ QMF_DOMAIN_ERROR FDK_QmfDomain_Configure(HANDLE_FDK_QMF_DOMAIN hqd) { if ((size > 4 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[4] == NULL)) { /* get work buffer of size QMF_WB_SECTION_SIZE */ - pWorkBuffer[4] = GetQmfWorkBufferCore5(); + pWorkBuffer[4] = GetQmfWorkBufferCore7(); } /* 8. distribute workbuffer over processing channels */ @@ -995,7 +991,7 @@ static void FDK_QmfDomain_FreeWorkBuffer(HANDLE_FDK_QMF_DOMAIN hqd) { if (pWorkBuffer[1]) FreeQmfWorkBufferCore1(&pWorkBuffer[1]); if (pWorkBuffer[2]) FreeQmfWorkBufferCore3(&pWorkBuffer[2]); if (pWorkBuffer[3]) FreeQmfWorkBufferCore4(&pWorkBuffer[3]); - if (pWorkBuffer[4]) FreeQmfWorkBufferCore5(&pWorkBuffer[4]); + if (pWorkBuffer[4]) FreeQmfWorkBufferCore7(&pWorkBuffer[4]); } void FDK_QmfDomain_FreeMem(HANDLE_FDK_QMF_DOMAIN hqd) { diff --git a/libSBRdec/src/sbr_ram.cpp b/libSBRdec/src/sbr_ram.cpp index 8b35fd2..a759d71 100644 --- a/libSBRdec/src/sbr_ram.cpp +++ b/libSBRdec/src/sbr_ram.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -109,9 +109,6 @@ amm-info@iis.fraunhofer.de #include "sbr_ram.h" -#define WORKBUFFER1_TAG 2 -#define WORKBUFFER2_TAG 3 - /*! \name StaticSbrData -- cgit v1.2.3 From e016635f0d3a5c7532b00711ce461f97a13f7bc2 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 19 Dec 2019 17:28:15 +0100 Subject: Avoid decoder internal clipping by converting the whole audio sample data path from 16 to 32 bit data width (FDKdec v3.2.0). Bug: 149514474 Test: atest DecoderTestXheAac DecoderTestAacDrc Change-Id: I8a504ab709e42e27a61fe29840212953742283a5 --- documentation/aacDecoder.pdf | Bin 490978 -> 490978 bytes libAACdec/src/FDK_delay.cpp | 26 ++--- libAACdec/src/FDK_delay.h | 6 +- libAACdec/src/aac_rom.h | 3 +- libAACdec/src/aacdecoder.cpp | 49 ++++---- libAACdec/src/aacdecoder.h | 11 +- libAACdec/src/aacdecoder_lib.cpp | 232 +++++++++++++++++++++---------------- libAACdec/src/block.cpp | 12 +- libAACdec/src/block.h | 8 +- libAACdec/src/conceal.cpp | 42 ++++--- libAACdec/src/conceal.h | 4 +- libAACdec/src/conceal_types.h | 4 +- libAACdec/src/ldfiltbank.cpp | 35 +++--- libAACdec/src/ldfiltbank.h | 5 +- libAACdec/src/usacdec_lpd.cpp | 34 +++--- libAACdec/src/usacdec_lpd.h | 19 +-- libFDK/include/FDK_qmf_domain.h | 5 - libFDK/include/mdct.h | 14 +-- libFDK/src/FDK_core.cpp | 4 +- libFDK/src/FDK_qmf_domain.cpp | 12 +- libPCMutils/include/limiter.h | 36 ++---- libPCMutils/src/limiter.cpp | 116 ++++++++----------- libPCMutils/src/version.h | 4 +- libSACdec/include/sac_dec_lib.h | 13 ++- libSACdec/src/sac_dec.cpp | 23 ++-- libSACdec/src/sac_dec.h | 5 +- libSACdec/src/sac_dec_interface.h | 8 +- libSACdec/src/sac_dec_lib.cpp | 24 ++-- libSACdec/src/sac_process.cpp | 30 +++-- libSACdec/src/sac_qmf.cpp | 4 +- libSACdec/src/sac_qmf.h | 4 +- libSACdec/src/sac_reshapeBBEnv.cpp | 18 +-- libSACdec/src/sac_rom.h | 15 --- libSBRdec/include/sbrdecoder.h | 15 ++- libSBRdec/src/HFgen_preFlat.cpp | 4 +- libSBRdec/src/hbe.cpp | 2 +- libSBRdec/src/hbe.h | 10 +- libSBRdec/src/sbr_dec.cpp | 26 +++-- libSBRdec/src/sbr_dec.h | 11 +- libSBRdec/src/sbr_ram.h | 5 +- libSBRdec/src/sbrdecoder.cpp | 32 ++--- 41 files changed, 488 insertions(+), 442 deletions(-) (limited to 'libSBRdec') diff --git a/documentation/aacDecoder.pdf b/documentation/aacDecoder.pdf index d04a7d6..cc7cf41 100644 Binary files a/documentation/aacDecoder.pdf and b/documentation/aacDecoder.pdf differ diff --git a/libAACdec/src/FDK_delay.cpp b/libAACdec/src/FDK_delay.cpp index 0ab1a66..0cc869c 100644 --- a/libAACdec/src/FDK_delay.cpp +++ b/libAACdec/src/FDK_delay.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -113,7 +113,7 @@ INT FDK_Delay_Create(FDK_SignalDelay* data, const USHORT delay, if (delay > 0) { data->delay_line = - (INT_PCM*)FDKcalloc(num_channels * delay, sizeof(INT_PCM)); + (PCM_DEC*)FDKcalloc(num_channels * delay, sizeof(PCM_DEC)); if (data->delay_line == NULL) { return -1; } @@ -126,36 +126,36 @@ INT FDK_Delay_Create(FDK_SignalDelay* data, const USHORT delay, return 0; } -void FDK_Delay_Apply(FDK_SignalDelay* data, FIXP_PCM* time_buffer, +void FDK_Delay_Apply(FDK_SignalDelay* data, PCM_DEC* time_buffer, const UINT frame_length, const UCHAR channel) { FDK_ASSERT(data != NULL); if (data->delay > 0) { - C_ALLOC_SCRATCH_START(tmp, FIXP_PCM, MAX_FRAME_LENGTH) + C_ALLOC_SCRATCH_START(tmp, PCM_DEC, MAX_FRAME_LENGTH) FDK_ASSERT(frame_length <= MAX_FRAME_LENGTH); FDK_ASSERT(channel < data->num_channels); FDK_ASSERT(time_buffer != NULL); if (frame_length >= data->delay) { FDKmemcpy(tmp, &time_buffer[frame_length - data->delay], - data->delay * sizeof(FIXP_PCM)); + data->delay * sizeof(PCM_DEC)); FDKmemmove(&time_buffer[data->delay], &time_buffer[0], - (frame_length - data->delay) * sizeof(FIXP_PCM)); + (frame_length - data->delay) * sizeof(PCM_DEC)); FDKmemcpy(&time_buffer[0], &data->delay_line[channel * data->delay], - data->delay * sizeof(FIXP_PCM)); + data->delay * sizeof(PCM_DEC)); FDKmemcpy(&data->delay_line[channel * data->delay], tmp, - data->delay * sizeof(FIXP_PCM)); + data->delay * sizeof(PCM_DEC)); } else { - FDKmemcpy(tmp, &time_buffer[0], frame_length * sizeof(FIXP_PCM)); + FDKmemcpy(tmp, &time_buffer[0], frame_length * sizeof(PCM_DEC)); FDKmemcpy(&time_buffer[0], &data->delay_line[channel * data->delay], - frame_length * sizeof(FIXP_PCM)); + frame_length * sizeof(PCM_DEC)); FDKmemcpy(&data->delay_line[channel * data->delay], &data->delay_line[channel * data->delay + frame_length], - (data->delay - frame_length) * sizeof(FIXP_PCM)); + (data->delay - frame_length) * sizeof(PCM_DEC)); FDKmemcpy(&data->delay_line[channel * data->delay + (data->delay - frame_length)], - tmp, frame_length * sizeof(FIXP_PCM)); + tmp, frame_length * sizeof(PCM_DEC)); } - C_ALLOC_SCRATCH_END(tmp, FIXP_PCM, MAX_FRAME_LENGTH) + C_ALLOC_SCRATCH_END(tmp, PCM_DEC, MAX_FRAME_LENGTH) } return; diff --git a/libAACdec/src/FDK_delay.h b/libAACdec/src/FDK_delay.h index f89c3a2..6317d9d 100644 --- a/libAACdec/src/FDK_delay.h +++ b/libAACdec/src/FDK_delay.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -109,7 +109,7 @@ amm-info@iis.fraunhofer.de * Structure representing one delay element for multiple channels. */ typedef struct { - INT_PCM* delay_line; /*!< Pointer which stores allocated delay line. */ + PCM_DEC* delay_line; /*!< Pointer which stores allocated delay line. */ USHORT delay; /*!< Delay required in samples (per channel). */ UCHAR num_channels; /*!< Number of channels to delay. */ } FDK_SignalDelay; @@ -137,7 +137,7 @@ INT FDK_Delay_Create(FDK_SignalDelay* data, const USHORT delay, * * \return void */ -void FDK_Delay_Apply(FDK_SignalDelay* data, FIXP_PCM* time_buffer, +void FDK_Delay_Apply(FDK_SignalDelay* data, PCM_DEC* time_buffer, const UINT frame_length, const UCHAR channel); /** diff --git a/libAACdec/src/aac_rom.h b/libAACdec/src/aac_rom.h index ffaf951..7a1597c 100644 --- a/libAACdec/src/aac_rom.h +++ b/libAACdec/src/aac_rom.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -108,6 +108,7 @@ amm-info@iis.fraunhofer.de #include "aacdec_hcr_types.h" #include "aacdec_hcrs.h" +#define PCM_AAC LONG #define PCM_DEC FIXP_DBL #define MAXVAL_PCM_DEC MAXVAL_DBL #define MINVAL_PCM_DEC MINVAL_DBL diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index f747b2d..6a0254d 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -1281,6 +1281,7 @@ LINKSPEC_CPP HANDLE_AACDECODER CAacDecoder_Open( /* Set default frame delay */ aacDecoder_drcSetParam(self->hDrcInfo, DRC_BS_DELAY, CConcealment_GetDelay(&self->concealCommonData)); + self->workBufferCore1 = (FIXP_DBL *)GetWorkBufferCore1(); self->workBufferCore2 = GetWorkBufferCore2(); if (self->workBufferCore2 == NULL) goto bail; @@ -1456,6 +1457,10 @@ LINKSPEC_CPP void CAacDecoder_Close(HANDLE_AACDECODER self) { FreeDrcInfo(&self->hDrcInfo); } + if (self->workBufferCore1 != NULL) { + FreeWorkBufferCore1((CWorkBufferCore1 **)&self->workBufferCore1); + } + /* Free WorkBufferCore2 */ if (self->workBufferCore2 != NULL) { FreeWorkBufferCore2(&self->workBufferCore2); @@ -1493,6 +1498,8 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, UCHAR downscaleFactor = self->downscaleFactor; UCHAR downscaleFactorInBS = self->downscaleFactorInBS; + self->aacOutDataHeadroom = (3); + // set profile and check for supported aot // leave profile on default (=-1) for all other supported MPEG-4 aot's except // aot=2 (=AAC-LC) @@ -2394,7 +2401,7 @@ bail: } LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( - HANDLE_AACDECODER self, const UINT flags, FIXP_PCM *pTimeData, + HANDLE_AACDECODER self, const UINT flags, PCM_DEC *pTimeData, const INT timeDataSize, const int timeDataChannelOffset) { AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK; @@ -3170,10 +3177,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( FDKmemcpy(drcChMap, self->chMapping, (8) * sizeof(UCHAR)); } - /* Turn on/off DRC modules level normalization in digital domain depending - * on the limiter status. */ - aacDecoder_drcSetParam(self->hDrcInfo, APPLY_NORMALIZATION, - (self->limiterEnableCurr) ? 0 : 1); + /* Turn off DRC modules level normalization in digital domain. */ + aacDecoder_drcSetParam(self->hDrcInfo, APPLY_NORMALIZATION, 0); /* deactivate legacy DRC in case uniDrc is active, i.e. uniDrc payload is * present and one of DRC or Loudness Normalization is switched on */ @@ -3325,9 +3330,11 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( &pAacDecoderStaticChannelInfo->drcData); } } + /* The DRC module demands to be called with the gain field holding the * gain scale. */ - self->extGain[0] = (FIXP_DBL)TDL_GAIN_SCALING; + self->extGain[0] = (FIXP_DBL)AACDEC_DRC_GAIN_SCALING; + /* DRC processing */ aacDecoder_drcApply( self->hDrcInfo, self->hSbrDecoder, pAacDecoderChannelInfo, @@ -3343,7 +3350,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( if (self->flushStatus && (self->flushCnt > 0) && !(flags & AACDEC_CONCEAL)) { FDKmemclear(pTimeData + offset, - sizeof(FIXP_PCM) * self->streamInfo.aacSamplesPerFrame); + sizeof(PCM_DEC) * self->streamInfo.aacSamplesPerFrame); } else switch (pAacDecoderChannelInfo->renderMode) { case AACDEC_RENDER_IMDCT: @@ -3355,7 +3362,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( !frameOk_butConceal), pAacDecoderChannelInfo->pComStaticData->pWorkBufferCore1 ->mdctOutTemp, - self->elFlags[el], elCh); + self->aacOutDataHeadroom, self->elFlags[el], elCh); self->extGainDelay = self->streamInfo.aacSamplesPerFrame; break; @@ -3376,7 +3383,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( &self->samplingRateInfo[streamIndex], (self->frameOK && !(flags & AACDEC_CONCEAL) && !frameOk_butConceal), - flags, self->flags[streamIndex]); + self->aacOutDataHeadroom, flags, self->flags[streamIndex]); self->extGainDelay = self->streamInfo.aacSamplesPerFrame; break; @@ -3388,7 +3395,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( if (!CConceal_TDFading_Applied[c]) { CConceal_TDFading_Applied[c] = CConcealment_TDFading( self->streamInfo.aacSamplesPerFrame, - &self->pAacDecoderStaticChannelInfo[c], pTimeData + offset, 0); + &self->pAacDecoderStaticChannelInfo[c], self->aacOutDataHeadroom, + pTimeData + offset, 0); if (c + 1 < (8) && c < aacChannels - 1) { /* update next TDNoise Seed to avoid muting in case of Parametric * Stereo */ @@ -3409,27 +3417,18 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( * LR) */ if ((aacChannels == 2) && bsPseudoLr) { int i, offset2; - const FIXP_SGL invSqrt2 = - FL2FXCONST_SGL(0.353553390593273f); /* scaled by -1 */ - FIXP_PCM *pTD = pTimeData; + const FIXP_SGL invSqrt2 = FL2FXCONST_SGL(0.707106781186547f); + PCM_DEC *pTD = pTimeData; offset2 = timeDataChannelOffset; for (i = 0; i < self->streamInfo.aacSamplesPerFrame; i++) { - FIXP_DBL L = FX_PCM2FX_DBL(pTD[0]); - FIXP_DBL R = FX_PCM2FX_DBL(pTD[offset2]); + FIXP_DBL L = PCM_DEC2FIXP_DBL(pTD[0]); + FIXP_DBL R = PCM_DEC2FIXP_DBL(pTD[offset2]); L = fMult(L, invSqrt2); R = fMult(R, invSqrt2); -#if (SAMPLE_BITS == 16) - pTD[0] = (FIXP_SGL)SATURATE_RIGHT_SHIFT(L + R + (FIXP_DBL)(1 << 14), - 15, FRACT_BITS); - pTD[offset2] = (FIXP_SGL)SATURATE_RIGHT_SHIFT( - L - R + (FIXP_DBL)(1 << 14), 15, FRACT_BITS); -#else - pTD[0] = SATURATE_LEFT_SHIFT(FX_DBL2FX_PCM(L + R), 1, DFRACT_BITS); - pTD[offset2] = - SATURATE_LEFT_SHIFT(FX_DBL2FX_PCM(L - R), 1, DFRACT_BITS); -#endif + pTD[0] = L + R; + pTD[offset2] = L - R; pTD++; } } diff --git a/libAACdec/src/aacdecoder.h b/libAACdec/src/aacdecoder.h index 20f4c45..bd1f38f 100644 --- a/libAACdec/src/aacdecoder.h +++ b/libAACdec/src/aacdecoder.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -191,6 +191,9 @@ struct AAC_DECODER_INSTANCE { INT outputInterleaved; /*!< PCM output format (interleaved/none interleaved). */ + INT aacOutDataHeadroom; /*!< Headroom of the output time signal to prevent + clipping */ + HANDLE_TRANSPORTDEC hInput; /*!< Transport layer handle. */ SamplingRateInfo @@ -235,6 +238,7 @@ struct AAC_DECODER_INSTANCE { CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[(8)]; /*!< Persistent channel memory */ + FIXP_DBL *workBufferCore1; FIXP_DBL *workBufferCore2; PCM_DEC *pTimeData2; INT timeData2Size; @@ -311,11 +315,10 @@ This structure is allocated once for each CPE. */ UCHAR limiterEnableUser; /*!< The limiter configuration requested by the library user */ UCHAR limiterEnableCurr; /*!< The current limiter configuration. */ + FIXP_DBL extGain[1]; /*!< Gain that must be applied to the output signal. */ UINT extGainDelay; /*!< Delay that must be accounted for extGain. */ - INT_PCM pcmOutputBuffer[(8) * (1024 * 2)]; - HANDLE_DRC_DECODER hUniDrcDecoder; UCHAR multibandDrcPresent; UCHAR numTimeSlots; @@ -427,7 +430,7 @@ LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, \return error status */ LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_DecodeFrame( - HANDLE_AACDECODER self, const UINT flags, FIXP_PCM *pTimeData, + HANDLE_AACDECODER self, const UINT flags, PCM_DEC *pTimeData, const INT timeDataSize, const int timeDataChannelOffset); /* Free config dependent AAC memory */ diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index 2ba0e86..f5ce7e0 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -119,8 +119,8 @@ amm-info@iis.fraunhofer.de /* Decoder library info */ #define AACDECODER_LIB_VL0 3 -#define AACDECODER_LIB_VL1 1 -#define AACDECODER_LIB_VL2 3 +#define AACDECODER_LIB_VL1 2 +#define AACDECODER_LIB_VL2 0 #define AACDECODER_LIB_TITLE "AAC Decoder Lib" #ifdef __ANDROID__ #define AACDECODER_LIB_BUILD_DATE "" @@ -1131,35 +1131,31 @@ static INT aacDecoder_EstimateNumberOfLostFrames(HANDLE_AACDECODER self) { return n; } -LINKSPEC_CPP AAC_DECODER_ERROR -aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, - const INT timeDataSize_extern, const UINT flags) { +LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self, + INT_PCM *pTimeData, + const INT timeDataSize, + const UINT flags) { AAC_DECODER_ERROR ErrorStatus; INT layer; INT nBits; + INT timeData2Size; + INT timeData3Size; + INT timeDataHeadroom; HANDLE_FDK_BITSTREAM hBs; int fTpInterruption = 0; /* Transport originated interruption detection. */ int fTpConceal = 0; /* Transport originated concealment. */ - INT_PCM *pTimeData = NULL; - INT timeDataSize = 0; UINT accessUnit = 0; UINT numAccessUnits = 1; UINT numPrerollAU = 0; - int fEndAuNotAdjusted = 0; /* The end of the access unit was not adjusted */ - int applyCrossfade = 1; /* flag indicates if flushing was possible */ - FIXP_PCM *pTimeDataFixpPcm; /* Signal buffer for decoding process before PCM - processing */ - INT timeDataFixpPcmSize; - PCM_DEC *pTimeDataPcmPost; /* Signal buffer for PCM post-processing */ - INT timeDataPcmPostSize; + int fEndAuNotAdjusted = 0; /* The end of the access unit was not adjusted */ + int applyCrossfade = 1; /* flag indicates if flushing was possible */ + PCM_DEC *pTimeData2; + PCM_AAC *pTimeData3; if (self == NULL) { return AAC_DEC_INVALID_HANDLE; } - pTimeData = self->pcmOutputBuffer; - timeDataSize = sizeof(self->pcmOutputBuffer) / sizeof(*self->pcmOutputBuffer); - if (flags & AACDEC_INTR) { self->streamInfo.numLostAccessUnits = 0; } @@ -1315,19 +1311,23 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, /* Use limiter configuration as requested. */ self->limiterEnableCurr = self->limiterEnableUser; } - /* reset limiter gain on a per frame basis */ - self->extGain[0] = FL2FXCONST_DBL(1.0f / (float)(1 << TDL_GAIN_SCALING)); - pTimeDataFixpPcm = pTimeData; - timeDataFixpPcmSize = timeDataSize; + /* reset DRC level normalization gain on a per frame basis */ + self->extGain[0] = AACDEC_DRC_GAIN_INIT_VALUE; + + pTimeData2 = self->pTimeData2; + timeData2Size = self->timeData2Size / sizeof(PCM_DEC); + pTimeData3 = (PCM_AAC *)self->pTimeData2; + timeData3Size = self->timeData2Size / sizeof(PCM_AAC); ErrorStatus = CAacDecoder_DecodeFrame( self, flags | (fTpConceal ? AACDEC_CONCEAL : 0) | ((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH : 0), - pTimeDataFixpPcm + 0, timeDataFixpPcmSize, - self->streamInfo.aacSamplesPerFrame + 0); + pTimeData2 + 0, timeData2Size, self->streamInfo.aacSamplesPerFrame + 0); + + timeDataHeadroom = self->aacOutDataHeadroom; /* if flushing for USAC DASH IPF was not possible go on with decoding * preroll */ @@ -1352,7 +1352,7 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, } } - /* If the current pTimeDataFixpPcm does not contain a valid signal, there + /* If the current pTimeData2 does not contain a valid signal, there * nothing else we can do, so bail. */ if (!IS_OUTPUT_VALID(ErrorStatus)) { goto bail; @@ -1366,10 +1366,10 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, self->streamInfo.numChannels = self->streamInfo.aacNumChannels; { - FDK_Delay_Apply(&self->usacResidualDelay, - pTimeDataFixpPcm + - 1 * (self->streamInfo.aacSamplesPerFrame + 0) + 0, - self->streamInfo.frameSize, 0); + FDK_Delay_Apply( + &self->usacResidualDelay, + pTimeData2 + 1 * (self->streamInfo.aacSamplesPerFrame + 0) + 0, + self->streamInfo.frameSize, 0); } /* Setting of internal MPS state; may be reset in CAacDecoder_SyncQmfMode @@ -1416,8 +1416,6 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, } } - self->qmfDomain.globalConf.TDinput = pTimeData; - switch (FDK_QmfDomain_Configure(&self->qmfDomain)) { default: case QMF_DOMAIN_INIT_ERROR: @@ -1474,18 +1472,18 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF, (self->mpsEnableCurr) ? 2 : 0); - INT_PCM *input; - input = (INT_PCM *)self->workBufferCore2; - FDKmemcpy(input, pTimeData, - sizeof(INT_PCM) * (self->streamInfo.numChannels) * + PCM_AAC *input; + input = (PCM_AAC *)self->workBufferCore2; + FDKmemcpy(input, pTimeData3, + sizeof(PCM_AAC) * (self->streamInfo.numChannels) * (self->streamInfo.frameSize)); /* apply SBR processing */ - sbrError = sbrDecoder_Apply(self->hSbrDecoder, input, pTimeData, - timeDataSize, &self->streamInfo.numChannels, - &self->streamInfo.sampleRate, - &self->mapDescr, self->chMapIndex, - self->frameOK, &self->psPossible); + sbrError = sbrDecoder_Apply( + self->hSbrDecoder, input, pTimeData3, timeData3Size, + &self->streamInfo.numChannels, &self->streamInfo.sampleRate, + &self->mapDescr, self->chMapIndex, self->frameOK, &self->psPossible, + self->aacOutDataHeadroom, &timeDataHeadroom); if (sbrError == SBRDEC_OK) { /* Update data in streaminfo structure. Assume that the SBR upsampling @@ -1564,10 +1562,11 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, if (err == 0) { err = mpegSurroundDecoder_Apply( (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, - (INT_PCM *)self->workBufferCore2, pTimeData, timeDataSize, + (PCM_AAC *)self->workBufferCore2, pTimeData3, timeData3Size, self->streamInfo.aacSamplesPerFrame, &nChannels, &frameSize, self->streamInfo.sampleRate, self->streamInfo.aot, - self->channelType, self->channelIndices, &self->mapDescr); + self->channelType, self->channelIndices, &self->mapDescr, + self->aacOutDataHeadroom, &timeDataHeadroom); } if (err == MPS_OUTPUT_BUFFER_TOO_SMALL) { @@ -1590,8 +1589,8 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, self->streamInfo.frameSize = self->mpsFrameSizeLast; /* ... and clear output buffer so that potentially corrupted data does * not reach the framework. */ - FDKmemclear(pTimeData, self->mpsOutChannelsLast * - self->mpsFrameSizeLast * sizeof(INT_PCM)); + FDKmemclear(pTimeData3, self->mpsOutChannelsLast * + self->mpsFrameSizeLast * sizeof(PCM_AAC)); /* Additionally proclaim that this frame had errors during decoding. */ ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR; @@ -1612,11 +1611,11 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF, 1); /* apply SBR processing */ - sbrError = sbrDecoder_Apply(self->hSbrDecoder, pTimeData, pTimeData, - timeDataSize, &self->streamInfo.numChannels, - &self->streamInfo.sampleRate, - &self->mapDescr, self->chMapIndex, - self->frameOK, &self->psPossible); + sbrError = sbrDecoder_Apply( + self->hSbrDecoder, pTimeData3, pTimeData3, timeData3Size, + &self->streamInfo.numChannels, &self->streamInfo.sampleRate, + &self->mapDescr, self->chMapIndex, self->frameOK, &self->psPossible, + self->aacOutDataHeadroom, &timeDataHeadroom); if (sbrError == SBRDEC_OK) { /* Update data in streaminfo structure. Assume that the SBR upsampling @@ -1644,17 +1643,15 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, } } - /* Use dedicated memory for PCM postprocessing */ - pTimeDataPcmPost = self->pTimeData2; - timeDataPcmPostSize = self->timeData2Size; - { - const int size = - self->streamInfo.frameSize * self->streamInfo.numChannels; - FDK_ASSERT(timeDataPcmPostSize >= size); - for (int i = 0; i < size; i++) { - pTimeDataPcmPost[i] = - (PCM_DEC)FX_PCM2PCM_DEC(pTimeData[i]) >> PCM_OUT_HEADROOM; + if ((INT)PCM_OUT_HEADROOM != timeDataHeadroom) { + for (int i = ((self->streamInfo.frameSize * + self->streamInfo.numChannels) - + 1); + i >= 0; i--) { + pTimeData2[i] = + (PCM_DEC)pTimeData3[i] >> (PCM_OUT_HEADROOM - timeDataHeadroom); + } } } @@ -1709,22 +1706,21 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, if ((self->streamInfo.numChannels > 1) && (0 || (self->sbrEnabled) || (self->mpsEnableCurr))) { /* interleaving/deinterleaving is performed on upper part of - * pTimeDataPcmPost. Check if this buffer is large enough. */ - if (timeDataPcmPostSize < - (INT)(2 * self->streamInfo.numChannels * - self->streamInfo.frameSize * sizeof(PCM_DEC))) { + * pTimeData2. Check if this buffer is large enough. */ + if (timeData2Size < (INT)(2 * self->streamInfo.numChannels * + self->streamInfo.frameSize)) { ErrorStatus = AAC_DEC_UNKNOWN; goto bail; } needsDeinterleaving = 1; drcWorkBuffer = - (FIXP_DBL *)pTimeDataPcmPost + + (FIXP_DBL *)pTimeData2 + self->streamInfo.numChannels * self->streamInfo.frameSize; FDK_deinterleave( - pTimeDataPcmPost, drcWorkBuffer, self->streamInfo.numChannels, + pTimeData2, drcWorkBuffer, self->streamInfo.numChannels, self->streamInfo.frameSize, self->streamInfo.frameSize); } else { - drcWorkBuffer = (FIXP_DBL *)pTimeDataPcmPost; + drcWorkBuffer = pTimeData2; } /* prepare Loudness Normalisation gain */ @@ -1759,7 +1755,7 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, if (needsDeinterleaving) { FDK_interleave( - drcWorkBuffer, pTimeDataPcmPost, self->streamInfo.numChannels, + drcWorkBuffer, pTimeData2, self->streamInfo.numChannels, self->streamInfo.frameSize, self->streamInfo.frameSize); } } @@ -1799,6 +1795,9 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, if (self->streamInfo.extAot != AOT_AAC_SLS) { INT pcmLimiterScale = 0; + INT interleaved = 0; + interleaved |= (self->sbrEnabled) ? 1 : 0; + interleaved |= (self->mpsEnableCurr) ? 1 : 0; PCMDMX_ERROR dmxErr = PCMDMX_OK; if ((flags & AACDEC_INTR) && (accessUnit == 0)) { /* delete data from the past (e.g. mixdown coeficients) */ @@ -1811,17 +1810,12 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, } } - INT interleaved = 0; - interleaved |= (self->sbrEnabled) ? 1 : 0; - interleaved |= (self->mpsEnableCurr) ? 1 : 0; - /* do PCM post processing */ - dmxErr = pcmDmx_ApplyFrame( - self->hPcmUtils, pTimeDataPcmPost, timeDataFixpPcmSize, - self->streamInfo.frameSize, &self->streamInfo.numChannels, - interleaved, self->channelType, self->channelIndices, - &self->mapDescr, - (self->limiterEnableCurr) ? &pcmLimiterScale : NULL); + dmxErr = pcmDmx_ApplyFrame(self->hPcmUtils, pTimeData2, timeData2Size, + self->streamInfo.frameSize, + &self->streamInfo.numChannels, interleaved, + self->channelType, self->channelIndices, + &self->mapDescr, &pcmLimiterScale); if (dmxErr == PCMDMX_OUTPUT_BUFFER_TOO_SMALL) { ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL; goto bail; @@ -1833,13 +1827,35 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR; } + pcmLimiterScale += PCM_OUT_HEADROOM; + if (flags & AACDEC_CLRHIST) { if (!(self->flags[0] & AC_USAC)) { + /* Reset DRC data */ + aacDecoder_drcReset(self->hDrcInfo); /* Delete the delayed signal. */ pcmLimiter_Reset(self->hLimiter); } } + /* Set applyExtGain if DRC processing is enabled and if + progRefLevelPresent is present for the first time. Consequences: The + headroom of the output signal can be set to AACDEC_DRC_GAIN_SCALING + only for audio formats which support legacy DRC Level Normalization. + For all other audio formats the headroom of the output + signal is set to PCM_OUT_HEADROOM. */ + if (self->hDrcInfo->enable && + (self->hDrcInfo->progRefLevelPresent == 1)) { + self->hDrcInfo->applyExtGain |= 1; + } + + /* Check whether time data buffer is large enough. */ + if (timeDataSize < + (self->streamInfo.numChannels * self->streamInfo.frameSize)) { + ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL; + goto bail; + } + if (self->limiterEnableCurr) { /* use workBufferCore2 buffer for interleaving */ PCM_LIM *pInterleaveBuffer; @@ -1848,44 +1864,72 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, /* Set actual signal parameters */ pcmLimiter_SetNChannels(self->hLimiter, self->streamInfo.numChannels); pcmLimiter_SetSampleRate(self->hLimiter, self->streamInfo.sampleRate); - pcmLimiterScale += PCM_OUT_HEADROOM; if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) || (self->mpsEnableCurr)) { - pInterleaveBuffer = (PCM_LIM *)pTimeDataPcmPost; + pInterleaveBuffer = (PCM_LIM *)pTimeData2; } else { - pInterleaveBuffer = (PCM_LIM *)pTimeData; + pInterleaveBuffer = (PCM_LIM *)self->workBufferCore2; + /* applyLimiter requests for interleaved data */ /* Interleave ouput buffer */ - FDK_interleave(pTimeDataPcmPost, pInterleaveBuffer, + FDK_interleave(pTimeData2, pInterleaveBuffer, self->streamInfo.numChannels, blockLength, self->streamInfo.frameSize); } + FIXP_DBL *pGainPerSample = NULL; + + if (self->hDrcInfo->enable && self->hDrcInfo->applyExtGain) { + pGainPerSample = self->workBufferCore1; + + if ((INT)GetRequiredMemWorkBufferCore1() < + (INT)(self->streamInfo.frameSize * sizeof(FIXP_DBL))) { + ErrorStatus = AAC_DEC_UNKNOWN; + goto bail; + } + + pcmLimiterScale = applyDrcLevelNormalization( + self->hDrcInfo, (PCM_DEC *)pInterleaveBuffer, self->extGain, + pGainPerSample, pcmLimiterScale, self->extGainDelay, + self->streamInfo.frameSize, self->streamInfo.numChannels, 1, 1); + } + pcmLimiter_Apply(self->hLimiter, pInterleaveBuffer, pTimeData, - self->extGain, &pcmLimiterScale, 1, - self->extGainDelay, self->streamInfo.frameSize); + pGainPerSample, pcmLimiterScale, + self->streamInfo.frameSize); { /* Announce the additional limiter output delay */ self->streamInfo.outputDelay += pcmLimiter_GetDelay(self->hLimiter); } } else { + if (self->hDrcInfo->enable && self->hDrcInfo->applyExtGain) { + pcmLimiterScale = applyDrcLevelNormalization( + self->hDrcInfo, pTimeData2, self->extGain, NULL, + pcmLimiterScale, self->extGainDelay, self->streamInfo.frameSize, + self->streamInfo.numChannels, + (interleaved || (self->streamInfo.numChannels == 1)) + ? 1 + : self->streamInfo.frameSize, + 0); + } + /* If numChannels = 1 we do not need interleaving. The same applies if SBR or MPS are used, since their output is interleaved already (resampled or not) */ if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) || (self->mpsEnableCurr)) { scaleValuesSaturate( - pTimeData, pTimeDataPcmPost, + pTimeData, pTimeData2, self->streamInfo.frameSize * self->streamInfo.numChannels, - PCM_OUT_HEADROOM); + pcmLimiterScale); } else { scaleValuesSaturate( - (INT_PCM *)self->workBufferCore2, pTimeDataPcmPost, + (INT_PCM *)self->workBufferCore2, pTimeData2, self->streamInfo.frameSize * self->streamInfo.numChannels, - PCM_OUT_HEADROOM); + pcmLimiterScale); /* Interleave ouput buffer */ FDK_interleave((INT_PCM *)self->workBufferCore2, pTimeData, self->streamInfo.numChannels, @@ -1981,20 +2025,8 @@ bail: ErrorStatus = AAC_DEC_UNKNOWN; } - /* Check whether external output buffer is large enough. */ - if (timeDataSize_extern < - self->streamInfo.numChannels * self->streamInfo.frameSize) { - ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL; - } - - /* Update external output buffer. */ - if (IS_OUTPUT_VALID(ErrorStatus)) { - FDKmemcpy(pTimeData_extern, pTimeData, - self->streamInfo.numChannels * self->streamInfo.frameSize * - sizeof(*pTimeData)); - } else { - FDKmemclear(pTimeData_extern, - timeDataSize_extern * sizeof(*pTimeData_extern)); + if (!IS_OUTPUT_VALID(ErrorStatus)) { + FDKmemclear(pTimeData, timeDataSize * sizeof(*pTimeData)); } return ErrorStatus; diff --git a/libAACdec/src/block.cpp b/libAACdec/src/block.cpp index b3d09a6..0bca577 100644 --- a/libAACdec/src/block.cpp +++ b/libAACdec/src/block.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -1015,9 +1015,9 @@ FIXP_DBL get_gain(const FIXP_DBL *x, const FIXP_DBL *y, int n) { void CBlock_FrequencyToTime( CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[], + CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[], const SHORT frameLen, const int frameOk, FIXP_DBL *pWorkBuffer1, - UINT elFlags, INT elCh) { + const INT aacOutDataHeadroom, UINT elFlags, INT elCh) { int fr, fl, tl, nSpec; #if defined(FDK_ASSERT_ENABLE) @@ -1213,6 +1213,7 @@ void CBlock_FrequencyToTime( bass_pf_1sf_delay(p2_synth, pitch, pit_gain, frameLen, (LpdSfd + 2) * L_SUBFR + BPF_SFD * L_SUBFR, frameLen - (LpdSfd + 4) * L_SUBFR, outSamples, + aacOutDataHeadroom, pAacDecoderStaticChannelInfo->mem_bpf); } @@ -1236,7 +1237,8 @@ void CBlock_FrequencyToTime( ? MLT_FLAG_CURR_ALIAS_SYMMETRY : 0); - scaleValuesSaturate(outSamples, tmp, frameLen, MDCT_OUT_HEADROOM); + scaleValuesSaturate(outSamples, tmp, frameLen, + MDCT_OUT_HEADROOM - aacOutDataHeadroom); } } @@ -1251,7 +1253,7 @@ void CBlock_FrequencyToTime( #include "ldfiltbank.h" void CBlock_FrequencyToTimeLowDelay( CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[], + CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[], const short frameLen) { InvMdctTransformLowDelay_fdk( SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient), diff --git a/libAACdec/src/block.h b/libAACdec/src/block.h index f0f56cd..f5118a2 100644 --- a/libAACdec/src/block.h +++ b/libAACdec/src/block.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -218,16 +218,16 @@ void ApplyTools(CAacDecoderChannelInfo *pAacDecoderChannelInfo[], */ void CBlock_FrequencyToTime( CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[], + CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[], const SHORT frameLen, const int frameOk, FIXP_DBL *pWorkBuffer1, - UINT elFlags, INT elCh); + const INT aacOutDataHeadroom, UINT elFlags, INT elCh); /** * \brief Transform double lapped MDCT (AAC-ELD) spectral data into time domain. */ void CBlock_FrequencyToTimeLowDelay( CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[], + CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[], const short frameLen); AAC_DECODER_ERROR CBlock_InverseQuantizeSpectralData( diff --git a/libAACdec/src/conceal.cpp b/libAACdec/src/conceal.cpp index 379e63a..0939bb5 100644 --- a/libAACdec/src/conceal.cpp +++ b/libAACdec/src/conceal.cpp @@ -226,7 +226,7 @@ static void CConcealment_ApplyRandomSign(int iRandomPhase, FIXP_DBL *spec, /* TimeDomainFading */ static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart, - FIXP_DBL fadeStop, FIXP_PCM *pcmdata); + FIXP_DBL fadeStop, PCM_DEC *pcmdata); static void CConcealment_TDFadeFillFadingStations(FIXP_DBL *fadingStations, int *fadingSteps, FIXP_DBL fadeStop, @@ -242,7 +242,9 @@ static int CConcealment_ApplyFadeOut( static int CConcealment_TDNoise_Random(ULONG *seed); static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo, - const int len, FIXP_PCM *const pcmdata); + const int len, + const INT aacOutDataHeadroom, + PCM_DEC *const pcmdata); static BLOCK_TYPE CConcealment_GetWinSeq(int prevWinSeq) { BLOCK_TYPE newWinSeq = BLOCK_LONG; @@ -1844,7 +1846,7 @@ Target fading level is determined by fading index cntFadeFrames. INT CConcealment_TDFading( int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo, - FIXP_PCM *pcmdata, FIXP_PCM *pcmdata_1) { + const INT aacOutDataHeadroom, PCM_DEC *pcmdata, PCM_DEC *pcmdata_1) { /* Do the fading in Time domain based on concealment states and core mode */ @@ -1957,7 +1959,8 @@ INT CConcealment_TDFading( start += len; } } - CConcealment_TDNoise_Apply(pConcealmentInfo, len, pcmdata); + CConcealment_TDNoise_Apply(pConcealmentInfo, len, aacOutDataHeadroom, + pcmdata); /* Save end-of-frame attenuation and fading type */ pConcealmentInfo->lastFadingType = fadingType; @@ -1969,12 +1972,11 @@ INT CConcealment_TDFading( /* attenuate pcmdata in Time Domain Fading process */ static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart, - FIXP_DBL fadeStop, FIXP_PCM *pcmdata) { + FIXP_DBL fadeStop, PCM_DEC *pcmdata) { int i; FIXP_DBL dStep; FIXP_DBL dGain; FIXP_DBL dGain_apply; - int bitshift = (DFRACT_BITS - SAMPLE_BITS); /* set start energy */ dGain = fadeStart; @@ -1987,7 +1989,7 @@ static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart, */ dGain_apply = fMax((FIXP_DBL)0, dGain); /* finally, attenuate samples */ - pcmdata[i] = (FIXP_PCM)((fMult(pcmdata[i], (dGain_apply))) >> bitshift); + pcmdata[i] = FIXP_DBL2PCM_DEC(fMult(pcmdata[i], dGain_apply)); } } @@ -2050,9 +2052,11 @@ static int CConcealment_TDNoise_Random(ULONG *seed) { } static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo, - const int len, FIXP_PCM *const pcmdata) { - FIXP_PCM *states = pConcealmentInfo->TDNoiseStates; - FIXP_PCM noiseVal; + const int len, + const INT aacOutDataHeadroom, + PCM_DEC *const pcmdata) { + PCM_DEC *states = pConcealmentInfo->TDNoiseStates; + PCM_DEC noiseVal; FIXP_DBL noiseValLong; FIXP_SGL *coef = pConcealmentInfo->TDNoiseCoef; FIXP_DBL TDNoiseAtt; @@ -2070,18 +2074,20 @@ static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo, /* create filtered noise */ states[2] = states[1]; states[1] = states[0]; - states[0] = ((FIXP_PCM)CConcealment_TDNoise_Random(&seed)); + states[0] = + FIXP_DBL2PCM_DEC((FIXP_DBL)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)); + noiseVal = FIXP_DBL2PCM_DEC(fMult(noiseValLong, TDNoiseAtt) >> + aacOutDataHeadroom); /* 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; + if (noiseVal > (PCM_DEC)0 && + pcmdata[ii] > (PCM_DEC)MAXVAL_PCM_DEC - noiseVal) { + noiseVal = noiseVal * (PCM_DEC)-1; + } else if (noiseVal < (PCM_DEC)0 && + pcmdata[ii] < (PCM_DEC)MINVAL_PCM_DEC - noiseVal) { + noiseVal = noiseVal * (PCM_DEC)-1; } pcmdata[ii] += noiseVal; diff --git a/libAACdec/src/conceal.h b/libAACdec/src/conceal.h index e01a796..0c002a5 100644 --- a/libAACdec/src/conceal.h +++ b/libAACdec/src/conceal.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -147,6 +147,6 @@ int CConcealment_GetLastFrameOk(CConcealmentInfo *hConcealmentInfo, INT CConcealment_TDFading( int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo, - FIXP_PCM *pcmdata, FIXP_PCM *pcmdata_1); + const INT aacOutDataHeadroom, PCM_DEC *pcmdata, PCM_DEC *pcmdata_1); #endif /* #ifndef CONCEAL_H */ diff --git a/libAACdec/src/conceal_types.h b/libAACdec/src/conceal_types.h index d90374e..36e7dec 100644 --- a/libAACdec/src/conceal_types.h +++ b/libAACdec/src/conceal_types.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -194,7 +194,7 @@ typedef struct { FIXP_DBL last_tcx_gain; INT last_tcx_gain_e; ULONG TDNoiseSeed; - FIXP_PCM TDNoiseStates[3]; + PCM_DEC TDNoiseStates[3]; FIXP_SGL TDNoiseCoef[3]; FIXP_SGL TDNoiseAtt; diff --git a/libAACdec/src/ldfiltbank.cpp b/libAACdec/src/ldfiltbank.cpp index 1898557..13e61a5 100644 --- a/libAACdec/src/ldfiltbank.cpp +++ b/libAACdec/src/ldfiltbank.cpp @@ -112,17 +112,20 @@ amm-info@iis.fraunhofer.de #if defined(__arm__) #endif -static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb, +static void multE2_DinvF_fdk(PCM_DEC *output, FIXP_DBL *x, const FIXP_WTB *fb, FIXP_DBL *z, const int N) { int i; - /* scale for FIXP_DBL -> INT_PCM conversion. */ - const int scale = (DFRACT_BITS - SAMPLE_BITS) - LDFB_HEADROOM; -#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0) + /* scale for FIXP_DBL -> PCM_DEC conversion: */ + const int scale = (DFRACT_BITS - PCM_OUT_BITS) - LDFB_HEADROOM + (3); + +#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - 1) > 0) FIXP_DBL rnd_val_wts0 = (FIXP_DBL)0; FIXP_DBL rnd_val_wts1 = (FIXP_DBL)0; +#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - WTS0 - 1) > 0) if (-WTS0 - 1 + scale) rnd_val_wts0 = (FIXP_DBL)(1 << (-WTS0 - 1 + scale - 1)); +#endif if (-WTS1 - 1 + scale) rnd_val_wts1 = (FIXP_DBL)(1 << (-WTS1 - 1 + scale - 1)); #endif @@ -141,16 +144,16 @@ static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb, tmp = (fMultDiv2(z[N / 2 + i], fb[N + N / 2 - 1 - i]) + fMultDiv2(z[i], fb[N + N / 2 + i])); -#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0) +#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - 1) > 0) FDK_ASSERT((-WTS1 - 1 + scale) >= 0); FDK_ASSERT(tmp <= ((FIXP_DBL)0x7FFFFFFF - rnd_val_wts1)); /* rounding must not cause overflow */ - output[(N * 3 / 4 - 1 - i)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT( + output[(N * 3 / 4 - 1 - i)] = (PCM_DEC)SATURATE_RIGHT_SHIFT( tmp + rnd_val_wts1, -WTS1 - 1 + scale, PCM_OUT_BITS); #else FDK_ASSERT((WTS1 + 1 - scale) >= 0); output[(N * 3 / 4 - 1 - i)] = - (FIXP_PCM)SATURATE_LEFT_SHIFT(tmp, WTS1 + 1 - scale, PCM_OUT_BITS); + (PCM_DEC)SATURATE_LEFT_SHIFT(tmp, WTS1 + 1 - scale, PCM_OUT_BITS); #endif z[i] = z0; @@ -173,22 +176,22 @@ static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb, tmp1 = (fMultDiv2(z[N / 2 + i], fb[N + N / 2 - 1 - i]) + fMultDiv2(z[i], fb[N + N / 2 + i])); -#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0) +#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - 1) > 0) FDK_ASSERT((-WTS0 - 1 + scale) >= 0); FDK_ASSERT(tmp0 <= ((FIXP_DBL)0x7FFFFFFF - rnd_val_wts0)); /* rounding must not cause overflow */ FDK_ASSERT(tmp1 <= ((FIXP_DBL)0x7FFFFFFF - rnd_val_wts1)); /* rounding must not cause overflow */ - output[(i - N / 4)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT( + output[(i - N / 4)] = (PCM_DEC)SATURATE_RIGHT_SHIFT( tmp0 + rnd_val_wts0, -WTS0 - 1 + scale, PCM_OUT_BITS); - output[(N * 3 / 4 - 1 - i)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT( + output[(N * 3 / 4 - 1 - i)] = (PCM_DEC)SATURATE_RIGHT_SHIFT( tmp1 + rnd_val_wts1, -WTS1 - 1 + scale, PCM_OUT_BITS); #else FDK_ASSERT((WTS0 + 1 - scale) >= 0); output[(i - N / 4)] = - (FIXP_PCM)SATURATE_LEFT_SHIFT(tmp0, WTS0 + 1 - scale, PCM_OUT_BITS); + (PCM_DEC)SATURATE_LEFT_SHIFT(tmp0, WTS0 + 1 - scale, PCM_OUT_BITS); output[(N * 3 / 4 - 1 - i)] = - (FIXP_PCM)SATURATE_LEFT_SHIFT(tmp1, WTS1 + 1 - scale, PCM_OUT_BITS); + (PCM_DEC)SATURATE_LEFT_SHIFT(tmp1, WTS1 + 1 - scale, PCM_OUT_BITS); #endif z[i] = z0; z[N + i] = z2; @@ -198,22 +201,22 @@ static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb, for (i = 0; i < N / 4; i++) { FIXP_DBL tmp0 = fMultDiv2(z[i], fb[N / 2 + i]); -#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0) +#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - 1) > 0) FDK_ASSERT((-WTS0 - 1 + scale) >= 0); FDK_ASSERT(tmp0 <= ((FIXP_DBL)0x7FFFFFFF - rnd_val_wts0)); /* rounding must not cause overflow */ - output[(N * 3 / 4 + i)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT( + output[(N * 3 / 4 + i)] = (PCM_DEC)SATURATE_RIGHT_SHIFT( tmp0 + rnd_val_wts0, -WTS0 - 1 + scale, PCM_OUT_BITS); #else FDK_ASSERT((WTS0 + 1 - scale) >= 0); output[(N * 3 / 4 + i)] = - (FIXP_PCM)SATURATE_LEFT_SHIFT(tmp0, WTS0 + 1 - scale, PCM_OUT_BITS); + (PCM_DEC)SATURATE_LEFT_SHIFT(tmp0, WTS0 + 1 - scale, PCM_OUT_BITS); #endif } } int InvMdctTransformLowDelay_fdk(FIXP_DBL *mdctData, const int mdctData_e, - FIXP_PCM *output, FIXP_DBL *fs_buffer, + PCM_DEC *output, FIXP_DBL *fs_buffer, const int N) { const FIXP_WTB *coef; FIXP_DBL gain = (FIXP_DBL)0; diff --git a/libAACdec/src/ldfiltbank.h b/libAACdec/src/ldfiltbank.h index b63da6b..02971d0 100644 --- a/libAACdec/src/ldfiltbank.h +++ b/libAACdec/src/ldfiltbank.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -104,9 +104,10 @@ amm-info@iis.fraunhofer.de #define LDFILTBANK_H #include "common_fix.h" +#include "aac_rom.h" int InvMdctTransformLowDelay_fdk(FIXP_DBL *mdctdata_m, const int mdctdata_e, - FIXP_PCM *mdctOut, FIXP_DBL *fs_buffer, + PCM_DEC *mdctOut, FIXP_DBL *fs_buffer, const int frameLength); #endif diff --git a/libAACdec/src/usacdec_lpd.cpp b/libAACdec/src/usacdec_lpd.cpp index de0c2de..fbf6fab 100644 --- a/libAACdec/src/usacdec_lpd.cpp +++ b/libAACdec/src/usacdec_lpd.cpp @@ -122,18 +122,21 @@ amm-info@iis.fraunhofer.de #include "ac_arith_coder.h" -void filtLP(const FIXP_DBL *syn, FIXP_PCM *syn_out, FIXP_DBL *noise, - const FIXP_SGL *filt, INT stop, int len) { +void filtLP(const FIXP_DBL *syn, PCM_DEC *syn_out, FIXP_DBL *noise, + const FIXP_SGL *filt, const INT aacOutDataHeadroom, INT stop, + int len) { INT i, j; FIXP_DBL tmp; + FDK_ASSERT((aacOutDataHeadroom - 1) >= -(MDCT_OUTPUT_SCALE)); + for (i = 0; i < stop; i++) { tmp = fMultDiv2(noise[i], filt[0]); // Filt in Q-1.16 for (j = 1; j <= len; j++) { tmp += fMult((noise[i - j] >> 1) + (noise[i + j] >> 1), filt[j]); } - syn_out[i] = (FIXP_PCM)(SATURATE_SHIFT( - (syn[i] >> 1) - (tmp >> 1), (MDCT_OUTPUT_SCALE - 1), PCM_OUT_BITS)); + syn_out[i] = (PCM_DEC)( + IMDCT_SCALE((syn[i] >> 1) - (tmp >> 1), aacOutDataHeadroom - 1)); } } @@ -143,8 +146,10 @@ void bass_pf_1sf_delay( FIXP_DBL *pit_gain, const int frame_length, /* (i) : frame length (should be 768|1024) */ const INT l_frame, - const INT l_next, /* (i) : look ahead for symmetric filtering */ - FIXP_PCM *synth_out, /* (o) : filtered synthesis (with delay of 1 subfr) */ + const INT l_next, /* (i) : look ahead for symmetric filtering */ + PCM_DEC *synth_out, /* (o) : filtered synthesis (with delay of 1 subfr) */ + const INT aacOutDataHeadroom, /* (i) : headroom of the output time signal to + prevent clipping */ FIXP_DBL mem_bpf[]) /* i/o : memory state [L_FILT+L_SUBFR] */ { INT i, sf, i_subfr, T, T2, lg; @@ -370,7 +375,7 @@ void bass_pf_1sf_delay( { filtLP(&syn[i_subfr - L_SUBFR], &synth_out[i_subfr], noise, - fdk_dec_filt_lp, L_SUBFR, L_FILT); + fdk_dec_filt_lp, aacOutDataHeadroom, L_SUBFR, L_FILT); } } @@ -383,9 +388,9 @@ void bass_pf_1sf_delay( /* Output scaling of the BPF memory */ scaleValues(mem_bpf, (L_FILT + L_SUBFR), -1); /* Copy the rest of the signal (after the fac) */ - scaleValuesSaturate((FIXP_PCM *)&synth_out[l_frame], - (FIXP_DBL *)&syn[l_frame - L_SUBFR], - (frame_length - l_frame), MDCT_OUT_HEADROOM); + scaleValuesSaturate( + (PCM_DEC *)&synth_out[l_frame], (FIXP_DBL *)&syn[l_frame - L_SUBFR], + (frame_length - l_frame), MDCT_OUT_HEADROOM - aacOutDataHeadroom); } return; @@ -1552,9 +1557,9 @@ void CLpdChannelStream_Decode( AAC_DECODER_ERROR CLpd_RenderTimeSignal( CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM *pTimeData, - INT lFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk, UINT flags, - UINT strmFlags) { + CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC *pTimeData, + INT lFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk, + const INT aacOutDataHeadroom, UINT flags, UINT strmFlags) { UCHAR *mod = pAacDecoderChannelInfo->data.usac.mod; AAC_DECODER_ERROR error = AAC_DEC_OK; int k, i_offset; @@ -2017,7 +2022,8 @@ AAC_DECODER_ERROR CLpd_RenderTimeSignal( { bass_pf_1sf_delay(p2_synth, pitch, pit_gain, lFrame, lFrame / facFB, mod[nbDiv - 1] ? (SynDelay - (lDiv / 2)) : SynDelay, - pTimeData, pAacDecoderStaticChannelInfo->mem_bpf); + pTimeData, aacOutDataHeadroom, + pAacDecoderStaticChannelInfo->mem_bpf); } } diff --git a/libAACdec/src/usacdec_lpd.h b/libAACdec/src/usacdec_lpd.h index 3e7938d..448dc55 100644 --- a/libAACdec/src/usacdec_lpd.h +++ b/libAACdec/src/usacdec_lpd.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -140,13 +140,14 @@ void CLpdChannelStream_Decode( * \param pTimeData pointer to output buffer * \param samplesPerFrame amount of output samples * \param pSamplingRateInfo holds the sampling rate information - * \param pWorkBuffer1 pointer to work buffer for temporal data + * \param aacOutDataHeadroom headroom of the output time signal to prevent + * clipping */ AAC_DECODER_ERROR CLpd_RenderTimeSignal( CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM *pTimeData, + CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC *pTimeData, INT samplesPerFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk, - UINT flags, UINT strmFlags); + const INT aacOutDataHeadroom, UINT flags, UINT strmFlags); static inline INT CLpd_FAC_getLength(int fNotShortBlock, int fac_length_long) { if (fNotShortBlock) { @@ -156,8 +157,9 @@ static inline INT CLpd_FAC_getLength(int fNotShortBlock, int fac_length_long) { } } -void filtLP(const FIXP_DBL *syn, FIXP_PCM *syn_out, FIXP_DBL *noise, - const FIXP_SGL *filt, INT stop, int len); +void filtLP(const FIXP_DBL *syn, PCM_DEC *syn_out, FIXP_DBL *noise, + const FIXP_SGL *filt, const INT aacOutDataHeadroom, INT stop, + int len); /** * \brief perform a low-frequency pitch enhancement on time domain signal @@ -171,13 +173,14 @@ void filtLP(const FIXP_DBL *syn, FIXP_PCM *syn_out, FIXP_DBL *noise, * \param[in] l_frame length of filtering, must be multiple of L_SUBFR * \param[in] l_next length of allowed look ahead on syn[i], i < l_frame+l_next * \param[out] synth_out pointer to time domain output signal + * \param[in] headroom of the output time signal to prevent clipping * \param[in,out] mem_bpf pointer to filter memory (L_FILT+L_SUBFR) */ void bass_pf_1sf_delay(FIXP_DBL syn[], const INT T_sf[], FIXP_DBL *pit_gain, const int frame_length, const INT l_frame, - const INT l_next, FIXP_PCM *synth_out, - FIXP_DBL mem_bpf[]); + const INT l_next, PCM_DEC *synth_out, + const INT aacOutDataHeadroom, FIXP_DBL mem_bpf[]); /** * \brief random sign generator for FD and TCX noise filling diff --git a/libFDK/include/FDK_qmf_domain.h b/libFDK/include/FDK_qmf_domain.h index aa247e9..0e83da3 100644 --- a/libFDK/include/FDK_qmf_domain.h +++ b/libFDK/include/FDK_qmf_domain.h @@ -160,8 +160,6 @@ H_ALLOC_MEM(QmfSlotsImag32, FIXP_DBL *) H_ALLOC_MEM(QmfOverlapBuffer16, FIXP_DBL) H_ALLOC_MEM(QmfOverlapBuffer32, FIXP_DBL) -#define QDOM_PCM INT_PCM - /** * Structure to hold the configuration data which is global whithin a QMF domain * instance. @@ -181,9 +179,6 @@ typedef struct { park a channel if only one processing channel is available. */ UCHAR parkChannel_requested; - QDOM_PCM - *TDinput; /*!< Pointer to time domain data used as input for the QMF - analysis. */ FIXP_DBL * pWorkBuffer[QMF_MAX_WB_SECTIONS]; /*!< Pointerarray to volatile memory. */ UINT flags; /*!< Flags to be set on all QMF analysis/synthesis filter diff --git a/libFDK/include/mdct.h b/libFDK/include/mdct.h index 1382374..e7cf3ad 100644 --- a/libFDK/include/mdct.h +++ b/libFDK/include/mdct.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -106,18 +106,16 @@ amm-info@iis.fraunhofer.de #include "common_fix.h" #define MDCT_OUT_HEADROOM 2 /* Output additional headroom */ -#define PCM_OUT_BITS SAMPLE_BITS + +#define PCM_OUT_BITS DFRACT_BITS #define PCM_OUT_HEADROOM 8 /* Must have the same values as DMXH_HEADROOM */ -#define MDCT_OUTPUT_SCALE (-MDCT_OUT_HEADROOM + (DFRACT_BITS - SAMPLE_BITS)) +#define MDCT_OUTPUT_SCALE (-MDCT_OUT_HEADROOM + (DFRACT_BITS - PCM_OUT_BITS)) /* Refer to "Output word length" in ISO/IEC 14496-3:2008(E) 23.2.3.6 */ #define MDCT_OUTPUT_GAIN 16 -#if (MDCT_OUTPUT_SCALE >= 0) -#define IMDCT_SCALE(x) SATURATE_RIGHT_SHIFT(x, MDCT_OUTPUT_SCALE, PCM_OUT_BITS) -#else -#define IMDCT_SCALE(x) SATURATE_LEFT_SHIFT(x, -MDCT_OUTPUT_SCALE, PCM_OUT_BITS) -#endif +#define IMDCT_SCALE(x, s) \ + SATURATE_RIGHT_SHIFT((x), ((s) + MDCT_OUTPUT_SCALE), PCM_OUT_BITS) #define IMDCT_SCALE_DBL(x) (FIXP_DBL)(x) #define IMDCT_SCALE_DBL_LSH1(x) SATURATE_LEFT_SHIFT_ALT((x), 1, DFRACT_BITS) diff --git a/libFDK/src/FDK_core.cpp b/libFDK/src/FDK_core.cpp index 75ea8a2..2f77179 100644 --- a/libFDK/src/FDK_core.cpp +++ b/libFDK/src/FDK_core.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -104,7 +104,7 @@ amm-info@iis.fraunhofer.de /* FDK tools library info */ #define FDK_TOOLS_LIB_VL0 3 -#define FDK_TOOLS_LIB_VL1 0 +#define FDK_TOOLS_LIB_VL1 1 #define FDK_TOOLS_LIB_VL2 0 #define FDK_TOOLS_LIB_TITLE "FDK Tools" #ifdef __ANDROID__ diff --git a/libFDK/src/FDK_qmf_domain.cpp b/libFDK/src/FDK_qmf_domain.cpp index 71e2ef5..77c5ca2 100644 --- a/libFDK/src/FDK_qmf_domain.cpp +++ b/libFDK/src/FDK_qmf_domain.cpp @@ -637,10 +637,10 @@ void FDK_QmfDomain_GetSlot(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch, const int ts, if (pQmfOutImag == NULL) { for (; b < fMin(lsb, stop_band); b++) { - pQmfOutReal[b] = scaleValue(real[b], lb_sf); + pQmfOutReal[b] = scaleValueSaturate(real[b], lb_sf); } for (; b < fMin(usb, stop_band); b++) { - pQmfOutReal[b] = scaleValue(real[b], hb_sf); + pQmfOutReal[b] = scaleValueSaturate(real[b], hb_sf); } for (; b < stop_band; b++) { pQmfOutReal[b] = (FIXP_DBL)0; @@ -648,12 +648,12 @@ void FDK_QmfDomain_GetSlot(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch, const int ts, } else { FDK_ASSERT(imag != NULL); for (; b < fMin(lsb, stop_band); b++) { - pQmfOutReal[b] = scaleValue(real[b], lb_sf); - pQmfOutImag[b] = scaleValue(imag[b], lb_sf); + pQmfOutReal[b] = scaleValueSaturate(real[b], lb_sf); + pQmfOutImag[b] = scaleValueSaturate(imag[b], lb_sf); } for (; b < fMin(usb, stop_band); b++) { - pQmfOutReal[b] = scaleValue(real[b], hb_sf); - pQmfOutImag[b] = scaleValue(imag[b], hb_sf); + pQmfOutReal[b] = scaleValueSaturate(real[b], hb_sf); + pQmfOutImag[b] = scaleValueSaturate(imag[b], hb_sf); } for (; b < stop_band; b++) { pQmfOutReal[b] = (FIXP_DBL)0; diff --git a/libPCMutils/include/limiter.h b/libPCMutils/include/limiter.h index fab7226..419e891 100644 --- a/libPCMutils/include/limiter.h +++ b/libPCMutils/include/limiter.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -109,8 +109,6 @@ amm-info@iis.fraunhofer.de #define TDL_ATTACK_DEFAULT_MS (15) /* default attack time in ms */ #define TDL_RELEASE_DEFAULT_MS (50) /* default release time in ms */ -#define TDL_GAIN_SCALING (15) /* scaling of gain value. */ - #ifdef __cplusplus extern "C" { #endif @@ -128,10 +126,7 @@ struct TDLimiter { unsigned int maxBufIdx, delayBufIdx; FIXP_DBL smoothState0; FIXP_DBL minGain; - - FIXP_DBL additionalGainPrev; - FIXP_DBL additionalGainFilterState; - FIXP_DBL additionalGainFilterState1; + INT scaling; }; typedef enum { @@ -255,27 +250,16 @@ TDLIMITER_ERROR pcmLimiter_SetThreshold(TDLimiterPtr limiter, /****************************************************************************** * pcmLimiter_Apply * - * limiter: limiter handle * - * pGain : pointer to gains to be applied to the signal before limiting, * - * which are downscaled by TDL_GAIN_SCALING bit. * - * These gains are delayed by gain_delay, and smoothed. * - * Smoothing is done by a butterworth lowpass filter with a cutoff * - * frequency which is fixed with respect to the sampling rate. * - * It is a substitute for the smoothing due to windowing and * - * overlap/add, if a gain is applied in frequency domain. * - * gain_scale: pointer to scaling exponents to be applied to the signal before * - * limiting, without delay and without smoothing * - * gain_size: number of elements in pGain, currently restricted to 1 * - * gain_delay: delay [samples] with which the gains in pGain shall be applied * - * gain_delay <= nSamples * - * samples: input/output buffer containing interleaved samples * - * precision of output will be DFRACT_BITS-TDL_GAIN_SCALING bits * - * nSamples: number of samples per channel * + * limiter: limiter handle * + * samplesIn: pointer to input buffer containing interleaved samples * + * samplesOut: pointer to output buffer containing interleaved samples * + * pGainPerSample: pointer to gains for each sample * + * scaling: scaling of output samples * + * nSamples: number of samples per channel * * returns: error code * ******************************************************************************/ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn, - INT_PCM* samplesOut, FIXP_DBL* pGain, - const INT* gain_scale, const UINT gain_size, - const UINT gain_delay, const UINT nSamples); + INT_PCM* samplesOut, FIXP_DBL* pGainPerSample, + const INT scaling, const UINT nSamples); #endif /* #ifndef LIMITER_H */ diff --git a/libPCMutils/src/limiter.cpp b/libPCMutils/src/limiter.cpp index 60e3e3b..598dc0c 100644 --- a/libPCMutils/src/limiter.cpp +++ b/libPCMutils/src/limiter.cpp @@ -152,7 +152,7 @@ TDLimiterPtr pcmLimiter_Create(unsigned int maxAttackMs, unsigned int releaseMs, limiter->attack = attack; limiter->attackConst = attackConst; limiter->releaseConst = releaseConst; - limiter->threshold = threshold >> TDL_GAIN_SCALING; + limiter->threshold = threshold; limiter->channels = maxChannels; limiter->maxChannels = maxChannels; limiter->sampleRate = maxSampleRate; @@ -165,18 +165,13 @@ TDLimiterPtr pcmLimiter_Create(unsigned int maxAttackMs, unsigned int releaseMs, /* apply limiter */ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn, - INT_PCM* samplesOut, FIXP_DBL* RESTRICT pGain, - const INT* RESTRICT gain_scale, - const UINT gain_size, const UINT gain_delay, - const UINT nSamples) { + INT_PCM* samplesOut, FIXP_DBL* pGainPerSample, + const INT scaling, const UINT nSamples) { unsigned int i, j; - FIXP_DBL tmp1; FIXP_DBL tmp2; - FIXP_DBL tmp, old, gain, additionalGain = 0, additionalGainUnfiltered; + FIXP_DBL tmp, old, gain, additionalGain = 0; FIXP_DBL minGain = FL2FXCONST_DBL(1.0f / (1 << 1)); - - FDK_ASSERT(gain_size == 1); - FDK_ASSERT(gain_delay <= nSamples); + UINT additionalGainAvailable = 1; if (limiter == NULL) return TDLIMIT_INVALID_HANDLE; @@ -185,7 +180,7 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn, unsigned int attack = limiter->attack; FIXP_DBL attackConst = limiter->attackConst; FIXP_DBL releaseConst = limiter->releaseConst; - FIXP_DBL threshold = limiter->threshold; + FIXP_DBL threshold = limiter->threshold >> scaling; FIXP_DBL max = limiter->max; FIXP_DBL* maxBuf = limiter->maxBuf; @@ -195,55 +190,34 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn, unsigned int delayBufIdx = limiter->delayBufIdx; FIXP_DBL smoothState0 = limiter->smoothState0; - FIXP_DBL additionalGainSmoothState = limiter->additionalGainFilterState; - FIXP_DBL additionalGainSmoothState1 = limiter->additionalGainFilterState1; - if (!gain_delay) { - additionalGain = pGain[0]; - if (gain_scale[0] > 0) { - additionalGain <<= gain_scale[0]; - } else { - additionalGain >>= -gain_scale[0]; - } + if (limiter->scaling != scaling) { + scaleValuesSaturate(delayBuf, attack * channels, + limiter->scaling - scaling); + scaleValuesSaturate(maxBuf, attack + 1, limiter->scaling - scaling); + max = scaleValueSaturate(max, limiter->scaling - scaling); + limiter->scaling = scaling; } - for (i = 0; i < nSamples; i++) { - if (gain_delay) { - if (i < gain_delay) { - additionalGainUnfiltered = limiter->additionalGainPrev; - } else { - additionalGainUnfiltered = pGain[0]; - } + if (pGainPerSample == NULL) { + additionalGainAvailable = 0; + } - /* Smooth additionalGain */ - /* [b,a] = butter(1, 0.01) */ - static const FIXP_SGL b[] = {FL2FXCONST_SGL(0.015466 * 2.0), - FL2FXCONST_SGL(0.015466 * 2.0)}; - static const FIXP_SGL a[] = {(FIXP_SGL)MAXVAL_SGL, - FL2FXCONST_SGL(-0.96907)}; - additionalGain = -fMult(additionalGainSmoothState, a[1]) + - fMultDiv2(additionalGainUnfiltered, b[0]) + - fMultDiv2(additionalGainSmoothState1, b[1]); - additionalGainSmoothState1 = additionalGainUnfiltered; - additionalGainSmoothState = additionalGain; - - /* Apply the additional scaling that has no delay and no smoothing */ - if (gain_scale[0] > 0) { - additionalGain <<= gain_scale[0]; - } else { - additionalGain >>= -gain_scale[0]; - } - } + for (i = 0; i < nSamples; i++) { /* get maximum absolute sample value of all channels, including the * additional gain. */ - tmp1 = (FIXP_DBL)0; + tmp = (FIXP_DBL)0; for (j = 0; j < channels; j++) { tmp2 = PCM_LIM2FIXP_DBL(samplesIn[j]); tmp2 = (tmp2 == (FIXP_DBL)MINVAL_DBL) ? (FIXP_DBL)MAXVAL_DBL : fAbs(tmp2); - tmp1 = fMax(tmp1, tmp2); + tmp = fMax(tmp, tmp2); + } + + if (additionalGainAvailable) { + additionalGain = pGainPerSample[i]; + tmp = fMult(tmp, additionalGain); } - tmp = fMult(tmp1, additionalGain); /* set threshold as lower border to save calculations in running maximum * algorithm */ @@ -314,22 +288,42 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn, /* lookahead delay, apply gain */ for (j = 0; j < channels; j++) { tmp = p_delayBuf[j]; - p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain); + + if (additionalGainAvailable) { + p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain); + } else { + p_delayBuf[j] = PCM_LIM2FIXP_DBL(samplesIn[j]); + } /* Apply gain to delayed signal */ tmp = fMultDiv2(tmp, gain); - +#if (SAMPLE_BITS == DFRACT_BITS) + samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM( + (FIXP_DBL)SATURATE_LEFT_SHIFT(tmp, scaling + 1, DFRACT_BITS)); +#else samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM((FIXP_DBL)SATURATE_LEFT_SHIFT( - tmp, TDL_GAIN_SCALING + 1, DFRACT_BITS)); + tmp + ((FIXP_DBL)0x8000 >> (scaling + 1)), scaling + 1, + DFRACT_BITS)); +#endif } gain >>= 1; } else { /* lookahead delay, apply gain=1.0f */ for (j = 0; j < channels; j++) { tmp = p_delayBuf[j]; - p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain); + if (additionalGainAvailable) { + p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain); + } else { + p_delayBuf[j] = PCM_LIM2FIXP_DBL(samplesIn[j]); + } + +#if (SAMPLE_BITS == DFRACT_BITS) + samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM( + (FIXP_DBL)SATURATE_LEFT_SHIFT(tmp, scaling, DFRACT_BITS)); +#else samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM((FIXP_DBL)SATURATE_LEFT_SHIFT( - tmp, TDL_GAIN_SCALING, DFRACT_BITS)); + tmp + ((FIXP_DBL)0x8000 >> scaling), scaling, DFRACT_BITS)); +#endif } } @@ -354,13 +348,9 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn, limiter->delayBufIdx = delayBufIdx; limiter->smoothState0 = smoothState0; - limiter->additionalGainFilterState = additionalGainSmoothState; - limiter->additionalGainFilterState1 = additionalGainSmoothState1; limiter->minGain = minGain; - limiter->additionalGainPrev = pGain[0]; - return TDLIMIT_OK; } } @@ -370,7 +360,7 @@ TDLIMITER_ERROR pcmLimiter_SetThreshold(TDLimiterPtr limiter, FIXP_DBL threshold) { if (limiter == NULL) return TDLIMIT_INVALID_HANDLE; - limiter->threshold = threshold >> TDL_GAIN_SCALING; + limiter->threshold = threshold; return TDLIMIT_OK; } @@ -384,13 +374,7 @@ TDLIMITER_ERROR pcmLimiter_Reset(TDLimiterPtr limiter) { limiter->cor = FL2FXCONST_DBL(1.0f / (1 << 1)); limiter->smoothState0 = FL2FXCONST_DBL(1.0f / (1 << 1)); limiter->minGain = FL2FXCONST_DBL(1.0f / (1 << 1)); - - limiter->additionalGainPrev = - FL2FXCONST_DBL(1.0f / (1 << TDL_GAIN_SCALING)); - limiter->additionalGainFilterState = - FL2FXCONST_DBL(1.0f / (1 << TDL_GAIN_SCALING)); - limiter->additionalGainFilterState1 = - FL2FXCONST_DBL(1.0f / (1 << TDL_GAIN_SCALING)); + limiter->scaling = 0; FDKmemset(limiter->maxBuf, 0, (limiter->attack + 1) * sizeof(FIXP_DBL)); FDKmemset(limiter->delayBuf, 0, diff --git a/libPCMutils/src/version.h b/libPCMutils/src/version.h index fa31af1..05371f8 100644 --- a/libPCMutils/src/version.h +++ b/libPCMutils/src/version.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -105,7 +105,7 @@ amm-info@iis.fraunhofer.de /* library info */ #define PCMUTIL_LIB_VL0 3 -#define PCMUTIL_LIB_VL1 0 +#define PCMUTIL_LIB_VL1 1 #define PCMUTIL_LIB_VL2 0 #define PCMUTIL_LIB_TITLE "PCM Utility Lib" #ifdef __ANDROID__ diff --git a/libSACdec/include/sac_dec_lib.h b/libSACdec/include/sac_dec_lib.h index 9913279..1827504 100644 --- a/libSACdec/include/sac_dec_lib.h +++ b/libSACdec/include/sac_dec_lib.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -252,7 +252,7 @@ typedef enum { scenario. Default parameter value is 3 frames. */ } SACDEC_PARAM; -#define PCM_MPS INT_PCM +#define PCM_MPS LONG /** * \brief MPEG Surround decoder handle. @@ -401,17 +401,22 @@ int mpegSurroundDecoder_Parse(CMpegSurroundDecoder *pMpegSurroundDecoder, * for each output audio channel is stored into. * \param mapDescr Channep map descriptor for output channel mapping * to be used (From MPEG PCE ordering to whatever is required). + * \param inDataHeadroom Headroom of SAC input time signal to prevent + * clipping. + * \param outDataHeadroom Pointer to headroom of SAC output time signal to + * prevent clipping. * * \return Error code. */ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder, - INT_PCM *input, PCM_MPS *pTimeData, + PCM_MPS *input, PCM_MPS *pTimeData, const int timeDataSize, int timeDataFrameSize, int *nChannels, int *frameSize, int sampleRate, AUDIO_OBJECT_TYPE coreCodec, AUDIO_CHANNEL_TYPE channelType[], UCHAR channelIndices[], - const FDK_channelMapDescr *const mapDescr); + const FDK_channelMapDescr *const mapDescr, + const INT inDataHeadroom, INT *outDataHeadroom); /** * \brief Deallocate a MPEG Surround decoder instance. diff --git a/libSACdec/src/sac_dec.cpp b/libSACdec/src/sac_dec.cpp index c1832f1..a7b50df 100644 --- a/libSACdec/src/sac_dec.cpp +++ b/libSACdec/src/sac_dec.cpp @@ -766,7 +766,7 @@ SACDEC_ERROR FDK_SpatialDecInit(spatialDec *self, SPATIAL_BS_FRAME *frame, /* output scaling */ for (nCh = 0; nCh < self->numOutputChannelsAT; nCh++) { - int outputScale = 0, outputGain_e = 0, scale = 0; + int outputScale = 0, outputGain_e = 0, scale = -(8) + (1); FIXP_DBL outputGain_m = getChGain(self, nCh, &outputGain_e); if (!isTwoChMode(self->upmixType) && !bypassMode) { @@ -775,7 +775,7 @@ SACDEC_ERROR FDK_SpatialDecInit(spatialDec *self, SPATIAL_BS_FRAME *frame, synthesis qmf */ } - scale = outputScale; + scale += outputScale; qmfChangeOutScalefactor(&self->pQmfDomain->QmfDomainOut[nCh].fb, scale); qmfChangeOutGain(&self->pQmfDomain->QmfDomainOut[nCh].fb, outputGain_m, @@ -1223,18 +1223,24 @@ static SACDEC_ERROR SpatialDecApplyParameterSets( !(self->stereoConfigIndex == 3)) { for (i = 0; i < self->qmfBands; i++) { self_qmfResidualReal__FDK_0_0[i] = - fMult(self_qmfResidualReal__FDK_0_0[i] << 1, + fMult(scaleValueSaturate(self_qmfResidualReal__FDK_0_0[i], + 1 + self->sacInDataHeadroom - (1)), self->clipProtectGain__FDK); self_qmfResidualImag__FDK_0_0[i] = - fMult(self_qmfResidualImag__FDK_0_0[i] << 1, + fMult(scaleValueSaturate(self_qmfResidualImag__FDK_0_0[i], + 1 + self->sacInDataHeadroom - (1)), self->clipProtectGain__FDK); } } else { for (i = 0; i < self->qmfBands; i++) { - self_qmfResidualReal__FDK_0_0[i] = fMult( - self_qmfResidualReal__FDK_0_0[i], self->clipProtectGain__FDK); - self_qmfResidualImag__FDK_0_0[i] = fMult( - self_qmfResidualImag__FDK_0_0[i], self->clipProtectGain__FDK); + self_qmfResidualReal__FDK_0_0[i] = + fMult(scaleValueSaturate(self_qmfResidualReal__FDK_0_0[i], + self->sacInDataHeadroom - (1)), + self->clipProtectGain__FDK); + self_qmfResidualImag__FDK_0_0[i] = + fMult(scaleValueSaturate(self_qmfResidualImag__FDK_0_0[i], + self->sacInDataHeadroom - (1)), + self->clipProtectGain__FDK); } } } @@ -1416,6 +1422,7 @@ SACDEC_ERROR SpatialDecApplyFrame( FDK_ASSERT(self != NULL); FDK_ASSERT(pControlFlags != NULL); FDK_ASSERT(pcmOutBuf != NULL); + FDK_ASSERT(self->sacInDataHeadroom >= (1)); self->errInt = err; /* Init internal error */ diff --git a/libSACdec/src/sac_dec.h b/libSACdec/src/sac_dec.h index 992acad..1c3df71 100644 --- a/libSACdec/src/sac_dec.h +++ b/libSACdec/src/sac_dec.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -523,6 +523,9 @@ struct spatialDec_struct { new frame after SSC change (aka decodeAfterConfigHasChangedFlag). */ SpatialDecConcealmentInfo concealInfo; + + INT sacInDataHeadroom; /* Headroom of the SAC input time signal to prevent + clipping */ }; #define SACDEC_SYNTAX_MPS 1 diff --git a/libSACdec/src/sac_dec_interface.h b/libSACdec/src/sac_dec_interface.h index a2eea92..05a9a75 100644 --- a/libSACdec/src/sac_dec_interface.h +++ b/libSACdec/src/sac_dec_interface.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -249,10 +249,10 @@ typedef struct { } MEM_REQUIREMENTS; -#define PCM_MPS INT_PCM -#define PCM_MPSF FIXP_PCM +#define PCM_MPS LONG +#define PCM_MPSF FIXP_DBL -#define FIXP_DBL2PCM_MPS(x) ((INT_PCM)FX_DBL2FX_PCM(x)) +#define FIXP_DBL2PCM_MPS(x) ((LONG)(x)) /* exposed functions (library interface) */ diff --git a/libSACdec/src/sac_dec_lib.cpp b/libSACdec/src/sac_dec_lib.cpp index bf6dedf..856a923 100644 --- a/libSACdec/src/sac_dec_lib.cpp +++ b/libSACdec/src/sac_dec_lib.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -1507,15 +1507,17 @@ bail: } int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder, - INT_PCM *input, PCM_MPS *pTimeData, + PCM_MPS *input, PCM_MPS *pTimeData, const int timeDataSize, int timeDataFrameSize, int *nChannels, int *frameSize, int sampleRate, AUDIO_OBJECT_TYPE coreCodec, AUDIO_CHANNEL_TYPE channelType[], UCHAR channelIndices[], - const FDK_channelMapDescr *const mapDescr) { + const FDK_channelMapDescr *const mapDescr, + const INT inDataHeadroom, INT *outDataHeadroom) { SACDEC_ERROR err = MPS_OK; PCM_MPS *pTimeOut = pTimeData; + PCM_MPS *TDinput = NULL; UINT initControlFlags = 0, controlFlags = 0; int timeDataRequiredSize = 0; int newData; @@ -1534,6 +1536,9 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder, return MPS_NOTOK; } + pMpegSurroundDecoder->pSpatialDec->sacInDataHeadroom = inDataHeadroom; + *outDataHeadroom = (INT)(8); + pMpegSurroundDecoder->pSpatialDec->pConfigCurrent = &pMpegSurroundDecoder ->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameDecode]; @@ -1682,8 +1687,7 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder, (timeDataFrameSize * pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsSynthesis) / pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsAnalysis; - pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput = - pTimeData + timeDataFrameSizeOut - timeDataFrameSize; + TDinput = pTimeData + timeDataFrameSizeOut - timeDataFrameSize; for (int i = *nChannels - 1; i >= 0; i--) { FDKmemmove(pTimeData + (i + 1) * timeDataFrameSizeOut - timeDataFrameSize, pTimeData + timeDataFrameSize * i, @@ -1694,8 +1698,8 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder, } else { if (pMpegSurroundDecoder->mpegSurroundUseTimeInterface) { FDKmemcpy(input, pTimeData, - sizeof(INT_PCM) * (*nChannels) * (*frameSize)); - pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput = input; + sizeof(PCM_MPS) * (*nChannels) * (*frameSize)); + TDinput = input; } } @@ -1707,8 +1711,8 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder, &pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameDecode], pMpegSurroundDecoder->mpegSurroundUseTimeInterface ? INPUTMODE_TIME : INPUTMODE_QMF_SBR, - pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput, NULL, NULL, - pTimeOut, *frameSize, &controlFlags, *nChannels, mapDescr); + TDinput, NULL, NULL, pTimeOut, *frameSize, &controlFlags, *nChannels, + mapDescr); *nChannels = pMpegSurroundDecoder->pSpatialDec->numOutputChannelsAT; if (err != @@ -1781,7 +1785,7 @@ void mpegSurroundDecoder_Close(CMpegSurroundDecoder *pMpegSurroundDecoder) { } #define SACDEC_VL0 2 -#define SACDEC_VL1 0 +#define SACDEC_VL1 1 #define SACDEC_VL2 0 int mpegSurroundDecoder_GetLibInfo(LIB_INFO *info) { diff --git a/libSACdec/src/sac_process.cpp b/libSACdec/src/sac_process.cpp index 95128f3..22091a9 100644 --- a/libSACdec/src/sac_process.cpp +++ b/libSACdec/src/sac_process.cpp @@ -187,8 +187,12 @@ SACDEC_ERROR SpatialDecQMFAnalysis(spatialDec *self, const PCM_MPS *inData, if (!isTwoChMode(self->upmixType) && !bypassMode) { int i; for (i = 0; i < self->qmfBands; i++) { - qmfReal[ch][i] = fMult(qmfReal[ch][i], self->clipProtectGain__FDK); - qmfImag[ch][i] = fMult(qmfImag[ch][i], self->clipProtectGain__FDK); + qmfReal[ch][i] = fMult( + scaleValueSaturate(qmfReal[ch][i], self->sacInDataHeadroom - (1)), + self->clipProtectGain__FDK); + qmfImag[ch][i] = fMult( + scaleValueSaturate(qmfImag[ch][i], self->sacInDataHeadroom - (1)), + self->clipProtectGain__FDK); } } } @@ -216,16 +220,17 @@ SACDEC_ERROR SpatialDecFeedQMF(spatialDec *self, FIXP_DBL **qmfInDataReal, /* Write Input data to pQmfRealAnalysis. */ if (self->bShareDelayWithSBR) { - FDK_QmfDomain_GetSlot( - &self->pQmfDomain->QmfDomainIn[ch], ts + HYBRID_FILTER_DELAY, 0, - MAX_QMF_BANDS_TO_HYBRID, pQmfRealAnalysis, pQmfImagAnalysis, 15); + FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch], + ts + HYBRID_FILTER_DELAY, 0, + MAX_QMF_BANDS_TO_HYBRID, pQmfRealAnalysis, + pQmfImagAnalysis, 15 + (1)); FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch], ts, MAX_QMF_BANDS_TO_HYBRID, self->qmfBands, - pQmfRealAnalysis, pQmfImagAnalysis, 15); + pQmfRealAnalysis, pQmfImagAnalysis, 15 + (1)); } else { FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch], ts, 0, self->qmfBands, pQmfRealAnalysis, - pQmfImagAnalysis, 15); + pQmfImagAnalysis, 15 + (1)); } if (ts == self->pQmfDomain->globalConf.nQmfTimeSlots - 1) { /* Is currently also needed in case we dont have any overlap. We need to @@ -501,8 +506,8 @@ SACDEC_ERROR SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding( for (pb = 0, qs = 3; pb < 2; pb++) { INT s; FIXP_DBL maxVal; - FIXP_SGL mReal1; - FIXP_SGL mReal0, mImag0; + FIXP_DBL mReal1; + FIXP_DBL mReal0, mImag0; FIXP_DBL iReal0, iImag0, iReal1; iReal0 = interpolateParameter(alpha, MReal0[pb], MRealPrev0[pb]); @@ -515,9 +520,9 @@ SACDEC_ERROR SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding( s = fMax(CntLeadingZeros(maxVal) - 1, 0); s = fMin(s, scale_param_m2); - mReal0 = FX_DBL2FX_SGL(iReal0 << s); - mImag0 = FX_DBL2FX_SGL(iImag0 << s); - mReal1 = FX_DBL2FX_SGL(iReal1 << s); + mReal0 = iReal0 << s; + mImag0 = iImag0 << s; + mReal1 = iReal1 << s; s = scale_param_m2 - s; @@ -934,6 +939,7 @@ SACDEC_ERROR SpatialDecSynthesis(spatialDec *self, const INT ts, self->pQmfDomain->QmfDomainIn[outCh].scaling.lb_scale -= self->clipProtectGainSF__FDK; + self->pQmfDomain->QmfDomainIn[outCh].scaling.lb_scale -= (1); } else { /* Call the QMF synthesis for dry. */ err = CalculateSpaceSynthesisQmf(&self->pQmfDomain->QmfDomainOut[outCh], diff --git a/libSACdec/src/sac_qmf.cpp b/libSACdec/src/sac_qmf.cpp index a075490..fd7599d 100644 --- a/libSACdec/src/sac_qmf.cpp +++ b/libSACdec/src/sac_qmf.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -110,7 +110,7 @@ amm-info@iis.fraunhofer.de SACDEC_ERROR CalculateSpaceSynthesisQmf( const HANDLE_FDK_QMF_DOMAIN_OUT hQmfDomainOutCh, const FIXP_DBL *Sr, - const FIXP_DBL *Si, const INT stride, INT_PCM *timeSig) { + const FIXP_DBL *Si, const INT stride, PCM_MPS *timeSig) { SACDEC_ERROR err = MPS_OK; if (hQmfDomainOutCh == NULL) { diff --git a/libSACdec/src/sac_qmf.h b/libSACdec/src/sac_qmf.h index d1dc837..5cd573e 100644 --- a/libSACdec/src/sac_qmf.h +++ b/libSACdec/src/sac_qmf.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -124,7 +124,7 @@ amm-info@iis.fraunhofer.de */ SACDEC_ERROR CalculateSpaceSynthesisQmf( const HANDLE_FDK_QMF_DOMAIN_OUT hQmfDomainOutCh, const FIXP_DBL *Sr, - const FIXP_DBL *Si, const INT stride, INT_PCM *timeSig); + const FIXP_DBL *Si, const INT stride, PCM_MPS *timeSig); /** * \brief Convert audio input data to qmf representation. diff --git a/libSACdec/src/sac_reshapeBBEnv.cpp b/libSACdec/src/sac_reshapeBBEnv.cpp index b44ce4e..272d009 100644 --- a/libSACdec/src/sac_reshapeBBEnv.cpp +++ b/libSACdec/src/sac_reshapeBBEnv.cpp @@ -253,17 +253,17 @@ static inline void slotAmp(FIXP_DBL *RESTRICT slotAmp_dry, dry = wet = FL2FXCONST_DBL(0.0f); for (qs = 0; qs < cplxBands; qs++) { - dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs]) + - fPow2Div2(pHybOutputImagDry[qs])); - wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs]) + - fPow2Div2(pHybOutputImagWet[qs])); + dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs] << (1)) + + fPow2Div2(pHybOutputImagDry[qs] << (1))); + wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs] << (1)) + + fPow2Div2(pHybOutputImagWet[qs] << (1))); } for (; qs < hybBands; qs++) { - dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs])); - wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs])); + dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs] << (1))); + wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs] << (1))); } - *slotAmp_dry = dry; - *slotAmp_wet = wet; + *slotAmp_dry = dry >> (2 * (1)); + *slotAmp_wet = wet >> (2 * (1)); } #if defined(__aarch64__) @@ -327,7 +327,7 @@ static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels, INT shapeActiv = 1; INT hybBands = fixMin(42, self->hybridBands); - INT staticScale = self->staticDecScale; + INT staticScale = self->staticDecScale + (1); INT cplxBands; cplxBands = fixMin(42, self->hybridBands); diff --git a/libSACdec/src/sac_rom.h b/libSACdec/src/sac_rom.h index 38f17f2..d317856 100644 --- a/libSACdec/src/sac_rom.h +++ b/libSACdec/src/sac_rom.h @@ -111,21 +111,12 @@ amm-info@iis.fraunhofer.de #include "machine_type.h" /* Global ROM table data type: */ -#ifndef ARCH_PREFER_MULT_32x32 -#define FIXP_CFG FIXP_SGL -#define FX_CFG2FX_DBL FX_SGL2FX_DBL -#define FX_CFG2FX_SGL -#define CFG(a) (FX_DBL2FXCONST_SGL(a)) -#define FL2FXCONST_CFG FL2FXCONST_SGL -#define FX_DBL2FX_CFG(x) FX_DBL2FX_SGL((FIXP_DBL)(x)) -#else #define FIXP_CFG FIXP_DBL #define FX_CFG2FX_DBL #define FX_CFG2FX_SGL FX_DBL2FX_SGL #define CFG(a) FIXP_DBL(a) #define FL2FXCONST_CFG FL2FXCONST_DBL #define FX_DBL2FX_CFG(x) ((FIXP_DBL)(x)) -#endif /* others */ #define SCALE_INV_ICC (2) @@ -133,15 +124,9 @@ amm-info@iis.fraunhofer.de #define QCC_SCALE 1 #define M1M2_DATA FIXP_DBL -#ifndef ARCH_PREFER_MULT_32x32 -#define M1M2_CDATA FIXP_SGL -#define M1M2_CDATA2FX_DBL(a) FX_SGL2FX_DBL(a) -#define FX_DBL2M1M2_CDATA(a) FX_DBL2FX_SGL(a) -#else #define M1M2_CDATA FIXP_DBL #define M1M2_CDATA2FX_DBL(a) (a) #define FX_DBL2M1M2_CDATA(a) (a) -#endif #define CLIP_PROTECT_GAIN_0(x) FL2FXCONST_CFG(((x) / (float)(1 << 0))) #define CLIP_PROTECT_GAIN_1(x) FL2FXCONST_CFG(((x) / (float)(1 << 1))) diff --git a/libSBRdec/include/sbrdecoder.h b/libSBRdec/include/sbrdecoder.h index cc55572..c09c985 100644 --- a/libSBRdec/include/sbrdecoder.h +++ b/libSBRdec/include/sbrdecoder.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -361,15 +361,20 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs, * error (0: core decoder found errors, 1: no errors). * \param psDecoded Pointer to a buffer holding a flag. Input: PS is * possible, Output: PS has been rendered. + * \param inDataHeadroom Headroom of the SBR input time signal to prevent + * clipping. + * \param outDataHeadroom Pointer to headroom of the SBR output time signal to + * prevent clipping. * * \return Error code. */ -SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input, - INT_PCM *timeData, const int timeDataSize, - int *numChannels, int *sampleRate, +SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, LONG *input, LONG *timeData, + const int timeDataSize, int *numChannels, + int *sampleRate, const FDK_channelMapDescr *const mapDescr, const int mapIdx, const int coreDecodedOk, - UCHAR *psDecoded); + UCHAR *psDecoded, const INT inDataHeadroom, + INT *outDataHeadroom); /** * \brief Close SBR decoder instance and free memory. diff --git a/libSBRdec/src/HFgen_preFlat.cpp b/libSBRdec/src/HFgen_preFlat.cpp index 268011e..ad4caba 100644 --- a/libSBRdec/src/HFgen_preFlat.cpp +++ b/libSBRdec/src/HFgen_preFlat.cpp @@ -897,10 +897,10 @@ void sbrDecoder_calculateGainVec(FIXP_DBL **sourceBufferReal, for (i = startSample; i < stopSample; i++) { maxVal |= (FIXP_DBL)((LONG)(sourceBufferReal[i][loBand]) ^ - ((LONG)sourceBufferReal[i][loBand] >> (SAMPLE_BITS - 1))); + ((LONG)sourceBufferReal[i][loBand] >> (DFRACT_BITS - 1))); maxVal |= (FIXP_DBL)((LONG)(sourceBufferImag[i][loBand]) ^ - ((LONG)sourceBufferImag[i][loBand] >> (SAMPLE_BITS - 1))); + ((LONG)sourceBufferImag[i][loBand] >> (DFRACT_BITS - 1))); } if (maxVal != FL2FX_DBL(0.0f)) { diff --git a/libSBRdec/src/hbe.cpp b/libSBRdec/src/hbe.cpp index 2284c42..d210bb6 100644 --- a/libSBRdec/src/hbe.cpp +++ b/libSBRdec/src/hbe.cpp @@ -957,7 +957,7 @@ QmfTransposerCreate(HANDLE_HBE_TRANSPOSER* hQmfTransposer, const int frameSize, hQmfTran->qmfOutBufSize = 2 * (hQmfTran->noCols / 2 + QMF_WIN_LEN - 1); hQmfTran->inBuf_F = - (INT_PCM*)FDKcalloc(QMF_SYNTH_CHANNELS + 20 + 1, sizeof(INT_PCM)); + (LONG*)FDKcalloc(QMF_SYNTH_CHANNELS + 20 + 1, sizeof(LONG)); /* buffered time signal needs to be delayed by synthesis_size; max * synthesis_size = 20; */ if (hQmfTran->inBuf_F == NULL) { diff --git a/libSBRdec/src/hbe.h b/libSBRdec/src/hbe.h index fdffe1e..3556783 100644 --- a/libSBRdec/src/hbe.h +++ b/libSBRdec/src/hbe.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -132,6 +132,9 @@ typedef enum { } KEEP_STATES_SYNCED_MODE; struct hbeTransposer { + FIXP_DBL anaQmfStates[HBE_QMF_FILTER_STATE_ANA_SIZE]; + FIXP_QSS synQmfStates[HBE_QMF_FILTER_STATE_SYN_SIZE]; + int xOverQmf[MAX_NUM_PATCHES_HBE]; int maxStretch; @@ -144,7 +147,7 @@ struct hbeTransposer { int stopBand; int bSbr41; - INT_PCM *inBuf_F; + LONG *inBuf_F; FIXP_DBL **qmfInBufReal_F; FIXP_DBL **qmfInBufImag_F; @@ -156,9 +159,6 @@ struct hbeTransposer { FIXP_DBL const *synthesisQmfPreModCos_F; FIXP_DBL const *synthesisQmfPreModSin_F; - FIXP_QAS anaQmfStates[HBE_QMF_FILTER_STATE_ANA_SIZE]; - FIXP_QSS synQmfStates[HBE_QMF_FILTER_STATE_SYN_SIZE]; - FIXP_DBL **qmfHBEBufReal_F; FIXP_DBL **qmfHBEBufImag_F; diff --git a/libSBRdec/src/sbr_dec.cpp b/libSBRdec/src/sbr_dec.cpp index 30611e7..b1fb0da 100644 --- a/libSBRdec/src/sbr_dec.cpp +++ b/libSBRdec/src/sbr_dec.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -259,17 +259,18 @@ static void copyHarmonicSpectrum(int *xOverQmf, FIXP_DBL **qmfReal, void sbr_dec( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */ - INT_PCM *timeIn, /*!< pointer to input time signal */ - INT_PCM *timeOut, /*!< pointer to output time signal */ + LONG *timeIn, /*!< pointer to input time signal */ + LONG *timeOut, /*!< pointer to output time signal */ HANDLE_SBR_DEC hSbrDecRight, /*!< handle to Decoder channel right */ - INT_PCM *timeOutRight, /*!< pointer to output time signal */ + LONG *timeOutRight, /*!< pointer to output time signal */ const int strideOut, /*!< Time data traversal strideOut */ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */ HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, /*!< Some control data of last frame */ const int applyProcessing, /*!< Flag for SBR operation */ - HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize) { + HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize, + const INT sbrInDataHeadroom) { int i, slot, reserve; int saveLbScale; int lastSlotOffs; @@ -278,7 +279,7 @@ void sbr_dec( /* temporary pointer / variable for QMF; required as we want to use temporary buffer creating one frame delay for HBE in LP mode */ - INT_PCM *pTimeInQmf = timeIn; + LONG *pTimeInQmf = timeIn; /* Number of QMF timeslots in the overlap buffer: */ int ov_len = hSbrDec->LppTrans.pSettings->overlap; @@ -341,8 +342,8 @@ void sbr_dec( } else { C_AALLOC_SCRATCH_START(qmfTemp, FIXP_DBL, 2 * (64)); qmfAnalysisFiltering(&hSbrDec->qmfDomainInCh->fb, pReal, pImag, - &hSbrDec->qmfDomainInCh->scaling, pTimeInQmf, 0, 1, - qmfTemp); + &hSbrDec->qmfDomainInCh->scaling, pTimeInQmf, + 0 + sbrInDataHeadroom, 1, qmfTemp); C_AALLOC_SCRATCH_END(qmfTemp, FIXP_DBL, 2 * (64)); } @@ -658,7 +659,7 @@ void sbr_dec( if (!(flags & SBRDEC_PS_DECODED)) { if (!(flags & SBRDEC_SKIP_QMF_SYN)) { - int outScalefactor = 0; + int outScalefactor = -(8); if (h_ps_d != NULL) { h_ps_d->procFrameBased = 1; /* we here do frame based processing */ @@ -743,6 +744,7 @@ void sbr_dec( */ FDK_ASSERT(hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis <= QMF_MAX_SYNTHESIS_BANDS); + qmfChangeOutScalefactor(synQmfRight, -(8)); FDKmemcpy(synQmfRight->FilterStates, synQmf->FilterStates, 9 * hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis * sizeof(FIXP_QSS)); @@ -814,7 +816,8 @@ void sbr_dec( : scaleFactorLowBand_no_ov, scaleFactorHighBand, synQmf->lsb, synQmf->usb); - outScalefactorL = outScalefactorR = 1; /* psDiffScale! (MPEG-PS) */ + outScalefactorL = outScalefactorR = + 1 + sbrInDataHeadroom; /* psDiffScale! (MPEG-PS) */ } sbrDecoder_drcApplySlot(/* right channel */ @@ -831,6 +834,9 @@ void sbr_dec( outScalefactorL += maxShift; if (!(flags & SBRDEC_SKIP_QMF_SYN)) { + qmfChangeOutScalefactor(synQmf, -(8)); + qmfChangeOutScalefactor(synQmfRight, -(8)); + qmfSynthesisFilteringSlot( synQmfRight, rQmfReal, /* QMF real buffer */ rQmfImag, /* QMF imag buffer */ diff --git a/libSBRdec/src/sbr_dec.h b/libSBRdec/src/sbr_dec.h index 156da03..eb9c394 100644 --- a/libSBRdec/src/sbr_dec.h +++ b/libSBRdec/src/sbr_dec.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -176,17 +176,18 @@ typedef SBR_CHANNEL *HANDLE_SBR_CHANNEL; void sbr_dec( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */ - INT_PCM *timeIn, /*!< pointer to input time signal */ - INT_PCM *timeOut, /*!< pointer to output time signal */ + LONG *timeIn, /*!< pointer to input time signal */ + LONG *timeOut, /*!< pointer to output time signal */ HANDLE_SBR_DEC hSbrDecRight, /*!< handle to Decoder channel right */ - INT_PCM *timeOutRight, /*!< pointer to output time signal */ + LONG *timeOutRight, /*!< pointer to output time signal */ INT strideOut, /*!< Time data traversal strideOut */ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */ HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, /*!< Some control data of last frame */ const int applyProcessing, /*!< Flag for SBR operation */ - HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize); + HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize, + const INT sbrInDataHeadroom); SBR_ERROR createSbrDec(SBR_CHANNEL *hSbrChannel, HANDLE_SBR_HEADER_DATA hHeaderData, diff --git a/libSBRdec/src/sbr_ram.h b/libSBRdec/src/sbr_ram.h index e00f8b5..452f835 100644 --- a/libSBRdec/src/sbr_ram.h +++ b/libSBRdec/src/sbr_ram.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -170,6 +170,9 @@ struct SBR_DECODER_INSTANCE { flushed consecutively. */ UINT flags; + + INT sbrInDataHeadroom; /* Headroom of the SBR input time signal to prevent + clipping */ }; H_ALLOC_MEM(Ram_SbrDecElement, SBR_DECODER_ELEMENT) diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp index 52403f6..6e4aad4 100644 --- a/libSBRdec/src/sbrdecoder.cpp +++ b/libSBRdec/src/sbrdecoder.cpp @@ -155,7 +155,7 @@ amm-info@iis.fraunhofer.de /* Decoder library info */ #define SBRDECODER_LIB_VL0 3 -#define SBRDECODER_LIB_VL1 0 +#define SBRDECODER_LIB_VL1 1 #define SBRDECODER_LIB_VL2 0 #define SBRDECODER_LIB_TITLE "SBR Decoder" #ifdef __ANDROID__ @@ -1570,10 +1570,10 @@ bail: * \return SBRDEC_OK if successfull, else error code */ static SBR_ERROR sbrDecoder_DecodeElement( - HANDLE_SBRDECODER self, QDOM_PCM *input, INT_PCM *timeData, - const int timeDataSize, const FDK_channelMapDescr *const mapDescr, - const int mapIdx, int channelIndex, const int elementIndex, - const int numInChannels, int *numOutChannels, const int psPossible) { + HANDLE_SBRDECODER self, LONG *input, LONG *timeData, const int timeDataSize, + const FDK_channelMapDescr *const mapDescr, const int mapIdx, + int channelIndex, const int elementIndex, const int numInChannels, + int *numOutChannels, const int psPossible) { SBR_DECODER_ELEMENT *hSbrElement = self->pSbrElement[elementIndex]; HANDLE_SBR_CHANNEL *pSbrChannel = self->pSbrElement[elementIndex]->pSbrChannel; @@ -1743,7 +1743,7 @@ static SBR_ERROR sbrDecoder_DecodeElement( timeData + offset1, strideOut, hSbrHeader, hFrameDataLeft, &pSbrChannel[0]->prevFrameData, (hSbrHeader->syncState == SBR_ACTIVE), h_ps_d, self->flags, - codecFrameSize); + codecFrameSize, self->sbrInDataHeadroom); if (stereo) { /* Process right channel */ @@ -1751,7 +1751,7 @@ static SBR_ERROR sbrDecoder_DecodeElement( timeData + offset1, NULL, NULL, strideOut, hSbrHeader, hFrameDataRight, &pSbrChannel[1]->prevFrameData, (hSbrHeader->syncState == SBR_ACTIVE), NULL, self->flags, - codecFrameSize); + codecFrameSize, self->sbrInDataHeadroom); } C_ALLOC_SCRATCH_END(pPsScratch, struct PS_DEC_COEFFICIENTS, 1) @@ -1771,14 +1771,14 @@ static SBR_ERROR sbrDecoder_DecodeElement( int copyFrameSize = codecFrameSize * self->pQmfDomain->QmfDomainOut->fb.no_channels; copyFrameSize /= self->pQmfDomain->QmfDomainIn->fb.no_channels; - INT_PCM *ptr; + LONG *ptr; INT i; FDK_ASSERT(strideOut == 2); ptr = timeData; for (i = copyFrameSize >> 1; i--;) { - INT_PCM tmp; /* This temporal variable is required because some - compilers can't do *ptr++ = *ptr++ correctly. */ + LONG tmp; /* This temporal variable is required because some compilers + can't do *ptr++ = *ptr++ correctly. */ tmp = *ptr++; *ptr++ = tmp; tmp = *ptr++; @@ -1791,12 +1791,13 @@ static SBR_ERROR sbrDecoder_DecodeElement( return errorStatus; } -SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input, - INT_PCM *timeData, const int timeDataSize, - int *numChannels, int *sampleRate, +SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, LONG *input, LONG *timeData, + const int timeDataSize, int *numChannels, + int *sampleRate, const FDK_channelMapDescr *const mapDescr, const int mapIdx, const int coreDecodedOk, - UCHAR *psDecoded) { + UCHAR *psDecoded, const INT inDataHeadroom, + INT *outDataHeadroom) { SBR_ERROR errorStatus = SBRDEC_OK; int psPossible; @@ -1833,6 +1834,9 @@ SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input, psPossible = 0; } + self->sbrInDataHeadroom = inDataHeadroom; + *outDataHeadroom = (INT)(8); + /* Make sure that even if no SBR data was found/parsed *psDecoded is returned * 1 if psPossible was 0. */ if (psPossible == 0) { -- cgit v1.2.3 From 7f7bbce892d9e8ed45e4ee2ee7dcefc1cd87a763 Mon Sep 17 00:00:00 2001 From: Anuj Joshi Date: Fri, 27 Mar 2020 10:43:08 +0530 Subject: Stop using __DATE__/__TIME__ on all builds Test: mmma external/libaac Bug: 151595970 Change-Id: Icd937cad3e4e2f70a5486cca424544eb410be26f --- Android.bp | 1 + libAACdec/src/aacdecoder_lib.cpp | 2 +- libAACenc/src/aacenc_lib.cpp | 2 +- libDRCdec/src/FDK_drcDecLib.cpp | 2 +- libFDK/src/FDK_core.cpp | 2 +- libMpegTPDec/src/tpdec_lib.cpp | 2 +- libMpegTPEnc/src/tpenc_lib.cpp | 2 +- libPCMutils/src/version.h | 2 +- libSACdec/src/sac_dec_lib.cpp | 2 +- libSACenc/src/sacenc_lib.cpp | 2 +- libSBRdec/src/sbrdecoder.cpp | 2 +- libSBRenc/src/sbr_encoder.cpp | 2 +- 12 files changed, 12 insertions(+), 11 deletions(-) (limited to 'libSBRdec') diff --git a/Android.bp b/Android.bp index 80a0347..4d52b71 100644 --- a/Android.bp +++ b/Android.bp @@ -23,6 +23,7 @@ cc_library_static { "-Wuninitialized", "-Wno-self-assign", "-Wno-implicit-fallthrough", + "-DSUPPRESS_BUILD_DATE_INFO", ], sanitize: { misc_undefined:[ diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index 86ec899..3a1fc48 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -122,7 +122,7 @@ amm-info@iis.fraunhofer.de #define AACDECODER_LIB_VL1 1 #define AACDECODER_LIB_VL2 2 #define AACDECODER_LIB_TITLE "AAC Decoder Lib" -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO #define AACDECODER_LIB_BUILD_DATE "" #define AACDECODER_LIB_BUILD_TIME "" #else diff --git a/libAACenc/src/aacenc_lib.cpp b/libAACenc/src/aacenc_lib.cpp index 0f0094f..a152c0d 100644 --- a/libAACenc/src/aacenc_lib.cpp +++ b/libAACenc/src/aacenc_lib.cpp @@ -112,7 +112,7 @@ amm-info@iis.fraunhofer.de #define AACENCODER_LIB_VL1 0 #define AACENCODER_LIB_VL2 0 #define AACENCODER_LIB_TITLE "AAC Encoder" -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO #define AACENCODER_LIB_BUILD_DATE "" #define AACENCODER_LIB_BUILD_TIME "" #else diff --git a/libDRCdec/src/FDK_drcDecLib.cpp b/libDRCdec/src/FDK_drcDecLib.cpp index 4f8ebc7..98a73ca 100644 --- a/libDRCdec/src/FDK_drcDecLib.cpp +++ b/libDRCdec/src/FDK_drcDecLib.cpp @@ -112,7 +112,7 @@ amm-info@iis.fraunhofer.de #define DRCDEC_LIB_VL1 1 #define DRCDEC_LIB_VL2 0 #define DRCDEC_LIB_TITLE "MPEG-D DRC Decoder Lib" -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO #define DRCDEC_LIB_BUILD_DATE "" #define DRCDEC_LIB_BUILD_TIME "" #else diff --git a/libFDK/src/FDK_core.cpp b/libFDK/src/FDK_core.cpp index 75ea8a2..52f8915 100644 --- a/libFDK/src/FDK_core.cpp +++ b/libFDK/src/FDK_core.cpp @@ -107,7 +107,7 @@ amm-info@iis.fraunhofer.de #define FDK_TOOLS_LIB_VL1 0 #define FDK_TOOLS_LIB_VL2 0 #define FDK_TOOLS_LIB_TITLE "FDK Tools" -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO #define FDK_TOOLS_LIB_BUILD_DATE "" #define FDK_TOOLS_LIB_BUILD_TIME "" #else diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp index 506aed3..0b8ff24 100644 --- a/libMpegTPDec/src/tpdec_lib.cpp +++ b/libMpegTPDec/src/tpdec_lib.cpp @@ -1750,7 +1750,7 @@ TRANSPORTDEC_ERROR transportDec_GetLibInfo(LIB_INFO *info) { info += i; info->module_id = FDK_TPDEC; -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO info->build_date = ""; info->build_time = ""; #else diff --git a/libMpegTPEnc/src/tpenc_lib.cpp b/libMpegTPEnc/src/tpenc_lib.cpp index 14ea5fe..77c19b5 100644 --- a/libMpegTPEnc/src/tpenc_lib.cpp +++ b/libMpegTPEnc/src/tpenc_lib.cpp @@ -647,7 +647,7 @@ TRANSPORTENC_ERROR transportEnc_GetLibInfo(LIB_INFO *info) { info->module_id = FDK_TPENC; info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2); LIB_VERSION_STRING(info); -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO info->build_date = ""; info->build_time = ""; #else diff --git a/libPCMutils/src/version.h b/libPCMutils/src/version.h index fa31af1..8e537ee 100644 --- a/libPCMutils/src/version.h +++ b/libPCMutils/src/version.h @@ -108,7 +108,7 @@ amm-info@iis.fraunhofer.de #define PCMUTIL_LIB_VL1 0 #define PCMUTIL_LIB_VL2 0 #define PCMUTIL_LIB_TITLE "PCM Utility Lib" -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO #define PCMUTIL_LIB_BUILD_DATE "" #define PCMUTIL_LIB_BUILD_TIME "" #else diff --git a/libSACdec/src/sac_dec_lib.cpp b/libSACdec/src/sac_dec_lib.cpp index bf6dedf..a07e1c9 100644 --- a/libSACdec/src/sac_dec_lib.cpp +++ b/libSACdec/src/sac_dec_lib.cpp @@ -1800,7 +1800,7 @@ int mpegSurroundDecoder_GetLibInfo(LIB_INFO *info) { info += i; info->module_id = FDK_MPSDEC; -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO info->build_date = ""; info->build_time = ""; #else diff --git a/libSACenc/src/sacenc_lib.cpp b/libSACenc/src/sacenc_lib.cpp index d6a1658..fcfe39b 100644 --- a/libSACenc/src/sacenc_lib.cpp +++ b/libSACenc/src/sacenc_lib.cpp @@ -130,7 +130,7 @@ Description of file contents #define SACENC_LIB_VL1 0 #define SACENC_LIB_VL2 0 #define SACENC_LIB_TITLE "MPEG Surround Encoder" -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO #define SACENC_LIB_BUILD_DATE "" #define SACENC_LIB_BUILD_TIME "" #else diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp index c827ced..89a2338 100644 --- a/libSBRdec/src/sbrdecoder.cpp +++ b/libSBRdec/src/sbrdecoder.cpp @@ -160,7 +160,7 @@ amm-info@iis.fraunhofer.de #define SBRDECODER_LIB_VL1 0 #define SBRDECODER_LIB_VL2 0 #define SBRDECODER_LIB_TITLE "SBR Decoder" -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO #define SBRDECODER_LIB_BUILD_DATE "" #define SBRDECODER_LIB_BUILD_TIME "" #else diff --git a/libSBRenc/src/sbr_encoder.cpp b/libSBRenc/src/sbr_encoder.cpp index df9e996..c1e083f 100644 --- a/libSBRenc/src/sbr_encoder.cpp +++ b/libSBRenc/src/sbr_encoder.cpp @@ -2560,7 +2560,7 @@ INT sbrEncoder_GetLibInfo(LIB_INFO *info) { info->version = LIB_VERSION(SBRENCODER_LIB_VL0, SBRENCODER_LIB_VL1, SBRENCODER_LIB_VL2); LIB_VERSION_STRING(info); -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO info->build_date = ""; info->build_time = ""; #else -- cgit v1.2.3 From ffff95538e9994d312ffdfbba94d88ed226ef7bf Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Mon, 6 Jul 2020 16:37:38 +0200 Subject: Fix heap buffer overflow in sbrDecoder_AssignQmfChannels2SbrChannels(). In the bug the SBR decoder has already set up 9 channels and tries to allocate one more channel. The assignment of the QMF channels to SBR channels fails since the QMF domain manages only 8+1 channels instead of 10 channels as reqeusted by SBR. Here we have added a check in sbrDecoder_InitElement() which will return with a parse error in case additional SBR channels would exceed the maximum number of SBR channels. This solves the potential heap buffer overflow. Bug: 158762825 Test: atest DecoderTestAacDrc DecoderTestAacFormat DecoderTestXheAac Change-Id: I0150ac6d5a47ffce883010f531928656eebc619e Merged-In: I0150ac6d5a47ffce883010f531928656eebc619e (cherry picked from commit bb8f983bf36ee2ad8af6acebf4823a58060004ab) --- libSBRdec/src/sbrdecoder.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'libSBRdec') diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp index 6e4aad4..55f929f 100644 --- a/libSBRdec/src/sbrdecoder.cpp +++ b/libSBRdec/src/sbrdecoder.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -617,10 +617,6 @@ SBR_ERROR sbrDecoder_InitElement( self->numSbrChannels -= self->pSbrElement[elementIndex]->nChannels; } - /* Save element ID for sanity checks and to have a fallback for concealment. - */ - self->pSbrElement[elementIndex]->elementID = elementID; - /* Determine amount of channels for this element */ switch (elementID) { case ID_NONE: @@ -653,12 +649,16 @@ SBR_ERROR sbrDecoder_InitElement( } /* Sanity check to avoid memory leaks */ - if (elChannels < self->pSbrElement[elementIndex]->nChannels) { + if (elChannels < self->pSbrElement[elementIndex]->nChannels || + (self->numSbrChannels + elChannels) > (8) + (1)) { self->numSbrChannels += self->pSbrElement[elementIndex]->nChannels; sbrError = SBRDEC_PARSE_ERROR; goto bail; } + /* Save element ID for sanity checks and to have a fallback for concealment. + */ + self->pSbrElement[elementIndex]->elementID = elementID; self->pSbrElement[elementIndex]->nChannels = elChannels; for (ch = 0; ch < elChannels; ch++) { -- cgit v1.2.3