From 6cfabd35363c3ef5e3b209b867169a500b3ccc3c Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Mon, 26 Feb 2018 20:17:00 +0100 Subject: Upgrade to FDKv2 Bug: 71430241 Test: CTS DecoderTest and DecoderTestAacDrc original-Change-Id: Iaa20f749b8a04d553b20247cfe1a8930ebbabe30 Apply clang-format also on header files. original-Change-Id: I14de1ef16bbc79ec0283e745f98356a10efeb2e4 Fixes for MPEG-D DRC original-Change-Id: If1de2d74bbbac84b3f67de3b88b83f6a23b8a15c Catch unsupported tw_mdct at an early stage original-Change-Id: Ied9dd00d754162a0e3ca1ae3e6b854315d818afe Fixing PVC transition frames original-Change-Id: Ib75725abe39252806c32d71176308f2c03547a4e Move qmf bands sanity check original-Change-Id: Iab540c3013c174d9490d2ae100a4576f51d8dbc4 Initialize scaling variable original-Change-Id: I3c4087101b70e998c71c1689b122b0d7762e0f9e Add 16 qmf band configuration to getSlotNrgHQ() original-Change-Id: I49a5d30f703a1b126ff163df9656db2540df21f1 Always apply byte alignment at the end of the AudioMuxElement original-Change-Id: I42d560287506d65d4c3de8bfe3eb9a4ebeb4efc7 Setup SBR element only if no parse error exists original-Change-Id: I1915b73704bc80ab882b9173d6bec59cbd073676 Additional array index check in HCR original-Change-Id: I18cc6e501ea683b5009f1bbee26de8ddd04d8267 Fix fade-in index selection in concealment module original-Change-Id: Ibf802ed6ed8c05e9257e1f3b6d0ac1162e9b81c1 Enable explicit backward compatible parser for AAC_LD original-Change-Id: I27e9c678dcb5d40ed760a6d1e06609563d02482d Skip spatial specific config in explicit backward compatible ASC original-Change-Id: Iff7cc365561319e886090cedf30533f562ea4d6e Update flags description in decoder API original-Change-Id: I9a5b4f8da76bb652f5580cbd3ba9760425c43830 Add QMF domain reset function original-Change-Id: I4f89a8a2c0277d18103380134e4ed86996e9d8d6 DRC upgrade v2.1.0 original-Change-Id: I5731c0540139dab220094cd978ef42099fc45b74 Fix integer overflow in sqrtFixp_lookup() original-Change-Id: I429a6f0d19aa2cc957e0f181066f0ca73968c914 Fix integer overflow in invSqrtNorm2() original-Change-Id: I84de5cbf9fb3adeb611db203fe492fabf4eb6155 Fix integer overflow in GenerateRandomVector() original-Change-Id: I3118a641008bd9484d479e5b0b1ee2b5d7d44d74 Fix integer overflow in adjustTimeSlot_EldGrid() original-Change-Id: I29d503c247c5c8282349b79df940416a512fb9d5 Fix integer overflow in FDKsbrEnc_codeEnvelope() original-Change-Id: I6b34b61ebb9d525b0c651ed08de2befc1f801449 Follow-up on: Fix integer overflow in adjustTimeSlot_EldGrid() original-Change-Id: I6f8f578cc7089e5eb7c7b93e580b72ca35ad689a Fix integer overflow in get_pk_v2() original-Change-Id: I63375bed40d45867f6eeaa72b20b1f33e815938c Fix integer overflow in Syn_filt_zero() original-Change-Id: Ie0c02fdfbe03988f9d3b20d10cd9fe4c002d1279 Fix integer overflow in CFac_CalcFacSignal() original-Change-Id: Id2d767c40066c591b51768e978eb8af3b803f0c5 Fix integer overflow in FDKaacEnc_FDKaacEnc_calcPeNoAH() original-Change-Id: Idcbd0f4a51ae2550ed106aa6f3d678d1f9724841 Fix integer overflow in sbrDecoder_calculateGainVec() original-Change-Id: I7081bcbe29c5cede9821b38d93de07c7add2d507 Fix integer overflow in CLpc_SynthesisLattice() original-Change-Id: I4a95ddc18de150102352d4a1845f06094764c881 Fix integer overflow in Pred_Lt4() original-Change-Id: I4dbd012b2de7d07c3e70a47b92e3bfae8dbc750a Fix integer overflow in FDKsbrEnc_InitSbrFastTransientDetector() original-Change-Id: I788cbec1a4a00f44c2f3a72ad7a4afa219807d04 Fix unsigned integer overflow in FDKaacEnc_WriteBitstream() original-Change-Id: I68fc75166e7d2cd5cd45b18dbe3d8c2a92f1822a Fix unsigned integer overflow in FDK_MetadataEnc_Init() original-Change-Id: Ie8d025f9bcdb2442c704bd196e61065c03c10af4 Fix overflow in pseudo random number generators original-Change-Id: I3e2551ee01356297ca14e3788436ede80bd5513c Fix unsigned integer overflow in sbrDecoder_Parse() original-Change-Id: I3f231b2f437e9c37db4d5b964164686710eee971 Fix unsigned integer overflow in longsub() original-Change-Id: I73c2bc50415cac26f1f5a29e125bbe75f9180a6e Fix unsigned integer overflow in CAacDecoder_DecodeFrame() original-Change-Id: Ifce2db4b1454b46fa5f887e9d383f1cc43b291e4 Fix overflow at CLpdChannelStream_Read() original-Change-Id: Idb9d822ce3a4272e4794b643644f5434e2d4bf3f Fix unsigned integer overflow in Hcr_State_BODY_SIGN_ESC__ESC_WORD() original-Change-Id: I1ccf77c0015684b85534c5eb97162740a870b71c Fix unsigned integer overflow in UsacConfig_Parse() original-Change-Id: Ie6d27f84b6ae7eef092ecbff4447941c77864d9f Fix unsigned integer overflow in aacDecoder_drcParse() original-Change-Id: I713f28e883eea3d70b6fa56a7b8f8c22bcf66ca0 Fix unsigned integer overflow in aacDecoder_drcReadCompression() original-Change-Id: Ia34dfeb88c4705c558bce34314f584965cafcf7a Fix unsigned integer overflow in CDataStreamElement_Read() original-Change-Id: Iae896cc1d11f0a893d21be6aa90bd3e60a2c25f0 Fix unsigned integer overflow in transportDec_AdjustEndOfAccessUnit() original-Change-Id: I64cf29a153ee784bb4a16fdc088baabebc0007dc Fix unsigned integer overflow in transportDec_GetAuBitsRemaining() original-Change-Id: I975b3420faa9c16a041874ba0db82e92035962e4 Fix unsigned integer overflow in extractExtendedData() original-Change-Id: I2a59eb09e2053cfb58dfb75fcecfad6b85a80a8f Fix signed integer overflow in CAacDecoder_ExtPayloadParse() original-Change-Id: I4ad5ca4e3b83b5d964f1c2f8c5e7b17c477c7929 Fix unsigned integer overflow in CAacDecoder_DecodeFrame() original-Change-Id: I29a39df77d45c52a0c9c5c83c1ba81f8d0f25090 Follow-up on: Fix integer overflow in CLpc_SynthesisLattice() original-Change-Id: I8fb194ffc073a3432a380845be71036a272d388f Fix signed integer overflow in _interpolateDrcGain() original-Change-Id: I879ec9ab14005069a7c47faf80e8bc6e03d22e60 Fix unsigned integer overflow in FDKreadBits() original-Change-Id: I1f47a6a8037ff70375aa8844947d5681bb4287ad Fix unsigned integer overflow in FDKbyteAlign() original-Change-Id: Id5f3a11a0c9e50fc6f76ed6c572dbd4e9f2af766 Fix unsigned integer overflow in FDK_get32() original-Change-Id: I9d33b8e97e3d38cbb80629cb859266ca0acdce96 Fix unsigned integer overflow in FDK_pushBack() original-Change-Id: Ic87f899bc8c6acf7a377a8ca7f3ba74c3a1e1c19 Fix unsigned integer overflow in FDK_pushForward() original-Change-Id: I3b754382f6776a34be1602e66694ede8e0b8effc Fix unsigned integer overflow in ReadPsData() original-Change-Id: I25361664ba8139e32bbbef2ca8c106a606ce9c37 Fix signed integer overflow in E_UTIL_residu() original-Change-Id: I8c3abd1f437ee869caa8fb5903ce7d3d641b6aad REVERT: Follow-up on: Integer overflow in CLpc_SynthesisLattice(). original-Change-Id: I3d340099acb0414795c8dfbe6362bc0a8f045f9b Follow-up on: Fix integer overflow in CLpc_SynthesisLattice() original-Change-Id: I4aedb8b3a187064e9f4d985175aa55bb99cc7590 Follow-up on: Fix unsigned integer overflow in aacDecoder_drcParse() original-Change-Id: I2aa2e13916213bf52a67e8b0518e7bf7e57fb37d Fix integer overflow in acelp original-Change-Id: Ie6390c136d84055f8b728aefbe4ebef6e029dc77 Fix unsigned integer overflow in aacDecoder_UpdateBitStreamCounters() original-Change-Id: I391ffd97ddb0b2c184cba76139bfb356a3b4d2e2 Adjust concealment default settings original-Change-Id: I6a95db935a327c47df348030bcceafcb29f54b21 Saturate estimatedStartPos original-Change-Id: I27be2085e0ae83ec9501409f65e003f6bcba1ab6 Negative shift exponent in _interpolateDrcGain() original-Change-Id: I18edb26b26d002aafd5e633d4914960f7a359c29 Negative shift exponent in calculateICC() original-Change-Id: I3dcd2ae98d2eb70ee0d59750863cbb2a6f4f8aba Too large shift exponent in FDK_put() original-Change-Id: Ib7d9aaa434d2d8de4a13b720ca0464b31ca9b671 Too large shift exponent in CalcInvLdData() original-Change-Id: I43e6e78d4cd12daeb1dcd5d82d1798bdc2550262 Member access within null pointer of type SBR_CHANNEL original-Change-Id: Idc5e4ea8997810376d2f36bbdf628923b135b097 Member access within null pointer of type CpePersistentData original-Change-Id: Ib6c91cb0d37882768e5baf63324e429589de0d9d Member access within null pointer FDKaacEnc_psyMain() original-Change-Id: I7729b7f4479970531d9dc823abff63ca52e01997 Member access within null pointer FDKaacEnc_GetPnsParam() original-Change-Id: I9aa3b9f3456ae2e0f7483dbd5b3dde95fc62da39 Member access within null pointer FDKsbrEnc_EnvEncodeFrame() original-Change-Id: I67936f90ea714e90b3e81bc0dd1472cc713eb23a Add HCR sanity check original-Change-Id: I6c1d9732ebcf6af12f50b7641400752f74be39f7 Fix memory issue for HBE edge case with 8:3 SBR original-Change-Id: I11ea58a61e69fbe8bf75034b640baee3011e63e9 Additional SBR parametrization sanity check for ELD original-Change-Id: Ie26026fbfe174c2c7b3691f6218b5ce63e322140 Add MPEG-D DRC channel layout check original-Change-Id: Iea70a74f171b227cce636a9eac4ba662777a2f72 Additional out-of-bounds checks in MPEG-D DRC original-Change-Id: Ife4a8c3452c6fde8a0a09e941154a39a769777d4 Change-Id: Ic63cb2f628720f54fe9b572b0cb528e2599c624e --- libFDK/src/mdct.cpp | 710 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 536 insertions(+), 174 deletions(-) (limited to 'libFDK/src/mdct.cpp') diff --git a/libFDK/src/mdct.cpp b/libFDK/src/mdct.cpp index 9a29aa1..6a6604c 100644 --- a/libFDK/src/mdct.cpp +++ b/libFDK/src/mdct.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,50 +90,206 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/*************************** Fraunhofer IIS FDK Tools ********************** +/******************* Library for basic calculation routines ******************** - Author(s): Josef Hoepfl, Manuel Jander - Description: MDCT routines + Author(s): Josef Hoepfl, Manuel Jander, Youliy Ninov, Daniel Hagel -******************************************************************************/ + Description: MDCT/MDST routines -#include "mdct.h" +*******************************************************************************/ +#include "mdct.h" #include "FDK_tools_rom.h" #include "dct.h" #include "fixpoint_math.h" - -void mdct_init( H_MDCT hMdct, - FIXP_DBL *overlap, - INT overlapBufferSize ) -{ +void mdct_init(H_MDCT hMdct, FIXP_DBL *overlap, INT overlapBufferSize) { hMdct->overlap.freq = overlap; - //FDKmemclear(overlap, overlapBufferSize*sizeof(FIXP_DBL)); + // FDKmemclear(overlap, overlapBufferSize*sizeof(FIXP_DBL)); hMdct->prev_fr = 0; hMdct->prev_nr = 0; hMdct->prev_tl = 0; hMdct->ov_size = overlapBufferSize; + hMdct->prevAliasSymmetry = 0; + hMdct->prevPrevAliasSymmetry = 0; + hMdct->pFacZir = NULL; + hMdct->pAsymOvlp = NULL; } +/* +This program implements the forward MDCT transform on an input block of data. +The input block is in a form (A,B,C,D) where A,B,C and D are the respective +1/4th segments of the block. The program takes the input block and folds it in +the form: +(-D-Cr,A-Br). This block is twice shorter and here the 'r' suffix denotes +flipping of the sequence (reversing the order of the samples). While folding the +input block in the above mentioned shorter block the program windows the data. +Because the two operations (windowing and folding) are not implemented +sequentially, but together the program's structure is not easy to understand. +Once the output (already windowed) block (-D-Cr,A-Br) is ready it is passed to +the DCT IV for processing. +*/ +INT mdct_block(H_MDCT hMdct, const INT_PCM *RESTRICT timeData, + const INT noInSamples, FIXP_DBL *RESTRICT mdctData, + const INT nSpec, const INT tl, const FIXP_WTP *pRightWindowPart, + const INT fr, SHORT *pMdctData_e) { + int i, n; + /* tl: transform length + fl: left window slope length + nl: left window slope offset + fr: right window slope length + nr: right window slope offset + See FDK_tools/doc/intern/mdct.tex for more detail. */ + int fl, nl, nr; + const FIXP_WTP *wls, *wrs; + + wrs = pRightWindowPart; + + /* Detect FRprevious / FL mismatches and override parameters accordingly */ + if (hMdct->prev_fr == + 0) { /* At start just initialize and pass parameters as they are */ + hMdct->prev_fr = fr; + hMdct->prev_wrs = wrs; + hMdct->prev_tl = tl; + } + + /* Derive NR */ + nr = (tl - fr) >> 1; + + /* Skip input samples if tl is smaller than block size */ + timeData += (noInSamples - tl) >> 1; + + /* windowing */ + for (n = 0; n < nSpec; n++) { + /* + * MDCT scale: + * + 1: fMultDiv2() in windowing. + * + 1: Because of factor 1/2 in Princen-Bradley compliant windowed TDAC. + */ + INT mdctData_e = 1 + 1; + + /* Derive left parameters */ + wls = hMdct->prev_wrs; + fl = hMdct->prev_fr; + nl = (tl - fl) >> 1; + + /* Here we implement a simplified version of what happens after the this + piece of code (see the comments below). We implement the folding of A and B + segments to (A-Br) but A is zero, because in this part of the MDCT sequence + the window coefficients with which A must be multiplied are zero. */ + for (i = 0; i < nl; i++) { +#if SAMPLE_BITS == DFRACT_BITS /* SPC_BITS and DFRACT_BITS should be equal. */ + mdctData[(tl / 2) + i] = -((FIXP_DBL)timeData[tl - i - 1] >> (1)); +#else + mdctData[(tl / 2) + i] = -(FIXP_DBL)timeData[tl - i - 1] + << (DFRACT_BITS - SAMPLE_BITS - 1); /* 0(A)-Br */ +#endif + } + + /* Implements the folding and windowing of the left part of the sequence, + that is segments A and B. The A segment is multiplied by the respective left + window coefficient and placed in a temporary variable. + + tmp0 = fMultDiv2((FIXP_PCM)timeData[i+nl], pLeftWindowPart[i].v.im); + + After this the B segment taken in reverse order is multiplied by the left + window and subtracted from the previously derived temporary variable, so + that finally we implement the A-Br operation. This output is written to the + right part of the MDCT output : (-D-Cr,A-Br). -void imdct_gain(FIXP_DBL *pGain_m, int *pGain_e, int tl) -{ + mdctData[(tl/2)+i+nl] = fMultSubDiv2(tmp0, (FIXP_PCM)timeData[tl-nl-i-1], + pLeftWindowPart[i].v.re);//A*window-Br*window + + The (A-Br) data is written to the output buffer (mdctData) without being + flipped. */ + for (i = 0; i < fl / 2; i++) { + FIXP_DBL tmp0; + tmp0 = fMultDiv2((FIXP_PCM)timeData[i + nl], wls[i].v.im); /* a*window */ + mdctData[(tl / 2) + i + nl] = + fMultSubDiv2(tmp0, (FIXP_PCM)timeData[tl - nl - i - 1], + wls[i].v.re); /* A*window-Br*window */ + } + + /* Right window slope offset */ + /* Here we implement a simplified version of what happens after the this + piece of code (see the comments below). We implement the folding of C and D + segments to (-D-Cr) but D is zero, because in this part of the MDCT sequence + the window coefficients with which D must be multiplied are zero. */ + for (i = 0; i < nr; i++) { +#if SAMPLE_BITS == \ + DFRACT_BITS /* This should be SPC_BITS instead of DFRACT_BITS. */ + mdctData[(tl / 2) - 1 - i] = -((FIXP_DBL)timeData[tl + i] >> (1)); +#else + mdctData[(tl / 2) - 1 - i] = + -(FIXP_DBL)timeData[tl + i] + << (DFRACT_BITS - SAMPLE_BITS - 1); /* -C flipped at placing */ +#endif + } + + /* Implements the folding and windowing of the right part of the sequence, + that is, segments C and D. The C segment is multiplied by the respective + right window coefficient and placed in a temporary variable. + + tmp1 = fMultDiv2((FIXP_PCM)timeData[tl+nr+i], pRightWindowPart[i].v.re); + + After this the D segment taken in reverse order is multiplied by the right + window and added from the previously derived temporary variable, so that we + get (C+Dr) operation. This output is negated to get (-C-Dr) and written to + the left part of the MDCT output while being reversed (flipped) at the same + time, so that from (-C-Dr) we get (-D-Cr)=> (-D-Cr,A-Br). + + mdctData[(tl/2)-nr-i-1] = -fMultAddDiv2(tmp1, + (FIXP_PCM)timeData[(tl*2)-nr-i-1], pRightWindowPart[i].v.im);*/ + for (i = 0; i < fr / 2; i++) { + FIXP_DBL tmp1; + tmp1 = fMultDiv2((FIXP_PCM)timeData[tl + nr + i], + wrs[i].v.re); /* C*window */ + mdctData[(tl / 2) - nr - i - 1] = + -fMultAddDiv2(tmp1, (FIXP_PCM)timeData[(tl * 2) - nr - i - 1], + wrs[i].v.im); /* -(C*window+Dr*window) and flip before + placing -> -Cr - D */ + } + + /* We pass the shortened folded data (-D-Cr,A-Br) to the MDCT function */ + dct_IV(mdctData, tl, &mdctData_e); + + pMdctData_e[n] = (SHORT)mdctData_e; + + timeData += tl; + mdctData += tl; + + hMdct->prev_wrs = wrs; + hMdct->prev_fr = fr; + hMdct->prev_tl = tl; + } + + return nSpec * tl; +} + +void imdct_gain(FIXP_DBL *pGain_m, int *pGain_e, int tl) { FIXP_DBL gain_m = *pGain_m; int gain_e = *pGain_e; int log2_tl; - log2_tl = DFRACT_BITS-1-fNormz((FIXP_DBL)tl); + gain_e += -MDCT_OUTPUT_GAIN - MDCT_OUT_HEADROOM + 1; + if (tl == 0) { + /* Dont regard the 2/N factor from the IDCT. It is compensated for somewhere + * else. */ + *pGain_e = gain_e; + return; + } - gain_e += -MDCT_OUTPUT_GAIN - log2_tl - MDCT_OUT_HEADROOM + 1; + log2_tl = DFRACT_BITS - 1 - fNormz((FIXP_DBL)tl); + gain_e += -log2_tl; /* Detect non-radix 2 transform length and add amplitude compensation factor which cannot be included into the exponent above */ - switch ( (tl) >> (log2_tl - 2) ) { - case 0x7: /* 10 ms, 1/tl = 1.0/(FDKpow(2.0, -log2_tl) * 0.53333333333333333333) */ + switch ((tl) >> (log2_tl - 2)) { + case 0x7: /* 10 ms, 1/tl = 1.0/(FDKpow(2.0, -log2_tl) * + 0.53333333333333333333) */ if (gain_m == (FIXP_DBL)0) { gain_m = FL2FXCONST_DBL(0.53333333333333333333f); } else { @@ -131,9 +298,17 @@ void imdct_gain(FIXP_DBL *pGain_m, int *pGain_e, int tl) break; case 0x6: /* 3/4 of radix 2, 1/tl = 1.0/(FDKpow(2.0, -log2_tl) * 2.0/3.0) */ if (gain_m == (FIXP_DBL)0) { - gain_m = FL2FXCONST_DBL(2.0/3.0f); + gain_m = FL2FXCONST_DBL(2.0 / 3.0f); } else { - gain_m = fMult(gain_m, FL2FXCONST_DBL(2.0/3.0f)); + gain_m = fMult(gain_m, FL2FXCONST_DBL(2.0 / 3.0f)); + } + break; + case 0x5: /* 0.8 of radix 2 (e.g. tl 160), 1/tl = 1.0/(FDKpow(2.0, -log2_tl) + * 0.8/1.5) */ + if (gain_m == (FIXP_DBL)0) { + gain_m = FL2FXCONST_DBL(0.53333333333333333333f); + } else { + gain_m = fMult(gain_m, FL2FXCONST_DBL(0.53333333333333333333f)); } break; case 0x4: @@ -149,12 +324,7 @@ void imdct_gain(FIXP_DBL *pGain_m, int *pGain_e, int tl) *pGain_e = gain_e; } -INT imdct_drain( - H_MDCT hMdct, - FIXP_DBL *output, - INT nrSamplesRoom - ) -{ +INT imdct_drain(H_MDCT hMdct, FIXP_DBL *output, INT nrSamplesRoom) { int buffered_samples = 0; if (nrSamplesRoom > 0) { @@ -162,61 +332,66 @@ INT imdct_drain( FDK_ASSERT(buffered_samples <= nrSamplesRoom); - if (buffered_samples > 0) { - FDKmemcpy(output, hMdct->overlap.time, buffered_samples*sizeof(FIXP_DBL)); + if (buffered_samples > 0) { + FDKmemcpy(output, hMdct->overlap.time, + buffered_samples * sizeof(FIXP_DBL)); hMdct->ov_offset = 0; } } return buffered_samples; } -INT imdct_copy_ov_and_nr( - H_MDCT hMdct, - FIXP_DBL * pTimeData, - INT nrSamples - ) -{ +INT imdct_copy_ov_and_nr(H_MDCT hMdct, FIXP_DBL *pTimeData, INT nrSamples) { FIXP_DBL *pOvl; int nt, nf, i; nt = fMin(hMdct->ov_offset, nrSamples); nrSamples -= nt; nf = fMin(hMdct->prev_nr, nrSamples); - nrSamples -= nf; - FDKmemcpy(pTimeData, hMdct->overlap.time, nt*sizeof(FIXP_DBL)); + FDKmemcpy(pTimeData, hMdct->overlap.time, nt * sizeof(FIXP_DBL)); pTimeData += nt; pOvl = hMdct->overlap.freq + hMdct->ov_size - 1; - for (i=0; iprevPrevAliasSymmetry == 0) { + for (i = 0; i < nf; i++) { + FIXP_DBL x = -(*pOvl--); + *pTimeData = IMDCT_SCALE_DBL(x); + pTimeData++; + } + } else { + for (i = 0; i < nf; i++) { + FIXP_DBL x = (*pOvl--); + *pTimeData = IMDCT_SCALE_DBL(x); + pTimeData++; + } } - return (nt+nf); + return (nt + nf); } -void imdct_adapt_parameters(H_MDCT hMdct, int *pfl, int *pnl, int tl, const FIXP_WTP *wls, int noOutSamples) -{ +void imdct_adapt_parameters(H_MDCT hMdct, int *pfl, int *pnl, int tl, + const FIXP_WTP *wls, int noOutSamples) { int fl = *pfl, nl = *pnl; int window_diff, use_current = 0, use_previous = 0; if (hMdct->prev_tl == 0) { - hMdct->prev_wrs = wls; - hMdct->prev_fr = fl; - hMdct->prev_nr = (noOutSamples-fl)>>1; - hMdct->prev_tl = noOutSamples; - hMdct->ov_offset = 0; + hMdct->prev_wrs = wls; + hMdct->prev_fr = fl; + hMdct->prev_nr = (noOutSamples - fl) >> 1; + hMdct->prev_tl = noOutSamples; + hMdct->ov_offset = 0; use_current = 1; } - window_diff = (hMdct->prev_fr - fl)>>1; + window_diff = (hMdct->prev_fr - fl) >> 1; - /* check if the previous window slope can be adjusted to match the current window slope */ + /* check if the previous window slope can be adjusted to match the current + * window slope */ if (hMdct->prev_nr + window_diff > 0) { use_current = 1; } - /* check if the current window slope can be adjusted to match the previous window slope */ - if (nl - window_diff > 0 ) { + /* check if the current window slope can be adjusted to match the previous + * window slope */ + if (nl - window_diff > 0) { use_previous = 1; } @@ -224,13 +399,11 @@ void imdct_adapt_parameters(H_MDCT hMdct, int *pfl, int *pnl, int tl, const FIXP if (use_current && use_previous) { if (fl < hMdct->prev_fr) { use_current = 0; - } else { - use_previous = 0; } } /* - * If the previous transform block is big enough, enlarge previous window overlap, - * if not, then shrink current window overlap. + * If the previous transform block is big enough, enlarge previous window + * overlap, if not, then shrink current window overlap. */ if (use_current) { hMdct->prev_nr += window_diff; @@ -245,29 +418,64 @@ void imdct_adapt_parameters(H_MDCT hMdct, int *pfl, int *pnl, int tl, const FIXP *pnl = nl; } -INT imdct_block( - H_MDCT hMdct, - FIXP_DBL *output, - FIXP_DBL *spectrum, - const SHORT scalefactor[], - const INT nSpec, - const INT noOutSamples, - const INT tl, - const FIXP_WTP *wls, - INT fl, - const FIXP_WTP *wrs, - const INT fr, - FIXP_DBL gain - ) -{ +/* +This program implements the inverse modulated lapped transform, a generalized +version of the inverse MDCT transform. Setting none of the MLT_*_ALIAS_FLAG +flags computes the IMDCT, setting all of them computes the IMDST. Other +combinations of these flags compute type III transforms used by the RSVD60 +multichannel tool for transitions between MDCT/MDST. The following description +relates to the IMDCT only. + +If we pass the data block (A,B,C,D,E,F) to the FORWARD MDCT it will produce two +outputs. The first one will be over the (A,B,C,D) part =>(-D-Cr,A-Br) and the +second one will be over the (C,D,E,F) part => (-F-Er,C-Dr), since there is a +overlap between consequtive passes of the algorithm. This overlap is over the +(C,D) segments. The two outputs will be given sequentially to the DCT IV +algorithm. At the INVERSE MDCT side we get two consecutive outputs from the IDCT +IV algorithm, namely the same blocks: (-D-Cr,A-Br) and (-F-Er,C-Dr). The first +of them lands in the Overlap buffer and the second is in the working one, which, +one algorithm pass later will substitute the one residing in the overlap +register. The IMDCT algorithm has to produce the C and D segments from the two +buffers. In order to do this we take the left part of the overlap +buffer(-D-Cr,A-Br), namely (-D-Cr) and add it appropriately to the right part of +the working buffer (-F-Er,C-Dr), namely (C-Dr), so that we get first the C +segment and later the D segment. We do this in the following way: From the right +part of the working buffer(C-Dr) we subtract the flipped left part of the +overlap buffer(-D-Cr): + +Result = (C-Dr) - flipped(-D-Cr) = C -Dr + Dr + C = 2C +We divide by two and get the C segment. What we did is adding the right part of +the first frame to the left part of the second one. While applying these +operation we multiply the respective segments with the appropriate window +functions. + +In order to get the D segment we do the following: +From the negated second part of the working buffer(C-Dr) we subtract the flipped +first part of the overlap buffer (-D-Cr): + +Result= - (C -Dr) - flipped(-D-Cr)= -C +Dr +Dr +C = 2Dr. +After dividing by two and flipping we get the D segment.What we did is adding +the right part of the first frame to the left part of the second one. While +applying these operation we multiply the respective segments with the +appropriate window functions. + +Once we have obtained the C and D segments the overlap buffer is emptied and the +current buffer is sent in it, so that the E and F segments are available for +decoding in the next algorithm pass.*/ +INT imlt_block(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *spectrum, + const SHORT scalefactor[], const INT nSpec, + const INT noOutSamples, const INT tl, const FIXP_WTP *wls, + INT fl, const FIXP_WTP *wrs, const INT fr, FIXP_DBL gain, + int flags) { FIXP_DBL *pOvl; FIXP_DBL *pOut0 = output, *pOut1; INT nl, nr; int w, i, nrSamples = 0, specShiftScale, transform_gain_e = 0; + int currAliasSymmetry = (flags & MLT_FLAG_CURR_ALIAS_SYMMETRY); /* Derive NR and NL */ - nr = (tl - fr)>>1; - nl = (tl - fl)>>1; + nr = (tl - fr) >> 1; + nl = (tl - fl) >> 1; /* Include 2/N IMDCT gain into gain factor and exponent. */ imdct_gain(&gain, &transform_gain_e, tl); @@ -279,107 +487,261 @@ INT imdct_block( pOvl = hMdct->overlap.freq + hMdct->ov_size - 1; - if ( noOutSamples > nrSamples ) { + if (noOutSamples > nrSamples) { /* Purge buffered output. */ - for (i=0; iov_offset; i++) { + for (i = 0; i < hMdct->ov_offset; i++) { *pOut0 = hMdct->overlap.time[i]; - pOut0 ++; + pOut0++; } nrSamples = hMdct->ov_offset; hMdct->ov_offset = 0; } - for (w=0; wprev_fr != fl) { + imdct_adapt_parameters(hMdct, &fl, &nl, tl, wls, noOutSamples); + } + specShiftScale = transform_gain_e; /* Setup window pointers */ pWindow = hMdct->prev_wrs; /* Current spectrum */ - pSpec = spectrum+w*tl; + pSpec = spectrum + w * tl; /* DCT IV of current spectrum. */ - dct_IV(pSpec, tl, &specShiftScale); + if (currAliasSymmetry == 0) { + if (hMdct->prevAliasSymmetry == 0) { + dct_IV(pSpec, tl, &specShiftScale); + } else { + FIXP_DBL _tmp[1024 + ALIGNMENT_DEFAULT / sizeof(FIXP_DBL)]; + FIXP_DBL *tmp = (FIXP_DBL *)ALIGN_PTR(_tmp); + C_ALLOC_ALIGNED_REGISTER(tmp, sizeof(_tmp)); + dct_III(pSpec, tmp, tl, &specShiftScale); + C_ALLOC_ALIGNED_UNREGISTER(tmp); + } + } else { + if (hMdct->prevAliasSymmetry == 0) { + FIXP_DBL _tmp[1024 + ALIGNMENT_DEFAULT / sizeof(FIXP_DBL)]; + FIXP_DBL *tmp = (FIXP_DBL *)ALIGN_PTR(_tmp); + C_ALLOC_ALIGNED_REGISTER(tmp, sizeof(_tmp)); + dst_III(pSpec, tmp, tl, &specShiftScale); + C_ALLOC_ALIGNED_UNREGISTER(tmp); + } else { + dst_IV(pSpec, tl, &specShiftScale); + } + } - /* Optional scaling of time domain - no yet windowed - of current spectrum */ - /* and de-scale current spectrum signal (time domain, no yet windowed) */ + /* Optional scaling of time domain - no yet windowed - of current spectrum + */ + /* and de-scale current spectrum signal (time domain, no yet windowed) */ if (gain != (FIXP_DBL)0) { scaleValuesWithFactor(pSpec, gain, tl, scalefactor[w] + specShiftScale); } else { - scaleValues(pSpec, tl, scalefactor[w] + specShiftScale); + int loc_scale = scalefactor[w] + specShiftScale; + DWORD_ALIGNED(pSpec); + scaleValues(pSpec, tl, loc_scale); } - if ( noOutSamples <= nrSamples ) { - /* Divert output first half to overlap buffer if we already got enough output samples. */ + if (noOutSamples <= nrSamples) { + /* Divert output first half to overlap buffer if we already got enough + * output samples. */ pOut0 = hMdct->overlap.time + hMdct->ov_offset; - hMdct->ov_offset += hMdct->prev_nr + fl/2; + hMdct->ov_offset += hMdct->prev_nr + fl / 2; } else { /* Account output samples */ - nrSamples += hMdct->prev_nr + fl/2; + nrSamples += hMdct->prev_nr + fl / 2; } /* NR output samples 0 .. NR. -overlap[TL/2..TL/2-NR] */ - for (i=0; iprev_nr; i++) { - FIXP_DBL x = - (*pOvl--); - *pOut0 = IMDCT_SCALE_DBL(x); - pOut0 ++; + if ((hMdct->pFacZir != 0) && (hMdct->prev_nr == fl / 2)) { + /* In the case of ACELP -> TCX20 -> FD short add FAC ZIR on nr signal part + */ + for (i = 0; i < hMdct->prev_nr; i++) { + FIXP_DBL x = -(*pOvl--); + *pOut0 = IMDCT_SCALE_DBL(x + hMdct->pFacZir[i]); + pOut0++; + } + hMdct->pFacZir = NULL; + } else { + /* Here we implement a simplified version of what happens after the this + piece of code (see the comments below). We implement the folding of C and + D segments from (-D-Cr) but D is zero, because in this part of the MDCT + sequence the window coefficients with which D must be multiplied are zero. + "pOut0" writes sequentially the C block from left to right. */ + if (hMdct->prevPrevAliasSymmetry == 0) { + for (i = 0; i < hMdct->prev_nr; i++) { + FIXP_DBL x = -(*pOvl--); + *pOut0 = IMDCT_SCALE_DBL(x); + pOut0++; + } + } else { + for (i = 0; i < hMdct->prev_nr; i++) { + FIXP_DBL x = *pOvl--; + *pOut0 = IMDCT_SCALE_DBL(x); + pOut0++; + } + } } - if ( noOutSamples <= nrSamples ) { - /* Divert output second half to overlap buffer if we already got enough output samples. */ - pOut1 = hMdct->overlap.time + hMdct->ov_offset + fl/2 - 1; - hMdct->ov_offset += fl/2 + nl; + if (noOutSamples <= nrSamples) { + /* Divert output second half to overlap buffer if we already got enough + * output samples. */ + pOut1 = hMdct->overlap.time + hMdct->ov_offset + fl / 2 - 1; + hMdct->ov_offset += fl / 2 + nl; } else { pOut1 = pOut0 + (fl - 1); - nrSamples += fl/2 + nl; + nrSamples += fl / 2 + nl; + } + + /* output samples before window crossing point NR .. TL/2. + * -overlap[TL/2-NR..TL/2-NR-FL/2] + current[NR..TL/2] */ + /* output samples after window crossing point TL/2 .. TL/2+FL/2. + * -overlap[0..FL/2] - current[TL/2..FL/2] */ + pCurr = pSpec + tl - fl / 2; + DWORD_ALIGNED(pCurr); + C_ALLOC_ALIGNED_REGISTER(pWindow, fl); + DWORD_ALIGNED(pWindow); + C_ALLOC_ALIGNED_UNREGISTER(pWindow); + + if (hMdct->prevPrevAliasSymmetry == 0) { + if (hMdct->prevAliasSymmetry == 0) { + if (!hMdct->pAsymOvlp) { + for (i = 0; i < fl / 2; i++) { + FIXP_DBL x0, x1; +#ifdef FUNCTION_cplxMult_nIm + /* This macro negates 4th parameter (*pOvl--) */ + /* and inverts the sign of result x1 */ + + /* This subroutine calculates the two output segments (C,D) from the + two availabe DCT IV data blocks, namely, (-D-Cr,A-Br) and + (-F-Er,C-Dr). "pOvl" is the pointer to the overlap block and points + to the end of the (-D-Cr) part of the overlap buffer (-D-Cr,A-Br). + It points to the end of the (-D-Cr) because it will read this part + in a flipped order. "pCurr" is the pointer to the current block + (-F-Er,C-Dr) and points to the beginning of the (C-Dr) block, + because this block will be read consequitively. "pWindow" is a + pointer to the used window coefficients. In pointer "x1" we get the + already computed from the function "Dr" segment. In pointer "x0" we + get the "C" segment. Since we have to output them sequentially the + "x0" pointer points to the beginnig of the output buffer (X,X), and + pointer "x1" points to the end of the output buffer (X,X). When we + get the output of the cplxMult_nIm function we write it sequentially + in the output buffer from the left to right ("x0"=>C) and right to + left ("x1"=>Dr) implementing flipping. At the end we get an output + in the form (C,D). */ + cplxMult_nIm(&x1, &x0, *pCurr++, *pOvl--, pWindow[i]); + *pOut0++ = IMDCT_SCALE_DBL(x0); + *pOut1-- = IMDCT_SCALE_DBL(x1); +#else + cplxMult(&x1, &x0, *pCurr++, -*pOvl--, pWindow[i]); + *pOut0 = IMDCT_SCALE_DBL(x0); + *pOut1 = IMDCT_SCALE_DBL(-x1); + pOut0++; + pOut1--; +#endif /* #ifdef FUNCTION_cplxMult_nIm */ + } + } else { + FIXP_DBL *pAsymOvl = hMdct->pAsymOvlp + fl / 2 - 1; + for (i = 0; i < fl / 2; i++) { + FIXP_DBL x0, x1; + x1 = -fMult(*pCurr, pWindow[i].v.re) + + fMult(*pAsymOvl, pWindow[i].v.im); + x0 = fMult(*pCurr, pWindow[i].v.im) - fMult(*pOvl, pWindow[i].v.re); + pCurr++; + pOvl--; + pAsymOvl--; + *pOut0++ = IMDCT_SCALE_DBL(x0); + *pOut1-- = IMDCT_SCALE_DBL(x1); + } + hMdct->pAsymOvlp = NULL; + } + } else { /* prevAliasingSymmetry == 1 */ + for (i = 0; i < fl / 2; i++) { + FIXP_DBL x0, x1; + cplxMult(&x1, &x0, *pCurr++, -*pOvl--, pWindow[i]); + *pOut0 = IMDCT_SCALE_DBL(x0); + *pOut1 = IMDCT_SCALE_DBL(x1); + pOut0++; + pOut1--; + } + } + } else { /* prevPrevAliasingSymmetry == 1 */ + if (hMdct->prevAliasSymmetry == 0) { + for (i = 0; i < fl / 2; i++) { + FIXP_DBL x0, x1; + cplxMult(&x1, &x0, *pCurr++, *pOvl--, pWindow[i]); + *pOut0 = IMDCT_SCALE_DBL(x0); + *pOut1 = IMDCT_SCALE_DBL(-x1); + pOut0++; + pOut1--; + } + } else { /* prevAliasingSymmetry == 1 */ + for (i = 0; i < fl / 2; i++) { + FIXP_DBL x0, x1; + cplxMult(&x1, &x0, *pCurr++, *pOvl--, pWindow[i]); + *pOut0 = IMDCT_SCALE_DBL(x0); + *pOut1 = IMDCT_SCALE_DBL(x1); + pOut0++; + pOut1--; + } + } } - /* output samples before window crossing point NR .. TL/2. -overlap[TL/2-NR..TL/2-NR-FL/2] + current[NR..TL/2] */ - /* output samples after window crossing point TL/2 .. TL/2+FL/2. -overlap[0..FL/2] - current[TL/2..FL/2] */ - pCurr = pSpec + tl - fl/2; - for (i=0; ipFacZir != 0) { + /* add FAC ZIR of previous ACELP -> mdct transition */ + FIXP_DBL *pOut = pOut0 - fl / 2; + FDK_ASSERT(fl / 2 <= 128); + for (i = 0; i < fl / 2; i++) { + pOut[i] += IMDCT_SCALE_DBL(hMdct->pFacZir[i]); + } + hMdct->pFacZir = NULL; } - pOut0 += (fl/2); + pOut0 += (fl / 2) + nl; /* NL output samples TL/2+FL/2..TL. - current[FL/2..0] */ - pOut1 += (fl/2) + 1; - pCurr = pSpec + tl - fl/2 - 1; - for (i=0; iprevAliasSymmetry == 0) { + for (i = 0; i < nl; i++) { + FIXP_DBL x = -(*pCurr--); + *pOut1++ = IMDCT_SCALE_DBL(x); + } + } else { + for (i = 0; i < nl; i++) { + FIXP_DBL x = *pCurr--; + *pOut1++ = IMDCT_SCALE_DBL(x); + } } /* Set overlap source pointer for next window pOvl = pSpec + tl/2 - 1; */ - pOvl = pSpec + tl/2 - 1; + pOvl = pSpec + tl / 2 - 1; /* Previous window values. */ hMdct->prev_nr = nr; hMdct->prev_fr = fr; hMdct->prev_tl = tl; hMdct->prev_wrs = wrs; + + /* Previous aliasing symmetry */ + hMdct->prevPrevAliasSymmetry = hMdct->prevAliasSymmetry; + hMdct->prevAliasSymmetry = currAliasSymmetry; } /* Save overlap */ - - pOvl = hMdct->overlap.freq + hMdct->ov_size - tl/2; - FDK_ASSERT(pOvl >= hMdct->overlap.time + hMdct->ov_offset); - FDK_ASSERT(tl/2 <= hMdct->ov_size); - for (i=0; ioverlap.freq + hMdct->ov_size - tl / 2; + FDKmemcpy(pOvl, &spectrum[(nSpec - 1) * tl], (tl / 2) * sizeof(FIXP_DBL)); return nrSamples; } - -- cgit v1.2.3 From a4d1f0ad52e2cf6f168d2193216602f52033fc27 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 23 May 2018 18:26:27 +0200 Subject: FDKv2 ubsan patches Bug: 80053205 Test: see bug for repro with FB "wow" atest DecoderTestAacDrc Fix signed integer overflows in CLpc_SynthesisLattice() Change-Id: Icbddfcc8c5fc73382ae5bf8c2a7703802c688e06 Fix signed integer overflows in imlt Change-Id: I687834fca2f1aab6210ed9862576b4f38fcdeb24 Fix overflow in addLowbandEnergies() Change-Id: Iaa9fdf9deb49c33ec6ca7ed3081c4ddaa920e9aa Concealment fix for audio frames containing acelp components Change-Id: Ibe5e83a6efa75a48f729984a161a76b826878f4e Fix out-of-bounds access in PS concealment Change-Id: I08809a03a40d1feaf00e41278db314d67e1efe88 Fix potential memory leak in setup of qmf domain Change-Id: Id9fc2448354dc7f1b439469128407305efa3def2 Reject channel config 13 Change-Id: Idf5236f6cd054df994e69c9c972c97f6768cf9e5 Fix unsigned integer overflow in configExtension() Change-Id: I8a1668810b85e6237c3892891444ff08f04b019b Fix unsigned integer overflow in CAacDecoder_DecodeFrame() Change-Id: I79678c571690178e6c37680f70a9b94dd3cbc439 Fix unsigned integer overflow in aacDecoder_UpdateBitStreamCounters() Change-Id: I3bff959da9f53fabb18cd0ae6c260e6256194526 Fix unsigned integer overflow in transportDec_readStream() Change-Id: I6a6f9f4acaa32fae0b5de9641f8787bbc7f8286b --- libAACdec/src/aacdecoder.cpp | 7 +-- libAACdec/src/aacdecoder_lib.cpp | 6 +-- libAACdec/src/conceal.cpp | 4 +- libAACdec/src/usacdec_acelp.cpp | 11 ++++- libAACdec/src/usacdec_acelp.h | 3 +- libAACdec/src/usacdec_lpd.cpp | 2 +- libFDK/include/cplx_mul.h | 20 --------- libFDK/include/mdct.h | 1 + libFDK/src/FDK_lpc.cpp | 15 +++++-- libFDK/src/FDK_qmf_domain.cpp | 97 +++++++++++++++++++++++++++------------- libFDK/src/mdct.cpp | 74 +++++++++++------------------- libMpegTPDec/src/tpdec_asc.cpp | 4 +- libMpegTPDec/src/tpdec_lib.cpp | 6 +-- libSBRdec/src/psbitdec.cpp | 4 ++ libSBRdec/src/psdec.h | 4 +- libSBRenc/src/tran_det.cpp | 18 ++++++-- 16 files changed, 150 insertions(+), 126 deletions(-) (limited to 'libFDK/src/mdct.cpp') diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index 3cbdffd..b8b1327 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -1589,9 +1589,6 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, case 14: ascChannels = 8; break; - case 13: /* 22.2 setup */ - ascChannels = 24; - break; default: return AAC_DEC_UNSUPPORTED_CHANNELCONFIG; } @@ -2837,7 +2834,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( /* usacExtElementStop = 1; */ } - usacExtBitPos = FDKgetValidBits(bs); + usacExtBitPos = (INT)FDKgetValidBits(bs); USAC_EXT_ELEMENT_TYPE usacExtElementType = self->pUsacConfig[streamIndex] @@ -2862,7 +2859,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( /* Skip any remaining bits of extension payload */ usacExtBitPos = (usacExtElementPayloadLength * 8) - - (usacExtBitPos - FDKgetValidBits(bs)); + (usacExtBitPos - (INT)FDKgetValidBits(bs)); if (usacExtBitPos < 0) { self->frameOK = 0; ErrorStatus = AAC_DEC_PARSE_ERROR; diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index e62d187..cd112b6 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -1082,15 +1082,15 @@ static void aacDecoder_UpdateBitStreamCounters(CStreamInfo *pSi, /* bit/byte counters */ { - int nBytes; + INT nBytes; nBytes = nBits >> 3; - pSi->numTotalBytes += nBytes; + pSi->numTotalBytes = (UINT)((INT)pSi->numTotalBytes + nBytes); if (IS_OUTPUT_VALID(ErrorStatus)) { pSi->numTotalAccessUnits++; } if (IS_DECODE_ERROR(ErrorStatus)) { - pSi->numBadBytes += nBytes; + pSi->numBadBytes = (UINT)((INT)pSi->numBadBytes + nBytes); pSi->numBadAccessUnits++; } } diff --git a/libAACdec/src/conceal.cpp b/libAACdec/src/conceal.cpp index 91ba488..a6064b6 100644 --- a/libAACdec/src/conceal.cpp +++ b/libAACdec/src/conceal.cpp @@ -158,8 +158,8 @@ amm-info@iis.fraunhofer.de #define CONCEAL_NOT_DEFINED ((UCHAR)-1) /* default settings */ -#define CONCEAL_DFLT_FADEOUT_FRAMES (0) -#define CONCEAL_DFLT_FADEIN_FRAMES (0) +#define CONCEAL_DFLT_FADEOUT_FRAMES (6) +#define CONCEAL_DFLT_FADEIN_FRAMES (5) #define CONCEAL_DFLT_MUTE_RELEASE_FRAMES (0) #define CONCEAL_DFLT_FADE_FACTOR (0.707106781186548f) /* 1/sqrt(2) */ diff --git a/libAACdec/src/usacdec_acelp.cpp b/libAACdec/src/usacdec_acelp.cpp index ec4437f..af1f488 100644 --- a/libAACdec/src/usacdec_acelp.cpp +++ b/libAACdec/src/usacdec_acelp.cpp @@ -1116,7 +1116,8 @@ void CLpd_AcelpPrepareInternalMem(const FIXP_DBL *synth, UCHAR last_lpd_mode, const FIXP_LPC *A_new, const INT A_new_exp, const FIXP_LPC *A_old, const INT A_old_exp, CAcelpStaticMem *acelp_mem, - INT coreCoderFrameLength, UCHAR lpd_mode) { + INT coreCoderFrameLength, INT clearOldExc, + UCHAR lpd_mode) { int l_div = coreCoderFrameLength / NB_DIV; /* length of one ACELP/TCX20 frame */ int l_div_partial; @@ -1154,6 +1155,13 @@ void CLpd_AcelpPrepareInternalMem(const FIXP_DBL *synth, UCHAR last_lpd_mode, &syn[PIT_MAX_MAX + L_INTERPOL - M_LP_FILTER_ORDER], M_LP_FILTER_ORDER * sizeof(FIXP_DBL)); + if (clearOldExc) { + FDKmemclear(old_exc_mem, (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL)); + C_ALLOC_SCRATCH_END(synth_buf, FIXP_DBL, + PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER); + return; + } + /* update past [PIT_MAX_MAX+L_INTERPOL] samples of exc memory */ if (last_lpd_mode == 1) { /* last frame was TCX20 */ if (last_last_lpd_mode == 0) { /* ACELP -> TCX20 -> ACELP transition */ @@ -1170,7 +1178,6 @@ void CLpd_AcelpPrepareInternalMem(const FIXP_DBL *synth, UCHAR last_lpd_mode, int exc_A_new_length = (coreCoderFrameLength / 2 > PIT_MAX_MAX + L_INTERPOL) ? PIT_MAX_MAX + L_INTERPOL : coreCoderFrameLength / 2; - int exc_A_old_length = PIT_MAX_MAX + L_INTERPOL - exc_A_new_length; E_UTIL_residu(A_old, A_old_exp, syn, old_exc_mem, exc_A_old_length); E_UTIL_residu(A_new, A_new_exp, &syn[exc_A_old_length], diff --git a/libAACdec/src/usacdec_acelp.h b/libAACdec/src/usacdec_acelp.h index 593a073..9de41ff 100644 --- a/libAACdec/src/usacdec_acelp.h +++ b/libAACdec/src/usacdec_acelp.h @@ -238,7 +238,8 @@ void CLpd_AcelpPrepareInternalMem(const FIXP_DBL *synth, UCHAR last_lpd_mode, const FIXP_LPC *A_new, const INT A_new_exp, const FIXP_LPC *A_old, const INT A_old_exp, CAcelpStaticMem *acelp_mem, - INT coreCoderFrameLength, UCHAR lpd_mode); + INT coreCoderFrameLength, INT clearOldExc, + UCHAR lpd_mode); /** * \brief Calculate zero input response (zir) of the acelp synthesis filter diff --git a/libAACdec/src/usacdec_lpd.cpp b/libAACdec/src/usacdec_lpd.cpp index 4ce6699..22069a6 100644 --- a/libAACdec/src/usacdec_lpd.cpp +++ b/libAACdec/src/usacdec_lpd.cpp @@ -1776,7 +1776,7 @@ AAC_DECODER_ERROR CLpd_RenderTimeSignal( pAacDecoderChannelInfo->data.usac.lp_coeff[k], pAacDecoderChannelInfo->data.usac.lp_coeff_exp[k], lp_prev, lp_prev_exp, &pAacDecoderStaticChannelInfo->acelp, lFrame, - mod[k]); + (last_frame_lost && k < 2), mod[k]); } } else { if (k == 0 && pAacDecoderStaticChannelInfo->IMdct.ov_offset != diff --git a/libFDK/include/cplx_mul.h b/libFDK/include/cplx_mul.h index 9c5da57..eb1afce 100644 --- a/libFDK/include/cplx_mul.h +++ b/libFDK/include/cplx_mul.h @@ -258,26 +258,6 @@ inline void cplxMult(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_DBL a_Re, const FIXP_DBL a_Im, const FIXP_DPK w) { cplxMult(c_Re, c_Im, a_Re, a_Im, w.v.re, w.v.im); } -#endif - -#if !defined(FUNCTION_cplxMult_nIm) -#define FUNCTION_cplxMult_nIm - -/* Same as cplxMult, but - a_Im must be negated, when used - c_re must be negated, when output -*/ -inline void cplxMult_nIm(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_DBL a_Re, - const FIXP_DBL a_Im, const FIXP_SPK w) { - *c_Re = -(fMult(a_Re, w.v.re) + fMult(a_Im, w.v.im)); - *c_Im = fMult(a_Re, w.v.im) - fMult(a_Im, w.v.re); -} - -inline void cplxMult_nIm(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_DBL a_Re, - const FIXP_DBL a_Im, const FIXP_DPK w) { - *c_Re = -(fMult(a_Re, w.v.re) + fMult(a_Im, w.v.im)); - *c_Im = fMult(a_Re, w.v.im) - fMult(a_Im, w.v.re); -} #endif /* ############################################################################# diff --git a/libFDK/include/mdct.h b/libFDK/include/mdct.h index e671da9..1382374 100644 --- a/libFDK/include/mdct.h +++ b/libFDK/include/mdct.h @@ -119,6 +119,7 @@ amm-info@iis.fraunhofer.de #define IMDCT_SCALE(x) SATURATE_LEFT_SHIFT(x, -MDCT_OUTPUT_SCALE, PCM_OUT_BITS) #endif #define IMDCT_SCALE_DBL(x) (FIXP_DBL)(x) +#define IMDCT_SCALE_DBL_LSH1(x) SATURATE_LEFT_SHIFT_ALT((x), 1, DFRACT_BITS) #define MLT_FLAG_CURR_ALIAS_SYMMETRY 1 diff --git a/libFDK/src/FDK_lpc.cpp b/libFDK/src/FDK_lpc.cpp index 2ba7707..7d7e691 100644 --- a/libFDK/src/FDK_lpc.cpp +++ b/libFDK/src/FDK_lpc.cpp @@ -184,12 +184,19 @@ void CLpc_SynthesisLattice(FIXP_DBL *signal, const int signal_size, for (i = signal_size; i != 0; i--) { FIXP_DBL *pState = state + order - 1; const FIXP_DBL *pCoeff = coeff + order - 1; - FIXP_DBL tmp; + FIXP_DBL tmp, accu; + + accu = + fMultSubDiv2(scaleValue(*pSignal, signal_e - 1), *pCoeff--, *pState--); + tmp = SATURATE_LEFT_SHIFT_ALT(accu, 1, DFRACT_BITS); - tmp = scaleValue(*pSignal, signal_e) - fMult(*pCoeff--, *pState--); for (j = order - 1; j != 0; j--) { - tmp = tmp - fMult(pCoeff[0], pState[0]); - pState[1] = pState[0] + fMult(*pCoeff--, tmp); + accu = fMultSubDiv2(tmp >> 1, pCoeff[0], pState[0]); + tmp = SATURATE_LEFT_SHIFT_ALT(accu, 1, DFRACT_BITS); + + accu = fMultAddDiv2(pState[0] >> 1, *pCoeff--, tmp); + pState[1] = SATURATE_LEFT_SHIFT_ALT(accu, 1, DFRACT_BITS); + pState--; } diff --git a/libFDK/src/FDK_qmf_domain.cpp b/libFDK/src/FDK_qmf_domain.cpp index 4b78931..043a372 100644 --- a/libFDK/src/FDK_qmf_domain.cpp +++ b/libFDK/src/FDK_qmf_domain.cpp @@ -274,17 +274,28 @@ static int FDK_QmfDomain_AllocatePersistentMemory(HANDLE_FDK_QMF_DOMAIN qd) { size = gc->nBandsAnalysis * 10; if (size > 0) { if (gc->nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_16) { - if (NULL == (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates16(ch))) - goto bail; + if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) { + if (NULL == + (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates16(ch))) + goto bail; + } } else if (gc->nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_24) { - if (NULL == (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates24(ch))) - goto bail; + if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) { + if (NULL == + (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates24(ch))) + goto bail; + } } else if (gc->nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_32) { - if (NULL == (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates32(ch))) - goto bail; + if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) { + if (NULL == + (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates32(ch))) + goto bail; + } } else { - if (NULL == (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates(ch))) - goto bail; + if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) { + if (NULL == (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates(ch))) + goto bail; + } } } else { qd->QmfDomainIn[ch].pAnaQmfStates = NULL; @@ -293,20 +304,36 @@ static int FDK_QmfDomain_AllocatePersistentMemory(HANDLE_FDK_QMF_DOMAIN qd) { size = gc->nQmfOvTimeSlots + gc->nQmfTimeSlots; if (size > 0) { if (gc->nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_16) { - if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal16(ch))) - goto bail; - if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag16(ch))) - goto bail; + if (qd->QmfDomainIn[ch].hQmfSlotsReal == NULL) { + if (NULL == + (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal16(ch))) + goto bail; + } + if (qd->QmfDomainIn[ch].hQmfSlotsImag == NULL) { + if (NULL == + (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag16(ch))) + goto bail; + } } else if (gc->nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_32) { - if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal32(ch))) - goto bail; - if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag32(ch))) - goto bail; + if (qd->QmfDomainIn[ch].hQmfSlotsReal == NULL) { + if (NULL == + (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal32(ch))) + goto bail; + } + if (qd->QmfDomainIn[ch].hQmfSlotsImag == NULL) { + if (NULL == + (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag32(ch))) + goto bail; + } } else { - if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal(ch))) - goto bail; - if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag(ch))) - goto bail; + if (qd->QmfDomainIn[ch].hQmfSlotsReal == NULL) { + if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal(ch))) + goto bail; + } + if (qd->QmfDomainIn[ch].hQmfSlotsImag == NULL) { + if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag(ch))) + goto bail; + } } } else { qd->QmfDomainIn[ch].hQmfSlotsReal = NULL; @@ -316,17 +343,23 @@ static int FDK_QmfDomain_AllocatePersistentMemory(HANDLE_FDK_QMF_DOMAIN qd) { size = gc->nQmfOvTimeSlots * gc->nQmfProcBands * CMPLX_MOD; if (size > 0) { if (gc->nQmfOvTimeSlots == QMF_DOMAIN_OV_TIMESLOTS_16) { - if (NULL == - (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer16(ch))) - goto bail; + if (qd->QmfDomainIn[ch].pOverlapBuffer == NULL) { + if (NULL == + (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer16(ch))) + goto bail; + } } else if (gc->nQmfOvTimeSlots == QMF_DOMAIN_OV_TIMESLOTS_32) { - if (NULL == - (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer32(ch))) - goto bail; + if (qd->QmfDomainIn[ch].pOverlapBuffer == NULL) { + if (NULL == + (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer32(ch))) + goto bail; + } } else { - if (NULL == - (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer(ch))) - goto bail; + if (qd->QmfDomainIn[ch].pOverlapBuffer == NULL) { + if (NULL == + (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer(ch))) + goto bail; + } } } else { qd->QmfDomainIn[ch].pOverlapBuffer = NULL; @@ -336,8 +369,10 @@ static int FDK_QmfDomain_AllocatePersistentMemory(HANDLE_FDK_QMF_DOMAIN qd) { for (ch = 0; ch < gc->nOutputChannels; ch++) { int size = gc->nBandsSynthesis * 9; if (size > 0) { - if (NULL == (qd->QmfDomainOut[ch].pSynQmfStates = GetSynQmfStates(ch))) - goto bail; + if (qd->QmfDomainOut[ch].pSynQmfStates == NULL) { + if (NULL == (qd->QmfDomainOut[ch].pSynQmfStates = GetSynQmfStates(ch))) + goto bail; + } } else { qd->QmfDomainOut[ch].pSynQmfStates = NULL; } diff --git a/libFDK/src/mdct.cpp b/libFDK/src/mdct.cpp index 6a6604c..d697cfb 100644 --- a/libFDK/src/mdct.cpp +++ b/libFDK/src/mdct.cpp @@ -541,11 +541,16 @@ INT imlt_block(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *spectrum, */ /* and de-scale current spectrum signal (time domain, no yet windowed) */ if (gain != (FIXP_DBL)0) { - scaleValuesWithFactor(pSpec, gain, tl, scalefactor[w] + specShiftScale); - } else { - int loc_scale = scalefactor[w] + specShiftScale; + for (i = 0; i < tl; i++) { + pSpec[i] = fMult(pSpec[i], gain); + } + } + + { + int loc_scale = + fixmin_I(scalefactor[w] + specShiftScale, (INT)DFRACT_BITS - 1); DWORD_ALIGNED(pSpec); - scaleValues(pSpec, tl, loc_scale); + scaleValuesSaturate(pSpec, tl, loc_scale); } if (noOutSamples <= nrSamples) { @@ -614,59 +619,34 @@ INT imlt_block(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *spectrum, if (!hMdct->pAsymOvlp) { for (i = 0; i < fl / 2; i++) { FIXP_DBL x0, x1; -#ifdef FUNCTION_cplxMult_nIm - /* This macro negates 4th parameter (*pOvl--) */ - /* and inverts the sign of result x1 */ - - /* This subroutine calculates the two output segments (C,D) from the - two availabe DCT IV data blocks, namely, (-D-Cr,A-Br) and - (-F-Er,C-Dr). "pOvl" is the pointer to the overlap block and points - to the end of the (-D-Cr) part of the overlap buffer (-D-Cr,A-Br). - It points to the end of the (-D-Cr) because it will read this part - in a flipped order. "pCurr" is the pointer to the current block - (-F-Er,C-Dr) and points to the beginning of the (C-Dr) block, - because this block will be read consequitively. "pWindow" is a - pointer to the used window coefficients. In pointer "x1" we get the - already computed from the function "Dr" segment. In pointer "x0" we - get the "C" segment. Since we have to output them sequentially the - "x0" pointer points to the beginnig of the output buffer (X,X), and - pointer "x1" points to the end of the output buffer (X,X). When we - get the output of the cplxMult_nIm function we write it sequentially - in the output buffer from the left to right ("x0"=>C) and right to - left ("x1"=>Dr) implementing flipping. At the end we get an output - in the form (C,D). */ - cplxMult_nIm(&x1, &x0, *pCurr++, *pOvl--, pWindow[i]); - *pOut0++ = IMDCT_SCALE_DBL(x0); - *pOut1-- = IMDCT_SCALE_DBL(x1); -#else - cplxMult(&x1, &x0, *pCurr++, -*pOvl--, pWindow[i]); - *pOut0 = IMDCT_SCALE_DBL(x0); - *pOut1 = IMDCT_SCALE_DBL(-x1); + cplxMultDiv2(&x1, &x0, *pCurr++, -*pOvl--, pWindow[i]); + *pOut0 = IMDCT_SCALE_DBL_LSH1(x0); + *pOut1 = IMDCT_SCALE_DBL_LSH1(-x1); pOut0++; pOut1--; -#endif /* #ifdef FUNCTION_cplxMult_nIm */ } } else { FIXP_DBL *pAsymOvl = hMdct->pAsymOvlp + fl / 2 - 1; for (i = 0; i < fl / 2; i++) { FIXP_DBL x0, x1; - x1 = -fMult(*pCurr, pWindow[i].v.re) + - fMult(*pAsymOvl, pWindow[i].v.im); - x0 = fMult(*pCurr, pWindow[i].v.im) - fMult(*pOvl, pWindow[i].v.re); + x1 = -fMultDiv2(*pCurr, pWindow[i].v.re) + + fMultDiv2(*pAsymOvl, pWindow[i].v.im); + x0 = fMultDiv2(*pCurr, pWindow[i].v.im) - + fMultDiv2(*pOvl, pWindow[i].v.re); pCurr++; pOvl--; pAsymOvl--; - *pOut0++ = IMDCT_SCALE_DBL(x0); - *pOut1-- = IMDCT_SCALE_DBL(x1); + *pOut0++ = IMDCT_SCALE_DBL_LSH1(x0); + *pOut1-- = IMDCT_SCALE_DBL_LSH1(x1); } hMdct->pAsymOvlp = NULL; } } else { /* prevAliasingSymmetry == 1 */ for (i = 0; i < fl / 2; i++) { FIXP_DBL x0, x1; - cplxMult(&x1, &x0, *pCurr++, -*pOvl--, pWindow[i]); - *pOut0 = IMDCT_SCALE_DBL(x0); - *pOut1 = IMDCT_SCALE_DBL(x1); + cplxMultDiv2(&x1, &x0, *pCurr++, -*pOvl--, pWindow[i]); + *pOut0 = IMDCT_SCALE_DBL_LSH1(x0); + *pOut1 = IMDCT_SCALE_DBL_LSH1(x1); pOut0++; pOut1--; } @@ -675,18 +655,18 @@ INT imlt_block(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *spectrum, if (hMdct->prevAliasSymmetry == 0) { for (i = 0; i < fl / 2; i++) { FIXP_DBL x0, x1; - cplxMult(&x1, &x0, *pCurr++, *pOvl--, pWindow[i]); - *pOut0 = IMDCT_SCALE_DBL(x0); - *pOut1 = IMDCT_SCALE_DBL(-x1); + cplxMultDiv2(&x1, &x0, *pCurr++, *pOvl--, pWindow[i]); + *pOut0 = IMDCT_SCALE_DBL_LSH1(x0); + *pOut1 = IMDCT_SCALE_DBL_LSH1(-x1); pOut0++; pOut1--; } } else { /* prevAliasingSymmetry == 1 */ for (i = 0; i < fl / 2; i++) { FIXP_DBL x0, x1; - cplxMult(&x1, &x0, *pCurr++, *pOvl--, pWindow[i]); - *pOut0 = IMDCT_SCALE_DBL(x0); - *pOut1 = IMDCT_SCALE_DBL(x1); + cplxMultDiv2(&x1, &x0, *pCurr++, *pOvl--, pWindow[i]); + *pOut0 = IMDCT_SCALE_DBL_LSH1(x0); + *pOut1 = IMDCT_SCALE_DBL_LSH1(x1); pOut0++; pOut1--; } diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp index b7fd2a1..b0f1c6a 100644 --- a/libMpegTPDec/src/tpdec_asc.cpp +++ b/libMpegTPDec/src/tpdec_asc.cpp @@ -1618,7 +1618,7 @@ static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc, usacConfigExtLength = (int)escapedValue(hBs, 4, 8, 16); /* Start bit position of config extension */ - nbits = FDKgetValidBits(hBs); + nbits = (INT)FDKgetValidBits(hBs); /* Return an error in case the bitbuffer fill level is too low. */ if (nbits < usacConfigExtLength * 8) { @@ -1650,7 +1650,7 @@ static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc, /* Skip remaining bits. If too many bits were parsed, assume error. */ usacConfigExtLength = - 8 * usacConfigExtLength - (nbits - FDKgetValidBits(hBs)); + 8 * usacConfigExtLength - (nbits - (INT)FDKgetValidBits(hBs)); if (usacConfigExtLength < 0) { return TRANSPORTDEC_PARSE_ERROR; } diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp index 5eeb7fc..1d8b7b3 100644 --- a/libMpegTPDec/src/tpdec_lib.cpp +++ b/libMpegTPDec/src/tpdec_lib.cpp @@ -1337,9 +1337,9 @@ static TRANSPORTDEC_ERROR transportDec_readStream(HANDLE_TRANSPORTDEC hTp, INT bitDistance, bfDelta; /* Obtain distance to next synch word */ - bitDistance = FDKgetValidBits(hBs); + bitDistance = (INT)FDKgetValidBits(hBs); error = synchronization(hTp, &headerBits); - bitDistance -= FDKgetValidBits(hBs); + bitDistance -= (INT)FDKgetValidBits(hBs); FDK_ASSERT(bitDistance >= 0); @@ -1380,7 +1380,7 @@ static TRANSPORTDEC_ERROR transportDec_readStream(HANDLE_TRANSPORTDEC hTp, int num, denom; /* Obtain estimate of number of lost frames */ - num = hTp->asc[0].m_samplingFrequency * (bfDelta + bitDistance) + + num = (INT)hTp->asc[0].m_samplingFrequency * (bfDelta + bitDistance) + hTp->remainder; denom = hTp->avgBitRate * hTp->asc[0].m_samplesPerFrame; if (num > 0) { diff --git a/libSBRdec/src/psbitdec.cpp b/libSBRdec/src/psbitdec.cpp index 1521178..f40a156 100644 --- a/libSBRdec/src/psbitdec.cpp +++ b/libSBRdec/src/psbitdec.cpp @@ -311,6 +311,7 @@ int DecodePs(struct PS_DEC *h_ps_d, /*!< PS handle */ pBsData->noEnv = 1; if (pBsData->bEnableIid) { + pBsData->bFineIidQ = h_ps_d->specificTo.mpeg.bPrevFrameFineIidQ; for (gr = 0; gr < NO_HI_RES_IID_BINS; gr++) { pBsData->aaIidIndex[pBsData->noEnv - 1][gr] = h_ps_d->specificTo.mpeg.aIidPrevFrameIndex[gr]; @@ -333,6 +334,9 @@ int DecodePs(struct PS_DEC *h_ps_d, /*!< PS handle */ } } + /* Update previous frame Iid quantization */ + h_ps_d->specificTo.mpeg.bPrevFrameFineIidQ = pBsData->bFineIidQ; + /* Update previous frame index buffers */ for (gr = 0; gr < NO_HI_RES_IID_BINS; gr++) { h_ps_d->specificTo.mpeg.aIidPrevFrameIndex[gr] = diff --git a/libSBRdec/src/psdec.h b/libSBRdec/src/psdec.h index b6d9a12..6ae1473 100644 --- a/libSBRdec/src/psdec.h +++ b/libSBRdec/src/psdec.h @@ -274,7 +274,9 @@ struct PS_DEC { previous frame */ SCHAR aIccPrevFrameIndex[NO_HI_RES_ICC_BINS]; /*!< The ICC index for previous frame */ - UCHAR lastUsb; /*!< uppermost WMF delay band of last frame */ + UCHAR + bPrevFrameFineIidQ; /*!< The IID quantization of the previous frame */ + UCHAR lastUsb; /*!< uppermost WMF delay band of last frame */ FIXP_DBL pHybridAnaStatesLFdmx [2 * 13 * NO_QMF_BANDS_HYBRID20]; /*!< Memory used in hybrid analysis diff --git a/libSBRenc/src/tran_det.cpp b/libSBRenc/src/tran_det.cpp index b6f1b9f..3b6765a 100644 --- a/libSBRenc/src/tran_det.cpp +++ b/libSBRenc/src/tran_det.cpp @@ -269,23 +269,33 @@ static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies, int *scaleEnergies, FIXP_DBL accu1 = FL2FXCONST_DBL(0.0f); FIXP_DBL accu2 = FL2FXCONST_DBL(0.0f); int tran_offdiv2 = tran_off >> nrgSzShift; + const int sc1 = + DFRACT_BITS - + fNormz((FIXP_DBL)fMax( + 1, (freqBandTable[0] * (YBufferWriteOffset - tran_offdiv2) - 1))); + const int sc2 = + DFRACT_BITS - + fNormz((FIXP_DBL)fMax( + 1, (freqBandTable[0] * + (tran_offdiv2 + (slots >> nrgSzShift) - YBufferWriteOffset) - + 1))); int ts, k; /* Sum up lowband energy from one frame at offset tran_off */ /* freqBandTable[LORES] has MAX_FREQ_COEFFS/2 +1 coeefs max. */ for (ts = tran_offdiv2; ts < YBufferWriteOffset; ts++) { for (k = 0; k < freqBandTable[0]; k++) { - accu1 += Energies[ts][k] >> 6; + accu1 += Energies[ts][k] >> sc1; } } for (; ts < tran_offdiv2 + (slots >> nrgSzShift); ts++) { for (k = 0; k < freqBandTable[0]; k++) { - accu2 += Energies[ts][k] >> 9; + accu2 += Energies[ts][k] >> sc2; } } - nrgTotal_m = fAddNorm(accu1, 1 - scaleEnergies[0], accu2, - 4 - scaleEnergies[1], &nrgTotal_e); + nrgTotal_m = fAddNorm(accu1, (sc1 - 5) - scaleEnergies[0], accu2, + (sc2 - 5) - scaleEnergies[1], &nrgTotal_e); nrgTotal_m = scaleValueSaturate(nrgTotal_m, nrgTotal_e); return (nrgTotal_m); -- cgit v1.2.3