diff options
author | Fraunhofer IIS FDK <audio-fdk@iis.fraunhofer.de> | 2018-02-26 20:17:00 +0100 |
---|---|---|
committer | Jean-Michel Trivi <jmtrivi@google.com> | 2018-04-19 11:21:15 -0700 |
commit | 6cfabd35363c3ef5e3b209b867169a500b3ccc3c (patch) | |
tree | 01c0a19f2735e8b5d2407555fe992d4230d089eb /libSBRdec/src/sbrdec_freq_sca.cpp | |
parent | 6288a1e34c4dede4c2806beb1736ece6580558c7 (diff) | |
download | fdk-aac-6cfabd35363c3ef5e3b209b867169a500b3ccc3c.tar.gz fdk-aac-6cfabd35363c3ef5e3b209b867169a500b3ccc3c.tar.bz2 fdk-aac-6cfabd35363c3ef5e3b209b867169a500b3ccc3c.zip |
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
Diffstat (limited to 'libSBRdec/src/sbrdec_freq_sca.cpp')
-rw-r--r-- | libSBRdec/src/sbrdec_freq_sca.cpp | 723 |
1 files changed, 373 insertions, 350 deletions
diff --git a/libSBRdec/src/sbrdec_freq_sca.cpp b/libSBRdec/src/sbrdec_freq_sca.cpp index 8adfbb1..165f94b 100644 --- a/libSBRdec/src/sbrdec_freq_sca.cpp +++ b/libSBRdec/src/sbrdec_freq_sca.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,11 +90,19 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** SBR decoder library ****************************** + + Author(s): + + Description: + +*******************************************************************************/ /*! \file - \brief Frequency scale calculation + \brief Frequency scale calculation */ #include "sbrdec_freq_sca.h" @@ -92,18 +111,16 @@ amm-info@iis.fraunhofer.de #include "sbr_rom.h" #include "env_extr.h" -#include "genericStds.h" /* need log() for debug-code only */ - -#define MAX_OCTAVE 29 -#define MAX_SECOND_REGION 50 - - -static int numberOfBands(FIXP_SGL bpo_div16, int start, int stop, int warpFlag); -static void CalcBands(UCHAR * diff, UCHAR start, UCHAR stop, UCHAR num_bands); -static SBR_ERROR modifyBands(UCHAR max_band, UCHAR * diff, UCHAR length); -static void cumSum(UCHAR start_value, UCHAR* diff, UCHAR length, UCHAR *start_adress); +#include "genericStds.h" /* need log() for debug-code only */ +#define MAX_OCTAVE 29 +#define MAX_SECOND_REGION 50 +static int numberOfBands(FIXP_SGL bpo_div16, int start, int stop, int warpFlag); +static void CalcBands(UCHAR *diff, UCHAR start, UCHAR stop, UCHAR num_bands); +static SBR_ERROR modifyBands(UCHAR max_band, UCHAR *diff, UCHAR length); +static void cumSum(UCHAR start_value, UCHAR *diff, UCHAR length, + UCHAR *start_adress); /*! \brief Retrieve QMF-band where the SBR range starts @@ -113,41 +130,61 @@ static void cumSum(UCHAR start_value, UCHAR* diff, UCHAR length, UCHAR *start_ad \return Number of start band */ -static UCHAR -getStartBand(UINT fs, /*!< Output sampling frequency */ - UCHAR startFreq, /*!< Index to table of possible start bands */ - UINT headerDataFlags) /*!< Info to SBR mode */ +static UCHAR getStartBand( + UINT fs, /*!< Output sampling frequency */ + UCHAR startFreq, /*!< Index to table of possible start bands */ + UINT headerDataFlags) /*!< Info to SBR mode */ { - INT band; - UINT fsMapped; + INT band; + UINT fsMapped = fs; + SBR_RATE rate = DUAL; + + if (headerDataFlags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) { + if (headerDataFlags & SBRDEC_QUAD_RATE) { + rate = QUAD; + } + fsMapped = sbrdec_mapToStdSampleRate(fs, 1); + } - fsMapped = fs; + FDK_ASSERT(2 * (rate + 1) <= (4)); switch (fsMapped) { + case 192000: + band = FDK_sbrDecoder_sbr_start_freq_192[startFreq]; + break; + case 176400: + band = FDK_sbrDecoder_sbr_start_freq_176[startFreq]; + break; + case 128000: + band = FDK_sbrDecoder_sbr_start_freq_128[startFreq]; + break; case 96000: case 88200: - band = FDK_sbrDecoder_sbr_start_freq_88[startFreq]; + band = FDK_sbrDecoder_sbr_start_freq_88[rate][startFreq]; break; case 64000: - band = FDK_sbrDecoder_sbr_start_freq_64[startFreq]; + band = FDK_sbrDecoder_sbr_start_freq_64[rate][startFreq]; break; case 48000: - band = FDK_sbrDecoder_sbr_start_freq_48[startFreq]; + band = FDK_sbrDecoder_sbr_start_freq_48[rate][startFreq]; break; case 44100: - band = FDK_sbrDecoder_sbr_start_freq_44[startFreq]; + band = FDK_sbrDecoder_sbr_start_freq_44[rate][startFreq]; + break; + case 40000: + band = FDK_sbrDecoder_sbr_start_freq_40[rate][startFreq]; break; case 32000: - band = FDK_sbrDecoder_sbr_start_freq_32[startFreq]; + band = FDK_sbrDecoder_sbr_start_freq_32[rate][startFreq]; break; case 24000: - band = FDK_sbrDecoder_sbr_start_freq_24[startFreq]; + band = FDK_sbrDecoder_sbr_start_freq_24[rate][startFreq]; break; case 22050: - band = FDK_sbrDecoder_sbr_start_freq_22[startFreq]; + band = FDK_sbrDecoder_sbr_start_freq_22[rate][startFreq]; break; case 16000: - band = FDK_sbrDecoder_sbr_start_freq_16[startFreq]; + band = FDK_sbrDecoder_sbr_start_freq_16[rate][startFreq]; break; default: band = 255; @@ -156,7 +193,6 @@ getStartBand(UINT fs, /*!< Output sampling frequency */ return band; } - /*! \brief Retrieve QMF-band where the SBR range starts @@ -165,29 +201,32 @@ getStartBand(UINT fs, /*!< Output sampling frequency */ \return Number of start band */ -static UCHAR -getStopBand(UINT fs, /*!< Output sampling frequency */ - UCHAR stopFreq, /*!< Index to table of possible start bands */ - UINT headerDataFlags, /*!< Info to SBR mode */ - UCHAR k0) /*!< Start freq index */ +static UCHAR getStopBand( + UINT fs, /*!< Output sampling frequency */ + UCHAR stopFreq, /*!< Index to table of possible start bands */ + UINT headerDataFlags, /*!< Info to SBR mode */ + UCHAR k0) /*!< Start freq index */ { UCHAR k2; if (stopFreq < 14) { - INT stopMin; - UCHAR diff_tot[MAX_OCTAVE + MAX_SECOND_REGION]; + INT stopMin; + INT num = 2 * (64); + UCHAR diff_tot[MAX_OCTAVE + MAX_SECOND_REGION]; UCHAR *diff0 = diff_tot; - UCHAR *diff1 = diff_tot+MAX_OCTAVE; + UCHAR *diff1 = diff_tot + MAX_OCTAVE; - if (fs < 32000) { - stopMin = (((2*6000*2*(64)) / fs) + 1) >> 1; + if (headerDataFlags & SBRDEC_QUAD_RATE) { + num >>= 1; } - else { + + if (fs < 32000) { + stopMin = (((2 * 6000 * num) / fs) + 1) >> 1; + } else { if (fs < 64000) { - stopMin = (((2*8000*2*(64)) / fs) + 1) >> 1; - } - else { - stopMin = (((2*10000*2*(64)) / fs) + 1) >> 1; + stopMin = (((2 * 8000 * num) / fs) + 1) >> 1; + } else { + stopMin = (((2 * 10000 * num) / fs) + 1) >> 1; } } @@ -196,44 +235,49 @@ getStopBand(UINT fs, /*!< Output sampling frequency */ based on a logarithmic scale. The vectors diff0 and diff1 are used temporarily here. */ - CalcBands( diff0, stopMin, 64, 13); - shellsort( diff0, 13); + CalcBands(diff0, stopMin, 64, 13); + shellsort(diff0, 13); cumSum(stopMin, diff0, 13, diff1); k2 = diff1[stopFreq]; - } - else if (stopFreq==14) - k2 = 2*k0; + } else if (stopFreq == 14) + k2 = 2 * k0; else - k2 = 3*k0; + k2 = 3 * k0; /* Limit to Nyquist */ - if (k2 > (64)) - k2 = (64); - + if (k2 > (64)) k2 = (64); /* Range checks */ /* 1 <= difference <= 48; 1 <= fs <= 96000 */ - if ( ((k2 - k0) > MAX_FREQ_COEFFS) || (k2 <= k0) ) { - return 255; + { + UCHAR max_freq_coeffs = (headerDataFlags & SBRDEC_QUAD_RATE) + ? MAX_FREQ_COEFFS_QUAD_RATE + : MAX_FREQ_COEFFS; + if (((k2 - k0) > max_freq_coeffs) || (k2 <= k0)) { + return 255; + } } - if (headerDataFlags & (SBRDEC_SYNTAX_USAC|SBRDEC_SYNTAX_RSVD50)) { + if (headerDataFlags & SBRDEC_QUAD_RATE) { + return k2; /* skip other checks: (k2 - k0) must be <= + MAX_FREQ_COEFFS_QUAD_RATE for all fs */ + } + if (headerDataFlags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) { /* 1 <= difference <= 35; 42000 <= fs <= 96000 */ - if ( (fs >= 42000) && ( (k2 - k0) > MAX_FREQ_COEFFS_FS44100 ) ) { + if ((fs >= 42000) && ((k2 - k0) > MAX_FREQ_COEFFS_FS44100)) { return 255; } /* 1 <= difference <= 32; 46009 <= fs <= 96000 */ - if ( (fs >= 46009) && ( (k2 - k0) > MAX_FREQ_COEFFS_FS48000 ) ) { + if ((fs >= 46009) && ((k2 - k0) > MAX_FREQ_COEFFS_FS48000)) { return 255; } - } - else { + } else { /* 1 <= difference <= 35; fs == 44100 */ - if ( (fs == 44100) && ( (k2 - k0) > MAX_FREQ_COEFFS_FS44100 ) ) { + if ((fs == 44100) && ((k2 - k0) > MAX_FREQ_COEFFS_FS44100)) { return 255; } /* 1 <= difference <= 32; 48000 <= fs <= 96000 */ - if ( (fs >= 48000) && ( (k2 - k0) > MAX_FREQ_COEFFS_FS48000 ) ) { + if ((fs >= 48000) && ((k2 - k0) > MAX_FREQ_COEFFS_FS48000)) { return 255; } } @@ -241,7 +285,6 @@ getStopBand(UINT fs, /*!< Output sampling frequency */ return k2; } - /*! \brief Generates master frequency tables @@ -252,29 +295,33 @@ getStopBand(UINT fs, /*!< Output sampling frequency */ \return errorCode, 0 if successful */ SBR_ERROR -sbrdecUpdateFreqScale(UCHAR * v_k_master, /*!< Master table to be created */ - UCHAR *numMaster, /*!< Number of entries in master table */ - UINT fs, /*!< SBR working sampling rate */ - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Control data from bitstream */ - UINT flags) -{ - FIXP_SGL bpo_div16; /* bands_per_octave divided by 16 */ - INT dk=0; +sbrdecUpdateFreqScale( + UCHAR *v_k_master, /*!< Master table to be created */ + UCHAR *numMaster, /*!< Number of entries in master table */ + UINT fs, /*!< SBR working sampling rate */ + HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Control data from bitstream */ + UINT flags) { + FIXP_SGL bpo_div16; /* bands_per_octave divided by 16 */ + INT dk = 0; /* Internal variables */ - UCHAR k0, k2, i; - UCHAR num_bands0 = 0; - UCHAR num_bands1 = 0; - UCHAR diff_tot[MAX_OCTAVE + MAX_SECOND_REGION]; + UCHAR k0, k2, i; + UCHAR num_bands0 = 0; + UCHAR num_bands1 = 0; + UCHAR diff_tot[MAX_OCTAVE + MAX_SECOND_REGION]; UCHAR *diff0 = diff_tot; - UCHAR *diff1 = diff_tot+MAX_OCTAVE; - INT k2_achived; - INT k2_diff; - INT incr=0; + UCHAR *diff1 = diff_tot + MAX_OCTAVE; + INT k2_achived; + INT k2_diff; + INT incr = 0; /* Determine start band */ + if (flags & SBRDEC_QUAD_RATE) { + fs >>= 1; + } + k0 = getStartBand(fs, hHeaderData->bs_data.startFreq, flags); if (k0 == 255) { return SBRDEC_UNSUPPORTED_CONFIG; @@ -288,127 +335,134 @@ sbrdecUpdateFreqScale(UCHAR * v_k_master, /*!< Master table to be created */ return SBRDEC_UNSUPPORTED_CONFIG; } - if(hHeaderData->bs_data.freqScale>0) { /* Bark */ + if (hHeaderData->bs_data.freqScale > 0) { /* Bark */ INT k1; - if(hHeaderData->bs_data.freqScale==1) { - bpo_div16 = FL2FXCONST_SGL(12.0f/16.0f); - } - else if(hHeaderData->bs_data.freqScale==2) { - bpo_div16 = FL2FXCONST_SGL(10.0f/16.0f); - } - else { - bpo_div16 = FL2FXCONST_SGL(8.0f/16.0f); + if (hHeaderData->bs_data.freqScale == 1) { + bpo_div16 = FL2FXCONST_SGL(12.0f / 16.0f); + } else if (hHeaderData->bs_data.freqScale == 2) { + bpo_div16 = FL2FXCONST_SGL(10.0f / 16.0f); + } else { + bpo_div16 = FL2FXCONST_SGL(8.0f / 16.0f); } + /* Ref: ISO/IEC 23003-3, Figure 12 - Flowchart calculation of fMaster for + * 4:1 system when bs_freq_scale > 0 */ + if (flags & SBRDEC_QUAD_RATE) { + if ((SHORT)k0 < (SHORT)(bpo_div16 >> ((FRACT_BITS - 1) - 4))) { + bpo_div16 = (FIXP_SGL)(k0 & (UCHAR)0xfe) + << ((FRACT_BITS - 1) - 4); /* bpo_div16 = floor(k0/2)*2 */ + } + } - if( 1000 * k2 > 2245 * k0 ) { /* Two or more regions */ - k1 = 2*k0; + if (1000 * k2 > 2245 * k0) { /* Two or more regions */ + k1 = 2 * k0; num_bands0 = numberOfBands(bpo_div16, k0, k1, 0); - num_bands1 = numberOfBands(bpo_div16, k1, k2, hHeaderData->bs_data.alterScale ); - if ( num_bands0 < 1) { + num_bands1 = + numberOfBands(bpo_div16, k1, k2, hHeaderData->bs_data.alterScale); + if (num_bands0 < 1) { return SBRDEC_UNSUPPORTED_CONFIG; } - if ( num_bands1 < 1 ) { + if (num_bands1 < 1) { return SBRDEC_UNSUPPORTED_CONFIG; } CalcBands(diff0, k0, k1, num_bands0); - shellsort( diff0, num_bands0); + shellsort(diff0, num_bands0); if (diff0[0] == 0) { -#ifdef DEBUG_TOOLS -#endif return SBRDEC_UNSUPPORTED_CONFIG; } cumSum(k0, diff0, num_bands0, v_k_master); CalcBands(diff1, k1, k2, num_bands1); - shellsort( diff1, num_bands1); - if(diff0[num_bands0-1] > diff1[0]) { + shellsort(diff1, num_bands1); + if (diff0[num_bands0 - 1] > diff1[0]) { SBR_ERROR err; - err = modifyBands(diff0[num_bands0-1],diff1, num_bands1); - if (err) - return SBRDEC_UNSUPPORTED_CONFIG; + err = modifyBands(diff0[num_bands0 - 1], diff1, num_bands1); + if (err) return SBRDEC_UNSUPPORTED_CONFIG; } /* Add 2nd region */ cumSum(k1, diff1, num_bands1, &v_k_master[num_bands0]); - *numMaster = num_bands0 + num_bands1; /* Output nr of bands */ + *numMaster = num_bands0 + num_bands1; /* Output nr of bands */ - } - else { /* Only one region */ - k1=k2; + } else { /* Only one region */ + k1 = k2; num_bands0 = numberOfBands(bpo_div16, k0, k1, 0); - if ( num_bands0 < 1) { + if (num_bands0 < 1) { return SBRDEC_UNSUPPORTED_CONFIG; } CalcBands(diff0, k0, k1, num_bands0); shellsort(diff0, num_bands0); if (diff0[0] == 0) { -#ifdef DEBUG_TOOLS -#endif return SBRDEC_UNSUPPORTED_CONFIG; } cumSum(k0, diff0, num_bands0, v_k_master); - *numMaster = num_bands0; /* Output nr of bands */ - + *numMaster = num_bands0; /* Output nr of bands */ + } + } else { /* Linear mode */ + if (hHeaderData->bs_data.alterScale == 0) { + dk = 1; + /* FLOOR to get to few number of bands (next lower even number) */ + num_bands0 = (k2 - k0) & 254; + } else { + dk = 2; + num_bands0 = (((k2 - k0) >> 1) + 1) & 254; /* ROUND to the closest fit */ } - } - else { /* Linear mode */ - if (hHeaderData->bs_data.alterScale==0) { - dk = 1; - /* FLOOR to get to few number of bands (next lower even number) */ - num_bands0 = (k2 - k0) & 254; - } else { - dk = 2; - num_bands0 = ( ((k2 - k0) >> 1) + 1 ) & 254; /* ROUND to the closest fit */ - } - if (num_bands0 < 1) { - return SBRDEC_UNSUPPORTED_CONFIG; - /* We must return already here because 'i' can become negative below. */ - } + if (num_bands0 < 1) { + return SBRDEC_UNSUPPORTED_CONFIG; + /* We must return already here because 'i' can become negative below. */ + } - k2_achived = k0 + num_bands0*dk; - k2_diff = k2 - k2_achived; + k2_achived = k0 + num_bands0 * dk; + k2_diff = k2 - k2_achived; - for(i=0;i<num_bands0;i++) - diff_tot[i] = dk; + for (i = 0; i < num_bands0; i++) diff_tot[i] = dk; - /* If linear scale wasn't achieved */ - /* and we got too wide SBR area */ - if (k2_diff < 0) { - incr = 1; - i = 0; - } + /* If linear scale wasn't achieved */ + /* and we got too wide SBR area */ + if (k2_diff < 0) { + incr = 1; + i = 0; + } - /* If linear scale wasn't achieved */ - /* and we got too small SBR area */ - if (k2_diff > 0) { - incr = -1; - i = num_bands0-1; - } + /* If linear scale wasn't achieved */ + /* and we got too small SBR area */ + if (k2_diff > 0) { + incr = -1; + i = num_bands0 - 1; + } - /* Adjust diff vector to get sepc. SBR range */ - while (k2_diff != 0) { - diff_tot[i] = diff_tot[i] - incr; - i = i + incr; - k2_diff = k2_diff + incr; - } + /* Adjust diff vector to get sepc. SBR range */ + while (k2_diff != 0) { + diff_tot[i] = diff_tot[i] - incr; + i = i + incr; + k2_diff = k2_diff + incr; + } - cumSum(k0, diff_tot, num_bands0, v_k_master);/* cumsum */ - *numMaster = num_bands0; /* Output nr of bands */ + cumSum(k0, diff_tot, num_bands0, v_k_master); /* cumsum */ + *numMaster = num_bands0; /* Output nr of bands */ } if (*numMaster < 1) { return SBRDEC_UNSUPPORTED_CONFIG; } + /* Ref: ISO/IEC 23003-3 Cor.3, "In 7.5.5.2, add to the requirements:"*/ + if (flags & SBRDEC_QUAD_RATE) { + int k; + for (k = 1; k < *numMaster; k++) { + if (!(v_k_master[k] - v_k_master[k - 1] <= k0 - 2)) { + return SBRDEC_UNSUPPORTED_CONFIG; + } + } + } /* Print out the calculated table @@ -417,7 +471,6 @@ sbrdecUpdateFreqScale(UCHAR * v_k_master, /*!< Master table to be created */ return SBRDEC_OK; } - /*! \brief Calculate frequency ratio of one SBR band @@ -427,56 +480,52 @@ sbrdecUpdateFreqScale(UCHAR * v_k_master, /*!< Master table to be created */ \return num_band-th root of k_start/k_stop */ -static FIXP_SGL calcFactorPerBand(int k_start, int k_stop, int num_bands) -{ -/* Scaled bandfactor and step 1 bit right to avoid overflow - * use double data type */ +static FIXP_SGL calcFactorPerBand(int k_start, int k_stop, int num_bands) { + /* Scaled bandfactor and step 1 bit right to avoid overflow + * use double data type */ FIXP_DBL bandfactor = FL2FXCONST_DBL(0.25f); /* Start value */ - FIXP_DBL step = FL2FXCONST_DBL(0.125f); /* Initial increment for factor */ + FIXP_DBL step = FL2FXCONST_DBL(0.125f); /* Initial increment for factor */ - int direction = 1; + int direction = 1; -/* Because saturation can't be done in INT IIS, - * changed start and stop data type from FIXP_SGL to FIXP_DBL */ - FIXP_DBL start = k_start << (DFRACT_BITS-8); - FIXP_DBL stop = k_stop << (DFRACT_BITS-8); + /* Because saturation can't be done in INT IIS, + * changed start and stop data type from FIXP_SGL to FIXP_DBL */ + FIXP_DBL start = k_start << (DFRACT_BITS - 8); + FIXP_DBL stop = k_stop << (DFRACT_BITS - 8); FIXP_DBL temp; - int j, i=0; + int j, i = 0; - while ( step > FL2FXCONST_DBL(0.0f)) { + while (step > FL2FXCONST_DBL(0.0f)) { i++; temp = stop; /* Calculate temp^num_bands: */ - for (j=0; j<num_bands; j++) - //temp = fMult(temp,bandfactor); - temp = fMultDiv2(temp,bandfactor)<<2; + for (j = 0; j < num_bands; j++) + // temp = fMult(temp,bandfactor); + temp = fMultDiv2(temp, bandfactor) << 2; - if (temp<start) { /* Factor too strong, make it weaker */ + if (temp < start) { /* Factor too strong, make it weaker */ if (direction == 0) /* Halfen step. Right shift is not done as fract because otherwise the lowest bit cannot be cleared due to rounding */ step = (FIXP_DBL)((LONG)step >> 1); direction = 1; bandfactor = bandfactor + step; - } - else { /* Factor is too weak: make it stronger */ - if (direction == 1) - step = (FIXP_DBL)((LONG)step >> 1); + } else { /* Factor is too weak: make it stronger */ + if (direction == 1) step = (FIXP_DBL)((LONG)step >> 1); direction = 0; bandfactor = bandfactor - step; } - if (i>100) { + if (i > 100) { step = FL2FXCONST_DBL(0.0f); } } - return FX_DBL2FX_SGL(bandfactor<<1); + return FX_DBL2FX_SGL(bandfactor << 1); } - /*! \brief Calculate number of SBR bands between start and stop band @@ -487,34 +536,35 @@ static FIXP_SGL calcFactorPerBand(int k_start, int k_stop, int num_bands) \return number of bands */ -static int -numberOfBands(FIXP_SGL bpo_div16, /*!< Input: number of bands per octave divided by 16 */ - int start, /*!< First QMF band of SBR frequency range */ - int stop, /*!< Last QMF band of SBR frequency range + 1 */ - int warpFlag) /*!< Stretching flag */ +static int numberOfBands( + FIXP_SGL bpo_div16, /*!< Input: number of bands per octave divided by 16 */ + int start, /*!< First QMF band of SBR frequency range */ + int stop, /*!< Last QMF band of SBR frequency range + 1 */ + int warpFlag) /*!< Stretching flag */ { FIXP_SGL num_bands_div128; - int num_bands; + int num_bands; - num_bands_div128 = FX_DBL2FX_SGL(fMult(FDK_getNumOctavesDiv8(start,stop),bpo_div16)); + num_bands_div128 = + FX_DBL2FX_SGL(fMult(FDK_getNumOctavesDiv8(start, stop), bpo_div16)); if (warpFlag) { /* Apply the warp factor of 1.3 to get wider bands. We use a value of 32768/25200 instead of the exact value to avoid critical cases of rounding. */ - num_bands_div128 = FX_DBL2FX_SGL(fMult(num_bands_div128, FL2FXCONST_SGL(25200.0/32768.0))); + num_bands_div128 = FX_DBL2FX_SGL( + fMult(num_bands_div128, FL2FXCONST_SGL(25200.0 / 32768.0))); } /* add scaled 1 for rounding to even numbers: */ - num_bands_div128 = num_bands_div128 + FL2FXCONST_SGL( 1.0f/128.0f ); + num_bands_div128 = num_bands_div128 + FL2FXCONST_SGL(1.0f / 128.0f); /* scale back to right aligned integer and double the value: */ num_bands = 2 * ((LONG)num_bands_div128 >> (FRACT_BITS - 7)); - return(num_bands); + return (num_bands); } - /*! \brief Calculate width of SBR bands @@ -522,11 +572,10 @@ numberOfBands(FIXP_SGL bpo_div16, /*!< Input: number of bands per octave divided this function calculates the width of each SBR band in QMF channels. The bands get wider from start to stop (bark scale). */ -static void -CalcBands(UCHAR * diff, /*!< Vector of widths to be calculated */ - UCHAR start, /*!< Lower end of subband range */ - UCHAR stop, /*!< Upper end of subband range */ - UCHAR num_bands) /*!< Desired number of bands */ +static void CalcBands(UCHAR *diff, /*!< Vector of widths to be calculated */ + UCHAR start, /*!< Lower end of subband range */ + UCHAR stop, /*!< Upper end of subband range */ + UCHAR num_bands) /*!< Desired number of bands */ { int i; int previous; @@ -535,18 +584,20 @@ CalcBands(UCHAR * diff, /*!< Vector of widths to be calculated */ FIXP_SGL bandfactor = calcFactorPerBand(start, stop, num_bands); previous = stop; /* Start with highest QMF channel */ - exact = (FIXP_SGL)(stop << (FRACT_BITS-8)); /* Shift left to gain some accuracy */ + exact = (FIXP_SGL)( + stop << (FRACT_BITS - 8)); /* Shift left to gain some accuracy */ - for(i=num_bands-1; i>=0; i--) { + for (i = num_bands - 1; i >= 0; i--) { /* Calculate border of next lower sbr band */ - exact = FX_DBL2FX_SGL(fMult(exact,bandfactor)); + exact = FX_DBL2FX_SGL(fMult(exact, bandfactor)); /* Add scaled 0.5 for rounding: - We use a value 128/256 instead of 0.5 to avoid some critical cases of rounding. */ - temp = exact + FL2FXCONST_SGL(128.0/32768.0); + We use a value 128/256 instead of 0.5 to avoid some critical cases of + rounding. */ + temp = exact + FL2FXCONST_SGL(128.0 / 32768.0); /* scale back to right alinged integer: */ - current = (LONG)temp >> (FRACT_BITS-8); + current = (LONG)temp >> (FRACT_BITS - 8); /* Save width of band i */ diff[i] = previous - current; @@ -554,20 +605,17 @@ CalcBands(UCHAR * diff, /*!< Vector of widths to be calculated */ } } - /*! \brief Calculate cumulated sum vector from delta vector */ -static void -cumSum(UCHAR start_value, UCHAR* diff, UCHAR length, UCHAR *start_adress) -{ +static void cumSum(UCHAR start_value, UCHAR *diff, UCHAR length, + UCHAR *start_adress) { int i; - start_adress[0]=start_value; - for(i=1; i<=length; i++) - start_adress[i] = start_adress[i-1] + diff[i-1]; + start_adress[0] = start_value; + for (i = 1; i <= length; i++) + start_adress[i] = start_adress[i - 1] + diff[i - 1]; } - /*! \brief Adapt width of frequency bands in the second region @@ -575,116 +623,96 @@ cumSum(UCHAR start_value, UCHAR* diff, UCHAR length, UCHAR *start_adress) is calculated separately. This function tries to avoid that the second region starts with a band smaller than the highest band of the first region. */ -static SBR_ERROR -modifyBands(UCHAR max_band_previous, UCHAR * diff, UCHAR length) -{ +static SBR_ERROR modifyBands(UCHAR max_band_previous, UCHAR *diff, + UCHAR length) { int change = max_band_previous - diff[0]; - /* Limit the change so that the last band cannot get narrower than the first one */ - if ( change > (diff[length-1]-diff[0])>>1 ) - change = (diff[length-1]-diff[0])>>1; + /* Limit the change so that the last band cannot get narrower than the first + * one */ + if (change > (diff[length - 1] - diff[0]) >> 1) + change = (diff[length - 1] - diff[0]) >> 1; diff[0] += change; - diff[length-1] -= change; + diff[length - 1] -= change; shellsort(diff, length); return SBRDEC_OK; } - /*! \brief Update high resolution frequency band table */ -static void -sbrdecUpdateHiRes(UCHAR * h_hires, - UCHAR * num_hires, - UCHAR * v_k_master, - UCHAR num_bands, - UCHAR xover_band) -{ +static void sbrdecUpdateHiRes(UCHAR *h_hires, UCHAR *num_hires, + UCHAR *v_k_master, UCHAR num_bands, + UCHAR xover_band) { UCHAR i; - *num_hires = num_bands-xover_band; + *num_hires = num_bands - xover_band; - for(i=xover_band; i<=num_bands; i++) { - h_hires[i-xover_band] = v_k_master[i]; + for (i = xover_band; i <= num_bands; i++) { + h_hires[i - xover_band] = v_k_master[i]; } } - /*! \brief Build low resolution table out of high resolution table */ -static void -sbrdecUpdateLoRes(UCHAR * h_lores, - UCHAR * num_lores, - UCHAR * h_hires, - UCHAR num_hires) -{ +static void sbrdecUpdateLoRes(UCHAR *h_lores, UCHAR *num_lores, UCHAR *h_hires, + UCHAR num_hires) { UCHAR i; - if( (num_hires & 1) == 0) { + if ((num_hires & 1) == 0) { /* If even number of hires bands */ *num_lores = num_hires >> 1; /* Use every second lores=hires[0,2,4...] */ - for(i=0; i<=*num_lores; i++) - h_lores[i] = h_hires[i*2]; - } - else { + for (i = 0; i <= *num_lores; i++) h_lores[i] = h_hires[i * 2]; + } else { /* Odd number of hires, which means xover is odd */ - *num_lores = (num_hires+1) >> 1; + *num_lores = (num_hires + 1) >> 1; /* Use lores=hires[0,1,3,5 ...] */ h_lores[0] = h_hires[0]; - for(i=1; i<=*num_lores; i++) { - h_lores[i] = h_hires[i*2-1]; + for (i = 1; i <= *num_lores; i++) { + h_lores[i] = h_hires[i * 2 - 1]; } } } - /*! - \brief Derive a low-resolution frequency-table from the master frequency table + \brief Derive a low-resolution frequency-table from the master frequency + table */ -void -sbrdecDownSampleLoRes(UCHAR *v_result, - UCHAR num_result, - UCHAR *freqBandTableRef, - UCHAR num_Ref) -{ +void sbrdecDownSampleLoRes(UCHAR *v_result, UCHAR num_result, + UCHAR *freqBandTableRef, UCHAR num_Ref) { int step; - int i,j; - int org_length,result_length; - int v_index[MAX_FREQ_COEFFS>>1]; + int i, j; + int org_length, result_length; + int v_index[MAX_FREQ_COEFFS >> 1]; /* init */ org_length = num_Ref; result_length = num_result; - v_index[0] = 0; /* Always use left border */ - i=0; - while(org_length > 0) { + v_index[0] = 0; /* Always use left border */ + i = 0; + while (org_length > 0) { /* Create downsample vector */ i++; step = org_length / result_length; org_length = org_length - step; result_length--; - v_index[i] = v_index[i-1] + step; + v_index[i] = v_index[i - 1] + step; } - for(j=0;j<=i;j++) { + for (j = 0; j <= i; j++) { /* Use downsample vector to index LoResolution vector */ - v_result[j]=freqBandTableRef[v_index[j]]; + v_result[j] = freqBandTableRef[v_index[j]]; } - } - /*! \brief Sorting routine */ -void shellsort(UCHAR *in, UCHAR n) -{ - +void shellsort(UCHAR *in, UCHAR n) { int i, j, v, w; int inc = 1; @@ -697,115 +725,110 @@ void shellsort(UCHAR *in, UCHAR n) for (i = inc; i < n; i++) { v = in[i]; j = i; - while ((w=in[j-inc]) > v) { + while ((w = in[j - inc]) > v) { in[j] = w; j -= inc; - if (j < inc) - break; + if (j < inc) break; } in[j] = v; } } while (inc > 1); - } - - /*! \brief Reset frequency band tables \return errorCode, 0 if successful */ SBR_ERROR -resetFreqBandTables(HANDLE_SBR_HEADER_DATA hHeaderData, const UINT flags) -{ +resetFreqBandTables(HANDLE_SBR_HEADER_DATA hHeaderData, const UINT flags) { SBR_ERROR err = SBRDEC_OK; - int k2,kx, lsb, usb; - int intTemp; - UCHAR nBandsLo, nBandsHi; + int k2, kx, lsb, usb; + int intTemp; + UCHAR nBandsLo, nBandsHi; HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData; /* Calculate master frequency function */ - err = sbrdecUpdateFreqScale(hFreq->v_k_master, - &hFreq->numMaster, - hHeaderData->sbrProcSmplRate, - hHeaderData, - flags); + err = sbrdecUpdateFreqScale(hFreq->v_k_master, &hFreq->numMaster, + hHeaderData->sbrProcSmplRate, hHeaderData, flags); - if ( err || (hHeaderData->bs_info.xover_band > hFreq->numMaster) ) { + if (err || (hHeaderData->bs_info.xover_band > hFreq->numMaster)) { return SBRDEC_UNSUPPORTED_CONFIG; } /* Derive Hiresolution from master frequency function */ - sbrdecUpdateHiRes(hFreq->freqBandTable[1], &nBandsHi, hFreq->v_k_master, hFreq->numMaster, hHeaderData->bs_info.xover_band ); + sbrdecUpdateHiRes(hFreq->freqBandTable[1], &nBandsHi, hFreq->v_k_master, + hFreq->numMaster, hHeaderData->bs_info.xover_band); /* Derive Loresolution from Hiresolution */ - sbrdecUpdateLoRes(hFreq->freqBandTable[0], &nBandsLo, hFreq->freqBandTable[1], nBandsHi); - + sbrdecUpdateLoRes(hFreq->freqBandTable[0], &nBandsLo, hFreq->freqBandTable[1], + nBandsHi); hFreq->nSfb[0] = nBandsLo; hFreq->nSfb[1] = nBandsHi; /* Check index to freqBandTable[0] */ - if ( !(nBandsLo > 0) || (nBandsLo > (MAX_FREQ_COEFFS>>1)) ) { + if (!(nBandsLo > 0) || + (nBandsLo > (((hHeaderData->numberOfAnalysisBands == 16) + ? MAX_FREQ_COEFFS_QUAD_RATE + : MAX_FREQ_COEFFS_DUAL_RATE) >> + 1))) { return SBRDEC_UNSUPPORTED_CONFIG; } lsb = hFreq->freqBandTable[0][0]; usb = hFreq->freqBandTable[0][nBandsLo]; - /* Additional check for lsb */ - if ( (lsb > (32)) || (lsb >= usb) ) { + /* Check for start frequency border k_x: + - ISO/IEC 14496-3 4.6.18.3.6 Requirements + - ISO/IEC 23003-3 7.5.5.2 Modifications and additions to the MPEG-4 SBR + tool + */ + /* Note that lsb > as hHeaderData->numberOfAnalysisBands is a valid SBR config + * for 24 band QMF analysis. */ + if ((lsb > ((flags & SBRDEC_QUAD_RATE) ? 16 : (32))) || (lsb >= usb)) { return SBRDEC_UNSUPPORTED_CONFIG; } - /* Calculate number of noise bands */ k2 = hFreq->freqBandTable[1][nBandsHi]; kx = hFreq->freqBandTable[1][0]; - if (hHeaderData->bs_data.noise_bands == 0) - { + if (hHeaderData->bs_data.noise_bands == 0) { hFreq->nNfb = 1; - } - else /* Calculate no of noise bands 1,2 or 3 bands/octave */ + } else /* Calculate no of noise bands 1,2 or 3 bands/octave */ { /* Fetch number of octaves divided by 32 */ - intTemp = (LONG)FDK_getNumOctavesDiv8(kx,k2) >> 2; + intTemp = (LONG)FDK_getNumOctavesDiv8(kx, k2) >> 2; /* Integer-Multiplication with number of bands: */ intTemp = intTemp * hHeaderData->bs_data.noise_bands; /* Add scaled 0.5 for rounding: */ - intTemp = intTemp + (LONG)FL2FXCONST_SGL(0.5f/32.0f); + intTemp = intTemp + (LONG)FL2FXCONST_SGL(0.5f / 32.0f); /* Convert to right-aligned integer: */ intTemp = intTemp >> (FRACT_BITS - 1 /*sign*/ - 5 /* rescale */); - /* Compare with float calculation */ - FDK_ASSERT( intTemp == (int)((hHeaderData->bs_data.noise_bands * FDKlog( (float)k2/kx) / (float)(FDKlog(2.0)))+0.5) ); - - if( intTemp==0) - intTemp=1; + if (intTemp == 0) intTemp = 1; hFreq->nNfb = intTemp; } hFreq->nInvfBands = hFreq->nNfb; - if( hFreq->nNfb > MAX_NOISE_COEFFS ) { + if (hFreq->nNfb > MAX_NOISE_COEFFS) { return SBRDEC_UNSUPPORTED_CONFIG; } /* Get noise bands */ - sbrdecDownSampleLoRes(hFreq->freqBandTableNoise, - hFreq->nNfb, - hFreq->freqBandTable[0], - nBandsLo); - - + sbrdecDownSampleLoRes(hFreq->freqBandTableNoise, hFreq->nNfb, + hFreq->freqBandTable[0], nBandsLo); + /* save old highband; required for overlap in usac + when headerchange occurs at XVAR and VARX frame; */ + hFreq->ov_highSubband = hFreq->highSubband; - hFreq->lowSubband = lsb; + hFreq->lowSubband = lsb; hFreq->highSubband = usb; return SBRDEC_OK; |