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 --- libAACenc/include/aacenc_lib.h | 2065 +++++++++------- libAACenc/src/aacEnc_ram.cpp | 252 +- libAACenc/src/aacEnc_ram.h | 273 ++- libAACenc/src/aacEnc_rom.cpp | 3494 ++++++++++++++++++--------- libAACenc/src/aacEnc_rom.h | 196 +- libAACenc/src/aacenc.cpp | 1383 ++++++----- libAACenc/src/aacenc.h | 436 ++-- libAACenc/src/aacenc_lib.cpp | 3473 +++++++++++++++------------ libAACenc/src/aacenc_pns.cpp | 508 ++-- libAACenc/src/aacenc_pns.h | 139 +- libAACenc/src/aacenc_tns.cpp | 1654 ++++++------- libAACenc/src/aacenc_tns.h | 211 +- libAACenc/src/adj_thr.cpp | 4162 +++++++++++++++++---------------- libAACenc/src/adj_thr.h | 229 +- libAACenc/src/adj_thr_data.h | 166 +- libAACenc/src/band_nrg.cpp | 422 ++-- libAACenc/src/band_nrg.h | 201 +- libAACenc/src/bandwidth.cpp | 473 ++-- libAACenc/src/bandwidth.h | 140 +- libAACenc/src/bit_cnt.cpp | 1714 ++++++-------- libAACenc/src/bit_cnt.h | 265 ++- libAACenc/src/bitenc.cpp | 1450 +++++------- libAACenc/src/bitenc.h | 223 +- libAACenc/src/block_switch.cpp | 765 +++--- libAACenc/src/block_switch.h | 198 +- libAACenc/src/channel_map.cpp | 846 ++++--- libAACenc/src/channel_map.h | 144 +- libAACenc/src/chaosmeasure.cpp | 220 +- libAACenc/src/chaosmeasure.h | 137 +- libAACenc/src/dyn_bits.cpp | 750 +++--- libAACenc/src/dyn_bits.h | 205 +- libAACenc/src/grp_data.cpp | 292 ++- libAACenc/src/grp_data.h | 158 +- libAACenc/src/intensity.cpp | 756 +++--- libAACenc/src/intensity.h | 167 +- libAACenc/src/interface.h | 209 +- libAACenc/src/line_pe.cpp | 323 +-- libAACenc/src/line_pe.h | 191 +- libAACenc/src/metadata_compressor.cpp | 2257 +++++++++++------- libAACenc/src/metadata_compressor.h | 239 +- libAACenc/src/metadata_main.cpp | 1655 +++++++------ libAACenc/src/metadata_main.h | 214 +- libAACenc/src/mps_main.cpp | 529 +++++ libAACenc/src/mps_main.h | 270 +++ libAACenc/src/ms_stereo.cpp | 448 ++-- libAACenc/src/ms_stereo.h | 148 +- libAACenc/src/noisedet.cpp | 211 +- libAACenc/src/noisedet.h | 142 +- libAACenc/src/pns_func.h | 210 +- libAACenc/src/pnsparam.cpp | 649 +++-- libAACenc/src/pnsparam.h | 178 +- libAACenc/src/pre_echo_control.cpp | 246 +- libAACenc/src/pre_echo_control.h | 152 +- libAACenc/src/psy_configuration.cpp | 932 ++++---- libAACenc/src/psy_configuration.h | 216 +- libAACenc/src/psy_const.h | 196 +- libAACenc/src/psy_data.h | 243 +- libAACenc/src/psy_main.cpp | 2145 +++++++++-------- libAACenc/src/psy_main.h | 225 +- libAACenc/src/qc_data.h | 319 +-- libAACenc/src/qc_main.cpp | 1921 ++++++++------- libAACenc/src/qc_main.h | 222 +- libAACenc/src/quantize.cpp | 368 ++- libAACenc/src/quantize.h | 158 +- libAACenc/src/sf_estim.cpp | 1170 +++++---- libAACenc/src/sf_estim.h | 152 +- libAACenc/src/spreading.cpp | 165 +- libAACenc/src/spreading.h | 139 +- libAACenc/src/tns_func.h | 196 +- libAACenc/src/tonality.cpp | 303 +-- libAACenc/src/tonality.h | 145 +- libAACenc/src/transform.cpp | 388 +-- libAACenc/src/transform.h | 182 +- 73 files changed, 25123 insertions(+), 21100 deletions(-) create mode 100644 libAACenc/src/mps_main.cpp create mode 100644 libAACenc/src/mps_main.h (limited to 'libAACenc') diff --git a/libAACenc/include/aacenc_lib.h b/libAACenc/include/aacenc_lib.h index 828a917..2e47571 100644 --- a/libAACenc/include/aacenc_lib.h +++ b/libAACenc/include/aacenc_lib.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,12 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/**************************** MPEG-4 HE-AAC Encoder ************************** + Author(s): M. Lohwasser - Initial author: M. Lohwasser -******************************************************************************/ + Description: + +*******************************************************************************/ /** * \file aacenc_lib.h @@ -94,87 +108,106 @@ amm-info@iis.fraunhofer.de \section Scope -This document describes the high-level interface and usage of the ISO/MPEG-2/4 AAC Encoder -library developed by the Fraunhofer Institute for Integrated Circuits (IIS). +This document describes the high-level interface and usage of the ISO/MPEG-2/4 +AAC Encoder library developed by the Fraunhofer Institute for Integrated +Circuits (IIS). -The library implements encoding on the basis of the MPEG-2 and MPEG-4 AAC Low-Complexity -standard, and depending on the library's configuration, MPEG-4 High-Efficiency AAC v2 and/or AAC-ELD standard. +The library implements encoding on the basis of the MPEG-2 and MPEG-4 AAC +Low-Complexity standard, and depending on the library's configuration, MPEG-4 +High-Efficiency AAC v2 and/or AAC-ELD standard. -All references to SBR (Spectral Band Replication) are only applicable to HE-AAC or AAC-ELD versions -of the library. All references to PS (Parametric Stereo) are only applicable to HE-AAC v2 -versions of the library. +All references to SBR (Spectral Band Replication) are only applicable to HE-AAC +or AAC-ELD versions of the library. All references to PS (Parametric Stereo) are +only applicable to HE-AAC v2 versions of the library. \section encBasics Encoder Basics -This document can only give a rough overview about the ISO/MPEG-2 and ISO/MPEG-4 AAC audio coding -standard. To understand all the terms in this document, you are encouraged to read the following documents. +This document can only give a rough overview about the ISO/MPEG-2 and ISO/MPEG-4 +AAC audio coding standard. To understand all the terms in this document, you are +encouraged to read the following documents. -- ISO/IEC 13818-7 (MPEG-2 AAC), which defines the syntax of MPEG-2 AAC audio bitstreams. -- ISO/IEC 14496-3 (MPEG-4 AAC, subparts 1 and 4), which defines the syntax of MPEG-4 AAC audio bitstreams. -- Lutzky, Schuller, Gayer, Krämer, Wabnik, "A guideline to audio codec delay", 116th AES Convention, May 8, 2004 +- ISO/IEC 13818-7 (MPEG-2 AAC), which defines the syntax of MPEG-2 AAC audio +bitstreams. +- ISO/IEC 14496-3 (MPEG-4 AAC, subparts 1 and 4), which defines the syntax of +MPEG-4 AAC audio bitstreams. +- Lutzky, Schuller, Gayer, Krämer, Wabnik, "A guideline to audio codec +delay", 116th AES Convention, May 8, 2004 -MPEG Advanced Audio Coding is based on a time-to-frequency mapping of the signal. The signal is -partitioned into overlapping portions and transformed into frequency domain. The spectral components -are then quantized and coded. \n -An MPEG-2 or MPEG-4 AAC audio bitstream is composed of frames. Contrary to MPEG-1/2 Layer-3 (mp3), the -length of individual frames is not restricted to a fixed number of bytes, but can take on any length -between 1 and 768 bytes. +MPEG Advanced Audio Coding is based on a time-to-frequency mapping of the +signal. The signal is partitioned into overlapping portions and transformed into +frequency domain. The spectral components are then quantized and coded. \n An +MPEG-2 or MPEG-4 AAC audio bitstream is composed of frames. Contrary to MPEG-1/2 +Layer-3 (mp3), the length of individual frames is not restricted to a fixed +number of bytes, but can take on any length between 1 and 768 bytes. \page LIBUSE Library Usage \section InterfaceDescription API Files -All API header files are located in the folder /include of the release package. All header files -are provided for usage in C/C++ programs. The AAC encoder library API functions are located at -aacenc_lib.h. +All API header files are located in the folder /include of the release package. +All header files are provided for usage in C/C++ programs. The AAC encoder +library API functions are located in aacenc_lib.h. -In binary releases the encoder core resides in statically linkable libraries called for example -libAACenc.a/libFDK.a (LINUX) or FDK_fastaaclib.lib (MS Visual C++) for the plain AAC-LC core encoder -and libSBRenc.a (LINUX) or FDK_sbrEncLib.lib (MS Visual C++) for the SBR (Spectral Band -Replication) and PS (Parametric Stereo) modules. +In binary releases the encoder core resides in statically linkable libraries +called for example libAACenc.a/libFDK.a (LINUX) or FDK_fastaaclib.lib (MS Visual +C++) for the plain AAC-LC core encoder and libSBRenc.a (LINUX) or +FDK_sbrEncLib.lib (MS Visual C++) for the SBR (Spectral Band Replication) and PS +(Parametric Stereo) modules. \section CallingSequence Calling Sequence -For encoding of ISO/MPEG-2/4 AAC bitstreams the following sequence is mandatory. Input read and output -write functions as well as the corresponding open and close functions are left out, since they may be -implemented differently according to the user's specific requirements. The example implementation in -main.cpp uses file-based input/output. - --# Call aacEncOpen() to allocate encoder instance with required \ref encOpen "configuration".\n -\dontinclude main.cpp -\skipline hAacEncoder = -\skipline aacEncOpen --# Call aacEncoder_SetParam() for each parameter to be set. AOT, samplingrate, channelMode, bitrate and transport type are \ref encParams "mandatory". +For encoding of ISO/MPEG-2/4 AAC bitstreams the following sequence is mandatory. +Input read and output write functions as well as the corresponding open and +close functions are left out, since they may be implemented differently +according to the user's specific requirements. The example implementation uses +file-based input/output. + +-# Call aacEncOpen() to allocate encoder instance with required \ref encOpen +"configuration". \code HANDLE_AACENCODER hAacEncoder = NULL; if ( (ErrorStatus = +aacEncOpen(&hAacEncoder,0,0)) != AACENC_OK ) { \endcode +-# Call aacEncoder_SetParam() for each parameter to be set. AOT, samplingrate, +channelMode, bitrate and transport type are \ref encParams "mandatory". \code +ErrorStatus = aacEncoder_SetParam(hAacEncoder, parameter, value); +\endcode +-# Call aacEncEncode() with NULL parameters to \ref encReconf "initialize" +encoder instance with present parameter set. \code ErrorStatus = +aacEncEncode(hAacEncoder, NULL, NULL, NULL, NULL); \endcode +-# Call aacEncInfo() to retrieve a configuration data block to be transmitted +out of band. This is required when using RFC3640 or RFC3016 like transport. \code - ErrorStatus = aacEncoder_SetParam(hAacEncoder, parameter, value); +AACENC_InfoStruct encInfo; +aacEncInfo(hAacEncoder, &encInfo); \endcode --# Call aacEncEncode() with NULL parameters to \ref encReconf "initialize" encoder instance with present parameter set. -\skipline aacEncEncode --# Call aacEncInfo() to retrieve a configuration data block to be transmitted out of band. This is required when using RFC3640 or RFC3016 like transport. -\dontinclude main.cpp -\skipline encInfo -\skipline aacEncInfo -# Encode input audio data in loop. -\skip Encode as long as -\skipline do -\until { -Feed \ref feedInBuf "input buffer" with new audio data and provide input/output \ref bufDes "arguments" to aacEncEncode(). -\skipline aacEncEncode -\until ; -Write \ref writeOutData "output data" to file or audio device. \skipline while +\code +do +{ +\endcode +Feed \ref feedInBuf "input buffer" with new audio data and provide input/output +\ref bufDes "arguments" to aacEncEncode(). \code ErrorStatus = +aacEncEncode(hAacEncoder, &inBufDesc, &outBufDesc, &inargs, &outargs); \endcode +Write \ref writeOutData "output data" to file or audio device. +\code +} while (ErrorStatus==AACENC_OK); +\endcode -# Call aacEncClose() and destroy encoder instance. -\skipline aacEncClose +\code +aacEncClose(&hAacEncoder); +\endcode + \section encOpen Encoder Instance Allocation -The assignment of the aacEncOpen() function is very flexible and can be used in the following way. -- If the amount of memory consumption is not an issue, the encoder instance can be allocated -for the maximum number of possible audio channels (for example 6 or 8) with the full functional range supported by the library. -This is the default open procedure for the AAC encoder if memory consumption does not need to be minimized. -\code aacEncOpen(&hAacEncoder,0,0) \endcode -- If the required MPEG-4 AOTs do not call for the full functional range of the library, encoder modules can be allocated selectively. -\verbatim +The assignment of the aacEncOpen() function is very flexible and can be used in +the following way. +- If the amount of memory consumption is not an issue, the encoder instance can +be allocated for the maximum number of possible audio channels (for example 6 or +8) with the full functional range supported by the library. This is the default +open procedure for the AAC encoder if memory consumption does not need to be +minimized. \code aacEncOpen(&hAacEncoder,0,0) \endcode +- If the required MPEG-4 AOTs do not call for the full functional range of the +library, encoder modules can be allocated selectively. \verbatim ------------------------------------------------------ AAC | SBR | PS | MD | FLAGS | value -----+-----+-----+----+-----------------------+------- @@ -191,129 +224,178 @@ This is the default open procedure for the AAC encoder if memory consumption doe - MD: Allocate Meta Data module within AAC encoder. \endverbatim \code aacEncOpen(&hAacEncoder,value,0) \endcode -- Specifying the maximum number of channels to be supported in the encoder instance can be done as follows. - - For example allocate an encoder instance which supports 2 channels for all supported AOTs. - The library itself may be capable of encoding up to 6 or 8 channels but in this example only 2 channel encoding is required and thus only buffers for 2 channels are allocated to save data memory. -\code aacEncOpen(&hAacEncoder,0,2) \endcode - - Additionally the maximum number of supported channels in the SBR module can be denoted separately.\n - In this example the encoder instance provides a maximum of 6 channels out of which up to 2 channels support SBR. - This encoder instance can produce for example 5.1 channel AAC-LC streams or stereo HE-AAC (v2) streams. - HE-AAC 5.1 multi channel is not possible since only 2 out of 6 channels support SBR, which saves data memory. -\code aacEncOpen(&hAacEncoder,0,6|(2<<8)) \endcode -\n +- Specifying the maximum number of channels to be supported in the encoder +instance can be done as follows. + - For example allocate an encoder instance which supports 2 channels for all +supported AOTs. The library itself may be capable of encoding up to 6 or 8 +channels but in this example only 2 channel encoding is required and thus only +buffers for 2 channels are allocated to save data memory. \code +aacEncOpen(&hAacEncoder,0,2) \endcode + - Additionally the maximum number of supported channels in the SBR module can +be denoted separately.\n In this example the encoder instance provides a maximum +of 6 channels out of which up to 2 channels support SBR. This encoder instance +can produce for example 5.1 channel AAC-LC streams or stereo HE-AAC (v2) +streams. HE-AAC 5.1 multi channel is not possible since only 2 out of 6 channels +support SBR, which saves data memory. \code aacEncOpen(&hAacEncoder,0,6|(2<<8)) +\endcode \n \section bufDes Input/Output Arguments \subsection allocIOBufs Provide Buffer Descriptors -In the present encoder API, the input and output buffers are described with \ref AACENC_BufDesc "buffer descriptors". This mechanism allows a flexible handling -of input and output buffers without impact to the actual encoding call. Optional buffers are necessary e.g. for ancillary data, meta data input or additional output -buffers describing superframing data in DAB+ or DRM+.\n -At least one input buffer for audio input data and one output buffer for bitstream data must be allocated. The input buffer size can be a user defined multiple -of the number of input channels. PCM input data will be copied from the user defined PCM buffer to an internal input buffer and so input data can be less than one AAC audio frame. -The output buffer size should be 6144 bits per channel excluding the LFE channel. -If the output data does not fit into the provided buffer, an AACENC_ERROR will be returned by aacEncEncode(). -\dontinclude main.cpp -\skipline inputBuffer -\until outputBuffer +In the present encoder API, the input and output buffers are described with \ref +AACENC_BufDesc "buffer descriptors". This mechanism allows a flexible handling +of input and output buffers without impact to the actual encoding call. Optional +buffers are necessary e.g. for ancillary data, meta data input or additional +output buffers describing superframing data in DAB+ or DRM+.\n At least one +input buffer for audio input data and one output buffer for bitstream data must +be allocated. The input buffer size can be a user defined multiple of the number +of input channels. PCM input data will be copied from the user defined PCM +buffer to an internal input buffer and so input data can be less than one AAC +audio frame. The output buffer size should be 6144 bits per channel excluding +the LFE channel. If the output data does not fit into the provided buffer, an +AACENC_ERROR will be returned by aacEncEncode(). \code static INT_PCM +inputBuffer[8*2048]; static UCHAR ancillaryBuffer[50]; static +AACENC_MetaData metaDataSetup; static UCHAR outputBuffer[8192]; +\endcode + All input and output buffer must be clustered in input and output buffer arrays. -\skipline inBuffer -\until outBufferElSize +\code +static void* inBuffer[] = { inputBuffer, ancillaryBuffer, &metaDataSetup +}; static INT inBufferIds[] = { IN_AUDIO_DATA, IN_ANCILLRY_DATA, +IN_METADATA_SETUP }; static INT inBufferSize[] = { sizeof(inputBuffer), +sizeof(ancillaryBuffer), sizeof(metaDataSetup) }; static INT inBufferElSize[] += { sizeof(INT_PCM), sizeof(UCHAR), sizeof(AACENC_MetaData) }; + +static void* outBuffer[] = { outputBuffer }; +static INT outBufferIds[] = { OUT_BITSTREAM_DATA }; +static INT outBufferSize[] = { sizeof(outputBuffer) }; +static INT outBufferElSize[] = { sizeof(UCHAR) }; +\endcode + Allocate buffer descriptors -\skipline AACENC_BufDesc -\skipline AACENC_BufDesc +\code +AACENC_BufDesc inBufDesc; +AACENC_BufDesc outBufDesc; +\endcode + Initialize input buffer descriptor -\skipline inBufDesc -\until bufElSizes +\code +inBufDesc.numBufs = sizeof(inBuffer)/sizeof(void*); +inBufDesc.bufs = (void**)&inBuffer; +inBufDesc.bufferIdentifiers = inBufferIds; +inBufDesc.bufSizes = inBufferSize; +inBufDesc.bufElSizes = inBufferElSize; +\endcode + Initialize output buffer descriptor -\skipline outBufDesc -\until bufElSizes +\code +outBufDesc.numBufs = sizeof(outBuffer)/sizeof(void*); +outBufDesc.bufs = (void**)&outBuffer; +outBufDesc.bufferIdentifiers = outBufferIds; +outBufDesc.bufSizes = outBufferSize; +outBufDesc.bufElSizes = outBufferElSize; +\endcode \subsection argLists Provide Input/Output Argument Lists -The input and output arguments of an aacEncEncode() call are described in argument structures. -\dontinclude main.cpp -\skipline AACENC_InArgs -\skipline AACENC_OutArgs +The input and output arguments of an aacEncEncode() call are described in +argument structures. \code AACENC_InArgs inargs; AACENC_OutArgs outargs; +\endcode \section feedInBuf Feed Input Buffer -The input buffer should be handled as a modulo buffer. New audio data in the form of pulse-code- -modulated samples (PCM) must be read from external and be fed to the input buffer depending on its -fill level. The required sample bitrate (represented by the data type INT_PCM which is 16, 24 or 32 -bits wide) is fixed and depends on library configuration (usually 16 bit). - -\dontinclude main.cpp -\skipline WAV_InputRead -\until ; -After the encoder's internal buffer is fed with incoming audio samples, and aacEncEncode() -processed the new input data, update/move remaining samples in input buffer, simulating a modulo buffer: -\skipline outargs.numInSamples>0 -\until } +The input buffer should be handled as a modulo buffer. New audio data in the +form of pulse-code- modulated samples (PCM) must be read from external and be +fed to the input buffer depending on its fill level. The required sample bitrate +(represented by the data type INT_PCM which is 16, 24 or 32 bits wide) is fixed +and depends on library configuration (usually 16 bit). \code inargs.numInSamples ++= WAV_InputRead ( wavIn, &inputBuffer[inargs.numInSamples], + FDKmin(encInfo.inputChannels*encInfo.frameLength, + sizeof(inputBuffer) / + sizeof(INT_PCM)-inargs.numInSamples), + SAMPLE_BITS + ); +\endcode -\section writeOutData Output Bitstream Data -If any AAC bitstream data is available, write it to output file or device. This can be done once the -following condition is true: -\dontinclude main.cpp -\skip Valid bitstream available -\skipline outargs +After the encoder's internal buffer is fed with incoming audio samples, and +aacEncEncode() processed the new input data, update/move remaining samples in +input buffer, simulating a modulo buffer: \code if (outargs.numInSamples>0) { + FDKmemmove( inputBuffer, + &inputBuffer[outargs.numInSamples], + sizeof(INT_PCM)*(inargs.numInSamples-outargs.numInSamples) ); + inargs.numInSamples -= outargs.numInSamples; +} +\endcode -\skipline outBytes>0 +\section writeOutData Output Bitstream Data +If any AAC bitstream data is available, write it to output file or device. This +can be done once the following condition is true: \code if +(outargs.numOutBytes>0) { -If you use file I/O then for example call mpegFileWrite_Write() from the library libMpegFileWrite +} +\endcode -\dontinclude main.cpp -\skipline mpegFileWrite_Write +If you use file I/O then for example call mpegFileWrite_Write() from the library +libMpegFileWrite \code mpegFileWrite_Write(hMpegFile, outputBuffer, +outargs.numOutBytes, aacEncoder_GetParam(hAacEncoder, AACENC_GRANULE_LENGTH)); +\endcode \section cfgMetaData Meta Data Configuration -If the present library is configured with Metadata support, it is possible to insert meta data side info into the generated -audio bitstream while encoding. +If the present library is configured with Metadata support, it is possible to +insert meta data side info into the generated audio bitstream while encoding. -To work with meta data the encoder instance has to be \ref encOpen "allocated" with meta data support. The meta data mode must be be configured with -the ::AACENC_METADATA_MODE parameter and aacEncoder_SetParam() function. -\code aacEncoder_SetParam(hAacEncoder, AACENC_METADATA_MODE, 0-2); \endcode +To work with meta data the encoder instance has to be \ref encOpen "allocated" +with meta data support. The meta data mode must be be configured with the +::AACENC_METADATA_MODE parameter and aacEncoder_SetParam() function. \code +aacEncoder_SetParam(hAacEncoder, AACENC_METADATA_MODE, 0-3); \endcode -This configuration indicates how to embed meta data into bitstrem. Either no insertion, MPEG or ETSI style. -The meta data itself must be specified within the meta data setup structure AACENC_MetaData. +This configuration indicates how to embed meta data into bitstrem. Either no +insertion, MPEG or ETSI style. The meta data itself must be specified within the +meta data setup structure AACENC_MetaData. -Changing one of the AACENC_MetaData setup parameters can be achieved from outside the library within ::IN_METADATA_SETUP input -buffer. There is no need to supply meta data setup structure every frame. If there is no new meta setup data available, the -encoder uses the previous setup or the default configuration in initial state. +Changing one of the AACENC_MetaData setup parameters can be achieved from +outside the library within ::IN_METADATA_SETUP input buffer. There is no need to +supply meta data setup structure every frame. If there is no new meta setup data +available, the encoder uses the previous setup or the default configuration in +initial state. -In general the audio compressor and limiter within the encoder library can be configured with the ::AACENC_METADATA_DRC_PROFILE parameter +In general the audio compressor and limiter within the encoder library can be +configured with the ::AACENC_METADATA_DRC_PROFILE parameter AACENC_MetaData::drc_profile and and AACENC_MetaData::comp_profile. \n \section encReconf Encoder Reconfiguration -The encoder library allows reconfiguration of the encoder instance with new settings -continuously between encoding frames. Each parameter to be changed must be set with -a single aacEncoder_SetParam() call. The internal status of each parameter can be -retrieved with an aacEncoder_GetParam() call.\n -There is no stand-alone reconfiguration function available. When parameters were -modified from outside the library, an internal control mechanism triggers the necessary +The encoder library allows reconfiguration of the encoder instance with new +settings continuously between encoding frames. Each parameter to be changed must +be set with a single aacEncoder_SetParam() call. The internal status of each +parameter can be retrieved with an aacEncoder_GetParam() call.\n There is no +stand-alone reconfiguration function available. When parameters were modified +from outside the library, an internal control mechanism triggers the necessary reconfiguration process which will be applied at the beginning of the following -aacEncEncode() call. This state can be observed from external via the AACENC_INIT_STATUS -and aacEncoder_GetParam() function. The reconfiguration process can also be applied -immediately when all parameters of an aacEncEncode() call are NULL with a valid encoder -handle.\n\n -The internal reconfiguration process can be controlled from extern with the following access. -\code aacEncoder_SetParam(hAacEncoder, AACENC_CONTROL_STATE, AACENC_CTRLFLAGS); \endcode +aacEncEncode() call. This state can be observed from external via the +AACENC_INIT_STATUS and aacEncoder_GetParam() function. The reconfiguration +process can also be applied immediately when all parameters of an aacEncEncode() +call are NULL with a valid encoder handle.\n\n The internal reconfiguration +process can be controlled from extern with the following access. \code +aacEncoder_SetParam(hAacEncoder, AACENC_CONTROL_STATE, AACENC_CTRLFLAGS); +\endcode \section encParams Encoder Parametrization -All parameteres listed in ::AACENC_PARAM can be modified within an encoder instance. +All parameteres listed in ::AACENC_PARAM can be modified within an encoder +instance. \subsection encMandatory Mandatory Encoder Parameters -The following parameters must be specified when the encoder instance is initialized. -\code -aacEncoder_SetParam(hAacEncoder, AACENC_AOT, value); +The following parameters must be specified when the encoder instance is +initialized. \code aacEncoder_SetParam(hAacEncoder, AACENC_AOT, value); aacEncoder_SetParam(hAacEncoder, AACENC_BITRATE, value); aacEncoder_SetParam(hAacEncoder, AACENC_SAMPLERATE, value); aacEncoder_SetParam(hAacEncoder, AACENC_CHANNELMODE, value); \endcode -Beyond that is an internal auto mode which preinitizializes the ::AACENC_BITRATE parameter -if the parameter was not set from extern. The bitrate depends on the number of effective -channels and sampling rate and is determined as follows. +Beyond that is an internal auto mode which preinitizializes the ::AACENC_BITRATE +parameter if the parameter was not set from extern. The bitrate depends on the +number of effective channels and sampling rate and is determined as follows. \code AAC-LC (AOT_AAC_LC): 1.5 bits per sample HE-AAC (AOT_SBR): 0.625 bits per sample (dualrate sbr) @@ -323,108 +405,266 @@ HE-AAC v2 (AOT_PS): 0.5 bits per sample \subsection channelMode Channel Mode Configuration The input audio data is described with the ::AACENC_CHANNELMODE parameter in the -aacEncoder_SetParam() call. It is not possible to use the encoder instance with a 'number of -input channels' argument. Instead, the channelMode must be set as follows. -\code aacEncoder_SetParam(hAacEncoder, AACENC_CHANNELMODE, value); \endcode -The parameter is specified in ::CHANNEL_MODE and can be mapped from the number of input channels -in the following way. -\dontinclude main.cpp -\skip CHANNEL_MODE chMode = MODE_INVALID; -\until return +aacEncoder_SetParam() call. It is not possible to use the encoder instance with +a 'number of input channels' argument. Instead, the channelMode must be set as +follows. \code aacEncoder_SetParam(hAacEncoder, AACENC_CHANNELMODE, value); +\endcode The parameter is specified in ::CHANNEL_MODE and can be mapped from the +number of input channels in the following way. \code CHANNEL_MODE chMode = +MODE_INVALID; + +switch (nChannels) { + case 1: chMode = MODE_1; break; + case 2: chMode = MODE_2; break; + case 3: chMode = MODE_1_2; break; + case 4: chMode = MODE_1_2_1; break; + case 5: chMode = MODE_1_2_2; break; + case 6: chMode = MODE_1_2_2_1; break; + case 7: chMode = MODE_6_1; break; + case 8: chMode = MODE_7_1_BACK; break; + default: + chMode = MODE_INVALID; +} +return chMode; +\endcode + +\subsection bitreservoir Bitreservoir Configuration +In AAC, the default bitreservoir configuration depends on the chosen bitrate per +frame and the number of effective channels. The size can be determined as below. +\f[ +bitreservoir = nEffChannels*6144 - (bitrate*framelength/samplerate) +\f] +Due to audio quality concerns it is not recommended to change the bitreservoir +size to a lower value than the default setting! However, for minimizing the +delay for streaming applications or for achieving a constant size of the +bitstream packages in each frame, it may be necessaray to change the +bitreservoir size. This can be done with the ::AACENC_PEAK_BITRATE parameter. +\code +aacEncoder_SetParam(hAacEncoder, AACENC_PEAK_BITRATE, value); +\endcode +By setting ::AACENC_BITRATEMODE to fixed framing, the bitreservoir is disabled. +A disabled bitreservoir results in a constant size for each bitstream package. +Please note that especially at lower bitrates a disabled bitreservoir can +downgrade the audio quality considerably! The default bitreservoir configuration +can be achieved as follows. \code aacEncoder_SetParam(hAacEncoder, +AACENC_BITRESERVOIR, -1); \endcode + +To achieve acceptable audio quality with a reduced bitreservoir size setting at +least 1000 bits per audio channel is recommended. For a multichannel audio file +with 5.1 channels the bitreservoir reduced to 5000 bits results in acceptable +audio quality. + + +\subsection vbrmode Variable Bitrate Mode +The encoder provides various Variable Bitrate Modes that differ in audio quality +and average overall bitrate. The given values are averages over time, different +encoder settings and strongly depend on the type of audio signal. The VBR +configurations can be adjusted via ::AACENC_BITRATEMODE encoder parameter. +\verbatim +-------------------------------------------- + VBR_MODE | Approx. Bitrate in kbps/channel + | AAC-LC | AAC-LD/AC_ELD +----------+---------------+----------------- + VBR_1 | 32 - 48 | 32 - 56 + VBR_2 | 40 - 56 | 40 - 64 + VBR_3 | 48 - 64 | 48 - 72 + VBR_4 | 64 - 80 | 64 - 88 + VBR_5 | 96 - 120 | 112 - 144 +-------------------------------------------- +\endverbatim +The bitrate ranges apply for individual audio channels. In case of multichannel +configurations the average bitrate might be estimated by multiplying with the +number of effective channels. This corresponds to all audio input channels +exclusively the low frequency channel. At configurations which are making use of +downmix modules the AAC core channels respectively downmix channels shall be +considered. For ::AACENC_AOT which are using SBR, the average bitrate can be +estimated by using the ratio of 0.5 for dualrate SBR and 0.75 for downsampled +SBR configurations. + \subsection encQual Audio Quality Considerations -The default encoder configuration is suggested to be used. Encoder tools such as TNS and PNS -are activated by default and are internally controlled (see \ref BEHAVIOUR_TOOLS). +The default encoder configuration is suggested to be used. Encoder tools such as +TNS and PNS are activated by default and are internally controlled (see \ref +BEHAVIOUR_TOOLS). -There is an additional quality parameter called ::AACENC_AFTERBURNER. In the default -configuration this quality switch is deactivated because it would cause a workload -increase which might be significant. If workload is not an issue in the application -we recommended to activate this feature. -\code aacEncoder_SetParam(hAacEncoder, AACENC_AFTERBURNER, 1); \endcode +There is an additional quality parameter called ::AACENC_AFTERBURNER. In the +default configuration this quality switch is deactivated because it would cause +a workload increase which might be significant. If workload is not an issue in +the application we recommended to activate this feature. \code +aacEncoder_SetParam(hAacEncoder, AACENC_AFTERBURNER, 0/1); \endcode \subsection encELD ELD Auto Configuration Mode -For ELD configuration a so called auto configurator is available which configures SBR and the SBR ratio by itself. -The configurator is used when the encoder parameter ::AACENC_SBR_MODE and ::AACENC_SBR_RATIO are not set explicitely. - -Based on sampling rate and chosen bitrate per channel a reasonable SBR configuration will be used. -\verbatim ------------------------------------------------------------- - Sampling Rate | Channel Bitrate | SBR | SBR Ratio ------------------+-----------------+------+----------------- - ]min, 16] kHz | min - 27999 | on | downsampled SBR - | 28000 - max | off | --- ------------------+-----------------+------+----------------- - ]16 - 24] kHz | min - 39999 | on | downsampled SBR - | 40000 - max | off | --- ------------------+-----------------+------+----------------- - ]24 - 32] kHz | min - 27999 | on | dualrate SBR - | 28000 - 55999 | on | downsampled SBR - | 56000 - max | off | --- ------------------+-----------------+------+----------------- - ]32 - 44.1] kHz | min - 63999 | on | dualrate SBR - | 64000 - max | off | --- ------------------+-----------------+------+----------------- - ]44.1 - 48] kHz | min - 63999 | on | dualrate SBR - | 64000 - max | off | --- ------------------------------------------------------------- +For ELD configuration a so called auto configurator is available which +configures SBR and the SBR ratio by itself. The configurator is used when the +encoder parameter ::AACENC_SBR_MODE and ::AACENC_SBR_RATIO are not set +explicitly. + +Based on sampling rate and chosen bitrate a reasonable SBR configuration will be +used. \verbatim +------------------------------------------------------------------ + Sampling Rate | Total Bitrate | No. of | SBR | SBR Ratio + [kHz] | [bit/s] | Chan | | + | | | | +---------------+-----------------+--------+-----+----------------- + ]min, 16[ | min - max | 1 | off | --- +---------------+-----------------+--------------+----------------- + [16] | min - 27999 | 1 | on | downsampled SBR + | 28000 - max | 1 | off | --- +---------------+-----------------+--------------+----------------- + ]16 - 24] | min - 39999 | 1 | on | downsampled SBR + | 40000 - max | 1 | off | --- +---------------+-----------------+--------------+----------------- + ]24 - 32] | min - 27999 | 1 | on | dualrate SBR + | 28000 - 55999 | 1 | on | downsampled SBR + | 56000 - max | 1 | off | --- +---------------+-----------------+--------------+----------------- + ]32 - 44.1] | min - 63999 | 1 | on | dualrate SBR + | 64000 - max | 1 | off | --- +---------------+-----------------+--------------+----------------- + ]44.1 - 48] | min - 63999 | 1 | on | dualrate SBR + | 64000 - max | 1 | off | --- + | | | | +---------------+-----------------+--------+-----+----------------- + ]min, 16[ | min - max | 2 | off | --- +---------------+-----------------+--------------+----------------- + [16] | min - 31999 | 2 | on | downsampled SBR + | 32000 - 63999 | 2 | on | downsampled SBR + | 64000 - max | 2 | off | --- +---------------+-----------------+--------------+----------------- + ]16 - 24] | min - 47999 | 2 | on | downsampled SBR + | 48000 - 79999 | 2 | on | downsampled SBR + | 80000 - max | 2 | off | --- +---------------+-----------------+--------------+----------------- + ]24 - 32] | min - 31999 | 2 | on | dualrate SBR + | 32000 - 67999 | 2 | on | dualrate SBR + | 68000 - 95999 | 2 | on | downsampled SBR + | 96000 - max | 2 | off | --- +---------------+-----------------+--------------+----------------- + ]32 - 44.1] | min - 43999 | 2 | on | dualrate SBR + | 44000 - 127999 | 2 | on | dualrate SBR + | 128000 - max | 2 | off | --- +---------------+-----------------+--------------+----------------- + ]44.1 - 48] | min - 43999 | 2 | on | dualrate SBR + | 44000 - 127999 | 2 | on | dualrate SBR + | 128000 - max | 2 | off | --- + | | | +------------------------------------------------------------------ \endverbatim +\subsection encDsELD Reduced Delay (Downscaled) Mode +The downscaled mode of AAC-ELD reduces the algorithmic delay of AAC-ELD by +virtually increasing the sampling rate. When using the downscaled mode, the +bitrate should be increased for keeping the same audio quality level. For common +signals, the bitrate should be increased by 25% for a downscale factor of 2. + +Currently, downscaling factors 2 and 4 are supported. +To enable the downscaled mode in the encoder, the framelength parameter +AACENC_GRANULE_LENGTH must be set accordingly to 256 or 240 for a downscale +factor of 2 or 128 or 120 for a downscale factor of 4. The default values of 512 +or 480 mean that no downscaling is applied. \code +aacEncoder_SetParam(hAacEncoder, AACENC_GRANULE_LENGTH, 256); +aacEncoder_SetParam(hAacEncoder, AACENC_GRANULE_LENGTH, 128); +\endcode + +Downscaled bitstreams are fully backwards compatible. However, the legacy +decoder needs to support high sample rate, e.g. 96kHz. The signaled sampling +rate is multiplied by the downscale factor. Although not required, downscaling +should be applied when decoding downscaled bitstreams. It reduces CPU workload +and the output will have the same sampling rate as the input. In an ideal +configuration both encoder and decoder should run with the same downscale +factor. + +The following table shows approximate filter bank delays in ms for common +sampling rates(sr) at framesize(fs), and downscale factor(dsf), based on this +formula: \f[ 1000 * fs / (dsf * sr) \f] -\section audiochCfg Audio Channel Configuration -The MPEG standard refers often to the so-called Channel Configuration. This Channel Configuration is used for a fixed Channel -Mapping. The configurations 1-7 are predefined in MPEG standard and used for implicit signalling within the encoded bitstream. -For user defined Configurations the Channel Configuration is set to 0 and the Channel Mapping must be explecitly described with an appropriate -Program Config Element. The present Encoder implementation does not allow the user to configure this Channel Configuration from -extern. The Encoder implementation supports fixed Channel Modes which are mapped to Channel Configuration as follow. \verbatim -------------------------------------------------------------------------------- - ChannelMode | ChCfg | front_El | side_El | back_El | lfe_El ------------------------+--------+---------------+----------+----------+-------- -MODE_1 | 1 | SCE | | | -MODE_2 | 2 | CPE | | | -MODE_1_2 | 3 | SCE, CPE | | | -MODE_1_2_1 | 4 | SCE, CPE | | SCE | -MODE_1_2_2 | 5 | SCE, CPE | | CPE | -MODE_1_2_2_1 | 6 | SCE, CPE | | CPE | LFE -MODE_1_2_2_2_1 | 7 | SCE, CPE, CPE | | CPE | LFE ------------------------+--------+---------------+----------+----------+-------- -MODE_7_1_REAR_SURROUND | 0 | SCE, CPE | | CPE, CPE | LFE -MODE_7_1_FRONT_CENTER | 0 | SCE, CPE, CPE | | CPE | LFE -------------------------------------------------------------------------------- - - SCE: Single Channel Element. - - CPE: Channel Pair. - - SCE: Low Frequency Element. +-------------------------------------- + | 512/2 | 512/4 | 480/2 | 480/4 +------+-------+-------+-------+------- +22050 | 17.41 | 8.71 | 16.33 | 8.16 +32000 | 12.00 | 6.00 | 11.25 | 5.62 +44100 | 8.71 | 4.35 | 8.16 | 4.08 +48000 | 8.00 | 4.00 | 7.50 | 3.75 +-------------------------------------- \endverbatim -Moreover, the Table describes all fixed Channel Elements for each Channel Mode which are assigned to a speaker arrangement. The -arrangement includes front, side, back and lfe Audio Channel Elements.\n -This mapping of Audio Channel Elements is defined in MPEG standard for Channel Config 1-7. The Channel assignment for MODE_1_1, -MODE_2_2 and MODE_2_1 is used from the ARIB standard. All other configurations are defined as suggested in MPEG.\n -In case of Channel Config 0 or writing matrix mixdown coefficients, the encoder enables the writing of Program Config Element -itself as described in \ref encPCE. The configuration used in Program Config Element refers to the denoted Table.\n -Beside the Channel Element assignment the Channel Modes are resposible for audio input data channel mapping. The Channel Mapping -of the audio data depends on the selected ::AACENC_CHANNELORDER which can be MPEG or WAV like order.\n -Following Table describes the complete channel mapping for both Channel Order configurations. +\section audiochCfg Audio Channel Configuration +The MPEG standard refers often to the so-called Channel Configuration. This +Channel Configuration is used for a fixed Channel Mapping. The configurations +1-7 and 11,12,14 are predefined in MPEG standard and used for implicit +signalling within the encoded bitstream. For user defined Configurations the +Channel Configuration is set to 0 and the Channel Mapping must be explecitly +described with an appropriate Program Config Element. The present Encoder +implementation does not allow the user to configure this Channel Configuration +from extern. The Encoder implementation supports fixed Channel Modes which are +mapped to Channel Configuration as follow. \verbatim +---------------------------------------------------------------------------------------- + ChannelMode | ChCfg | Height | front_El | side_El | back_El | +lfe_El +-----------------------+-------+--------+---------------+----------+----------+--------- +MODE_1 | 1 | NORM | SCE | | | +MODE_2 | 2 | NORM | CPE | | | +MODE_1_2 | 3 | NORM | SCE, CPE | | | +MODE_1_2_1 | 4 | NORM | SCE, CPE | | SCE | +MODE_1_2_2 | 5 | NORM | SCE, CPE | | CPE | +MODE_1_2_2_1 | 6 | NORM | SCE, CPE | | CPE | +LFE MODE_1_2_2_2_1 | 7 | NORM | SCE, CPE, CPE | | CPE +| LFE MODE_6_1 | 11 | NORM | SCE, CPE | | CPE, +SCE | LFE MODE_7_1_BACK | 12 | NORM | SCE, CPE | | +CPE, CPE | LFE +-----------------------+-------+--------+---------------+----------+----------+--------- +MODE_7_1_TOP_FRONT | 14 | NORM | SCE, CPE | | CPE | +LFE | | TOP | CPE | | | +-----------------------+-------+--------+---------------+----------+----------+--------- +MODE_7_1_REAR_SURROUND | 0 | NORM | SCE, CPE | | CPE, CPE | +LFE MODE_7_1_FRONT_CENTER | 0 | NORM | SCE, CPE, CPE | | CPE +| LFE +---------------------------------------------------------------------------------------- +- NORM: Normal Height Layer. - TOP: Top Height Layer. - BTM: Bottom Height +Layer. +- SCE: Single Channel Element. - CPE: Channel Pair. - LFE: Low Frequency +Element. \endverbatim + +The Table describes all fixed Channel Elements for each Channel Mode which are +assigned to a speaker arrangement. The arrangement includes front, side, back +and lfe Audio Channel Elements in the normal height layer, possibly followed by +front, side, and back elements in the top and bottom layer (Channel +Configuration 14). \n This mapping of Audio Channel Elements is defined in MPEG +standard for Channel Config 1-7 and 11,12,14.\n In case of Channel Config 0 or +writing matrix mixdown coefficients, the encoder enables the writing of Program +Config Element itself as described in \ref encPCE. The configuration used in +Program Config Element refers to the denoted Table.\n Beside the Channel Element +assignment the Channel Modes are resposible for audio input data channel +mapping. The Channel Mapping of the audio data depends on the selected +::AACENC_CHANNELORDER which can be MPEG or WAV like order.\n Following table +describes the complete channel mapping for both Channel Order configurations. \verbatim --------------------------------------------------------------------------------------- ChannelMode | MPEG-Channelorder | WAV-Channelorder -----------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+--- -MODE_1 | 0 | | | | | | | | 0 | | | | | | | -MODE_2 | 0 | 1 | | | | | | | 0 | 1 | | | | | | -MODE_1_2 | 0 | 1 | 2 | | | | | | 2 | 0 | 1 | | | | | -MODE_1_2_1 | 0 | 1 | 2 | 3 | | | | | 2 | 0 | 1 | 3 | | | | -MODE_1_2_2 | 0 | 1 | 2 | 3 | 4 | | | | 2 | 0 | 1 | 3 | 4 | | | -MODE_1_2_2_1 | 0 | 1 | 2 | 3 | 4 | 5 | | | 2 | 0 | 1 | 4 | 5 | 3 | | -MODE_1_2_2_2_1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 2 | 6 | 7 | 0 | 1 | 4 | 5 | 3 +MODE_1 | 0 | | | | | | | | 0 | | | | | | +| MODE_2 | 0 | 1 | | | | | | | 0 | 1 | | | | +| | MODE_1_2 | 0 | 1 | 2 | | | | | | 2 | 0 | 1 | | +| | | MODE_1_2_1 | 0 | 1 | 2 | 3 | | | | | 2 | 0 | 1 | 3 +| | | | MODE_1_2_2 | 0 | 1 | 2 | 3 | 4 | | | | 2 | 0 | 1 +| 3 | 4 | | | MODE_1_2_2_1 | 0 | 1 | 2 | 3 | 4 | 5 | | | 2 | 0 +| 1 | 4 | 5 | 3 | | MODE_1_2_2_2_1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 2 +| 6 | 7 | 0 | 1 | 4 | 5 | 3 MODE_6_1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | +| 2 | 0 | 1 | 4 | 5 | 6 | 3 | MODE_7_1_BACK | 0 | 1 | 2 | 3 | 4 | 5 | 6 +| 7 | 2 | 0 | 1 | 6 | 7 | 4 | 5 | 3 MODE_7_1_TOP_FRONT | 0 | 1 | 2 | 3 | 4 | +5 | 6 | 7 | 2 | 0 | 1 | 4 | 5 | 3 | 6 | 7 -----------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+--- -MODE_7_1_REAR_SURROUND | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 2 | 0 | 1 | 6 | 7 | 4 | 5 | 3 -MODE_7_1_FRONT_CENTER | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 2 | 6 | 7 | 0 | 1 | 4 | 5 | 3 +MODE_7_1_REAR_SURROUND | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 2 | 0 | 1 | 6 | 7 | 4 | +5 | 3 MODE_7_1_FRONT_CENTER | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 2 | 6 | 7 | 0 | 1 +| 4 | 5 | 3 --------------------------------------------------------------------------------------- \endverbatim -The denoted mapping is important for correct audio channel assignment when using MPEG or WAV ordering. The incoming audio -channels are distributed MPEG like starting at the front channels and ending at the back channels. The distribution is used as -described in Table concering Channel Config and fix channel elements. Please see the following example for clarification. +The denoted mapping is important for correct audio channel assignment when using +MPEG or WAV ordering. The incoming audio channels are distributed MPEG like +starting at the front channels and ending at the back channels. The distribution +is used as described in Table concering Channel Config and fix channel elements. +Please see the following example for clarification. \verbatim Example: MODE_1_2_2_1 - WAV-Channelorder 5.1 @@ -444,201 +684,276 @@ Example: MODE_1_2_2_1 - WAV-Channelorder 5.1 \section suppBitrates Supported Bitrates The FDK AAC Encoder provides a wide range of supported bitrates. -The minimum and maximum allowed bitrate depends on the Audio Object Type. For AAC-LC the minimum -bitrate is the bitrate that is required to write the most basic and minimal valid bitstream. -It consists of the bitstream format header information and other static/mandatory information -within the AAC payload. The maximum AAC framesize allowed by the MPEG-4 standard -determines the maximum allowed bitrate for AAC-LC. For HE-AAC and HE-AAC v2 a library internal -look-up table is used. - -A good working point in terms of audio quality, sampling rate and bitrate, is at 1 to 1.5 -bits/audio sample for AAC-LC, 0.625 bits/audio sample for dualrate HE-AAC, 1.125 bits/audio sample -for downsampled HE-AAC and 0.5 bits/audio sample for HE-AAC v2. -For example for one channel with a sampling frequency of 48 kHz, the range from -48 kbit/s to 72 kbit/s achieves reasonable audio quality for AAC-LC. - -For HE-AAC and HE-AAC v2 the lowest possible audio input sampling frequency is 16 kHz because then the -AAC-LC core encoder operates in dual rate mode at its lowest possible sampling frequency, which is 8 kHz. -HE-AAC v2 requires stereo input audio data. - -Please note that in HE-AAC or HE-AAC v2 mode the encoder supports much higher bitrates than are -appropriate for HE-AAC or HE-AAC v2. For example, at a bitrate of more than 64 kbit/s for a stereo -audio signal at 44.1 kHz it usually makes sense to use AAC-LC, which will produce better audio -quality at that bitrate than HE-AAC or HE-AAC v2. +The minimum and maximum allowed bitrate depends on the Audio Object Type. For +AAC-LC the minimum bitrate is the bitrate that is required to write the most +basic and minimal valid bitstream. It consists of the bitstream format header +information and other static/mandatory information within the AAC payload. The +maximum AAC framesize allowed by the MPEG-4 standard determines the maximum +allowed bitrate for AAC-LC. For HE-AAC and HE-AAC v2 a library internal look-up +table is used. + +A good working point in terms of audio quality, sampling rate and bitrate, is at +1 to 1.5 bits/audio sample for AAC-LC, 0.625 bits/audio sample for dualrate +HE-AAC, 1.125 bits/audio sample for downsampled HE-AAC and 0.5 bits/audio sample +for HE-AAC v2. For example for one channel with a sampling frequency of 48 kHz, +the range from 48 kbit/s to 72 kbit/s achieves reasonable audio quality for +AAC-LC. + +For HE-AAC and HE-AAC v2 the lowest possible audio input sampling frequency is +16 kHz because then the AAC-LC core encoder operates in dual rate mode at its +lowest possible sampling frequency, which is 8 kHz. HE-AAC v2 requires stereo +input audio data. + +Please note that in HE-AAC or HE-AAC v2 mode the encoder supports much higher +bitrates than are appropriate for HE-AAC or HE-AAC v2. For example, at a bitrate +of more than 64 kbit/s for a stereo audio signal at 44.1 kHz it usually makes +sense to use AAC-LC, which will produce better audio quality at that bitrate +than HE-AAC or HE-AAC v2. \section reommendedConfig Recommended Sampling Rate and Bitrate Combinations -The following table provides an overview of recommended encoder configuration parameters -which we determined by virtue of numerous listening tests. +The following table provides an overview of recommended encoder configuration +parameters which we determined by virtue of numerous listening tests. \subsection reommendedConfigLC AAC-LC, HE-AAC, HE-AACv2 in Dualrate SBR mode. \verbatim ----------------------------------------------------------------------------------- -Audio Object Type | Bit Rate Range | Supported | Preferred | No. of - | [bit/s] | Sampling Rates | Sampl. | Chan. - | | [kHz] | Rate | - | | | [kHz] | +Audio Object Type | Bit Rate Range | Supported | Preferred | No. +of | [bit/s] | Sampling Rates | Sampl. | Chan. | +| [kHz] | Rate | | | +| [kHz] | -------------------+------------------+-----------------------+------------+------- -AAC LC + SBR + PS | 8000 - 11999 | 22.05, 24.00 | 24.00 | 2 -AAC LC + SBR + PS | 12000 - 17999 | 32.00 | 32.00 | 2 -AAC LC + SBR + PS | 18000 - 39999 | 32.00, 44.10, 48.00 | 44.10 | 2 -AAC LC + SBR + PS | 40000 - 56000 | 32.00, 44.10, 48.00 | 48.00 | 2 +AAC LC + SBR + PS | 8000 - 11999 | 22.05, 24.00 | 24.00 | 2 +AAC LC + SBR + PS | 12000 - 17999 | 32.00 | 32.00 | 2 +AAC LC + SBR + PS | 18000 - 39999 | 32.00, 44.10, 48.00 | 44.10 | 2 +AAC LC + SBR + PS | 40000 - 64000 | 32.00, 44.10, 48.00 | 48.00 | 2 -------------------+------------------+-----------------------+------------+------- -AAC LC + SBR | 8000 - 11999 | 22.05, 24.00 | 24.00 | 1 -AAC LC + SBR | 12000 - 17999 | 32.00 | 32.00 | 1 -AAC LC + SBR | 18000 - 39999 | 32.00, 44.10, 48.00 | 44.10 | 1 -AAC LC + SBR | 40000 - 56000 | 32.00, 44.10, 48.00 | 48.00 | 1 -AAC LC + SBR | 16000 - 27999 | 32.00, 44.10, 48.00 | 32.00 | 2 -AAC LC + SBR | 28000 - 63999 | 32.00, 44.10, 48.00 | 44.10 | 2 -AAC LC + SBR | 64000 - 128000 | 32.00, 44.10, 48.00 | 48.00 | 2 +AAC LC + SBR | 8000 - 11999 | 22.05, 24.00 | 24.00 | 1 +AAC LC + SBR | 12000 - 17999 | 32.00 | 32.00 | 1 +AAC LC + SBR | 18000 - 39999 | 32.00, 44.10, 48.00 | 44.10 | 1 +AAC LC + SBR | 40000 - 64000 | 32.00, 44.10, 48.00 | 48.00 | 1 -------------------+------------------+-----------------------+------------+------- -AAC LC + SBR | 64000 - 69999 | 32.00, 44.10, 48.00 | 32.00 | 5, 5.1 -AAC LC + SBR | 70000 - 159999 | 32.00, 44.10, 48.00 | 44.10 | 5, 5.1 -AAC LC + SBR | 160000 - 245999 | 32.00, 44.10, 48.00 | 48.00 | 5 -AAC LC + SBR | 160000 - 265999 | 32.00, 44.10, 48.00 | 48.00 | 5.1 +AAC LC + SBR | 16000 - 27999 | 32.00, 44.10, 48.00 | 32.00 | 2 +AAC LC + SBR | 28000 - 63999 | 32.00, 44.10, 48.00 | 44.10 | 2 +AAC LC + SBR | 64000 - 128000 | 32.00, 44.10, 48.00 | 48.00 | 2 -------------------+------------------+-----------------------+------------+------- -AAC LC | 8000 - 15999 | 11.025, 12.00, 16.00 | 12.00 | 1 -AAC LC | 16000 - 23999 | 16.00 | 16.00 | 1 -AAC LC | 24000 - 31999 | 16.00, 22.05, 24.00 | 24.00 | 1 -AAC LC | 32000 - 55999 | 32.00 | 32.00 | 1 -AAC LC | 56000 - 160000 | 32.00, 44.10, 48.00 | 44.10 | 1 -AAC LC | 160001 - 288000 | 48.00 | 48.00 | 1 +AAC LC + SBR | 64000 - 69999 | 32.00, 44.10, 48.00 | 32.00 | +5, 5.1 AAC LC + SBR | 70000 - 239999 | 32.00, 44.10, 48.00 | 44.10 +| 5, 5.1 AAC LC + SBR | 240000 - 319999 | 32.00, 44.10, 48.00 | +48.00 | 5, 5.1 -------------------+------------------+-----------------------+------------+------- -AAC LC | 16000 - 23999 | 11.025, 12.00, 16.00 | 12.00 | 2 -AAC LC | 24000 - 31999 | 16.00 | 16.00 | 2 -AAC LC | 32000 - 39999 | 16.00, 22.05, 24.00 | 22.05 | 2 -AAC LC | 40000 - 95999 | 32.00 | 32.00 | 2 -AAC LC | 96000 - 111999 | 32.00, 44.10, 48.00 | 32.00 | 2 -AAC LC | 112000 - 320001 | 32.00, 44.10, 48.00 | 44.10 | 2 -AAC LC | 320002 - 576000 | 48.00 | 48.00 | 2 +AAC LC | 8000 - 15999 | 11.025, 12.00, 16.00 | 12.00 | 1 +AAC LC | 16000 - 23999 | 16.00 | 16.00 | 1 +AAC LC | 24000 - 31999 | 16.00, 22.05, 24.00 | 24.00 | 1 +AAC LC | 32000 - 55999 | 32.00 | 32.00 | 1 +AAC LC | 56000 - 160000 | 32.00, 44.10, 48.00 | 44.10 | 1 +AAC LC | 160001 - 288000 | 48.00 | 48.00 | 1 -------------------+------------------+-----------------------+------------+------- -AAC LC | 160000 - 239999 | 32.00 | 32.00 | 5, 5.1 -AAC LC | 240000 - 279999 | 32.00, 44.10, 48.00 | 32.00 | 5, 5.1 -AAC LC | 280000 - 800000 | 32.00, 44.10, 48.00 | 44.10 | 5, 5.1 +AAC LC | 16000 - 23999 | 11.025, 12.00, 16.00 | 12.00 | 2 +AAC LC | 24000 - 31999 | 16.00 | 16.00 | 2 +AAC LC | 32000 - 39999 | 16.00, 22.05, 24.00 | 22.05 | 2 +AAC LC | 40000 - 95999 | 32.00 | 32.00 | 2 +AAC LC | 96000 - 111999 | 32.00, 44.10, 48.00 | 32.00 | 2 +AAC LC | 112000 - 320001 | 32.00, 44.10, 48.00 | 44.10 | 2 +AAC LC | 320002 - 576000 | 48.00 | 48.00 | 2 +-------------------+------------------+-----------------------+------------+------- +AAC LC | 160000 - 239999 | 32.00 | 32.00 | +5, 5.1 AAC LC | 240000 - 279999 | 32.00, 44.10, 48.00 | 32.00 +| 5, 5.1 AAC LC | 280000 - 800000 | 32.00, 44.10, 48.00 | +44.10 | 5, 5.1 ----------------------------------------------------------------------------------- \endverbatim \n -\subsection reommendedConfigLD AAC-LD, AAC-ELD, AAC-ELD with SBR in Dualrate SBR mode. -\verbatim +\subsection reommendedConfigLD AAC-LD, AAC-ELD, AAC-ELD with SBR in Dualrate SBR +mode. Unlike to HE-AAC configuration the SBR is not covered by ELD audio object +type and needs to be enabled explicitly. Use ::AACENC_SBR_MODE to configure SBR +and its samplingrate ratio with ::AACENC_SBR_RATIO parameter. \verbatim ----------------------------------------------------------------------------------- -Audio Object Type | Bit Rate Range | Supported | Preferred | No. of - | [bit/s] | Sampling Rates | Sampl. | Chan. - | | [kHz] | Rate | - | | | [kHz] | +Audio Object Type | Bit Rate Range | Supported | Preferred | No. +of | [bit/s] | Sampling Rates | Sampl. | Chan. | +| [kHz] | Rate | | | +| [kHz] | -------------------+------------------+-----------------------+------------+------- -ELD + SBR | 18000 - 24999 | 32.00 - 44.10 | 32.00 | 1 -ELD + SBR | 25000 - 31999 | 32.00 - 48.00 | 32.00 | 1 -ELD + SBR | 32000 - 64000 | 32.00 - 48.00 | 48.00 | 1 +ELD + SBR | 18000 - 24999 | 32.00 - 44.10 | 32.00 | 1 +ELD + SBR | 25000 - 31999 | 32.00 - 48.00 | 32.00 | 1 +ELD + SBR | 32000 - 64000 | 32.00 - 48.00 | 48.00 | 1 -------------------+------------------+-----------------------+------------+------- -ELD + SBR | 32000 - 51999 | 32.00 - 48.00 | 44.10 | 2 -ELD + SBR | 52000 - 128000 | 32.00 - 48.00 | 48.00 | 2 +ELD + SBR | 32000 - 51999 | 32.00 - 48.00 | 44.10 | 2 +ELD + SBR | 52000 - 128000 | 32.00 - 48.00 | 48.00 | 2 -------------------+------------------+-----------------------+------------+------- -ELD + SBR | 72000 - 160000 | 44.10 - 48.00 | 48.00 | 3 +ELD + SBR | 78000 - 160000 | 32.00 - 48.00 | 48.00 | 3 -------------------+------------------+-----------------------+------------+------- -ELD + SBR | 96000 - 212000 | 44.10 - 48.00 | 48.00 | 4 +ELD + SBR | 104000 - 212000 | 32.00 - 48.00 | 48.00 | 4 -------------------+------------------+-----------------------+------------+------- -ELD + SBR | 120000 - 246000 | 44.10 - 48.00 | 48.00 | 5 +ELD + SBR | 130000 - 246000 | 32.00 - 48.00 | 48.00 | +5, 5.1 -------------------+------------------+-----------------------+------------+------- -ELD + SBR | 120000 - 266000 | 44.10 - 48.00 | 48.00 | 5.1 +LD, ELD | 16000 - 19999 | 16.00 - 24.00 | 16.00 | 1 +LD, ELD | 20000 - 39999 | 16.00 - 32.00 | 24.00 | 1 +LD, ELD | 40000 - 49999 | 22.05 - 32.00 | 32.00 | 1 +LD, ELD | 50000 - 61999 | 24.00 - 44.10 | 32.00 | 1 +LD, ELD | 62000 - 84999 | 32.00 - 48.00 | 44.10 | 1 +LD, ELD | 85000 - 192000 | 44.10 - 48.00 | 48.00 | 1 -------------------+------------------+-----------------------+------------+------- -LD, ELD | 16000 - 19999 | 16.00 - 24.00 | 16.00 | 1 -LD, ELD | 20000 - 39999 | 16.00 - 32.00 | 24.00 | 1 -LD, ELD | 40000 - 49999 | 22.05 - 32.00 | 32.00 | 1 -LD, ELD | 50000 - 61999 | 24.00 - 44.10 | 32.00 | 1 -LD, ELD | 62000 - 84999 | 32.00 - 48.00 | 44.10 | 1 -LD, ELD | 85000 - 192000 | 44.10 - 48.00 | 48.00 | 1 +LD, ELD | 64000 - 75999 | 24.00 - 32.00 | 32.00 | 2 +LD, ELD | 76000 - 97999 | 24.00 - 44.10 | 32.00 | 2 +LD, ELD | 98000 - 135999 | 32.00 - 48.00 | 44.10 | 2 +LD, ELD | 136000 - 384000 | 44.10 - 48.00 | 48.00 | 2 -------------------+------------------+-----------------------+------------+------- -LD, ELD | 64000 - 75999 | 24.00 - 32.00 | 32.00 | 2 -LD, ELD | 76000 - 97999 | 24.00 - 44.10 | 32.00 | 2 -LD, ELD | 98000 - 135999 | 32.00 - 48.00 | 44.10 | 2 -LD, ELD | 136000 - 384000 | 44.10 - 48.00 | 48.00 | 2 +LD, ELD | 96000 - 113999 | 24.00 - 32.00 | 32.00 | 3 +LD, ELD | 114000 - 146999 | 24.00 - 44.10 | 32.00 | 3 +LD, ELD | 147000 - 203999 | 32.00 - 48.00 | 44.10 | 3 +LD, ELD | 204000 - 576000 | 44.10 - 48.00 | 48.00 | 3 -------------------+------------------+-----------------------+------------+------- -LD, ELD | 96000 - 113999 | 24.00 - 32.00 | 32.00 | 3 -LD, ELD | 114000 - 146999 | 24.00 - 44.10 | 32.00 | 3 -LD, ELD | 147000 - 203999 | 32.00 - 48.00 | 44.10 | 3 -LD, ELD | 204000 - 576000 | 44.10 - 48.00 | 48.00 | 3 +LD, ELD | 128000 - 151999 | 24.00 - 32.00 | 32.00 | 4 +LD, ELD | 152000 - 195999 | 24.00 - 44.10 | 32.00 | 4 +LD, ELD | 196000 - 271999 | 32.00 - 48.00 | 44.10 | 4 +LD, ELD | 272000 - 768000 | 44.10 - 48.00 | 48.00 | 4 -------------------+------------------+-----------------------+------------+------- -LD, ELD | 128000 - 151999 | 24.00 - 32.00 | 32.00 | 4 -LD, ELD | 152000 - 195999 | 24.00 - 44.10 | 32.00 | 4 -LD, ELD | 196000 - 271999 | 32.00 - 48.00 | 44.10 | 4 -LD, ELD | 272000 - 768000 | 44.10 - 48.00 | 48.00 | 4 --------------------+------------------+-----------------------+------------+------- -LD, ELD | 160000 - 189999 | 24.00 - 32.00 | 32.00 | 5 -LD, ELD | 190000 - 244999 | 24.00 - 44.10 | 32.00 | 5 -LD, ELD | 245000 - 339999 | 32.00 - 48.00 | 44.10 | 5 -LD, ELD | 340000 - 960000 | 44.10 - 48.00 | 48.00 | 5 +LD, ELD | 160000 - 189999 | 24.00 - 32.00 | 32.00 | +5, 5.1 LD, ELD | 190000 - 244999 | 24.00 - 44.10 | 32.00 +| 5, 5.1 LD, ELD | 245000 - 339999 | 32.00 - 48.00 | +44.10 | 5, 5.1 LD, ELD | 340000 - 960000 | 44.10 - 48.00 | +48.00 | 5, 5.1 ----------------------------------------------------------------------------------- \endverbatim \n \subsection reommendedConfigELD AAC-ELD with SBR in Downsampled SBR mode. \verbatim ----------------------------------------------------------------------------------- -Audio Object Type | Bit Rate Range | Supported | Preferred | No. of - | [bit/s] | Sampling Rates | Sampl. | Chan. - | | [kHz] | Rate | - | | | [kHz] | +Audio Object Type | Bit Rate Range | Supported | Preferred | No. +of | [bit/s] | Sampling Rates | Sampl. | Chan. | +| [kHz] | Rate | | | +| [kHz] | +-------------------+------------------+-----------------------+------------+------- +ELD + SBR | 18000 - 24999 | 16.00 - 22.05 | 22.05 | 1 +(downsampled SBR) | 25000 - 31999 | 16.00 - 24.00 | 24.00 | 1 + | 32000 - 47999 | 22.05 - 32.00 | 32.00 | 1 + | 48000 - 64000 | 22.05 - 48.00 | 32.00 | 1 +-------------------+------------------+-----------------------+------------+------- +ELD + SBR | 32000 - 51999 | 16.00 - 24.00 | 24.00 | 2 +(downsampled SBR) | 52000 - 59999 | 22.05 - 24.00 | 24.00 | 2 + | 60000 - 95999 | 22.05 - 32.00 | 32.00 | 2 + | 96000 - 128000 | 22.05 - 48.00 | 32.00 | 2 +-------------------+------------------+-----------------------+------------+------- +ELD + SBR | 78000 - 99999 | 22.05 - 24.00 | 24.00 | 3 +(downsampled SBR) | 100000 - 143999 | 22.05 - 32.00 | 32.00 | 3 + | 144000 - 159999 | 22.05 - 48.00 | 32.00 | 3 + | 160000 - 192000 | 32.00 - 48.00 | 32.00 | 3 +-------------------+------------------+-----------------------+------------+------- +ELD + SBR | 104000 - 149999 | 22.05 - 24.00 | 24.00 | 4 +(downsampled SBR) | 150000 - 191999 | 22.05 - 32.00 | 32.00 | 4 + | 192000 - 211999 | 22.05 - 48.00 | 32.00 | 4 + | 212000 - 256000 | 32.00 - 48.00 | 32.00 | 4 -------------------+------------------+-----------------------+------------+------- -ELD + SBR | 18000 - 24999 | 16.00 - 22.05 | 22.05 | 1 -(downsampled SBR) | 25000 - 35999 | 22.05 - 32.00 | 24.00 | 1 - | 36000 - 64000 | 32.00 - 48.00 | 32.00 | 1 +ELD + SBR | 130000 - 171999 | 22.05 - 24.00 | 24.00 | +5, 5.1 (downsampled SBR) | 172000 - 239999 | 22.05 - 32.00 | 32.00 +| 5, 5.1 | 240000 - 320000 | 32.00 - 48.00 | 32.00 | 5, 5.1 ----------------------------------------------------------------------------------- \endverbatim \n +\subsection reommendedConfigELDv2 AAC-ELD v2, AAC-ELD v2 with SBR. +The ELD v2 212 configuration must be configured explicitly with +::AACENC_CHANNELMODE parameter according MODE_212 value. SBR can be configured +separately through ::AACENC_SBR_MODE and ::AACENC_SBR_RATIO parameter. Following +configurations shall apply to both framelengths 480 and 512. For ELD v2 +configuration without SBR and framelength 480 the supported sampling rate is +restricted to the range from 16 kHz up to 24 kHz. \verbatim +----------------------------------------------------------------------------------- +Audio Object Type | Bit Rate Range | Supported | Preferred | No. +of | [bit/s] | Sampling Rates | Sampl. | Chan. | +| [kHz] | Rate | | | +| [kHz] | +-------------------+------------------+-----------------------+------------+------- +ELD-212 | 16000 - 19999 | 16.00 - 24.00 | 16.00 | 2 +(without SBR) | 20000 - 39999 | 16.00 - 32.00 | 24.00 | 2 + | 40000 - 49999 | 22.05 - 32.00 | 32.00 | 2 + | 50000 - 61999 | 24.00 - 44.10 | 32.00 | 2 + | 62000 - 84999 | 32.00 - 48.00 | 44.10 | 2 + | 85000 - 192000 | 44.10 - 48.00 | 48.00 | 2 +-------------------+------------------+-----------------------+------------+------- +ELD-212 + SBR | 18000 - 20999 | 32.00 | 32.00 | 2 +(dualrate SBR) | 21000 - 25999 | 32.00 - 44.10 | 32.00 | 2 + | 26000 - 31999 | 32.00 - 48.00 | 44.10 | 2 + | 32000 - 64000 | 32.00 - 48.00 | 48.00 | 2 +-------------------+------------------+-----------------------+------------+------- +ELD-212 + SBR | 18000 - 19999 | 16.00 - 22.05 | 22.05 | 2 +(downsampled SBR) | 20000 - 24999 | 16.00 - 24.00 | 22.05 | 2 + | 25000 - 31999 | 16.00 - 24.00 | 24.00 | 2 + | 32000 - 64000 | 24.00 - 24.00 | 24.00 | 2 +-------------------+------------------+-----------------------+------------+------- +\endverbatim \n \page ENCODERBEHAVIOUR Encoder Behaviour \section BEHAVIOUR_BANDWIDTH Bandwidth -The FDK AAC encoder usually does not use the full frequency range of the input signal, but restricts the bandwidth -according to certain library-internal settings. They can be changed in the table "bandWidthTable" in the -file bandwidth.cpp (if available). - -The encoder API provides the ::AACENC_BANDWIDTH parameter to adjust the bandwidth explicitly. -\code -aacEncoder_SetParam(hAacEncoder, AACENC_BANDWIDTH, value); -\endcode - -However it is not recommended to change these settings, because they are based on numerious listening -tests and careful tweaks to ensure the best overall encoding quality. - -Theoretically a signal of for example 48 kHz can contain frequencies up to 24 kHz, but to use this full range -in an audio encoder usually does not make sense. Usually the encoder has a very limited amount of -bits to spend (typically 128 kbit/s for stereo 48 kHz content) and to allow full range bandwidth would -waste a lot of these bits for frequencies the human ear is hardly able to perceive anyway, if at all. Hence it -is wise to use the available bits for the really important frequency range and just skip the rest. -At lower bitrates (e. g. <= 80 kbit/s for stereo 48 kHz content) the encoder will choose an even smaller -bandwidth, because an encoded signal with smaller bandwidth and hence less artifacts sounds better than a signal -with higher bandwidth but then more coding artefacts across all frequencies. These artefacts would occur if -small bitrates and high bandwidths are chosen because the available bits are just not enough to encode all -frequencies well. - -Unfortunately some people evaluate encoding quality based on possible bandwidth as well, but it is a two-sided -sword considering the trade-off described above. - -Another aspect is workload consumption. The higher the allowed bandwidth, the more frequency lines have to be -processed, which in turn increases the workload. +The FDK AAC encoder usually does not use the full frequency range of the input +signal, but restricts the bandwidth according to certain library-internal +settings. They can be changed in the table "bandWidthTable" in the file +bandwidth.cpp (if available). + +The encoder API provides the ::AACENC_BANDWIDTH parameter to adjust the +bandwidth explicitly. \code aacEncoder_SetParam(hAacEncoder, AACENC_BANDWIDTH, +value); \endcode + +However it is not recommended to change these settings, because they are based +on numerous listening tests and careful tweaks to ensure the best overall +encoding quality. Also, the maximum bandwidth that can be set manually by the +user is 20kHz or fs/2, whichever value is smaller. + +Theoretically a signal of for example 48 kHz can contain frequencies up to 24 +kHz, but to use this full range in an audio encoder usually does not make sense. +Usually the encoder has a very limited amount of bits to spend (typically 128 +kbit/s for stereo 48 kHz content) and to allow full range bandwidth would waste +a lot of these bits for frequencies the human ear is hardly able to perceive +anyway, if at all. Hence it is wise to use the available bits for the really +important frequency range and just skip the rest. At lower bitrates (e. g. <= 80 +kbit/s for stereo 48 kHz content) the encoder will choose an even smaller +bandwidth, because an encoded signal with smaller bandwidth and hence less +artifacts sounds better than a signal with higher bandwidth but then more coding +artefacts across all frequencies. These artefacts would occur if small bitrates +and high bandwidths are chosen because the available bits are just not enough to +encode all frequencies well. + +Unfortunately some people evaluate encoding quality based on possible bandwidth +as well, but it is a double-edged sword considering the trade-off described +above. + +Another aspect is workload consumption. The higher the allowed bandwidth, the +more frequency lines have to be processed, which in turn increases the workload. \section FRAMESIZES_AND_BIT_RESERVOIR Frame Sizes & Bit Reservoir For AAC there is a difference between constant bit rate and constant frame -length due to the so-called bit reservoir technique, which allows the encoder to use less -bits in an AAC frame for those audio signal sections which are easy to encode, -and then spend them at a later point in -time for more complex audio sections. The extent to which this "bit exchange" -is done is limited to allow for reliable and relatively low delay real time -streaming. +length due to the so-called bit reservoir technique, which allows the encoder to +use less bits in an AAC frame for those audio signal sections which are easy to +encode, and then spend them at a later point in time for more complex audio +sections. The extent to which this "bit exchange" is done is limited to allow +for reliable and relatively low delay real time streaming. Therefore, for +AAC-ELD, the bitreservoir is limited. It varies between 500 and 4000 bits/frame, +depending on the bitrate/channel. +- For a bitrate of 12kbps/channel and below, the AAC-ELD bitreservoir is 500 +bits/frame. +- For a bitrate of 70kbps/channel and above, the AAC-ELD bitreservoir is 4000 +bits/frame. +- Between 12kbps/channel and 70kbps/channel, the AAC-ELD bitrervoir is increased +linearly. +- For AAC-LC, the bitrate is only limited by the maximum AAC frame length. It +is, regardless of the available bit reservoir, defined as 6144 bits per channel. + Over a longer period in time the bitrate will be constant in the AAC constant bitrate mode, e.g. for ISDN transmission. This means that in AAC each bitstream frame will in general have a different length in bytes but over time it -will reach the target bitrate. One could also make an MPEG compliant +will reach the target bitrate. + + +One could also make an MPEG compliant AAC encoder which always produces constant length packages for each AAC frame, but the audio quality would be considerably worse since the bit reservoir technique would have to be switched off completely. A higher bit rate would have to be used to get the same audio quality as with an enabled bit reservoir. -The maximum AAC frame length, regardless of the available bit reservoir, is defined -as 6144 bits per channel. - For mp3 by the way, the same bit reservoir technique exists, but there each bit stream frame has a constant length for a given bit rate (ignoring the padding byte). In mp3 there is a so-called "back pointer" which tells @@ -653,8 +968,8 @@ in this Fraunhofer IIS AAC encoder. AAC has been designed in that way. \subsection BEHAVIOUR_ESTIM_AVG_FRAMESIZES Estimating Average Frame Sizes A HE-AAC v1 or v2 audio frame contains 2048 PCM samples per channel (there is -also one mode with 1920 samples per channel but this is only for special purposes -such as DAB+ digital radio). +also one mode with 1920 samples per channel but this is only for special +purposes such as DAB+ digital radio). The number of HE-AAC frames \f$N\_FRAMES\f$ per second at 44.1 kHz is: @@ -662,7 +977,8 @@ The number of HE-AAC frames \f$N\_FRAMES\f$ per second at 44.1 kHz is: N\_FRAMES = 44100 / 2048 = 21.5332 \f] -At a bit rate of 8 kbps the average number of bits per frame \f$N\_BITS\_PER\_FRAME\f$ is: +At a bit rate of 8 kbps the average number of bits per frame +\f$N\_BITS\_PER\_FRAME\f$ is: \f[ N\_BITS\_PER\_FRAME = 8000 / 21.5332 = 371.52 @@ -670,7 +986,8 @@ N\_BITS\_PER\_FRAME = 8000 / 21.5332 = 371.52 which is about 46.44 bytes per encoded frame. -At a bit rate of 32 kbps, which is quite high for single channel HE-AAC v1, it is: +At a bit rate of 32 kbps, which is quite high for single channel HE-AAC v1, it +is: \f[ N\_BITS\_PER\_FRAME = 32000 / 21.5332 = 1486 @@ -678,385 +995,551 @@ N\_BITS\_PER\_FRAME = 32000 / 21.5332 = 1486 which is about 185.76 bytes per encoded frame. -These bits/frame figures are average figures where each AAC frame generally has a different -size in bytes. To calculate the same for AAC-LC just use 1024 instead of 2048 PCM samples per -frame and channel. -For AAC-LD/ELD it is either 480 or 512 PCM samples per frame and channel. +These bits/frame figures are average figures where each AAC frame generally has +a different size in bytes. To calculate the same for AAC-LC just use 1024 +instead of 2048 PCM samples per frame and channel. For AAC-LD/ELD it is either +480 or 512 PCM samples per frame and channel. \section BEHAVIOUR_TOOLS Encoder Tools -The AAC encoder supports TNS, PNS, MS, Intensity and activates these tools depending on the audio signal and -the encoder configuration (i.e. bitrate or AOT). It is not required to configure these tools manually. +The AAC encoder supports TNS, PNS, MS, Intensity and activates these tools +depending on the audio signal and the encoder configuration (i.e. bitrate or +AOT). It is not required to configure these tools manually. -PNS improves encoding quality only for certain bitrates. Therefore it makes sense to activate PNS only for -these bitrates and save the processing power required for PNS (about 10 % of the encoder) when using other -bitrates. This is done automatically inside the encoder library. PNS is disabled inside the encoder library if -an MPEG-2 AOT is choosen since PNS is an MPEG-4 AAC feature. +PNS improves encoding quality only for certain bitrates. Therefore it makes +sense to activate PNS only for these bitrates and save the processing power +required for PNS (about 10 % of the encoder) when using other bitrates. This is +done automatically inside the encoder library. PNS is disabled inside the +encoder library if an MPEG-2 AOT is choosen since PNS is an MPEG-4 AAC feature. -If SBR is activated, the encoder automatically deactivates PNS internally. If TNS is disabled but PNS is allowed, -the encoder deactivates PNS calculation internally. +If SBR is activated, the encoder automatically deactivates PNS internally. If +TNS is disabled but PNS is allowed, the encoder deactivates PNS calculation +internally. */ -#ifndef _AAC_ENC_LIB_H_ -#define _AAC_ENC_LIB_H_ +#ifndef AACENC_LIB_H +#define AACENC_LIB_H #include "machine_type.h" #include "FDK_audio.h" - /** * AAC encoder error codes. */ typedef enum { - AACENC_OK = 0x0000, /*!< No error happened. All fine. */ + AACENC_OK = 0x0000, /*!< No error happened. All fine. */ - AACENC_INVALID_HANDLE = 0x0020, /*!< Handle passed to function call was invalid. */ - AACENC_MEMORY_ERROR = 0x0021, /*!< Memory allocation failed. */ - AACENC_UNSUPPORTED_PARAMETER = 0x0022, /*!< Parameter not available. */ - AACENC_INVALID_CONFIG = 0x0023, /*!< Configuration not provided. */ + AACENC_INVALID_HANDLE = + 0x0020, /*!< Handle passed to function call was invalid. */ + AACENC_MEMORY_ERROR = 0x0021, /*!< Memory allocation failed. */ + AACENC_UNSUPPORTED_PARAMETER = 0x0022, /*!< Parameter not available. */ + AACENC_INVALID_CONFIG = 0x0023, /*!< Configuration not provided. */ - AACENC_INIT_ERROR = 0x0040, /*!< General initialization error. */ - AACENC_INIT_AAC_ERROR = 0x0041, /*!< AAC library initialization error. */ - AACENC_INIT_SBR_ERROR = 0x0042, /*!< SBR library initialization error. */ - AACENC_INIT_TP_ERROR = 0x0043, /*!< Transport library initialization error. */ - AACENC_INIT_META_ERROR = 0x0044, /*!< Meta data library initialization error. */ + AACENC_INIT_ERROR = 0x0040, /*!< General initialization error. */ + AACENC_INIT_AAC_ERROR = 0x0041, /*!< AAC library initialization error. */ + AACENC_INIT_SBR_ERROR = 0x0042, /*!< SBR library initialization error. */ + AACENC_INIT_TP_ERROR = 0x0043, /*!< Transport library initialization error. */ + AACENC_INIT_META_ERROR = + 0x0044, /*!< Meta data library initialization error. */ + AACENC_INIT_MPS_ERROR = 0x0045, /*!< MPS library initialization error. */ - AACENC_ENCODE_ERROR = 0x0060, /*!< The encoding process was interrupted by an unexpected error. */ + AACENC_ENCODE_ERROR = 0x0060, /*!< The encoding process was interrupted by an + unexpected error. */ - AACENC_ENCODE_EOF = 0x0080 /*!< End of file reached. */ + AACENC_ENCODE_EOF = 0x0080 /*!< End of file reached. */ } AACENC_ERROR; - /** * AAC encoder buffer descriptors identifier. - * This identifier are used within buffer descriptors AACENC_BufDesc::bufferIdentifiers. + * This identifier are used within buffer descriptors + * AACENC_BufDesc::bufferIdentifiers. */ typedef enum { - /* Input buffer identifier. */ - IN_AUDIO_DATA = 0, /*!< Audio input buffer, interleaved INT_PCM samples. */ - IN_ANCILLRY_DATA = 1, /*!< Ancillary data to be embedded into bitstream. */ - IN_METADATA_SETUP = 2, /*!< Setup structure for embedding meta data. */ + /* Input buffer identifier. */ + IN_AUDIO_DATA = 0, /*!< Audio input buffer, interleaved INT_PCM samples. */ + IN_ANCILLRY_DATA = 1, /*!< Ancillary data to be embedded into bitstream. */ + IN_METADATA_SETUP = 2, /*!< Setup structure for embedding meta data. */ - /* Output buffer identifier. */ - OUT_BITSTREAM_DATA = 3, /*!< Buffer holds bitstream output data. */ - OUT_AU_SIZES = 4 /*!< Buffer contains sizes of each access unit. This information - is necessary for superframing. */ + /* Output buffer identifier. */ + OUT_BITSTREAM_DATA = 3, /*!< Buffer holds bitstream output data. */ + OUT_AU_SIZES = + 4 /*!< Buffer contains sizes of each access unit. This information + is necessary for superframing. */ } AACENC_BufferIdentifier; - /** * AAC encoder handle. */ typedef struct AACENCODER *HANDLE_AACENCODER; - /** * Provides some info about the encoder configuration. */ typedef struct { + UINT maxOutBufBytes; /*!< Maximum number of encoder bitstream bytes within one + frame. Size depends on maximum number of supported + channels in encoder instance. For superframing (as + used for example in DAB+), size has to be a multiple + accordingly. */ - UINT maxOutBufBytes; /*!< Maximum number of encoder bitstream bytes within one frame. - Size depends on maximum number of supported channels in encoder instance. - For superframing (as used for example in DAB+), size has to be a multiple accordingly. */ + UINT maxAncBytes; /*!< Maximum number of ancillary data bytes which can be + inserted into bitstream within one frame. */ - UINT maxAncBytes; /*!< Maximum number of ancillary data bytes which can be inserted into - bitstream within one frame. */ + UINT inBufFillLevel; /*!< Internal input buffer fill level in samples per + channel. This parameter will automatically be cleared + if samplingrate or channel(Mode/Order) changes. */ - UINT inBufFillLevel; /*!< Internal input buffer fill level in samples per channel. This parameter - will automatically be cleared if samplingrate or channel(Mode/Order) changes. */ + UINT inputChannels; /*!< Number of input channels expected in encoding + process. */ - UINT inputChannels; /*!< Number of input channels expected in encoding process. */ + UINT frameLength; /*!< Amount of input audio samples consumed each frame per + channel, depending on audio object type configuration. */ - UINT frameLength; /*!< Amount of input audio samples consumed each frame per channel, depending - on audio object type configuration. */ + UINT nDelay; /*!< Codec delay in PCM samples/channel. Depends on framelength + and AOT. Does not include framing delay for filling up encoder + PCM input buffer. */ - UINT encoderDelay; /*!< Codec delay in PCM samples/channel. Depends on framelength and AOT. Does not - include framing delay for filling up encoder PCM input buffer. */ + UINT nDelayCore; /*!< Codec delay in PCM samples/channel, w/o delay caused by + the decoder SBR module. This delay is needed to correctly + write edit lists for gapless playback. The decoder may not + know how much delay is introdcued by SBR, since it may not + know if SBR is active at all (implicit signaling), + therefore the deocder must take into account any delay + caused by the SBR module. */ - UCHAR confBuf[64]; /*!< Configuration buffer in binary format as an AudioSpecificConfig - or StreamMuxConfig according to the selected transport type. */ + UCHAR confBuf[64]; /*!< Configuration buffer in binary format as an + AudioSpecificConfig or StreamMuxConfig according to the + selected transport type. */ - UINT confSize; /*!< Number of valid bytes in confBuf. */ + UINT confSize; /*!< Number of valid bytes in confBuf. */ } AACENC_InfoStruct; - /** * Describes the input and output buffers for an aacEncEncode() call. */ typedef struct { - INT numBufs; /*!< Number of buffers. */ - void **bufs; /*!< Pointer to vector containing buffer addresses. */ - INT *bufferIdentifiers; /*!< Identifier of each buffer element. See ::AACENC_BufferIdentifier. */ - INT *bufSizes; /*!< Size of each buffer in 8-bit bytes. */ - INT *bufElSizes; /*!< Size of each buffer element in bytes. */ + INT numBufs; /*!< Number of buffers. */ + void **bufs; /*!< Pointer to vector containing buffer addresses. */ + INT *bufferIdentifiers; /*!< Identifier of each buffer element. See + ::AACENC_BufferIdentifier. */ + INT *bufSizes; /*!< Size of each buffer in 8-bit bytes. */ + INT *bufElSizes; /*!< Size of each buffer element in bytes. */ } AACENC_BufDesc; - /** * Defines the input arguments for an aacEncEncode() call. */ typedef struct { - INT numInSamples; /*!< Number of valid input audio samples (multiple of input channels). */ - INT numAncBytes; /*!< Number of ancillary data bytes to be encoded. */ + INT numInSamples; /*!< Number of valid input audio samples (multiple of input + channels). */ + INT numAncBytes; /*!< Number of ancillary data bytes to be encoded. */ } AACENC_InArgs; - /** * Defines the output arguments for an aacEncEncode() call. */ typedef struct { - INT numOutBytes; /*!< Number of valid bitstream bytes generated during aacEncEncode(). */ - INT numInSamples; /*!< Number of input audio samples consumed by the encoder. */ - INT numAncBytes; /*!< Number of ancillary data bytes consumed by the encoder. */ + INT numOutBytes; /*!< Number of valid bitstream bytes generated during + aacEncEncode(). */ + INT numInSamples; /*!< Number of input audio samples consumed by the encoder. + */ + INT numAncBytes; /*!< Number of ancillary data bytes consumed by the encoder. + */ + INT bitResState; /*!< State of the bit reservoir in bits. */ } AACENC_OutArgs; - /** * Meta Data Compression Profiles. */ typedef enum { - AACENC_METADATA_DRC_NONE = 0, /*!< None. */ - AACENC_METADATA_DRC_FILMSTANDARD = 1, /*!< Film standard. */ - AACENC_METADATA_DRC_FILMLIGHT = 2, /*!< Film light. */ - AACENC_METADATA_DRC_MUSICSTANDARD = 3, /*!< Music standard. */ - AACENC_METADATA_DRC_MUSICLIGHT = 4, /*!< Music light. */ - AACENC_METADATA_DRC_SPEECH = 5 /*!< Speech. */ + AACENC_METADATA_DRC_NONE = 0, /*!< None. */ + AACENC_METADATA_DRC_FILMSTANDARD = 1, /*!< Film standard. */ + AACENC_METADATA_DRC_FILMLIGHT = 2, /*!< Film light. */ + AACENC_METADATA_DRC_MUSICSTANDARD = 3, /*!< Music standard. */ + AACENC_METADATA_DRC_MUSICLIGHT = 4, /*!< Music light. */ + AACENC_METADATA_DRC_SPEECH = 5, /*!< Speech. */ + AACENC_METADATA_DRC_NOT_PRESENT = + 256 /*!< Disable writing gain factor (used for comp_profile only). */ } AACENC_METADATA_DRC_PROFILE; - /** * Meta Data setup structure. */ typedef struct { + AACENC_METADATA_DRC_PROFILE + drc_profile; /*!< MPEG DRC compression profile. See + ::AACENC_METADATA_DRC_PROFILE. */ + AACENC_METADATA_DRC_PROFILE + comp_profile; /*!< ETSI heavy compression profile. See + ::AACENC_METADATA_DRC_PROFILE. */ + + INT drc_TargetRefLevel; /*!< Used to define expected level to: + Scaled with 16 bit. x*2^16. */ + INT comp_TargetRefLevel; /*!< Adjust limiter to avoid overload. + Scaled with 16 bit. x*2^16. */ + + INT prog_ref_level_present; /*!< Flag, if prog_ref_level is present */ + INT prog_ref_level; /*!< Programme Reference Level = Dialogue Level: + -31.75dB .. 0 dB ; stepsize: 0.25dB + Scaled with 16 bit. x*2^16.*/ + + UCHAR PCE_mixdown_idx_present; /*!< Flag, if dmx-idx should be written in + programme config element */ + UCHAR ETSI_DmxLvl_present; /*!< Flag, if dmx-lvl should be written in + ETSI-ancData */ + + SCHAR centerMixLevel; /*!< Center downmix level (0...7, according to table) */ + SCHAR surroundMixLevel; /*!< Surround downmix level (0...7, according to + table) */ + + UCHAR + dolbySurroundMode; /*!< Indication for Dolby Surround Encoding Mode. + - 0: Dolby Surround mode not indicated + - 1: 2-ch audio part is not Dolby surround encoded + - 2: 2-ch audio part is Dolby surround encoded */ + + UCHAR drcPresentationMode; /*!< Indicatin for DRC Presentation Mode. + - 0: Presentation mode not inticated + - 1: Presentation mode 1 + - 2: Presentation mode 2 */ + + struct { + /* extended ancillary data */ + UCHAR extAncDataEnable; /*< Indicates if MPEG4_ext_ancillary_data() exists. + - 0: No MPEG4_ext_ancillary_data(). + - 1: Insert MPEG4_ext_ancillary_data(). */ + + UCHAR + extDownmixLevelEnable; /*< Indicates if ext_downmixing_levels() exists. + - 0: No ext_downmixing_levels(). + - 1: Insert ext_downmixing_levels(). */ + UCHAR extDownmixLevel_A; /*< Downmix level index A (0...7, according to + table) */ + UCHAR extDownmixLevel_B; /*< Downmix level index B (0...7, according to + table) */ + + UCHAR dmxGainEnable; /*< Indicates if ext_downmixing_global_gains() exists. + - 0: No ext_downmixing_global_gains(). + - 1: Insert ext_downmixing_global_gains(). */ + INT dmxGain5; /*< Gain factor for downmix to 5 channels. + -15.75dB .. -15.75dB; stepsize: 0.25dB + Scaled with 16 bit. x*2^16.*/ + INT dmxGain2; /*< Gain factor for downmix to 2 channels. + -15.75dB .. -15.75dB; stepsize: 0.25dB + Scaled with 16 bit. x*2^16.*/ + + UCHAR lfeDmxEnable; /*< Indicates if ext_downmixing_lfe_level() exists. + - 0: No ext_downmixing_lfe_level(). + - 1: Insert ext_downmixing_lfe_level(). */ + UCHAR lfeDmxLevel; /*< Downmix level index for LFE (0..15, according to + table) */ + + } ExtMetaData; - AACENC_METADATA_DRC_PROFILE drc_profile; /*!< MPEG DRC compression profile. See ::AACENC_METADATA_DRC_PROFILE. */ - AACENC_METADATA_DRC_PROFILE comp_profile; /*!< ETSI heavy compression profile. See ::AACENC_METADATA_DRC_PROFILE. */ - - INT drc_TargetRefLevel; /*!< Used to define expected level to: - Scaled with 16 bit. x*2^16. */ - INT comp_TargetRefLevel; /*!< Adjust limiter to avoid overload. - Scaled with 16 bit. x*2^16. */ - - INT prog_ref_level_present; /*!< Flag, if prog_ref_level is present */ - INT prog_ref_level; /*!< Programme Reference Level = Dialogue Level: - -31.75dB .. 0 dB ; stepsize: 0.25dB - Scaled with 16 bit. x*2^16.*/ - - UCHAR PCE_mixdown_idx_present; /*!< Flag, if dmx-idx should be written in programme config element */ - UCHAR ETSI_DmxLvl_present; /*!< Flag, if dmx-lvl should be written in ETSI-ancData */ - - SCHAR centerMixLevel; /*!< Center downmix level (0...7, according to table) */ - SCHAR surroundMixLevel; /*!< Surround downmix level (0...7, according to table) */ - - UCHAR dolbySurroundMode; /*!< Indication for Dolby Surround Encoding Mode. - - 0: Dolby Surround mode not indicated - - 1: 2-ch audio part is not Dolby surround encoded - - 2: 2-ch audio part is Dolby surround encoded */ } AACENC_MetaData; - /** * AAC encoder control flags. * - * In interaction with the ::AACENC_CONTROL_STATE parameter it is possible to get information about the internal - * initialization process. It is also possible to overwrite the internal state from extern when necessary. + * In interaction with the ::AACENC_CONTROL_STATE parameter it is possible to + * get information about the internal initialization process. It is also + * possible to overwrite the internal state from extern when necessary. */ -typedef enum -{ - AACENC_INIT_NONE = 0x0000, /*!< Do not trigger initialization. */ - AACENC_INIT_CONFIG = 0x0001, /*!< Initialize all encoder modules configuration. */ - AACENC_INIT_STATES = 0x0002, /*!< Reset all encoder modules history buffer. */ - AACENC_INIT_TRANSPORT = 0x1000, /*!< Initialize transport lib with new parameters. */ - AACENC_RESET_INBUFFER = 0x2000, /*!< Reset fill level of internal input buffer. */ - AACENC_INIT_ALL = 0xFFFF /*!< Initialize all. */ -} -AACENC_CTRLFLAGS; - +typedef enum { + AACENC_INIT_NONE = 0x0000, /*!< Do not trigger initialization. */ + AACENC_INIT_CONFIG = + 0x0001, /*!< Initialize all encoder modules configuration. */ + AACENC_INIT_STATES = 0x0002, /*!< Reset all encoder modules history buffer. */ + AACENC_INIT_TRANSPORT = + 0x1000, /*!< Initialize transport lib with new parameters. */ + AACENC_RESET_INBUFFER = + 0x2000, /*!< Reset fill level of internal input buffer. */ + AACENC_INIT_ALL = 0xFFFF /*!< Initialize all. */ +} AACENC_CTRLFLAGS; /** * \brief AAC encoder setting parameters. * - * Use aacEncoder_SetParam() function to configure, or use aacEncoder_GetParam() function to read - * the internal status of the following parameters. + * Use aacEncoder_SetParam() function to configure, or use aacEncoder_GetParam() + * function to read the internal status of the following parameters. */ -typedef enum -{ - AACENC_AOT = 0x0100, /*!< Audio object type. See ::AUDIO_OBJECT_TYPE in FDK_audio.h. - - 2: MPEG-4 AAC Low Complexity. - - 5: MPEG-4 AAC Low Complexity with Spectral Band Replication (HE-AAC). - - 29: MPEG-4 AAC Low Complexity with Spectral Band Replication and Parametric Stereo (HE-AAC v2). - This configuration can be used only with stereo input audio data. - - 23: MPEG-4 AAC Low-Delay. - - 39: MPEG-4 AAC Enhanced Low-Delay. Since there is no ::AUDIO_OBJECT_TYPE for ELD in - combination with SBR defined, enable SBR explicitely by ::AACENC_SBR_MODE parameter. */ - - AACENC_BITRATE = 0x0101, /*!< Total encoder bitrate. This parameter is mandatory and interacts with ::AACENC_BITRATEMODE. - - CBR: Bitrate in bits/second. - See \ref suppBitrates for details. */ - - AACENC_BITRATEMODE = 0x0102, /*!< Bitrate mode. Configuration can be different kind of bitrate configurations: - - 0: Constant bitrate, use bitrate according to ::AACENC_BITRATE. (default) - Within none LD/ELD ::AUDIO_OBJECT_TYPE, the CBR mode makes use of full allowed bitreservoir. - In contrast, at Low-Delay ::AUDIO_OBJECT_TYPE the bitreservoir is kept very small. - - 8: LD/ELD full bitreservoir for packet based transmission. */ - - AACENC_SAMPLERATE = 0x0103, /*!< Audio input data sampling rate. Encoder supports following sampling rates: - 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000 */ - - AACENC_SBR_MODE = 0x0104, /*!< Configure SBR independently of the chosen Audio Object Type ::AUDIO_OBJECT_TYPE. - This parameter is for ELD audio object type only. - - -1: Use ELD SBR auto configurator (default). - - 0: Disable Spectral Band Replication. - - 1: Enable Spectral Band Replication. */ - - AACENC_GRANULE_LENGTH = 0x0105, /*!< Core encoder (AAC) audio frame length in samples: - - 1024: Default configuration. - - 512: Default LD/ELD configuration. - - 480: Optional length in LD/ELD configuration. */ - - AACENC_CHANNELMODE = 0x0106, /*!< Set explicit channel mode. Channel mode must match with number of input channels. - - 1-7 and 33,34: MPEG channel modes supported, see ::CHANNEL_MODE in FDK_audio.h. */ - - AACENC_CHANNELORDER = 0x0107, /*!< Input audio data channel ordering scheme: - - 0: MPEG channel ordering (e. g. 5.1: C, L, R, SL, SR, LFE). (default) - - 1: WAVE file format channel ordering (e. g. 5.1: L, R, C, LFE, SL, SR). */ - - AACENC_SBR_RATIO = 0x0108, /*!< Controls activation of downsampled SBR. With downsampled SBR, the delay will be - shorter. On the other hand, for achieving the same quality level, downsampled SBR - needs more bits than dual-rate SBR. - With downsampled SBR, the AAC encoder will work at the same sampling rate as the - SBR encoder (single rate). - Downsampled SBR is supported for AAC-ELD and HE-AACv1. - - 1: Downsampled SBR (default for ELD). - - 2: Dual-rate SBR (default for HE-AAC). */ - - AACENC_AFTERBURNER = 0x0200, /*!< This parameter controls the use of the afterburner feature. - The afterburner is a type of analysis by synthesis algorithm which increases the - audio quality but also the required processing power. It is recommended to always - activate this if additional memory consumption and processing power consumption - is not a problem. If increased MHz and memory consumption are an issue then the MHz - and memory cost of this optional module need to be evaluated against the improvement - in audio quality on a case by case basis. - - 0: Disable afterburner (default). - - 1: Enable afterburner. */ - - AACENC_BANDWIDTH = 0x0203, /*!< Core encoder audio bandwidth: - - 0: Determine bandwidth internally (default, see chapter \ref BEHAVIOUR_BANDWIDTH). - - 1 to fs/2: Frequency bandwidth in Hertz. (Experts only, better do not - touch this value to avoid degraded audio quality) */ - - AACENC_PEAK_BITRATE = 0x0207, /*!< Peak bitrate configuration parameter to adjust maximum bits per audio frame. Bitrate is in bits/second. - The peak bitrate will internally be limited to the chosen bitrate ::AACENC_BITRATE as lower limit - and the number_of_effective_channels*6144 bit as upper limit. - - Setting the peak bitrate equal to ::AACENC_BITRATE does not necessarily mean that the audio frames - will be of constant size. Since the peak bitate is in bits/second, the frame sizes can vary by - one byte in one or the other direction over various frames. However, it is not recommended to reduce - the peak pitrate to ::AACENC_BITRATE - it would disable the bitreservoir, which would affect the - audio quality by a large amount. */ - - AACENC_TRANSMUX = 0x0300, /*!< Transport type to be used. See ::TRANSPORT_TYPE in FDK_audio.h. Following - types can be configured in encoder library: - - 0: raw access units - - 1: ADIF bitstream format - - 2: ADTS bitstream format - - 6: Audio Mux Elements (LATM) with muxConfigPresent = 1 - - 7: Audio Mux Elements (LATM) with muxConfigPresent = 0, out of band StreamMuxConfig - - 10: Audio Sync Stream (LOAS) */ - - AACENC_HEADER_PERIOD = 0x0301, /*!< Frame count period for sending in-band configuration buffers within LATM/LOAS - transport layer. Additionally this parameter configures the PCE repetition period - in raw_data_block(). See \ref encPCE. - - 0xFF: auto-mode default 10 for TT_MP4_ADTS, TT_MP4_LOAS and TT_MP4_LATM_MCP1, otherwise 0. - - n: Frame count period. */ - - AACENC_SIGNALING_MODE = 0x0302, /*!< Signaling mode of the extension AOT: - - 0: Implicit backward compatible signaling (default for non-MPEG-4 based - AOT's and for the transport formats ADIF and ADTS) - - A stream that uses implicit signaling can be decoded by every AAC decoder, even AAC-LC-only decoders - - An AAC-LC-only decoder will only decode the low-frequency part of the stream, resulting in a band-limited output - - This method works with all transport formats - - This method does not work with downsampled SBR - - 1: Explicit backward compatible signaling - - A stream that uses explicit backward compatible signaling can be decoded by every AAC decoder, even AAC-LC-only decoders - - An AAC-LC-only decoder will only decode the low-frequency part of the stream, resulting in a band-limited output - - A decoder not capable of decoding PS will only decode the AAC-LC+SBR part. - If the stream contained PS, the result will be a a decoded mono downmix - - This method does not work with ADIF or ADTS. For LOAS/LATM, it only works with AudioMuxVersion==1 - - This method does work with downsampled SBR - - 2: Explicit hierarchical signaling (default for MPEG-4 based AOT's and for all transport formats excluding ADIF and ADTS) - - A stream that uses explicit hierarchical signaling can be decoded only by HE-AAC decoders - - An AAC-LC-only decoder will not decode a stream that uses explicit hierarchical signaling - - A decoder not capable of decoding PS will not decode the stream at all if it contained PS - - This method does not work with ADIF or ADTS. It works with LOAS/LATM and the MPEG-4 File format - - This method does work with downsampled SBR - - For making sure that the listener always experiences the best audio quality, - explicit hierarchical signaling should be used. - This makes sure that only a full HE-AAC-capable decoder will decode those streams. - The audio is played at full bandwidth. - For best backwards compatibility, it is recommended to encode with implicit SBR signaling. - A decoder capable of AAC-LC only will then only decode the AAC part, which means the decoded - audio will sound band-limited. - - For MPEG-2 transport types (ADTS,ADIF), only implicit signaling is possible. - - For LOAS and LATM, explicit backwards compatible signaling only works together with AudioMuxVersion==1. - The reason is that, for explicit backwards compatible signaling, additional information will be appended to the ASC. - A decoder that is only capable of decoding AAC-LC will skip this part. - Nevertheless, for jumping to the end of the ASC, it needs to know the ASC length. - Transmitting the length of the ASC is a feature of AudioMuxVersion==1, it is not possible to transmit the - length of the ASC with AudioMuxVersion==0, therefore an AAC-LC-only decoder will not be able to parse a - LOAS/LATM stream that was being encoded with AudioMuxVersion==0. - - For downsampled SBR, explicit signaling is mandatory. The reason for this is that the - extension sampling frequency (which is in case of SBR the sampling frequqncy of the SBR part) - can only be signaled in explicit mode. - - For AAC-ELD, the SBR information is transmitted in the ELDSpecific Config, which is part of the - AudioSpecificConfig. Therefore, the settings here will have no effect on AAC-ELD.*/ - - AACENC_TPSUBFRAMES = 0x0303, /*!< Number of sub frames in a transport frame for LOAS/LATM or ADTS (default 1). - - ADTS: Maximum number of sub frames restricted to 4. - - LOAS/LATM: Maximum number of sub frames restricted to 2.*/ - - AACENC_AUDIOMUXVER = 0x0304, /*!< AudioMuxVersion to be used for LATM. (AudioMuxVersionA, currently not implemented): - - 0: Default, no transmission of tara Buffer fullness, no ASC length and including actual latm Buffer fullnes. - - 1: Transmission of tara Buffer fullness, ASC length and actual latm Buffer fullness. - - 2: Transmission of tara Buffer fullness, ASC length and maximum level of latm Buffer fullness. */ - - AACENC_PROTECTION = 0x0306, /*!< Configure protection in tranpsort layer: - - 0: No protection. (default) - - 1: CRC active for ADTS bitstream format. */ - - AACENC_ANCILLARY_BITRATE = 0x0500, /*!< Constant ancillary data bitrate in bits/second. - - 0: Either no ancillary data or insert exact number of bytes, denoted via - input parameter, numAncBytes in AACENC_InArgs. - - else: Insert ancillary data with specified bitrate. */ - - AACENC_METADATA_MODE = 0x0600, /*!< Configure Meta Data. See ::AACENC_MetaData for further details: - - 0: Do not embed any metadata. - - 1: Embed MPEG defined metadata only. - - 2: Embed all metadata. */ - - AACENC_CONTROL_STATE = 0xFF00, /*!< There is an automatic process which internally reconfigures the encoder instance - when a configuration parameter changed or an error occured. This paramerter allows - overwriting or getting the control status of this process. See ::AACENC_CTRLFLAGS. */ - - AACENC_NONE = 0xFFFF /*!< ------ */ +typedef enum { + AACENC_AOT = + 0x0100, /*!< Audio object type. See ::AUDIO_OBJECT_TYPE in FDK_audio.h. + - 2: MPEG-4 AAC Low Complexity. + - 5: MPEG-4 AAC Low Complexity with Spectral Band Replication + (HE-AAC). + - 29: MPEG-4 AAC Low Complexity with Spectral Band + Replication and Parametric Stereo (HE-AAC v2). This + configuration can be used only with stereo input audio data. + - 23: MPEG-4 AAC Low-Delay. + - 39: MPEG-4 AAC Enhanced Low-Delay. Since there is no + ::AUDIO_OBJECT_TYPE for ELD in combination with SBR defined, + enable SBR explicitely by ::AACENC_SBR_MODE parameter. The ELD + v2 212 configuration can be configured by ::AACENC_CHANNELMODE + parameter. + - 129: MPEG-2 AAC Low Complexity. + - 132: MPEG-2 AAC Low Complexity with Spectral Band + Replication (HE-AAC). + + Please note that the virtual MPEG-2 AOT's basically disables + non-existing Perceptual Noise Substitution tool in AAC encoder + and controls the MPEG_ID flag in adts header. The virtual + MPEG-2 AOT doesn't prohibit specific transport formats. */ + + AACENC_BITRATE = 0x0101, /*!< Total encoder bitrate. This parameter is + mandatory and interacts with ::AACENC_BITRATEMODE. + - CBR: Bitrate in bits/second. + - VBR: Variable bitrate. Bitrate argument will + be ignored. See \ref suppBitrates for details. */ + + AACENC_BITRATEMODE = 0x0102, /*!< Bitrate mode. Configuration can be different + kind of bitrate configurations: + - 0: Constant bitrate, use bitrate according + to ::AACENC_BITRATE. (default) Within none + LD/ELD ::AUDIO_OBJECT_TYPE, the CBR mode makes + use of full allowed bitreservoir. In contrast, + at Low-Delay ::AUDIO_OBJECT_TYPE the + bitreservoir is kept very small. + - 1: Variable bitrate mode, \ref vbrmode + "very low bitrate". + - 2: Variable bitrate mode, \ref vbrmode + "low bitrate". + - 3: Variable bitrate mode, \ref vbrmode + "medium bitrate". + - 4: Variable bitrate mode, \ref vbrmode + "high bitrate". + - 5: Variable bitrate mode, \ref vbrmode + "very high bitrate". */ + + AACENC_SAMPLERATE = 0x0103, /*!< Audio input data sampling rate. Encoder + supports following sampling rates: 8000, 11025, + 12000, 16000, 22050, 24000, 32000, 44100, + 48000, 64000, 88200, 96000 */ + + AACENC_SBR_MODE = 0x0104, /*!< Configure SBR independently of the chosen Audio + Object Type ::AUDIO_OBJECT_TYPE. This parameter + is for ELD audio object type only. + - -1: Use ELD SBR auto configurator (default). + - 0: Disable Spectral Band Replication. + - 1: Enable Spectral Band Replication. */ + + AACENC_GRANULE_LENGTH = + 0x0105, /*!< Core encoder (AAC) audio frame length in samples: + - 1024: Default configuration. + - 512: Default length in LD/ELD configuration. + - 480: Length in LD/ELD configuration. + - 256: Length for ELD reduced delay mode (x2). + - 240: Length for ELD reduced delay mode (x2). + - 128: Length for ELD reduced delay mode (x4). + - 120: Length for ELD reduced delay mode (x4). */ + + AACENC_CHANNELMODE = 0x0106, /*!< Set explicit channel mode. Channel mode must + match with number of input channels. + - 1-7, 11,12,14 and 33,34: MPEG channel + modes supported, see ::CHANNEL_MODE in + FDK_audio.h. */ + + AACENC_CHANNELORDER = + 0x0107, /*!< Input audio data channel ordering scheme: + - 0: MPEG channel ordering (e. g. 5.1: C, L, R, SL, SR, LFE). + (default) + - 1: WAVE file format channel ordering (e. g. 5.1: L, R, C, + LFE, SL, SR). */ + + AACENC_SBR_RATIO = + 0x0108, /*!< Controls activation of downsampled SBR. With downsampled + SBR, the delay will be shorter. On the other hand, for + achieving the same quality level, downsampled SBR needs more + bits than dual-rate SBR. With downsampled SBR, the AAC encoder + will work at the same sampling rate as the SBR encoder (single + rate). Downsampled SBR is supported for AAC-ELD and HE-AACv1. + - 1: Downsampled SBR (default for ELD). + - 2: Dual-rate SBR (default for HE-AAC). */ + + AACENC_AFTERBURNER = + 0x0200, /*!< This parameter controls the use of the afterburner feature. + The afterburner is a type of analysis by synthesis algorithm + which increases the audio quality but also the required + processing power. It is recommended to always activate this if + additional memory consumption and processing power consumption + is not a problem. If increased MHz and memory consumption are + an issue then the MHz and memory cost of this optional module + need to be evaluated against the improvement in audio quality + on a case by case basis. + - 0: Disable afterburner (default). + - 1: Enable afterburner. */ + + AACENC_BANDWIDTH = 0x0203, /*!< Core encoder audio bandwidth: + - 0: Determine audio bandwidth internally + (default, see chapter \ref BEHAVIOUR_BANDWIDTH). + - 1 to fs/2: Audio bandwidth in Hertz. Limited + to 20kHz max. Not usable if SBR is active. This + setting is for experts only, better do not touch + this value to avoid degraded audio quality. */ + + AACENC_PEAK_BITRATE = + 0x0207, /*!< Peak bitrate configuration parameter to adjust maximum bits + per audio frame. Bitrate is in bits/second. The peak bitrate + will internally be limited to the chosen bitrate + ::AACENC_BITRATE as lower limit and the + number_of_effective_channels*6144 bit as upper limit. + + Setting the peak bitrate equal to ::AACENC_BITRATE does not + necessarily mean that the audio frames will be of constant + size. Since the peak bitate is in bits/second, the frame sizes + can vary by one byte in one or the other direction over various + frames. However, it is not recommended to reduce the peak + pitrate to ::AACENC_BITRATE - it would disable the + bitreservoir, which would affect the audio quality by a large + amount. */ + + AACENC_TRANSMUX = 0x0300, /*!< Transport type to be used. See ::TRANSPORT_TYPE + in FDK_audio.h. Following types can be configured + in encoder library: + - 0: raw access units + - 1: ADIF bitstream format + - 2: ADTS bitstream format + - 6: Audio Mux Elements (LATM) with + muxConfigPresent = 1 + - 7: Audio Mux Elements (LATM) with + muxConfigPresent = 0, out of band StreamMuxConfig + - 10: Audio Sync Stream (LOAS) */ + + AACENC_HEADER_PERIOD = + 0x0301, /*!< Frame count period for sending in-band configuration buffers + within LATM/LOAS transport layer. Additionally this parameter + configures the PCE repetition period in raw_data_block(). See + \ref encPCE. + - 0xFF: auto-mode default 10 for TT_MP4_ADTS, TT_MP4_LOAS and + TT_MP4_LATM_MCP1, otherwise 0. + - n: Frame count period. */ + + AACENC_SIGNALING_MODE = + 0x0302, /*!< Signaling mode of the extension AOT: + - 0: Implicit backward compatible signaling (default for + non-MPEG-4 based AOT's and for the transport formats ADIF and + ADTS) + - A stream that uses implicit signaling can be decoded + by every AAC decoder, even AAC-LC-only decoders + - An AAC-LC-only decoder will only decode the + low-frequency part of the stream, resulting in a band-limited + output + - This method works with all transport formats + - This method does not work with downsampled SBR + - 1: Explicit backward compatible signaling + - A stream that uses explicit backward compatible + signaling can be decoded by every AAC decoder, even AAC-LC-only + decoders + - An AAC-LC-only decoder will only decode the + low-frequency part of the stream, resulting in a band-limited + output + - A decoder not capable of decoding PS will only decode + the AAC-LC+SBR part. If the stream contained PS, the result + will be a a decoded mono downmix + - This method does not work with ADIF or ADTS. For + LOAS/LATM, it only works with AudioMuxVersion==1 + - This method does work with downsampled SBR + - 2: Explicit hierarchical signaling (default for MPEG-4 + based AOT's and for all transport formats excluding ADIF and + ADTS) + - A stream that uses explicit hierarchical signaling can + be decoded only by HE-AAC decoders + - An AAC-LC-only decoder will not decode a stream that + uses explicit hierarchical signaling + - A decoder not capable of decoding PS will not decode + the stream at all if it contained PS + - This method does not work with ADIF or ADTS. It works + with LOAS/LATM and the MPEG-4 File format + - This method does work with downsampled SBR + + For making sure that the listener always experiences the + best audio quality, explicit hierarchical signaling should be + used. This makes sure that only a full HE-AAC-capable decoder + will decode those streams. The audio is played at full + bandwidth. For best backwards compatibility, it is recommended + to encode with implicit SBR signaling. A decoder capable of + AAC-LC only will then only decode the AAC part, which means the + decoded audio will sound band-limited. + + For MPEG-2 transport types (ADTS,ADIF), only implicit + signaling is possible. + + For LOAS and LATM, explicit backwards compatible signaling + only works together with AudioMuxVersion==1. The reason is + that, for explicit backwards compatible signaling, additional + information will be appended to the ASC. A decoder that is only + capable of decoding AAC-LC will skip this part. Nevertheless, + for jumping to the end of the ASC, it needs to know the ASC + length. Transmitting the length of the ASC is a feature of + AudioMuxVersion==1, it is not possible to transmit the length + of the ASC with AudioMuxVersion==0, therefore an AAC-LC-only + decoder will not be able to parse a LOAS/LATM stream that was + being encoded with AudioMuxVersion==0. + + For downsampled SBR, explicit signaling is mandatory. The + reason for this is that the extension sampling frequency (which + is in case of SBR the sampling frequqncy of the SBR part) can + only be signaled in explicit mode. + + For AAC-ELD, the SBR information is transmitted in the + ELDSpecific Config, which is part of the AudioSpecificConfig. + Therefore, the settings here will have no effect on AAC-ELD.*/ + + AACENC_TPSUBFRAMES = + 0x0303, /*!< Number of sub frames in a transport frame for LOAS/LATM or + ADTS (default 1). + - ADTS: Maximum number of sub frames restricted to 4. + - LOAS/LATM: Maximum number of sub frames restricted to 2.*/ + + AACENC_AUDIOMUXVER = + 0x0304, /*!< AudioMuxVersion to be used for LATM. (AudioMuxVersionA, + currently not implemented): + - 0: Default, no transmission of tara Buffer fullness, no ASC + length and including actual latm Buffer fullnes. + - 1: Transmission of tara Buffer fullness, ASC length and + actual latm Buffer fullness. + - 2: Transmission of tara Buffer fullness, ASC length and + maximum level of latm Buffer fullness. */ + + AACENC_PROTECTION = 0x0306, /*!< Configure protection in transport layer: + - 0: No protection. (default) + - 1: CRC active for ADTS transport format. */ + + AACENC_ANCILLARY_BITRATE = + 0x0500, /*!< Constant ancillary data bitrate in bits/second. + - 0: Either no ancillary data or insert exact number of + bytes, denoted via input parameter, numAncBytes in + AACENC_InArgs. + - else: Insert ancillary data with specified bitrate. */ + + AACENC_METADATA_MODE = 0x0600, /*!< Configure Meta Data. See ::AACENC_MetaData + for further details: + - 0: Do not embed any metadata. + - 1: Embed dynamic_range_info metadata. + - 2: Embed dynamic_range_info and + ancillary_data metadata. + - 3: Embed ancillary_data metadata. */ + + AACENC_CONTROL_STATE = + 0xFF00, /*!< There is an automatic process which internally reconfigures + the encoder instance when a configuration parameter changed or + an error occured. This paramerter allows overwriting or getting + the control status of this process. See ::AACENC_CTRLFLAGS. */ + + AACENC_NONE = 0xFFFF /*!< ------ */ } AACENC_PARAM; - #ifdef __cplusplus extern "C" { #endif @@ -1064,33 +1547,40 @@ extern "C" { /** * \brief Open an instance of the encoder. * - * Allocate memory for an encoder instance with a functional range denoted by the function parameters. - * Preinitialize encoder instance with default configuration. + * Allocate memory for an encoder instance with a functional range denoted by + * the function parameters. Preinitialize encoder instance with default + * configuration. * * \param phAacEncoder A pointer to an encoder handle. Initialized on return. - * \param encModules Specify encoder modules to be supported in this encoder instance: - * - 0x0: Allocate memory for all available encoder modules. - * - else: Select memory allocation regarding encoder modules. Following flags are possible and can be combined. + * \param encModules Specify encoder modules to be supported in this encoder + * instance: + * - 0x0: Allocate memory for all available encoder + * modules. + * - else: Select memory allocation regarding encoder + * modules. Following flags are possible and can be combined. * - 0x01: AAC module. * - 0x02: SBR module. * - 0x04: PS module. + * - 0x08: MPS module. * - 0x10: Metadata module. - * - example: (0x01|0x02|0x04|0x10) allocates all modules and is equivalent to default configuration denotet by 0x0. - * \param maxChannels Number of channels to be allocated. This parameter can be used in different ways: - * - 0: Allocate maximum number of AAC and SBR channels as supported by the library. - * - nChannels: Use same maximum number of channels for allocating memory in AAC and SBR module. - * - nChannels | (nSbrCh<<8): Number of SBR channels can be different to AAC channels to save data memory. + * - example: (0x01|0x02|0x04|0x08|0x10) allocates + * all modules and is equivalent to default configuration denotet by 0x0. + * \param maxChannels Number of channels to be allocated. This parameter can + * be used in different ways: + * - 0: Allocate maximum number of AAC and SBR channels as + * supported by the library. + * - nChannels: Use same maximum number of channels for + * allocating memory in AAC and SBR module. + * - nChannels | (nSbrCh<<8): Number of SBR channels can be + * different to AAC channels to save data memory. * * \return * - AACENC_OK, on succes. - * - AACENC_INVALID_HANDLE, AACENC_MEMORY_ERROR, AACENC_INVALID_CONFIG, on failure. + * - AACENC_INVALID_HANDLE, AACENC_MEMORY_ERROR, AACENC_INVALID_CONFIG, + * on failure. */ -AACENC_ERROR aacEncOpen( - HANDLE_AACENCODER *phAacEncoder, - const UINT encModules, - const UINT maxChannels - ); - +AACENC_ERROR aacEncOpen(HANDLE_AACENCODER *phAacEncoder, const UINT encModules, + const UINT maxChannels); /** * \brief Close the encoder instance. @@ -1103,63 +1593,72 @@ AACENC_ERROR aacEncOpen( * - AACENC_OK, on success. * - AACENC_INVALID_HANDLE, on failure. */ -AACENC_ERROR aacEncClose( - HANDLE_AACENCODER *phAacEncoder - ); - +AACENC_ERROR aacEncClose(HANDLE_AACENCODER *phAacEncoder); /** * \brief Encode audio data. * - * This function is mainly for encoding audio data. In addition the function can be used for an encoder (re)configuration - * process. - * - PCM input data will be retrieved from external input buffer until the fill level allows encoding a single frame. - * This functionality allows an external buffer with reduced size in comparison to the AAC or HE-AAC audio frame length. - * - If the value of the input samples argument is zero, just internal reinitialization will be applied if it is - * requested. - * - At the end of a file the flushing process can be triggerd via setting the value of the input samples argument to -1. - * The encoder delay lines are fully flushed when the encoder returns no valid bitstream data AACENC_OutArgs::numOutBytes. - * Furthermore the end of file is signaled by the return value AACENC_ENCODE_EOF. - * - If an error occured in the previous frame or any of the encoder parameters changed, an internal reinitialization - * process will be applied before encoding the incoming audio samples. - * - The function can also be used for an independent reconfiguration process without encoding. The first parameter has to be a - * valid encoder handle and all other parameters can be set to NULL. - * - If the size of the external bitbuffer in outBufDesc is not sufficient for writing the whole bitstream, an internal - * error will be the return value and a reconfiguration will be triggered. + * This function is mainly for encoding audio data. In addition the function can + * be used for an encoder (re)configuration process. + * - PCM input data will be retrieved from external input buffer until the fill + * level allows encoding a single frame. This functionality allows an external + * buffer with reduced size in comparison to the AAC or HE-AAC audio frame + * length. + * - If the value of the input samples argument is zero, just internal + * reinitialization will be applied if it is requested. + * - At the end of a file the flushing process can be triggerd via setting the + * value of the input samples argument to -1. The encoder delay lines are fully + * flushed when the encoder returns no valid bitstream data + * AACENC_OutArgs::numOutBytes. Furthermore the end of file is signaled by the + * return value AACENC_ENCODE_EOF. + * - If an error occured in the previous frame or any of the encoder parameters + * changed, an internal reinitialization process will be applied before encoding + * the incoming audio samples. + * - The function can also be used for an independent reconfiguration process + * without encoding. The first parameter has to be a valid encoder handle and + * all other parameters can be set to NULL. + * - If the size of the external bitbuffer in outBufDesc is not sufficient for + * writing the whole bitstream, an internal error will be the return value and a + * reconfiguration will be triggered. * * \param hAacEncoder A valid AAC encoder handle. * \param inBufDesc Input buffer descriptor, see AACENC_BufDesc: - * - At least one input buffer with audio data is expected. - * - Optionally a second input buffer with ancillary data can be fed. + * - At least one input buffer with audio data is + * expected. + * - Optionally a second input buffer with + * ancillary data can be fed. * \param outBufDesc Output buffer descriptor, see AACENC_BufDesc: - * - Provide one output buffer for the encoded bitstream. + * - Provide one output buffer for the encoded + * bitstream. * \param inargs Input arguments, see AACENC_InArgs. * \param outargs Output arguments, AACENC_OutArgs. * * \return * - AACENC_OK, on success. - * - AACENC_INVALID_HANDLE, AACENC_ENCODE_ERROR, on failure in encoding process. - * - AACENC_INVALID_CONFIG, AACENC_INIT_ERROR, AACENC_INIT_AAC_ERROR, AACENC_INIT_SBR_ERROR, AACENC_INIT_TP_ERROR, - * AACENC_INIT_META_ERROR, on failure in encoder initialization. + * - AACENC_INVALID_HANDLE, AACENC_ENCODE_ERROR, on failure in encoding + * process. + * - AACENC_INVALID_CONFIG, AACENC_INIT_ERROR, AACENC_INIT_AAC_ERROR, + * AACENC_INIT_SBR_ERROR, AACENC_INIT_TP_ERROR, AACENC_INIT_META_ERROR, + * AACENC_INIT_MPS_ERROR, on failure in encoder initialization. + * - AACENC_UNSUPPORTED_PARAMETER, on incorrect input or output buffer + * descriptor initialization. * - AACENC_ENCODE_EOF, when flushing fully concluded. */ -AACENC_ERROR aacEncEncode( - const HANDLE_AACENCODER hAacEncoder, - const AACENC_BufDesc *inBufDesc, - const AACENC_BufDesc *outBufDesc, - const AACENC_InArgs *inargs, - AACENC_OutArgs *outargs - ); - +AACENC_ERROR aacEncEncode(const HANDLE_AACENCODER hAacEncoder, + const AACENC_BufDesc *inBufDesc, + const AACENC_BufDesc *outBufDesc, + const AACENC_InArgs *inargs, AACENC_OutArgs *outargs); /** * \brief Acquire info about present encoder instance. * - * This function retrieves information of the encoder configuration. In addition to informative internal states, - * a configuration data block of the current encoder settings will be returned. The format is either Audio Specific Config - * in case of Raw Packets transport format or StreamMuxConfig in case of LOAS/LATM transport format. The configuration - * data block is binary coded as specified in ISO/IEC 14496-3 (MPEG-4 audio), to be used directly for MPEG-4 File Format - * or RFC3016 or RFC3640 applications. + * This function retrieves information of the encoder configuration. In addition + * to informative internal states, a configuration data block of the current + * encoder settings will be returned. The format is either Audio Specific Config + * in case of Raw Packets transport format or StreamMuxConfig in case of + * LOAS/LATM transport format. The configuration data block is binary coded as + * specified in ISO/IEC 14496-3 (MPEG-4 audio), to be used directly for MPEG-4 + * File Format or RFC3016 or RFC3640 applications. * * \param hAacEncoder A valid AAC encoder handle. * \param pInfo Pointer to AACENC_InfoStruct. Filled on return. @@ -1168,50 +1667,45 @@ AACENC_ERROR aacEncEncode( * - AACENC_OK, on succes. * - AACENC_INIT_ERROR, on failure. */ -AACENC_ERROR aacEncInfo( - const HANDLE_AACENCODER hAacEncoder, - AACENC_InfoStruct *pInfo - ); - +AACENC_ERROR aacEncInfo(const HANDLE_AACENCODER hAacEncoder, + AACENC_InfoStruct *pInfo); /** * \brief Set one single AAC encoder parameter. * - * This function allows configuration of all encoder parameters specified in ::AACENC_PARAM. Each parameter must be - * set with a separate function call. An internal validation of the configuration value range will be done and an - * internal reconfiguration will be signaled. The actual configuration adoption is part of the subsequent aacEncEncode() call. + * This function allows configuration of all encoder parameters specified in + * ::AACENC_PARAM. Each parameter must be set with a separate function call. An + * internal validation of the configuration value range will be done and an + * internal reconfiguration will be signaled. The actual configuration adoption + * is part of the subsequent aacEncEncode() call. * * \param hAacEncoder A valid AAC encoder handle. * \param param Parameter to be set. See ::AACENC_PARAM. - * \param value Parameter value. See parameter description in ::AACENC_PARAM. + * \param value Parameter value. See parameter description in + * ::AACENC_PARAM. * * \return * - AACENC_OK, on success. - * - AACENC_INVALID_HANDLE, AACENC_UNSUPPORTED_PARAMETER, AACENC_INVALID_CONFIG, on failure. + * - AACENC_INVALID_HANDLE, AACENC_UNSUPPORTED_PARAMETER, + * AACENC_INVALID_CONFIG, on failure. */ -AACENC_ERROR aacEncoder_SetParam( - const HANDLE_AACENCODER hAacEncoder, - const AACENC_PARAM param, - const UINT value - ); - +AACENC_ERROR aacEncoder_SetParam(const HANDLE_AACENCODER hAacEncoder, + const AACENC_PARAM param, const UINT value); /** * \brief Get one single AAC encoder parameter. * - * This function is the complement to aacEncoder_SetParam(). After encoder reinitialization with user defined settings, - * the internal status can be obtained of each parameter, specified with ::AACENC_PARAM. + * This function is the complement to aacEncoder_SetParam(). After encoder + * reinitialization with user defined settings, the internal status can be + * obtained of each parameter, specified with ::AACENC_PARAM. * * \param hAacEncoder A valid AAC encoder handle. * \param param Parameter to be returned. See ::AACENC_PARAM. * * \return Internal configuration value of specifed parameter ::AACENC_PARAM. */ -UINT aacEncoder_GetParam( - const HANDLE_AACENCODER hAacEncoder, - const AACENC_PARAM param - ); - +UINT aacEncoder_GetParam(const HANDLE_AACENCODER hAacEncoder, + const AACENC_PARAM param); /** * \brief Get information about encoder library build. @@ -1224,13 +1718,10 @@ UINT aacEncoder_GetParam( * - AACENC_OK, on success. * - AACENC_INVALID_HANDLE, AACENC_INIT_ERROR, on failure. */ -AACENC_ERROR aacEncGetLibInfo( - LIB_INFO *info - ); - +AACENC_ERROR aacEncGetLibInfo(LIB_INFO *info); #ifdef __cplusplus } #endif -#endif /* _AAC_ENC_LIB_H_ */ +#endif /* AACENC_LIB_H */ diff --git a/libAACenc/src/aacEnc_ram.cpp b/libAACenc/src/aacEnc_ram.cpp index be3eea2..77b1131 100644 --- a/libAACenc/src/aacEnc_ram.cpp +++ b/libAACenc/src/aacEnc_ram.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,14 +90,16 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** + + Author(s): M. Lohwasser, M. Gayer -/****************************************************************************** + Description: - Initial authors: M. Lohwasser, M. Gayer - Contents/description: +*******************************************************************************/ -******************************************************************************/ /*! \file \brief Memory layout @@ -95,100 +108,101 @@ amm-info@iis.fraunhofer.de #include "aacEnc_ram.h" - C_AALLOC_MEM (AACdynamic_RAM, FIXP_DBL, AAC_ENC_DYN_RAM_SIZE/sizeof(FIXP_DBL)) +C_AALLOC_MEM(AACdynamic_RAM, FIXP_DBL, AAC_ENC_DYN_RAM_SIZE / sizeof(FIXP_DBL)) /* - Static memory areas, must not be overwritten in other sections of the decoder ! + Static memory areas, must not be overwritten in other sections of the decoder + ! */ /* The structure AacEncoder contains all Encoder structures. */ -C_ALLOC_MEM (Ram_aacEnc_AacEncoder, AAC_ENC, 1) - +C_ALLOC_MEM(Ram_aacEnc_AacEncoder, struct AAC_ENC, 1) /* The structure PSY_INTERNAl contains all psych configuration and data pointer. * PsyStatic holds last and current Psych data. - * PsyInputBuffer contains time input. Signal is needed at the beginning of Psych. - Memory can be reused after signal is in time domain. - * PsyData contains spectral, nrg and threshold information. Necessary data are - copied into PsyOut, so memory is available after leaving psych. - * TnsData, ChaosMeasure, PnsData are temporarily necessary, e.g. use memory from - PsyInputBuffer. + * PsyInputBuffer contains time input. Signal is needed at the beginning of + Psych. Memory can be reused after signal is in time domain. + * PsyData contains spectral, nrg and threshold information. Necessary data + are copied into PsyOut, so memory is available after leaving psych. + * TnsData, ChaosMeasure, PnsData are temporarily necessary, e.g. use memory + from PsyInputBuffer. */ -C_ALLOC_MEM2 (Ram_aacEnc_PsyElement, PSY_ELEMENT, 1, (8)) - -C_ALLOC_MEM (Ram_aacEnc_PsyInternal, PSY_INTERNAL, 1) -C_ALLOC_MEM2 (Ram_aacEnc_PsyStatic, PSY_STATIC, 1, (8)) +C_ALLOC_MEM2(Ram_aacEnc_PsyElement, PSY_ELEMENT, 1, ((8))) -C_ALLOC_MEM2 (Ram_aacEnc_PsyInputBuffer, INT_PCM, MAX_INPUT_BUFFER_SIZE, (8)) +C_ALLOC_MEM(Ram_aacEnc_PsyInternal, PSY_INTERNAL, 1) +C_ALLOC_MEM2(Ram_aacEnc_PsyStatic, PSY_STATIC, 1, (8)) - PSY_DYNAMIC *GetRam_aacEnc_PsyDynamic (int n, UCHAR* dynamic_RAM) { - FDK_ASSERT(dynamic_RAM!=0); - return ((PSY_DYNAMIC*) (dynamic_RAM + P_BUF_1 + n*sizeof(PSY_DYNAMIC))); - } +C_ALLOC_MEM2(Ram_aacEnc_PsyInputBuffer, INT_PCM, MAX_INPUT_BUFFER_SIZE, (8)) - C_ALLOC_MEM (Ram_bsOutbuffer, UCHAR, OUTPUTBUFFER_SIZE) +PSY_DYNAMIC *GetRam_aacEnc_PsyDynamic(int n, UCHAR *dynamic_RAM) { + FDK_ASSERT(dynamic_RAM != 0); + /* The reinterpret_cast is used to suppress a compiler warning. We know that + * (dynamic_RAM + P_BUF_1 + n*sizeof(PSY_DYNAMIC)) is sufficiently aligned, so + * the cast is safe */ + return reinterpret_cast(reinterpret_cast( + dynamic_RAM + P_BUF_1 + n * sizeof(PSY_DYNAMIC))); +} /* The structure PSY_OUT holds all psychoaccoustic data needed in quantization module */ -C_ALLOC_MEM2 (Ram_aacEnc_PsyOut, PSY_OUT, 1, (1)) - -C_ALLOC_MEM2 (Ram_aacEnc_PsyOutElements, PSY_OUT_ELEMENT, 1, (1)*(8)) -C_ALLOC_MEM2 (Ram_aacEnc_PsyOutChannel, PSY_OUT_CHANNEL, 1, (1)*(8)) +C_ALLOC_MEM2(Ram_aacEnc_PsyOut, PSY_OUT, 1, (1)) +C_ALLOC_MEM2(Ram_aacEnc_PsyOutElements, PSY_OUT_ELEMENT, 1, (1) * ((8))) +C_ALLOC_MEM2(Ram_aacEnc_PsyOutChannel, PSY_OUT_CHANNEL, 1, (1) * (8)) /* - The structure QC_STATE contains preinitialized settings and quantizer structures. + The structure QC_STATE contains preinitialized settings and quantizer + structures. * AdjustThreshold structure contains element-wise settings. * ElementBits contains elemnt-wise bit consumption settings. * When CRC is active, lookup table is necessary for fast crc calculation. - * Bitcounter contains buffer to find optimal codebooks and minimal bit consumption. - Values are temporarily, so dynamic memory can be used. + * Bitcounter contains buffer to find optimal codebooks and minimal bit + consumption. Values are temporarily, so dynamic memory can be used. */ -C_ALLOC_MEM (Ram_aacEnc_QCstate, QC_STATE, 1) -C_ALLOC_MEM (Ram_aacEnc_AdjustThreshold, ADJ_THR_STATE, 1) - -C_ALLOC_MEM2 (Ram_aacEnc_AdjThrStateElement, ATS_ELEMENT, 1, (8)) -C_ALLOC_MEM2 (Ram_aacEnc_ElementBits, ELEMENT_BITS, 1, (8)) -C_ALLOC_MEM (Ram_aacEnc_BitCntrState, BITCNTR_STATE, 1) - - INT *GetRam_aacEnc_BitLookUp(int n, UCHAR* dynamic_RAM) { - FDK_ASSERT(dynamic_RAM!=0); - return ((INT*) (dynamic_RAM + P_BUF_1)); - } - INT *GetRam_aacEnc_MergeGainLookUp(int n, UCHAR* dynamic_RAM) { - FDK_ASSERT(dynamic_RAM!=0); - return ((INT*) (dynamic_RAM + P_BUF_1 + sizeof(INT)*(MAX_SFB_LONG*(CODE_BOOK_ESC_NDX+1)))); - } - +C_ALLOC_MEM(Ram_aacEnc_QCstate, QC_STATE, 1) +C_ALLOC_MEM(Ram_aacEnc_AdjustThreshold, ADJ_THR_STATE, 1) + +C_ALLOC_MEM2(Ram_aacEnc_AdjThrStateElement, ATS_ELEMENT, 1, ((8))) +C_ALLOC_MEM2(Ram_aacEnc_ElementBits, ELEMENT_BITS, 1, ((8))) +C_ALLOC_MEM(Ram_aacEnc_BitCntrState, struct BITCNTR_STATE, 1) + +INT *GetRam_aacEnc_BitLookUp(int n, UCHAR *dynamic_RAM) { + FDK_ASSERT(dynamic_RAM != 0); + /* The reinterpret_cast is used to suppress a compiler warning. We know that + * (dynamic_RAM + P_BUF_1) is sufficiently aligned, so the cast is safe */ + return reinterpret_cast( + reinterpret_cast(dynamic_RAM + P_BUF_1)); +} +INT *GetRam_aacEnc_MergeGainLookUp(int n, UCHAR *dynamic_RAM) { + FDK_ASSERT(dynamic_RAM != 0); + /* The reinterpret_cast is used to suppress a compiler warning. We know that + * (dynamic_RAM + P_BUF_1 + sizeof(INT)*(MAX_SFB_LONG*(CODE_BOOK_ESC_NDX+1))) + * is sufficiently aligned, so the cast is safe */ + return reinterpret_cast(reinterpret_cast( + dynamic_RAM + P_BUF_1 + + sizeof(INT) * (MAX_SFB_LONG * (CODE_BOOK_ESC_NDX + 1)))); +} /* - The structure QC_OUT contains settings and structures holding all necessary information - needed in bitstreamwriter. + The structure QC_OUT contains settings and structures holding all necessary + information needed in bitstreamwriter. */ -C_ALLOC_MEM2 (Ram_aacEnc_QCout, QC_OUT, 1, (1)) -C_ALLOC_MEM2 (Ram_aacEnc_QCelement, QC_OUT_ELEMENT, (1), (8)) - QC_OUT_CHANNEL *GetRam_aacEnc_QCchannel (int n, UCHAR* dynamic_RAM) { - FDK_ASSERT(dynamic_RAM!=0); - return ((QC_OUT_CHANNEL*) (dynamic_RAM + P_BUF_0 + n*sizeof(QC_OUT_CHANNEL))); - } - - - - - - - - - - - - +C_ALLOC_MEM2(Ram_aacEnc_QCout, QC_OUT, 1, (1)) +C_ALLOC_MEM2(Ram_aacEnc_QCelement, QC_OUT_ELEMENT, 1, (1) * ((8))) +QC_OUT_CHANNEL *GetRam_aacEnc_QCchannel(int n, UCHAR *dynamic_RAM) { + FDK_ASSERT(dynamic_RAM != 0); + /* The reinterpret_cast is used to suppress a compiler warning. We know that + * (dynamic_RAM + P_BUF_0 + n*sizeof(QC_OUT_CHANNEL)) is sufficiently aligned, + * so the cast is safe */ + return reinterpret_cast(reinterpret_cast( + dynamic_RAM + P_BUF_0 + n * sizeof(QC_OUT_CHANNEL))); +} diff --git a/libAACenc/src/aacEnc_ram.h b/libAACenc/src/aacEnc_ram.h index cf7da7c..0775aae 100644 --- a/libAACenc/src/aacEnc_ram.h +++ b/libAACenc/src/aacEnc_ram.h @@ -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,23 +90,24 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/****************************************************************************** + Author(s): M. Lohwasser, M. Gayer - Initial authors: M. Lohwasser, M. Gayer - Contents/description: + Description: -******************************************************************************/ +*******************************************************************************/ /*! \file - \brief Memory layout + \brief Memory layout \author Markus Lohwasser */ -#ifndef AAC_ENC_RAM_H -#define AAC_ENC_RAM_H +#ifndef AACENC_RAM_H +#define AACENC_RAM_H #include "common_fix.h" @@ -107,32 +119,35 @@ amm-info@iis.fraunhofer.de #include "bit_cnt.h" #include "psy_const.h" - #define OUTPUTBUFFER_SIZE (8192) /*!< Output buffer size has to be at least 6144 bits per channel (768 bytes). FDK bitbuffer implementation expects buffer of size 2^n. */ - +#define OUTPUTBUFFER_SIZE \ + (8192) /*!< Output buffer size has to be at least 6144 bits per channel \ + (768 bytes). FDK bitbuffer implementation expects buffer of \ + size 2^n. */ /* - Moved AAC_ENC struct definition from aac_enc.cpp into aacEnc_ram.h to get size and respective - static memory in aacEnc_ram.cpp. - aac_enc.h is the outward visible header file and putting the struct into would cause necessity - of additional visible header files outside library. + Moved AAC_ENC struct definition from aac_enc.cpp into aacEnc_ram.h to get size + and respective static memory in aacEnc_ram.cpp. aac_enc.h is the outward + visible header file and putting the struct into would cause necessity of + additional visible header files outside library. */ /* define hBitstream size: max AAC framelength is 6144 bits/channel */ -/*#define BUFFER_BITSTR_SIZE ((6400*(8)/bbWordSize) +((bbWordSize - 1) / bbWordSize))*/ +/*#define BUFFER_BITSTR_SIZE ((6400*(8)/bbWordSize) +((bbWordSize - 1) / + * bbWordSize))*/ struct AAC_ENC { + AACENC_CONFIG *config; - AACENC_CONFIG *config; + INT ancillaryBitsPerFrame; /* ancillary bits per frame calculated from + ancillary rate */ - INT ancillaryBitsPerFrame; /* ancillary bits per frame calculated from ancillary rate */ + CHANNEL_MAPPING channelMapping; - CHANNEL_MAPPING channelMapping; + QC_STATE *qcKernel; + QC_OUT *qcOut[(1)]; - QC_STATE *qcKernel; - QC_OUT *qcOut[(1)]; - - PSY_OUT *psyOut[(1)]; - PSY_INTERNAL *psyKernel; + PSY_OUT *psyOut[(1)]; + PSY_INTERNAL *psyKernel; /* lifetime vars */ @@ -140,50 +155,61 @@ struct AAC_ENC { INT bandwidth90dB; AACENC_BITRATE_MODE bitrateMode; - INT dontWriteAdif; /* use: write ADIF header only before 1st frame */ - - FIXP_DBL *dynamic_RAM; + INT dontWriteAdif; /* use: write ADIF header only before 1st frame */ + FIXP_DBL *dynamic_RAM; - INT maxChannels; /* used while allocation */ + INT maxChannels; /* used while allocation */ INT maxElements; INT maxFrames; - AUDIO_OBJECT_TYPE aot; /* AOT to be used while encoding. */ + AUDIO_OBJECT_TYPE aot; /* AOT to be used while encoding. */ +}; -} ; - -#define maxSize(a,b) ( ((a)>(b)) ? (a) : (b) ) - -#define BIT_LOOK_UP_SIZE ( sizeof(INT)*(MAX_SFB_LONG*(CODE_BOOK_ESC_NDX+1)) ) -#define MERGE_GAIN_LOOK_UP_SIZE ( sizeof(INT)*MAX_SFB_LONG ) +#define maxSize(a, b) (((a) > (b)) ? (a) : (b)) +#define BIT_LOOK_UP_SIZE \ + (sizeof(INT) * (MAX_SFB_LONG * (CODE_BOOK_ESC_NDX + 1))) +#define MERGE_GAIN_LOOK_UP_SIZE (sizeof(INT) * MAX_SFB_LONG) +/* Size of AhFlag buffer in function FDKaacEnc_adaptThresholdsToPe() */ +#define ADJ_THR_AH_FLAG_SIZE (sizeof(UCHAR) * ((8)) * (2) * MAX_GROUPED_SFB) +/* Size of ThrExp buffer in function FDKaacEnc_adaptThresholdsToPe() */ +#define ADJ_THR_THR_EXP_SIZE (sizeof(FIXP_DBL) * ((8)) * (2) * MAX_GROUPED_SFB) +/* Size of sfbNActiveLinesLdData buffer in function FDKaacEnc_correctThresh() */ +#define ADJ_THR_ACT_LIN_LD_DATA_SIZE \ + (sizeof(FIXP_DBL) * ((8)) * (2) * MAX_GROUPED_SFB) +/* Total amount of dynamic buffer needed in adjust thresholds functionality */ +#define ADJ_THR_SIZE \ + (ADJ_THR_AH_FLAG_SIZE + ADJ_THR_THR_EXP_SIZE + ADJ_THR_ACT_LIN_LD_DATA_SIZE) /* Dynamic RAM - Allocation */ /* - ++++++++++++++++++++++++++++++++++++++++++++ - | P_BUF_0 | P_BUF_1 | - ++++++++++++++++++++++++++++++++++++++++++++ - | QC_OUT_CH | PSY_DYN | - ++++++++++++++++++++++++++++++++++++++++++++ - | | BitLookUp+MergeGainLookUp | - ++++++++++++++++++++++++++++++++++++++++++++ - | | Bitstream output buffer | - ++++++++++++++++++++++++++++++++++++++++++++ + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + | P_BUF_0 | P_BUF_1 | + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + | QC_OUT_CH | PSY_DYN | + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + | | BitLookUp+MergeGainLookUp | + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + | | AH_FLAG | THR_EXP | ACT_LIN_LD_DATA | + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + | | Bitstream output buffer | + +++++++++++++++++++++++++++++++++++++++++++++++++++++ */ -#define BUF_SIZE_0 ( ALIGN_SIZE(sizeof(QC_OUT_CHANNEL)*(8)) ) -#define BUF_SIZE_1 ( ALIGN_SIZE(maxSize(sizeof(PSY_DYNAMIC), \ - (BIT_LOOK_UP_SIZE+MERGE_GAIN_LOOK_UP_SIZE))) ) - -#define P_BUF_0 ( 0 ) -#define P_BUF_1 ( P_BUF_0 + BUF_SIZE_0 ) +#define BUF_SIZE_0 (ALIGN_SIZE(sizeof(QC_OUT_CHANNEL) * (8))) +#define BUF_SIZE_1 \ + (ALIGN_SIZE(maxSize(maxSize(sizeof(PSY_DYNAMIC), \ + (BIT_LOOK_UP_SIZE + MERGE_GAIN_LOOK_UP_SIZE)), \ + ADJ_THR_SIZE))) -#define AAC_ENC_DYN_RAM_SIZE ( BUF_SIZE_0 + BUF_SIZE_1 ) +#define P_BUF_0 (0) +#define P_BUF_1 (P_BUF_0 + BUF_SIZE_0) +#define AAC_ENC_DYN_RAM_SIZE (BUF_SIZE_0 + BUF_SIZE_1) - H_ALLOC_MEM (AACdynamic_RAM, FIXP_DBL) +H_ALLOC_MEM(AACdynamic_RAM, FIXP_DBL) /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ END - Dynamic RAM - Allocation */ @@ -191,36 +217,33 @@ END - Dynamic RAM - Allocation */ /* See further Memory Allocation details in aacEnc_ram.cpp */ - H_ALLOC_MEM (Ram_aacEnc_AacEncoder, AAC_ENC) - - H_ALLOC_MEM (Ram_aacEnc_PsyElement, PSY_ELEMENT) - - H_ALLOC_MEM (Ram_aacEnc_PsyInternal, PSY_INTERNAL) - H_ALLOC_MEM (Ram_aacEnc_PsyStatic, PSY_STATIC) - H_ALLOC_MEM (Ram_aacEnc_PsyInputBuffer, INT_PCM) +H_ALLOC_MEM(Ram_aacEnc_AacEncoder, AAC_ENC) - PSY_DYNAMIC *GetRam_aacEnc_PsyDynamic (int n, UCHAR* dynamic_RAM); - H_ALLOC_MEM (Ram_bsOutbuffer, UCHAR) +H_ALLOC_MEM(Ram_aacEnc_PsyElement, PSY_ELEMENT) - H_ALLOC_MEM (Ram_aacEnc_PsyOutChannel, PSY_OUT_CHANNEL) +H_ALLOC_MEM(Ram_aacEnc_PsyInternal, PSY_INTERNAL) +H_ALLOC_MEM(Ram_aacEnc_PsyStatic, PSY_STATIC) +H_ALLOC_MEM(Ram_aacEnc_PsyInputBuffer, INT_PCM) - H_ALLOC_MEM (Ram_aacEnc_PsyOut, PSY_OUT) - H_ALLOC_MEM (Ram_aacEnc_PsyOutElements, PSY_OUT_ELEMENT) +PSY_DYNAMIC *GetRam_aacEnc_PsyDynamic(int n, UCHAR *dynamic_RAM); - H_ALLOC_MEM (Ram_aacEnc_QCstate, QC_STATE) - H_ALLOC_MEM (Ram_aacEnc_AdjustThreshold, ADJ_THR_STATE) +H_ALLOC_MEM(Ram_aacEnc_PsyOutChannel, PSY_OUT_CHANNEL) - H_ALLOC_MEM (Ram_aacEnc_AdjThrStateElement, ATS_ELEMENT) - H_ALLOC_MEM (Ram_aacEnc_ElementBits, ELEMENT_BITS) - H_ALLOC_MEM (Ram_aacEnc_BitCntrState, BITCNTR_STATE) +H_ALLOC_MEM(Ram_aacEnc_PsyOut, PSY_OUT) +H_ALLOC_MEM(Ram_aacEnc_PsyOutElements, PSY_OUT_ELEMENT) - INT *GetRam_aacEnc_BitLookUp(int n, UCHAR* dynamic_RAM); - INT *GetRam_aacEnc_MergeGainLookUp(int n, UCHAR* dynamic_RAM); - QC_OUT_CHANNEL *GetRam_aacEnc_QCchannel (int n, UCHAR* dynamic_RAM); +H_ALLOC_MEM(Ram_aacEnc_QCstate, QC_STATE) +H_ALLOC_MEM(Ram_aacEnc_AdjustThreshold, ADJ_THR_STATE) - H_ALLOC_MEM (Ram_aacEnc_QCout, QC_OUT) - H_ALLOC_MEM (Ram_aacEnc_QCelement, QC_OUT_ELEMENT) +H_ALLOC_MEM(Ram_aacEnc_AdjThrStateElement, ATS_ELEMENT) +H_ALLOC_MEM(Ram_aacEnc_ElementBits, ELEMENT_BITS) +H_ALLOC_MEM(Ram_aacEnc_BitCntrState, BITCNTR_STATE) +INT *GetRam_aacEnc_BitLookUp(int n, UCHAR *dynamic_RAM); +INT *GetRam_aacEnc_MergeGainLookUp(int n, UCHAR *dynamic_RAM); +QC_OUT_CHANNEL *GetRam_aacEnc_QCchannel(int n, UCHAR *dynamic_RAM); -#endif /* #ifndef AAC_ENC_RAM_H */ +H_ALLOC_MEM(Ram_aacEnc_QCout, QC_OUT) +H_ALLOC_MEM(Ram_aacEnc_QCelement, QC_OUT_ELEMENT) +#endif /* #ifndef AACENC_RAM_H */ diff --git a/libAACenc/src/aacEnc_rom.cpp b/libAACenc/src/aacEnc_rom.cpp index c6477e3..ac0fa9d 100644 --- a/libAACenc/src/aacEnc_rom.cpp +++ b/libAACenc/src/aacEnc_rom.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,574 +90,723 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/****************************************************************************** + Author(s): M. Lohwasser, M. Gayer - Initial authors: M. Lohwasser, M. Gayer - Contents/description: + Description: -******************************************************************************/ +*******************************************************************************/ #include "aacEnc_rom.h" /* Huffman Tables */ -const ULONG FDKaacEnc_huff_ltab1_2[3][3][3][3]= -{ - { - { {0x000b0009,0x00090007,0x000b0009}, {0x000a0008,0x00070006,0x000a0008}, {0x000b0009,0x00090008,0x000b0009} }, - { {0x000a0008,0x00070006,0x000a0007}, {0x00070006,0x00050005,0x00070006}, {0x00090007,0x00070006,0x000a0008} }, - { {0x000b0009,0x00090007,0x000b0008}, {0x00090008,0x00070006,0x00090008}, {0x000b0009,0x00090007,0x000b0009} } - }, - { - { {0x00090008,0x00070006,0x00090007}, {0x00070006,0x00050005,0x00070006}, {0x00090007,0x00070006,0x00090008} }, - { {0x00070006,0x00050005,0x00070006}, {0x00050005,0x00010003,0x00050005}, {0x00070006,0x00050005,0x00070006} }, - { {0x00090008,0x00070006,0x00090007}, {0x00070006,0x00050005,0x00070006}, {0x00090008,0x00070006,0x00090008} } - }, - { - { {0x000b0009,0x00090007,0x000b0009}, {0x00090008,0x00070006,0x00090008}, {0x000b0008,0x00090007,0x000b0009} }, - { {0x000a0008,0x00070006,0x00090007}, {0x00070006,0x00050004,0x00070006}, {0x00090008,0x00070006,0x000a0007} }, - { {0x000b0009,0x00090007,0x000b0009}, {0x000a0007,0x00070006,0x00090008}, {0x000b0009,0x00090007,0x000b0009} } - } -}; - - -const ULONG FDKaacEnc_huff_ltab3_4[3][3][3][3]= -{ - { - { {0x00010004,0x00040005,0x00080008}, {0x00040005,0x00050004,0x00080008}, {0x00090009,0x00090008,0x000a000b} }, - { {0x00040005,0x00060005,0x00090008}, {0x00060005,0x00060004,0x00090008}, {0x00090008,0x00090007,0x000a000a} }, - { {0x00090009,0x000a0008,0x000d000b}, {0x00090008,0x00090008,0x000b000a}, {0x000b000b,0x000a000a,0x000c000b} } - }, - { - { {0x00040004,0x00060005,0x000a0008}, {0x00060004,0x00070004,0x000a0008}, {0x000a0008,0x000a0008,0x000c000a} }, - { {0x00050004,0x00070004,0x000b0008}, {0x00060004,0x00070004,0x000a0007}, {0x00090008,0x00090007,0x000b0009} }, - { {0x00090008,0x000a0008,0x000d000a}, {0x00080007,0x00090007,0x000c0009}, {0x000a000a,0x000b0009,0x000c000a} } - }, - { - { {0x00080008,0x000a0008,0x000f000b}, {0x00090008,0x000b0007,0x000f000a}, {0x000d000b,0x000e000a,0x0010000c} }, - { {0x00080008,0x000a0007,0x000e000a}, {0x00090007,0x000a0007,0x000e0009}, {0x000c000a,0x000c0009,0x000f000b} }, - { {0x000b000b,0x000c000a,0x0010000c}, {0x000a000a,0x000b0009,0x000f000b}, {0x000c000b,0x000c000a,0x000f000b} } - } -}; - -const ULONG FDKaacEnc_huff_ltab5_6[9][9]= -{ - {0x000d000b, 0x000c000a, 0x000b0009, 0x000b0009, 0x000a0009, 0x000b0009, 0x000b0009, 0x000c000a, 0x000d000b}, - {0x000c000a, 0x000b0009, 0x000a0008, 0x00090007, 0x00080007, 0x00090007, 0x000a0008, 0x000b0009, 0x000c000a}, - {0x000c0009, 0x000a0008, 0x00090006, 0x00080006, 0x00070006, 0x00080006, 0x00090006, 0x000a0008, 0x000b0009}, - {0x000b0009, 0x00090007, 0x00080006, 0x00050004, 0x00040004, 0x00050004, 0x00080006, 0x00090007, 0x000b0009}, - {0x000a0009, 0x00080007, 0x00070006, 0x00040004, 0x00010004, 0x00040004, 0x00070006, 0x00080007, 0x000b0009}, - {0x000b0009, 0x00090007, 0x00080006, 0x00050004, 0x00040004, 0x00050004, 0x00080006, 0x00090007, 0x000b0009}, - {0x000b0009, 0x000a0008, 0x00090006, 0x00080006, 0x00070006, 0x00080006, 0x00090006, 0x000a0008, 0x000b0009}, - {0x000c000a, 0x000b0009, 0x000a0008, 0x00090007, 0x00080007, 0x00090007, 0x000a0007, 0x000b0008, 0x000c000a}, - {0x000d000b, 0x000c000a, 0x000c0009, 0x000b0009, 0x000a0009, 0x000a0009, 0x000b0009, 0x000c000a, 0x000d000b} -}; - -const ULONG FDKaacEnc_huff_ltab7_8[8][8]= -{ - {0x00010005, 0x00030004, 0x00060005, 0x00070006, 0x00080007, 0x00090008, 0x000a0009, 0x000b000a}, - {0x00030004, 0x00040003, 0x00060004, 0x00070005, 0x00080006, 0x00080007, 0x00090007, 0x00090008}, - {0x00060005, 0x00060004, 0x00070004, 0x00080005, 0x00080006, 0x00090007, 0x00090007, 0x000a0008}, - {0x00070006, 0x00070005, 0x00080005, 0x00080006, 0x00090006, 0x00090007, 0x000a0008, 0x000a0008}, - {0x00080007, 0x00080006, 0x00090006, 0x00090006, 0x000a0007, 0x000a0007, 0x000a0008, 0x000b0009}, - {0x00090008, 0x00080007, 0x00090006, 0x00090007, 0x000a0007, 0x000a0008, 0x000b0008, 0x000b000a}, - {0x000a0009, 0x00090007, 0x00090007, 0x000a0008, 0x000a0008, 0x000b0008, 0x000c0009, 0x000c0009}, - {0x000b000a, 0x000a0008, 0x000a0008, 0x000a0008, 0x000b0009, 0x000b0009, 0x000c0009, 0x000c000a} -}; - -const ULONG FDKaacEnc_huff_ltab9_10[13][13]= -{ - {0x00010006, 0x00030005, 0x00060006, 0x00080006, 0x00090007, 0x000a0008, 0x000a0009, 0x000b000a, 0x000b000a, 0x000c000a, 0x000c000b, 0x000d000b, 0x000d000c}, - {0x00030005, 0x00040004, 0x00060004, 0x00070005, 0x00080006, 0x00080007, 0x00090007, 0x000a0008, 0x000a0008, 0x000a0009, 0x000b000a, 0x000c000a, 0x000c000b}, - {0x00060006, 0x00060004, 0x00070005, 0x00080005, 0x00080006, 0x00090006, 0x000a0007, 0x000a0008, 0x000a0008, 0x000b0009, 0x000c0009, 0x000c000a, 0x000c000a}, - {0x00080006, 0x00070005, 0x00080005, 0x00090005, 0x00090006, 0x000a0007, 0x000a0007, 0x000b0008, 0x000b0008, 0x000b0009, 0x000c0009, 0x000c000a, 0x000d000a}, - {0x00090007, 0x00080006, 0x00090006, 0x00090006, 0x000a0006, 0x000a0007, 0x000b0007, 0x000b0008, 0x000b0008, 0x000c0009, 0x000c0009, 0x000c000a, 0x000d000a}, - {0x000a0008, 0x00090007, 0x00090006, 0x000a0007, 0x000b0007, 0x000b0007, 0x000b0008, 0x000c0008, 0x000b0008, 0x000c0009, 0x000c000a, 0x000d000a, 0x000d000b}, - {0x000b0009, 0x00090007, 0x000a0007, 0x000b0007, 0x000b0007, 0x000b0008, 0x000c0008, 0x000c0009, 0x000c0009, 0x000c0009, 0x000d000a, 0x000d000a, 0x000d000b}, - {0x000b0009, 0x000a0008, 0x000a0008, 0x000b0008, 0x000b0008, 0x000c0008, 0x000c0009, 0x000d0009, 0x000d0009, 0x000d000a, 0x000d000a, 0x000d000b, 0x000d000b}, - {0x000b0009, 0x000a0008, 0x000a0008, 0x000b0008, 0x000b0008, 0x000b0008, 0x000c0009, 0x000c0009, 0x000d000a, 0x000d000a, 0x000e000a, 0x000d000b, 0x000e000b}, - {0x000b000a, 0x000a0009, 0x000b0009, 0x000b0009, 0x000c0009, 0x000c0009, 0x000c0009, 0x000c000a, 0x000d000a, 0x000d000a, 0x000e000b, 0x000e000b, 0x000e000c}, - {0x000c000a, 0x000b0009, 0x000b0009, 0x000c0009, 0x000c0009, 0x000c000a, 0x000d000a, 0x000d000a, 0x000d000a, 0x000e000b, 0x000e000b, 0x000e000b, 0x000f000c}, - {0x000c000b, 0x000b000a, 0x000c0009, 0x000c000a, 0x000c000a, 0x000d000a, 0x000d000a, 0x000d000a, 0x000d000b, 0x000e000b, 0x000e000b, 0x000f000b, 0x000f000c}, - {0x000d000b, 0x000c000a, 0x000c000a, 0x000c000a, 0x000d000a, 0x000d000a, 0x000d000a, 0x000d000b, 0x000e000b, 0x000e000c, 0x000e000c, 0x000e000c, 0x000f000c} -}; - -const UCHAR FDKaacEnc_huff_ltab11[17][17]= -{ - {0x04, 0x05, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0b, 0x0c, 0x0c, 0x0a}, - {0x05, 0x04, 0x05, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x08}, - {0x06, 0x05, 0x05, 0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, - {0x07, 0x06, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, - {0x08, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, - {0x08, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, - {0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, - {0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, - {0x0a, 0x09, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x08}, - {0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x08}, - {0x0b, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0a, 0x0b, 0x0b, 0x08}, - {0x0b, 0x0a, 0x09, 0x09, 0x0a, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x08}, - {0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x09}, - {0x0b, 0x0a, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x09}, - {0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x09}, - {0x0c, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, 0x09}, - {0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x05} -}; - -const UCHAR FDKaacEnc_huff_ltabscf[121]= -{ - 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, - 0x13, 0x13, 0x13, 0x12, 0x13, 0x12, 0x11, 0x11, 0x10, 0x11, 0x10, 0x10, 0x10, 0x10, 0x0f, 0x0f, - 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0c, 0x0b, 0x0a, 0x0a, - 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x01, 0x04, 0x04, 0x05, - 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, - 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x10, 0x0f, 0x10, 0x0f, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, - 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, - 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 -}; - - -const USHORT FDKaacEnc_huff_ctab1[3][3][3][3]= -{ - { - { {0x07f8,0x01f1,0x07fd}, {0x03f5,0x0068,0x03f0}, {0x07f7,0x01ec,0x07f5} }, - { {0x03f1,0x0072,0x03f4}, {0x0074,0x0011,0x0076}, {0x01eb,0x006c,0x03f6} }, - { {0x07fc,0x01e1,0x07f1}, {0x01f0,0x0061,0x01f6}, {0x07f2,0x01ea,0x07fb} } - }, - { - { {0x01f2,0x0069,0x01ed}, {0x0077,0x0017,0x006f}, {0x01e6,0x0064,0x01e5} }, - { {0x0067,0x0015,0x0062}, {0x0012,0x0000,0x0014}, {0x0065,0x0016,0x006d} }, - { {0x01e9,0x0063,0x01e4}, {0x006b,0x0013,0x0071}, {0x01e3,0x0070,0x01f3} } - }, - { - { {0x07fe,0x01e7,0x07f3}, {0x01ef,0x0060,0x01ee}, {0x07f0,0x01e2,0x07fa} }, - { {0x03f3,0x006a,0x01e8}, {0x0075,0x0010,0x0073}, {0x01f4,0x006e,0x03f7} }, - { {0x07f6,0x01e0,0x07f9}, {0x03f2,0x0066,0x01f5}, {0x07ff,0x01f7,0x07f4} } - } -}; - -const USHORT FDKaacEnc_huff_ctab2[3][3][3][3]= -{ - { - { {0x01f3,0x006f,0x01fd}, {0x00eb,0x0023,0x00ea}, {0x01f7,0x00e8,0x01fa} }, - { {0x00f2,0x002d,0x0070}, {0x0020,0x0006,0x002b}, {0x006e,0x0028,0x00e9} }, - { {0x01f9,0x0066,0x00f8}, {0x00e7,0x001b,0x00f1}, {0x01f4,0x006b,0x01f5} } - }, - { - { {0x00ec,0x002a,0x006c}, {0x002c,0x000a,0x0027}, {0x0067,0x001a,0x00f5} }, - { {0x0024,0x0008,0x001f}, {0x0009,0x0000,0x0007}, {0x001d,0x000b,0x0030} }, - { {0x00ef,0x001c,0x0064}, {0x001e,0x000c,0x0029}, {0x00f3,0x002f,0x00f0} } - }, - { - { {0x01fc,0x0071,0x01f2}, {0x00f4,0x0021,0x00e6}, {0x00f7,0x0068,0x01f8} }, - { {0x00ee,0x0022,0x0065}, {0x0031,0x0002,0x0026}, {0x00ed,0x0025,0x006a} }, - { {0x01fb,0x0072,0x01fe}, {0x0069,0x002e,0x00f6}, {0x01ff,0x006d,0x01f6} } - } -}; - -const USHORT FDKaacEnc_huff_ctab3[3][3][3][3]= -{ - { - { {0x0000,0x0009,0x00ef}, {0x000b,0x0019,0x00f0}, {0x01eb,0x01e6,0x03f2} }, - { {0x000a,0x0035,0x01ef}, {0x0034,0x0037,0x01e9}, {0x01ed,0x01e7,0x03f3} }, - { {0x01ee,0x03ed,0x1ffa}, {0x01ec,0x01f2,0x07f9}, {0x07f8,0x03f8,0x0ff8} } - }, - { - { {0x0008,0x0038,0x03f6}, {0x0036,0x0075,0x03f1}, {0x03eb,0x03ec,0x0ff4} }, - { {0x0018,0x0076,0x07f4}, {0x0039,0x0074,0x03ef}, {0x01f3,0x01f4,0x07f6} }, - { {0x01e8,0x03ea,0x1ffc}, {0x00f2,0x01f1,0x0ffb}, {0x03f5,0x07f3,0x0ffc} } - }, - { - { {0x00ee,0x03f7,0x7ffe}, {0x01f0,0x07f5,0x7ffd}, {0x1ffb,0x3ffa,0xffff} }, - { {0x00f1,0x03f0,0x3ffc}, {0x01ea,0x03ee,0x3ffb}, {0x0ff6,0x0ffa,0x7ffc} }, - { {0x07f2,0x0ff5,0xfffe}, {0x03f4,0x07f7,0x7ffb}, {0x0ff7,0x0ff9,0x7ffa} } - } -}; - -const USHORT FDKaacEnc_huff_ctab4[3][3][3][3]= -{ - { - { {0x0007,0x0016,0x00f6}, {0x0018,0x0008,0x00ef}, {0x01ef,0x00f3,0x07f8} }, - { {0x0019,0x0017,0x00ed}, {0x0015,0x0001,0x00e2}, {0x00f0,0x0070,0x03f0} }, - { {0x01ee,0x00f1,0x07fa}, {0x00ee,0x00e4,0x03f2}, {0x07f6,0x03ef,0x07fd} } - }, - { - { {0x0005,0x0014,0x00f2}, {0x0009,0x0004,0x00e5}, {0x00f4,0x00e8,0x03f4} }, - { {0x0006,0x0002,0x00e7}, {0x0003,0x0000,0x006b}, {0x00e3,0x0069,0x01f3} }, - { {0x00eb,0x00e6,0x03f6}, {0x006e,0x006a,0x01f4}, {0x03ec,0x01f0,0x03f9} } - }, - { - { {0x00f5,0x00ec,0x07fb}, {0x00ea,0x006f,0x03f7}, {0x07f9,0x03f3,0x0fff} }, - { {0x00e9,0x006d,0x03f8}, {0x006c,0x0068,0x01f5}, {0x03ee,0x01f2,0x07f4} }, - { {0x07f7,0x03f1,0x0ffe}, {0x03ed,0x01f1,0x07f5}, {0x07fe,0x03f5,0x07fc} } - } -}; -const USHORT FDKaacEnc_huff_ctab5[9][9]= -{ - {0x1fff, 0x0ff7, 0x07f4, 0x07e8, 0x03f1, 0x07ee, 0x07f9, 0x0ff8, 0x1ffd}, - {0x0ffd, 0x07f1, 0x03e8, 0x01e8, 0x00f0, 0x01ec, 0x03ee, 0x07f2, 0x0ffa}, - {0x0ff4, 0x03ef, 0x01f2, 0x00e8, 0x0070, 0x00ec, 0x01f0, 0x03ea, 0x07f3}, - {0x07eb, 0x01eb, 0x00ea, 0x001a, 0x0008, 0x0019, 0x00ee, 0x01ef, 0x07ed}, - {0x03f0, 0x00f2, 0x0073, 0x000b, 0x0000, 0x000a, 0x0071, 0x00f3, 0x07e9}, - {0x07ef, 0x01ee, 0x00ef, 0x0018, 0x0009, 0x001b, 0x00eb, 0x01e9, 0x07ec}, - {0x07f6, 0x03eb, 0x01f3, 0x00ed, 0x0072, 0x00e9, 0x01f1, 0x03ed, 0x07f7}, - {0x0ff6, 0x07f0, 0x03e9, 0x01ed, 0x00f1, 0x01ea, 0x03ec, 0x07f8, 0x0ff9}, - {0x1ffc, 0x0ffc, 0x0ff5, 0x07ea, 0x03f3, 0x03f2, 0x07f5, 0x0ffb, 0x1ffe} -}; - -const USHORT FDKaacEnc_huff_ctab6[9][9]= -{ - {0x07fe, 0x03fd, 0x01f1, 0x01eb, 0x01f4, 0x01ea, 0x01f0, 0x03fc, 0x07fd}, - {0x03f6, 0x01e5, 0x00ea, 0x006c, 0x0071, 0x0068, 0x00f0, 0x01e6, 0x03f7}, - {0x01f3, 0x00ef, 0x0032, 0x0027, 0x0028, 0x0026, 0x0031, 0x00eb, 0x01f7}, - {0x01e8, 0x006f, 0x002e, 0x0008, 0x0004, 0x0006, 0x0029, 0x006b, 0x01ee}, - {0x01ef, 0x0072, 0x002d, 0x0002, 0x0000, 0x0003, 0x002f, 0x0073, 0x01fa}, - {0x01e7, 0x006e, 0x002b, 0x0007, 0x0001, 0x0005, 0x002c, 0x006d, 0x01ec}, - {0x01f9, 0x00ee, 0x0030, 0x0024, 0x002a, 0x0025, 0x0033, 0x00ec, 0x01f2}, - {0x03f8, 0x01e4, 0x00ed, 0x006a, 0x0070, 0x0069, 0x0074, 0x00f1, 0x03fa}, - {0x07ff, 0x03f9, 0x01f6, 0x01ed, 0x01f8, 0x01e9, 0x01f5, 0x03fb, 0x07fc} -}; - -const USHORT FDKaacEnc_huff_ctab7[8][8]= -{ - {0x0000, 0x0005, 0x0037, 0x0074, 0x00f2, 0x01eb, 0x03ed, 0x07f7}, - {0x0004, 0x000c, 0x0035, 0x0071, 0x00ec, 0x00ee, 0x01ee, 0x01f5}, - {0x0036, 0x0034, 0x0072, 0x00ea, 0x00f1, 0x01e9, 0x01f3, 0x03f5}, - {0x0073, 0x0070, 0x00eb, 0x00f0, 0x01f1, 0x01f0, 0x03ec, 0x03fa}, - {0x00f3, 0x00ed, 0x01e8, 0x01ef, 0x03ef, 0x03f1, 0x03f9, 0x07fb}, - {0x01ed, 0x00ef, 0x01ea, 0x01f2, 0x03f3, 0x03f8, 0x07f9, 0x07fc}, - {0x03ee, 0x01ec, 0x01f4, 0x03f4, 0x03f7, 0x07f8, 0x0ffd, 0x0ffe}, - {0x07f6, 0x03f0, 0x03f2, 0x03f6, 0x07fa, 0x07fd, 0x0ffc, 0x0fff} -}; - -const USHORT FDKaacEnc_huff_ctab8[8][8]= -{ - {0x000e, 0x0005, 0x0010, 0x0030, 0x006f, 0x00f1, 0x01fa, 0x03fe}, - {0x0003, 0x0000, 0x0004, 0x0012, 0x002c, 0x006a, 0x0075, 0x00f8}, - {0x000f, 0x0002, 0x0006, 0x0014, 0x002e, 0x0069, 0x0072, 0x00f5}, - {0x002f, 0x0011, 0x0013, 0x002a, 0x0032, 0x006c, 0x00ec, 0x00fa}, - {0x0071, 0x002b, 0x002d, 0x0031, 0x006d, 0x0070, 0x00f2, 0x01f9}, - {0x00ef, 0x0068, 0x0033, 0x006b, 0x006e, 0x00ee, 0x00f9, 0x03fc}, - {0x01f8, 0x0074, 0x0073, 0x00ed, 0x00f0, 0x00f6, 0x01f6, 0x01fd}, - {0x03fd, 0x00f3, 0x00f4, 0x00f7, 0x01f7, 0x01fb, 0x01fc, 0x03ff} -}; - -const USHORT FDKaacEnc_huff_ctab9[13][13]= -{ - {0x0000, 0x0005, 0x0037, 0x00e7, 0x01de, 0x03ce, 0x03d9, 0x07c8, 0x07cd, 0x0fc8, 0x0fdd, 0x1fe4, 0x1fec}, - {0x0004, 0x000c, 0x0035, 0x0072, 0x00ea, 0x00ed, 0x01e2, 0x03d1, 0x03d3, 0x03e0, 0x07d8, 0x0fcf, 0x0fd5}, - {0x0036, 0x0034, 0x0071, 0x00e8, 0x00ec, 0x01e1, 0x03cf, 0x03dd, 0x03db, 0x07d0, 0x0fc7, 0x0fd4, 0x0fe4}, - {0x00e6, 0x0070, 0x00e9, 0x01dd, 0x01e3, 0x03d2, 0x03dc, 0x07cc, 0x07ca, 0x07de, 0x0fd8, 0x0fea, 0x1fdb}, - {0x01df, 0x00eb, 0x01dc, 0x01e6, 0x03d5, 0x03de, 0x07cb, 0x07dd, 0x07dc, 0x0fcd, 0x0fe2, 0x0fe7, 0x1fe1}, - {0x03d0, 0x01e0, 0x01e4, 0x03d6, 0x07c5, 0x07d1, 0x07db, 0x0fd2, 0x07e0, 0x0fd9, 0x0feb, 0x1fe3, 0x1fe9}, - {0x07c4, 0x01e5, 0x03d7, 0x07c6, 0x07cf, 0x07da, 0x0fcb, 0x0fda, 0x0fe3, 0x0fe9, 0x1fe6, 0x1ff3, 0x1ff7}, - {0x07d3, 0x03d8, 0x03e1, 0x07d4, 0x07d9, 0x0fd3, 0x0fde, 0x1fdd, 0x1fd9, 0x1fe2, 0x1fea, 0x1ff1, 0x1ff6}, - {0x07d2, 0x03d4, 0x03da, 0x07c7, 0x07d7, 0x07e2, 0x0fce, 0x0fdb, 0x1fd8, 0x1fee, 0x3ff0, 0x1ff4, 0x3ff2}, - {0x07e1, 0x03df, 0x07c9, 0x07d6, 0x0fca, 0x0fd0, 0x0fe5, 0x0fe6, 0x1feb, 0x1fef, 0x3ff3, 0x3ff4, 0x3ff5}, - {0x0fe0, 0x07ce, 0x07d5, 0x0fc6, 0x0fd1, 0x0fe1, 0x1fe0, 0x1fe8, 0x1ff0, 0x3ff1, 0x3ff8, 0x3ff6, 0x7ffc}, - {0x0fe8, 0x07df, 0x0fc9, 0x0fd7, 0x0fdc, 0x1fdc, 0x1fdf, 0x1fed, 0x1ff5, 0x3ff9, 0x3ffb, 0x7ffd, 0x7ffe}, - {0x1fe7, 0x0fcc, 0x0fd6, 0x0fdf, 0x1fde, 0x1fda, 0x1fe5, 0x1ff2, 0x3ffa, 0x3ff7, 0x3ffc, 0x3ffd, 0x7fff} -}; - -const USHORT FDKaacEnc_huff_ctab10[13][13]= -{ - {0x0022, 0x0008, 0x001d, 0x0026, 0x005f, 0x00d3, 0x01cf, 0x03d0, 0x03d7, 0x03ed, 0x07f0, 0x07f6, 0x0ffd}, - {0x0007, 0x0000, 0x0001, 0x0009, 0x0020, 0x0054, 0x0060, 0x00d5, 0x00dc, 0x01d4, 0x03cd, 0x03de, 0x07e7}, - {0x001c, 0x0002, 0x0006, 0x000c, 0x001e, 0x0028, 0x005b, 0x00cd, 0x00d9, 0x01ce, 0x01dc, 0x03d9, 0x03f1}, - {0x0025, 0x000b, 0x000a, 0x000d, 0x0024, 0x0057, 0x0061, 0x00cc, 0x00dd, 0x01cc, 0x01de, 0x03d3, 0x03e7}, - {0x005d, 0x0021, 0x001f, 0x0023, 0x0027, 0x0059, 0x0064, 0x00d8, 0x00df, 0x01d2, 0x01e2, 0x03dd, 0x03ee}, - {0x00d1, 0x0055, 0x0029, 0x0056, 0x0058, 0x0062, 0x00ce, 0x00e0, 0x00e2, 0x01da, 0x03d4, 0x03e3, 0x07eb}, - {0x01c9, 0x005e, 0x005a, 0x005c, 0x0063, 0x00ca, 0x00da, 0x01c7, 0x01ca, 0x01e0, 0x03db, 0x03e8, 0x07ec}, - {0x01e3, 0x00d2, 0x00cb, 0x00d0, 0x00d7, 0x00db, 0x01c6, 0x01d5, 0x01d8, 0x03ca, 0x03da, 0x07ea, 0x07f1}, - {0x01e1, 0x00d4, 0x00cf, 0x00d6, 0x00de, 0x00e1, 0x01d0, 0x01d6, 0x03d1, 0x03d5, 0x03f2, 0x07ee, 0x07fb}, - {0x03e9, 0x01cd, 0x01c8, 0x01cb, 0x01d1, 0x01d7, 0x01df, 0x03cf, 0x03e0, 0x03ef, 0x07e6, 0x07f8, 0x0ffa}, - {0x03eb, 0x01dd, 0x01d3, 0x01d9, 0x01db, 0x03d2, 0x03cc, 0x03dc, 0x03ea, 0x07ed, 0x07f3, 0x07f9, 0x0ff9}, - {0x07f2, 0x03ce, 0x01e4, 0x03cb, 0x03d8, 0x03d6, 0x03e2, 0x03e5, 0x07e8, 0x07f4, 0x07f5, 0x07f7, 0x0ffb}, - {0x07fa, 0x03ec, 0x03df, 0x03e1, 0x03e4, 0x03e6, 0x03f0, 0x07e9, 0x07ef, 0x0ff8, 0x0ffe, 0x0ffc, 0x0fff} -}; - -const USHORT FDKaacEnc_huff_ctab11[21][17]= -{ - {0x0000, 0x0006, 0x0019, 0x003d, 0x009c, 0x00c6, 0x01a7, 0x0390, 0x03c2, 0x03df, 0x07e6, 0x07f3, 0x0ffb, 0x07ec, 0x0ffa, 0x0ffe, 0x038e}, - {0x0005, 0x0001, 0x0008, 0x0014, 0x0037, 0x0042, 0x0092, 0x00af, 0x0191, 0x01a5, 0x01b5, 0x039e, 0x03c0, 0x03a2, 0x03cd, 0x07d6, 0x00ae}, - {0x0017, 0x0007, 0x0009, 0x0018, 0x0039, 0x0040, 0x008e, 0x00a3, 0x00b8, 0x0199, 0x01ac, 0x01c1, 0x03b1, 0x0396, 0x03be, 0x03ca, 0x009d}, - {0x003c, 0x0015, 0x0016, 0x001a, 0x003b, 0x0044, 0x0091, 0x00a5, 0x00be, 0x0196, 0x01ae, 0x01b9, 0x03a1, 0x0391, 0x03a5, 0x03d5, 0x0094}, - {0x009a, 0x0036, 0x0038, 0x003a, 0x0041, 0x008c, 0x009b, 0x00b0, 0x00c3, 0x019e, 0x01ab, 0x01bc, 0x039f, 0x038f, 0x03a9, 0x03cf, 0x0093}, - {0x00bf, 0x003e, 0x003f, 0x0043, 0x0045, 0x009e, 0x00a7, 0x00b9, 0x0194, 0x01a2, 0x01ba, 0x01c3, 0x03a6, 0x03a7, 0x03bb, 0x03d4, 0x009f}, - {0x01a0, 0x008f, 0x008d, 0x0090, 0x0098, 0x00a6, 0x00b6, 0x00c4, 0x019f, 0x01af, 0x01bf, 0x0399, 0x03bf, 0x03b4, 0x03c9, 0x03e7, 0x00a8}, - {0x01b6, 0x00ab, 0x00a4, 0x00aa, 0x00b2, 0x00c2, 0x00c5, 0x0198, 0x01a4, 0x01b8, 0x038c, 0x03a4, 0x03c4, 0x03c6, 0x03dd, 0x03e8, 0x00ad}, - {0x03af, 0x0192, 0x00bd, 0x00bc, 0x018e, 0x0197, 0x019a, 0x01a3, 0x01b1, 0x038d, 0x0398, 0x03b7, 0x03d3, 0x03d1, 0x03db, 0x07dd, 0x00b4}, - {0x03de, 0x01a9, 0x019b, 0x019c, 0x01a1, 0x01aa, 0x01ad, 0x01b3, 0x038b, 0x03b2, 0x03b8, 0x03ce, 0x03e1, 0x03e0, 0x07d2, 0x07e5, 0x00b7}, - {0x07e3, 0x01bb, 0x01a8, 0x01a6, 0x01b0, 0x01b2, 0x01b7, 0x039b, 0x039a, 0x03ba, 0x03b5, 0x03d6, 0x07d7, 0x03e4, 0x07d8, 0x07ea, 0x00ba}, - {0x07e8, 0x03a0, 0x01bd, 0x01b4, 0x038a, 0x01c4, 0x0392, 0x03aa, 0x03b0, 0x03bc, 0x03d7, 0x07d4, 0x07dc, 0x07db, 0x07d5, 0x07f0, 0x00c1}, - {0x07fb, 0x03c8, 0x03a3, 0x0395, 0x039d, 0x03ac, 0x03ae, 0x03c5, 0x03d8, 0x03e2, 0x03e6, 0x07e4, 0x07e7, 0x07e0, 0x07e9, 0x07f7, 0x0190}, - {0x07f2, 0x0393, 0x01be, 0x01c0, 0x0394, 0x0397, 0x03ad, 0x03c3, 0x03c1, 0x03d2, 0x07da, 0x07d9, 0x07df, 0x07eb, 0x07f4, 0x07fa, 0x0195}, - {0x07f8, 0x03bd, 0x039c, 0x03ab, 0x03a8, 0x03b3, 0x03b9, 0x03d0, 0x03e3, 0x03e5, 0x07e2, 0x07de, 0x07ed, 0x07f1, 0x07f9, 0x07fc, 0x0193}, - {0x0ffd, 0x03dc, 0x03b6, 0x03c7, 0x03cc, 0x03cb, 0x03d9, 0x03da, 0x07d3, 0x07e1, 0x07ee, 0x07ef, 0x07f5, 0x07f6, 0x0ffc, 0x0fff, 0x019d}, - {0x01c2, 0x00b5, 0x00a1, 0x0096, 0x0097, 0x0095, 0x0099, 0x00a0, 0x00a2, 0x00ac, 0x00a9, 0x00b1, 0x00b3, 0x00bb, 0x00c0, 0x018f, 0x0004}, - {0x0018, 0x002e, 0x0000, 0x005a, 0x00a5, 0x00f8, 0x00b7, 0x0094, 0x00f9, 0x004d, 0x0021, 0x002b, 0x004f, 0x007b, 0x00bc, 0x0046, 0x0015}, - {0x0042, 0x0037, 0x0078, 0x000d, 0x0068, 0x005f, 0x000d, 0x005e, 0x005a, 0x00be, 0x0063, 0x007e, 0x001f, 0x0092, 0x001a, 0x00ab, 0x0032}, - {0x00e6, 0x0037, 0x0000, 0x0058, 0x000b, 0x005a, 0x00e1, 0x005d, 0x0029, 0x0017, 0x007e, 0x0069, 0x00aa, 0x0054, 0x0029, 0x0032, 0x0041}, - {0x0046, 0x00ea, 0x0034, 0x00ea, 0x0011, 0x001b, 0x00a9, 0x0094, 0x00e2, 0x0031, 0x00d0, 0x00e5, 0x0007, 0x0070, 0x0069, 0x003e, 0x0021} -}; - -const ULONG FDKaacEnc_huff_ctabscf[121]= -{ - 0x0003ffe8, 0x0003ffe6, 0x0003ffe7, 0x0003ffe5, 0x0007fff5, 0x0007fff1, 0x0007ffed, 0x0007fff6, - 0x0007ffee, 0x0007ffef, 0x0007fff0, 0x0007fffc, 0x0007fffd, 0x0007ffff, 0x0007fffe, 0x0007fff7, - 0x0007fff8, 0x0007fffb, 0x0007fff9, 0x0003ffe4, 0x0007fffa, 0x0003ffe3, 0x0001ffef, 0x0001fff0, - 0x0000fff5, 0x0001ffee, 0x0000fff2, 0x0000fff3, 0x0000fff4, 0x0000fff1, 0x00007ff6, 0x00007ff7, - 0x00003ff9, 0x00003ff5, 0x00003ff7, 0x00003ff3, 0x00003ff6, 0x00003ff2, 0x00001ff7, 0x00001ff5, - 0x00000ff9, 0x00000ff7, 0x00000ff6, 0x000007f9, 0x00000ff4, 0x000007f8, 0x000003f9, 0x000003f7, - 0x000003f5, 0x000001f8, 0x000001f7, 0x000000fa, 0x000000f8, 0x000000f6, 0x00000079, 0x0000003a, - 0x00000038, 0x0000001a, 0x0000000b, 0x00000004, 0x00000000, 0x0000000a, 0x0000000c, 0x0000001b, - 0x00000039, 0x0000003b, 0x00000078, 0x0000007a, 0x000000f7, 0x000000f9, 0x000001f6, 0x000001f9, - 0x000003f4, 0x000003f6, 0x000003f8, 0x000007f5, 0x000007f4, 0x000007f6, 0x000007f7, 0x00000ff5, - 0x00000ff8, 0x00001ff4, 0x00001ff6, 0x00001ff8, 0x00003ff8, 0x00003ff4, 0x0000fff0, 0x00007ff4, - 0x0000fff6, 0x00007ff5, 0x0003ffe2, 0x0007ffd9, 0x0007ffda, 0x0007ffdb, 0x0007ffdc, 0x0007ffdd, - 0x0007ffde, 0x0007ffd8, 0x0007ffd2, 0x0007ffd3, 0x0007ffd4, 0x0007ffd5, 0x0007ffd6, 0x0007fff2, - 0x0007ffdf, 0x0007ffe7, 0x0007ffe8, 0x0007ffe9, 0x0007ffea, 0x0007ffeb, 0x0007ffe6, 0x0007ffe0, - 0x0007ffe1, 0x0007ffe2, 0x0007ffe3, 0x0007ffe4, 0x0007ffe5, 0x0007ffd7, 0x0007ffec, 0x0007fff4, - 0x0007fff3 -}; +const ULONG FDKaacEnc_huff_ltab1_2[3][3][3][3] = { + {{{0x000b0009, 0x00090007, 0x000b0009}, + {0x000a0008, 0x00070006, 0x000a0008}, + {0x000b0009, 0x00090008, 0x000b0009}}, + {{0x000a0008, 0x00070006, 0x000a0007}, + {0x00070006, 0x00050005, 0x00070006}, + {0x00090007, 0x00070006, 0x000a0008}}, + {{0x000b0009, 0x00090007, 0x000b0008}, + {0x00090008, 0x00070006, 0x00090008}, + {0x000b0009, 0x00090007, 0x000b0009}}}, + {{{0x00090008, 0x00070006, 0x00090007}, + {0x00070006, 0x00050005, 0x00070006}, + {0x00090007, 0x00070006, 0x00090008}}, + {{0x00070006, 0x00050005, 0x00070006}, + {0x00050005, 0x00010003, 0x00050005}, + {0x00070006, 0x00050005, 0x00070006}}, + {{0x00090008, 0x00070006, 0x00090007}, + {0x00070006, 0x00050005, 0x00070006}, + {0x00090008, 0x00070006, 0x00090008}}}, + {{{0x000b0009, 0x00090007, 0x000b0009}, + {0x00090008, 0x00070006, 0x00090008}, + {0x000b0008, 0x00090007, 0x000b0009}}, + {{0x000a0008, 0x00070006, 0x00090007}, + {0x00070006, 0x00050004, 0x00070006}, + {0x00090008, 0x00070006, 0x000a0007}}, + {{0x000b0009, 0x00090007, 0x000b0009}, + {0x000a0007, 0x00070006, 0x00090008}, + {0x000b0009, 0x00090007, 0x000b0009}}}}; + +const ULONG FDKaacEnc_huff_ltab3_4[3][3][3][3] = { + {{{0x00010004, 0x00040005, 0x00080008}, + {0x00040005, 0x00050004, 0x00080008}, + {0x00090009, 0x00090008, 0x000a000b}}, + {{0x00040005, 0x00060005, 0x00090008}, + {0x00060005, 0x00060004, 0x00090008}, + {0x00090008, 0x00090007, 0x000a000a}}, + {{0x00090009, 0x000a0008, 0x000d000b}, + {0x00090008, 0x00090008, 0x000b000a}, + {0x000b000b, 0x000a000a, 0x000c000b}}}, + {{{0x00040004, 0x00060005, 0x000a0008}, + {0x00060004, 0x00070004, 0x000a0008}, + {0x000a0008, 0x000a0008, 0x000c000a}}, + {{0x00050004, 0x00070004, 0x000b0008}, + {0x00060004, 0x00070004, 0x000a0007}, + {0x00090008, 0x00090007, 0x000b0009}}, + {{0x00090008, 0x000a0008, 0x000d000a}, + {0x00080007, 0x00090007, 0x000c0009}, + {0x000a000a, 0x000b0009, 0x000c000a}}}, + {{{0x00080008, 0x000a0008, 0x000f000b}, + {0x00090008, 0x000b0007, 0x000f000a}, + {0x000d000b, 0x000e000a, 0x0010000c}}, + {{0x00080008, 0x000a0007, 0x000e000a}, + {0x00090007, 0x000a0007, 0x000e0009}, + {0x000c000a, 0x000c0009, 0x000f000b}}, + {{0x000b000b, 0x000c000a, 0x0010000c}, + {0x000a000a, 0x000b0009, 0x000f000b}, + {0x000c000b, 0x000c000a, 0x000f000b}}}}; + +const ULONG FDKaacEnc_huff_ltab5_6[9][9] = { + {0x000d000b, 0x000c000a, 0x000b0009, 0x000b0009, 0x000a0009, 0x000b0009, + 0x000b0009, 0x000c000a, 0x000d000b}, + {0x000c000a, 0x000b0009, 0x000a0008, 0x00090007, 0x00080007, 0x00090007, + 0x000a0008, 0x000b0009, 0x000c000a}, + {0x000c0009, 0x000a0008, 0x00090006, 0x00080006, 0x00070006, 0x00080006, + 0x00090006, 0x000a0008, 0x000b0009}, + {0x000b0009, 0x00090007, 0x00080006, 0x00050004, 0x00040004, 0x00050004, + 0x00080006, 0x00090007, 0x000b0009}, + {0x000a0009, 0x00080007, 0x00070006, 0x00040004, 0x00010004, 0x00040004, + 0x00070006, 0x00080007, 0x000b0009}, + {0x000b0009, 0x00090007, 0x00080006, 0x00050004, 0x00040004, 0x00050004, + 0x00080006, 0x00090007, 0x000b0009}, + {0x000b0009, 0x000a0008, 0x00090006, 0x00080006, 0x00070006, 0x00080006, + 0x00090006, 0x000a0008, 0x000b0009}, + {0x000c000a, 0x000b0009, 0x000a0008, 0x00090007, 0x00080007, 0x00090007, + 0x000a0007, 0x000b0008, 0x000c000a}, + {0x000d000b, 0x000c000a, 0x000c0009, 0x000b0009, 0x000a0009, 0x000a0009, + 0x000b0009, 0x000c000a, 0x000d000b}}; + +const ULONG FDKaacEnc_huff_ltab7_8[8][8] = { + {0x00010005, 0x00030004, 0x00060005, 0x00070006, 0x00080007, 0x00090008, + 0x000a0009, 0x000b000a}, + {0x00030004, 0x00040003, 0x00060004, 0x00070005, 0x00080006, 0x00080007, + 0x00090007, 0x00090008}, + {0x00060005, 0x00060004, 0x00070004, 0x00080005, 0x00080006, 0x00090007, + 0x00090007, 0x000a0008}, + {0x00070006, 0x00070005, 0x00080005, 0x00080006, 0x00090006, 0x00090007, + 0x000a0008, 0x000a0008}, + {0x00080007, 0x00080006, 0x00090006, 0x00090006, 0x000a0007, 0x000a0007, + 0x000a0008, 0x000b0009}, + {0x00090008, 0x00080007, 0x00090006, 0x00090007, 0x000a0007, 0x000a0008, + 0x000b0008, 0x000b000a}, + {0x000a0009, 0x00090007, 0x00090007, 0x000a0008, 0x000a0008, 0x000b0008, + 0x000c0009, 0x000c0009}, + {0x000b000a, 0x000a0008, 0x000a0008, 0x000a0008, 0x000b0009, 0x000b0009, + 0x000c0009, 0x000c000a}}; + +const ULONG FDKaacEnc_huff_ltab9_10[13][13] = { + {0x00010006, 0x00030005, 0x00060006, 0x00080006, 0x00090007, 0x000a0008, + 0x000a0009, 0x000b000a, 0x000b000a, 0x000c000a, 0x000c000b, 0x000d000b, + 0x000d000c}, + {0x00030005, 0x00040004, 0x00060004, 0x00070005, 0x00080006, 0x00080007, + 0x00090007, 0x000a0008, 0x000a0008, 0x000a0009, 0x000b000a, 0x000c000a, + 0x000c000b}, + {0x00060006, 0x00060004, 0x00070005, 0x00080005, 0x00080006, 0x00090006, + 0x000a0007, 0x000a0008, 0x000a0008, 0x000b0009, 0x000c0009, 0x000c000a, + 0x000c000a}, + {0x00080006, 0x00070005, 0x00080005, 0x00090005, 0x00090006, 0x000a0007, + 0x000a0007, 0x000b0008, 0x000b0008, 0x000b0009, 0x000c0009, 0x000c000a, + 0x000d000a}, + {0x00090007, 0x00080006, 0x00090006, 0x00090006, 0x000a0006, 0x000a0007, + 0x000b0007, 0x000b0008, 0x000b0008, 0x000c0009, 0x000c0009, 0x000c000a, + 0x000d000a}, + {0x000a0008, 0x00090007, 0x00090006, 0x000a0007, 0x000b0007, 0x000b0007, + 0x000b0008, 0x000c0008, 0x000b0008, 0x000c0009, 0x000c000a, 0x000d000a, + 0x000d000b}, + {0x000b0009, 0x00090007, 0x000a0007, 0x000b0007, 0x000b0007, 0x000b0008, + 0x000c0008, 0x000c0009, 0x000c0009, 0x000c0009, 0x000d000a, 0x000d000a, + 0x000d000b}, + {0x000b0009, 0x000a0008, 0x000a0008, 0x000b0008, 0x000b0008, 0x000c0008, + 0x000c0009, 0x000d0009, 0x000d0009, 0x000d000a, 0x000d000a, 0x000d000b, + 0x000d000b}, + {0x000b0009, 0x000a0008, 0x000a0008, 0x000b0008, 0x000b0008, 0x000b0008, + 0x000c0009, 0x000c0009, 0x000d000a, 0x000d000a, 0x000e000a, 0x000d000b, + 0x000e000b}, + {0x000b000a, 0x000a0009, 0x000b0009, 0x000b0009, 0x000c0009, 0x000c0009, + 0x000c0009, 0x000c000a, 0x000d000a, 0x000d000a, 0x000e000b, 0x000e000b, + 0x000e000c}, + {0x000c000a, 0x000b0009, 0x000b0009, 0x000c0009, 0x000c0009, 0x000c000a, + 0x000d000a, 0x000d000a, 0x000d000a, 0x000e000b, 0x000e000b, 0x000e000b, + 0x000f000c}, + {0x000c000b, 0x000b000a, 0x000c0009, 0x000c000a, 0x000c000a, 0x000d000a, + 0x000d000a, 0x000d000a, 0x000d000b, 0x000e000b, 0x000e000b, 0x000f000b, + 0x000f000c}, + {0x000d000b, 0x000c000a, 0x000c000a, 0x000c000a, 0x000d000a, 0x000d000a, + 0x000d000a, 0x000d000b, 0x000e000b, 0x000e000c, 0x000e000c, 0x000e000c, + 0x000f000c}}; + +const UCHAR FDKaacEnc_huff_ltab11[17][17] = { + {0x04, 0x05, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, + 0x0c, 0x0b, 0x0c, 0x0c, 0x0a}, + {0x05, 0x04, 0x05, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, + 0x0a, 0x0a, 0x0a, 0x0b, 0x08}, + {0x06, 0x05, 0x05, 0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, + 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, + {0x07, 0x06, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, + 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, + {0x08, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, + 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, + {0x08, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, + 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, + {0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, + 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, + {0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, + 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, + {0x0a, 0x09, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, + 0x0a, 0x0a, 0x0a, 0x0b, 0x08}, + {0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, + 0x0a, 0x0a, 0x0b, 0x0b, 0x08}, + {0x0b, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, + 0x0b, 0x0a, 0x0b, 0x0b, 0x08}, + {0x0b, 0x0a, 0x09, 0x09, 0x0a, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x08}, + {0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x09}, + {0x0b, 0x0a, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x09}, + {0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x09}, + {0x0c, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0c, 0x0c, 0x09}, + {0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x09, 0x05}}; + +const UCHAR FDKaacEnc_huff_ltabscf[121] = { + 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x12, 0x13, 0x12, + 0x11, 0x11, 0x10, 0x11, 0x10, 0x10, 0x10, 0x10, 0x0f, 0x0f, 0x0e, + 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, + 0x0c, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x07, + 0x06, 0x06, 0x05, 0x04, 0x03, 0x01, 0x04, 0x04, 0x05, 0x06, 0x06, + 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x10, 0x0f, + 0x10, 0x0f, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13}; + +const USHORT FDKaacEnc_huff_ctab1[3][3][3][3] = {{{{0x07f8, 0x01f1, 0x07fd}, + {0x03f5, 0x0068, 0x03f0}, + {0x07f7, 0x01ec, 0x07f5}}, + {{0x03f1, 0x0072, 0x03f4}, + {0x0074, 0x0011, 0x0076}, + {0x01eb, 0x006c, 0x03f6}}, + {{0x07fc, 0x01e1, 0x07f1}, + {0x01f0, 0x0061, 0x01f6}, + {0x07f2, 0x01ea, 0x07fb}}}, + {{{0x01f2, 0x0069, 0x01ed}, + {0x0077, 0x0017, 0x006f}, + {0x01e6, 0x0064, 0x01e5}}, + {{0x0067, 0x0015, 0x0062}, + {0x0012, 0x0000, 0x0014}, + {0x0065, 0x0016, 0x006d}}, + {{0x01e9, 0x0063, 0x01e4}, + {0x006b, 0x0013, 0x0071}, + {0x01e3, 0x0070, 0x01f3}}}, + {{{0x07fe, 0x01e7, 0x07f3}, + {0x01ef, 0x0060, 0x01ee}, + {0x07f0, 0x01e2, 0x07fa}}, + {{0x03f3, 0x006a, 0x01e8}, + {0x0075, 0x0010, 0x0073}, + {0x01f4, 0x006e, 0x03f7}}, + {{0x07f6, 0x01e0, 0x07f9}, + {0x03f2, 0x0066, 0x01f5}, + {0x07ff, 0x01f7, 0x07f4}}}}; + +const USHORT FDKaacEnc_huff_ctab2[3][3][3][3] = {{{{0x01f3, 0x006f, 0x01fd}, + {0x00eb, 0x0023, 0x00ea}, + {0x01f7, 0x00e8, 0x01fa}}, + {{0x00f2, 0x002d, 0x0070}, + {0x0020, 0x0006, 0x002b}, + {0x006e, 0x0028, 0x00e9}}, + {{0x01f9, 0x0066, 0x00f8}, + {0x00e7, 0x001b, 0x00f1}, + {0x01f4, 0x006b, 0x01f5}}}, + {{{0x00ec, 0x002a, 0x006c}, + {0x002c, 0x000a, 0x0027}, + {0x0067, 0x001a, 0x00f5}}, + {{0x0024, 0x0008, 0x001f}, + {0x0009, 0x0000, 0x0007}, + {0x001d, 0x000b, 0x0030}}, + {{0x00ef, 0x001c, 0x0064}, + {0x001e, 0x000c, 0x0029}, + {0x00f3, 0x002f, 0x00f0}}}, + {{{0x01fc, 0x0071, 0x01f2}, + {0x00f4, 0x0021, 0x00e6}, + {0x00f7, 0x0068, 0x01f8}}, + {{0x00ee, 0x0022, 0x0065}, + {0x0031, 0x0002, 0x0026}, + {0x00ed, 0x0025, 0x006a}}, + {{0x01fb, 0x0072, 0x01fe}, + {0x0069, 0x002e, 0x00f6}, + {0x01ff, 0x006d, 0x01f6}}}}; + +const USHORT FDKaacEnc_huff_ctab3[3][3][3][3] = {{{{0x0000, 0x0009, 0x00ef}, + {0x000b, 0x0019, 0x00f0}, + {0x01eb, 0x01e6, 0x03f2}}, + {{0x000a, 0x0035, 0x01ef}, + {0x0034, 0x0037, 0x01e9}, + {0x01ed, 0x01e7, 0x03f3}}, + {{0x01ee, 0x03ed, 0x1ffa}, + {0x01ec, 0x01f2, 0x07f9}, + {0x07f8, 0x03f8, 0x0ff8}}}, + {{{0x0008, 0x0038, 0x03f6}, + {0x0036, 0x0075, 0x03f1}, + {0x03eb, 0x03ec, 0x0ff4}}, + {{0x0018, 0x0076, 0x07f4}, + {0x0039, 0x0074, 0x03ef}, + {0x01f3, 0x01f4, 0x07f6}}, + {{0x01e8, 0x03ea, 0x1ffc}, + {0x00f2, 0x01f1, 0x0ffb}, + {0x03f5, 0x07f3, 0x0ffc}}}, + {{{0x00ee, 0x03f7, 0x7ffe}, + {0x01f0, 0x07f5, 0x7ffd}, + {0x1ffb, 0x3ffa, 0xffff}}, + {{0x00f1, 0x03f0, 0x3ffc}, + {0x01ea, 0x03ee, 0x3ffb}, + {0x0ff6, 0x0ffa, 0x7ffc}}, + {{0x07f2, 0x0ff5, 0xfffe}, + {0x03f4, 0x07f7, 0x7ffb}, + {0x0ff7, 0x0ff9, 0x7ffa}}}}; + +const USHORT FDKaacEnc_huff_ctab4[3][3][3][3] = {{{{0x0007, 0x0016, 0x00f6}, + {0x0018, 0x0008, 0x00ef}, + {0x01ef, 0x00f3, 0x07f8}}, + {{0x0019, 0x0017, 0x00ed}, + {0x0015, 0x0001, 0x00e2}, + {0x00f0, 0x0070, 0x03f0}}, + {{0x01ee, 0x00f1, 0x07fa}, + {0x00ee, 0x00e4, 0x03f2}, + {0x07f6, 0x03ef, 0x07fd}}}, + {{{0x0005, 0x0014, 0x00f2}, + {0x0009, 0x0004, 0x00e5}, + {0x00f4, 0x00e8, 0x03f4}}, + {{0x0006, 0x0002, 0x00e7}, + {0x0003, 0x0000, 0x006b}, + {0x00e3, 0x0069, 0x01f3}}, + {{0x00eb, 0x00e6, 0x03f6}, + {0x006e, 0x006a, 0x01f4}, + {0x03ec, 0x01f0, 0x03f9}}}, + {{{0x00f5, 0x00ec, 0x07fb}, + {0x00ea, 0x006f, 0x03f7}, + {0x07f9, 0x03f3, 0x0fff}}, + {{0x00e9, 0x006d, 0x03f8}, + {0x006c, 0x0068, 0x01f5}, + {0x03ee, 0x01f2, 0x07f4}}, + {{0x07f7, 0x03f1, 0x0ffe}, + {0x03ed, 0x01f1, 0x07f5}, + {0x07fe, 0x03f5, 0x07fc}}}}; + +const USHORT FDKaacEnc_huff_ctab5[9][9] = { + {0x1fff, 0x0ff7, 0x07f4, 0x07e8, 0x03f1, 0x07ee, 0x07f9, 0x0ff8, 0x1ffd}, + {0x0ffd, 0x07f1, 0x03e8, 0x01e8, 0x00f0, 0x01ec, 0x03ee, 0x07f2, 0x0ffa}, + {0x0ff4, 0x03ef, 0x01f2, 0x00e8, 0x0070, 0x00ec, 0x01f0, 0x03ea, 0x07f3}, + {0x07eb, 0x01eb, 0x00ea, 0x001a, 0x0008, 0x0019, 0x00ee, 0x01ef, 0x07ed}, + {0x03f0, 0x00f2, 0x0073, 0x000b, 0x0000, 0x000a, 0x0071, 0x00f3, 0x07e9}, + {0x07ef, 0x01ee, 0x00ef, 0x0018, 0x0009, 0x001b, 0x00eb, 0x01e9, 0x07ec}, + {0x07f6, 0x03eb, 0x01f3, 0x00ed, 0x0072, 0x00e9, 0x01f1, 0x03ed, 0x07f7}, + {0x0ff6, 0x07f0, 0x03e9, 0x01ed, 0x00f1, 0x01ea, 0x03ec, 0x07f8, 0x0ff9}, + {0x1ffc, 0x0ffc, 0x0ff5, 0x07ea, 0x03f3, 0x03f2, 0x07f5, 0x0ffb, 0x1ffe}}; + +const USHORT FDKaacEnc_huff_ctab6[9][9] = { + {0x07fe, 0x03fd, 0x01f1, 0x01eb, 0x01f4, 0x01ea, 0x01f0, 0x03fc, 0x07fd}, + {0x03f6, 0x01e5, 0x00ea, 0x006c, 0x0071, 0x0068, 0x00f0, 0x01e6, 0x03f7}, + {0x01f3, 0x00ef, 0x0032, 0x0027, 0x0028, 0x0026, 0x0031, 0x00eb, 0x01f7}, + {0x01e8, 0x006f, 0x002e, 0x0008, 0x0004, 0x0006, 0x0029, 0x006b, 0x01ee}, + {0x01ef, 0x0072, 0x002d, 0x0002, 0x0000, 0x0003, 0x002f, 0x0073, 0x01fa}, + {0x01e7, 0x006e, 0x002b, 0x0007, 0x0001, 0x0005, 0x002c, 0x006d, 0x01ec}, + {0x01f9, 0x00ee, 0x0030, 0x0024, 0x002a, 0x0025, 0x0033, 0x00ec, 0x01f2}, + {0x03f8, 0x01e4, 0x00ed, 0x006a, 0x0070, 0x0069, 0x0074, 0x00f1, 0x03fa}, + {0x07ff, 0x03f9, 0x01f6, 0x01ed, 0x01f8, 0x01e9, 0x01f5, 0x03fb, 0x07fc}}; + +const USHORT FDKaacEnc_huff_ctab7[8][8] = { + {0x0000, 0x0005, 0x0037, 0x0074, 0x00f2, 0x01eb, 0x03ed, 0x07f7}, + {0x0004, 0x000c, 0x0035, 0x0071, 0x00ec, 0x00ee, 0x01ee, 0x01f5}, + {0x0036, 0x0034, 0x0072, 0x00ea, 0x00f1, 0x01e9, 0x01f3, 0x03f5}, + {0x0073, 0x0070, 0x00eb, 0x00f0, 0x01f1, 0x01f0, 0x03ec, 0x03fa}, + {0x00f3, 0x00ed, 0x01e8, 0x01ef, 0x03ef, 0x03f1, 0x03f9, 0x07fb}, + {0x01ed, 0x00ef, 0x01ea, 0x01f2, 0x03f3, 0x03f8, 0x07f9, 0x07fc}, + {0x03ee, 0x01ec, 0x01f4, 0x03f4, 0x03f7, 0x07f8, 0x0ffd, 0x0ffe}, + {0x07f6, 0x03f0, 0x03f2, 0x03f6, 0x07fa, 0x07fd, 0x0ffc, 0x0fff}}; + +const USHORT FDKaacEnc_huff_ctab8[8][8] = { + {0x000e, 0x0005, 0x0010, 0x0030, 0x006f, 0x00f1, 0x01fa, 0x03fe}, + {0x0003, 0x0000, 0x0004, 0x0012, 0x002c, 0x006a, 0x0075, 0x00f8}, + {0x000f, 0x0002, 0x0006, 0x0014, 0x002e, 0x0069, 0x0072, 0x00f5}, + {0x002f, 0x0011, 0x0013, 0x002a, 0x0032, 0x006c, 0x00ec, 0x00fa}, + {0x0071, 0x002b, 0x002d, 0x0031, 0x006d, 0x0070, 0x00f2, 0x01f9}, + {0x00ef, 0x0068, 0x0033, 0x006b, 0x006e, 0x00ee, 0x00f9, 0x03fc}, + {0x01f8, 0x0074, 0x0073, 0x00ed, 0x00f0, 0x00f6, 0x01f6, 0x01fd}, + {0x03fd, 0x00f3, 0x00f4, 0x00f7, 0x01f7, 0x01fb, 0x01fc, 0x03ff}}; + +const USHORT FDKaacEnc_huff_ctab9[13][13] = { + {0x0000, 0x0005, 0x0037, 0x00e7, 0x01de, 0x03ce, 0x03d9, 0x07c8, 0x07cd, + 0x0fc8, 0x0fdd, 0x1fe4, 0x1fec}, + {0x0004, 0x000c, 0x0035, 0x0072, 0x00ea, 0x00ed, 0x01e2, 0x03d1, 0x03d3, + 0x03e0, 0x07d8, 0x0fcf, 0x0fd5}, + {0x0036, 0x0034, 0x0071, 0x00e8, 0x00ec, 0x01e1, 0x03cf, 0x03dd, 0x03db, + 0x07d0, 0x0fc7, 0x0fd4, 0x0fe4}, + {0x00e6, 0x0070, 0x00e9, 0x01dd, 0x01e3, 0x03d2, 0x03dc, 0x07cc, 0x07ca, + 0x07de, 0x0fd8, 0x0fea, 0x1fdb}, + {0x01df, 0x00eb, 0x01dc, 0x01e6, 0x03d5, 0x03de, 0x07cb, 0x07dd, 0x07dc, + 0x0fcd, 0x0fe2, 0x0fe7, 0x1fe1}, + {0x03d0, 0x01e0, 0x01e4, 0x03d6, 0x07c5, 0x07d1, 0x07db, 0x0fd2, 0x07e0, + 0x0fd9, 0x0feb, 0x1fe3, 0x1fe9}, + {0x07c4, 0x01e5, 0x03d7, 0x07c6, 0x07cf, 0x07da, 0x0fcb, 0x0fda, 0x0fe3, + 0x0fe9, 0x1fe6, 0x1ff3, 0x1ff7}, + {0x07d3, 0x03d8, 0x03e1, 0x07d4, 0x07d9, 0x0fd3, 0x0fde, 0x1fdd, 0x1fd9, + 0x1fe2, 0x1fea, 0x1ff1, 0x1ff6}, + {0x07d2, 0x03d4, 0x03da, 0x07c7, 0x07d7, 0x07e2, 0x0fce, 0x0fdb, 0x1fd8, + 0x1fee, 0x3ff0, 0x1ff4, 0x3ff2}, + {0x07e1, 0x03df, 0x07c9, 0x07d6, 0x0fca, 0x0fd0, 0x0fe5, 0x0fe6, 0x1feb, + 0x1fef, 0x3ff3, 0x3ff4, 0x3ff5}, + {0x0fe0, 0x07ce, 0x07d5, 0x0fc6, 0x0fd1, 0x0fe1, 0x1fe0, 0x1fe8, 0x1ff0, + 0x3ff1, 0x3ff8, 0x3ff6, 0x7ffc}, + {0x0fe8, 0x07df, 0x0fc9, 0x0fd7, 0x0fdc, 0x1fdc, 0x1fdf, 0x1fed, 0x1ff5, + 0x3ff9, 0x3ffb, 0x7ffd, 0x7ffe}, + {0x1fe7, 0x0fcc, 0x0fd6, 0x0fdf, 0x1fde, 0x1fda, 0x1fe5, 0x1ff2, 0x3ffa, + 0x3ff7, 0x3ffc, 0x3ffd, 0x7fff}}; + +const USHORT FDKaacEnc_huff_ctab10[13][13] = { + {0x0022, 0x0008, 0x001d, 0x0026, 0x005f, 0x00d3, 0x01cf, 0x03d0, 0x03d7, + 0x03ed, 0x07f0, 0x07f6, 0x0ffd}, + {0x0007, 0x0000, 0x0001, 0x0009, 0x0020, 0x0054, 0x0060, 0x00d5, 0x00dc, + 0x01d4, 0x03cd, 0x03de, 0x07e7}, + {0x001c, 0x0002, 0x0006, 0x000c, 0x001e, 0x0028, 0x005b, 0x00cd, 0x00d9, + 0x01ce, 0x01dc, 0x03d9, 0x03f1}, + {0x0025, 0x000b, 0x000a, 0x000d, 0x0024, 0x0057, 0x0061, 0x00cc, 0x00dd, + 0x01cc, 0x01de, 0x03d3, 0x03e7}, + {0x005d, 0x0021, 0x001f, 0x0023, 0x0027, 0x0059, 0x0064, 0x00d8, 0x00df, + 0x01d2, 0x01e2, 0x03dd, 0x03ee}, + {0x00d1, 0x0055, 0x0029, 0x0056, 0x0058, 0x0062, 0x00ce, 0x00e0, 0x00e2, + 0x01da, 0x03d4, 0x03e3, 0x07eb}, + {0x01c9, 0x005e, 0x005a, 0x005c, 0x0063, 0x00ca, 0x00da, 0x01c7, 0x01ca, + 0x01e0, 0x03db, 0x03e8, 0x07ec}, + {0x01e3, 0x00d2, 0x00cb, 0x00d0, 0x00d7, 0x00db, 0x01c6, 0x01d5, 0x01d8, + 0x03ca, 0x03da, 0x07ea, 0x07f1}, + {0x01e1, 0x00d4, 0x00cf, 0x00d6, 0x00de, 0x00e1, 0x01d0, 0x01d6, 0x03d1, + 0x03d5, 0x03f2, 0x07ee, 0x07fb}, + {0x03e9, 0x01cd, 0x01c8, 0x01cb, 0x01d1, 0x01d7, 0x01df, 0x03cf, 0x03e0, + 0x03ef, 0x07e6, 0x07f8, 0x0ffa}, + {0x03eb, 0x01dd, 0x01d3, 0x01d9, 0x01db, 0x03d2, 0x03cc, 0x03dc, 0x03ea, + 0x07ed, 0x07f3, 0x07f9, 0x0ff9}, + {0x07f2, 0x03ce, 0x01e4, 0x03cb, 0x03d8, 0x03d6, 0x03e2, 0x03e5, 0x07e8, + 0x07f4, 0x07f5, 0x07f7, 0x0ffb}, + {0x07fa, 0x03ec, 0x03df, 0x03e1, 0x03e4, 0x03e6, 0x03f0, 0x07e9, 0x07ef, + 0x0ff8, 0x0ffe, 0x0ffc, 0x0fff}}; + +const USHORT FDKaacEnc_huff_ctab11[21][17] = { + {0x0000, 0x0006, 0x0019, 0x003d, 0x009c, 0x00c6, 0x01a7, 0x0390, 0x03c2, + 0x03df, 0x07e6, 0x07f3, 0x0ffb, 0x07ec, 0x0ffa, 0x0ffe, 0x038e}, + {0x0005, 0x0001, 0x0008, 0x0014, 0x0037, 0x0042, 0x0092, 0x00af, 0x0191, + 0x01a5, 0x01b5, 0x039e, 0x03c0, 0x03a2, 0x03cd, 0x07d6, 0x00ae}, + {0x0017, 0x0007, 0x0009, 0x0018, 0x0039, 0x0040, 0x008e, 0x00a3, 0x00b8, + 0x0199, 0x01ac, 0x01c1, 0x03b1, 0x0396, 0x03be, 0x03ca, 0x009d}, + {0x003c, 0x0015, 0x0016, 0x001a, 0x003b, 0x0044, 0x0091, 0x00a5, 0x00be, + 0x0196, 0x01ae, 0x01b9, 0x03a1, 0x0391, 0x03a5, 0x03d5, 0x0094}, + {0x009a, 0x0036, 0x0038, 0x003a, 0x0041, 0x008c, 0x009b, 0x00b0, 0x00c3, + 0x019e, 0x01ab, 0x01bc, 0x039f, 0x038f, 0x03a9, 0x03cf, 0x0093}, + {0x00bf, 0x003e, 0x003f, 0x0043, 0x0045, 0x009e, 0x00a7, 0x00b9, 0x0194, + 0x01a2, 0x01ba, 0x01c3, 0x03a6, 0x03a7, 0x03bb, 0x03d4, 0x009f}, + {0x01a0, 0x008f, 0x008d, 0x0090, 0x0098, 0x00a6, 0x00b6, 0x00c4, 0x019f, + 0x01af, 0x01bf, 0x0399, 0x03bf, 0x03b4, 0x03c9, 0x03e7, 0x00a8}, + {0x01b6, 0x00ab, 0x00a4, 0x00aa, 0x00b2, 0x00c2, 0x00c5, 0x0198, 0x01a4, + 0x01b8, 0x038c, 0x03a4, 0x03c4, 0x03c6, 0x03dd, 0x03e8, 0x00ad}, + {0x03af, 0x0192, 0x00bd, 0x00bc, 0x018e, 0x0197, 0x019a, 0x01a3, 0x01b1, + 0x038d, 0x0398, 0x03b7, 0x03d3, 0x03d1, 0x03db, 0x07dd, 0x00b4}, + {0x03de, 0x01a9, 0x019b, 0x019c, 0x01a1, 0x01aa, 0x01ad, 0x01b3, 0x038b, + 0x03b2, 0x03b8, 0x03ce, 0x03e1, 0x03e0, 0x07d2, 0x07e5, 0x00b7}, + {0x07e3, 0x01bb, 0x01a8, 0x01a6, 0x01b0, 0x01b2, 0x01b7, 0x039b, 0x039a, + 0x03ba, 0x03b5, 0x03d6, 0x07d7, 0x03e4, 0x07d8, 0x07ea, 0x00ba}, + {0x07e8, 0x03a0, 0x01bd, 0x01b4, 0x038a, 0x01c4, 0x0392, 0x03aa, 0x03b0, + 0x03bc, 0x03d7, 0x07d4, 0x07dc, 0x07db, 0x07d5, 0x07f0, 0x00c1}, + {0x07fb, 0x03c8, 0x03a3, 0x0395, 0x039d, 0x03ac, 0x03ae, 0x03c5, 0x03d8, + 0x03e2, 0x03e6, 0x07e4, 0x07e7, 0x07e0, 0x07e9, 0x07f7, 0x0190}, + {0x07f2, 0x0393, 0x01be, 0x01c0, 0x0394, 0x0397, 0x03ad, 0x03c3, 0x03c1, + 0x03d2, 0x07da, 0x07d9, 0x07df, 0x07eb, 0x07f4, 0x07fa, 0x0195}, + {0x07f8, 0x03bd, 0x039c, 0x03ab, 0x03a8, 0x03b3, 0x03b9, 0x03d0, 0x03e3, + 0x03e5, 0x07e2, 0x07de, 0x07ed, 0x07f1, 0x07f9, 0x07fc, 0x0193}, + {0x0ffd, 0x03dc, 0x03b6, 0x03c7, 0x03cc, 0x03cb, 0x03d9, 0x03da, 0x07d3, + 0x07e1, 0x07ee, 0x07ef, 0x07f5, 0x07f6, 0x0ffc, 0x0fff, 0x019d}, + {0x01c2, 0x00b5, 0x00a1, 0x0096, 0x0097, 0x0095, 0x0099, 0x00a0, 0x00a2, + 0x00ac, 0x00a9, 0x00b1, 0x00b3, 0x00bb, 0x00c0, 0x018f, 0x0004}, + {0x0018, 0x002e, 0x0000, 0x005a, 0x00a5, 0x00f8, 0x00b7, 0x0094, 0x00f9, + 0x004d, 0x0021, 0x002b, 0x004f, 0x007b, 0x00bc, 0x0046, 0x0015}, + {0x0042, 0x0037, 0x0078, 0x000d, 0x0068, 0x005f, 0x000d, 0x005e, 0x005a, + 0x00be, 0x0063, 0x007e, 0x001f, 0x0092, 0x001a, 0x00ab, 0x0032}, + {0x00e6, 0x0037, 0x0000, 0x0058, 0x000b, 0x005a, 0x00e1, 0x005d, 0x0029, + 0x0017, 0x007e, 0x0069, 0x00aa, 0x0054, 0x0029, 0x0032, 0x0041}, + {0x0046, 0x00ea, 0x0034, 0x00ea, 0x0011, 0x001b, 0x00a9, 0x0094, 0x00e2, + 0x0031, 0x00d0, 0x00e5, 0x0007, 0x0070, 0x0069, 0x003e, 0x0021}}; + +const ULONG FDKaacEnc_huff_ctabscf[121] = { + 0x0003ffe8, 0x0003ffe6, 0x0003ffe7, 0x0003ffe5, 0x0007fff5, 0x0007fff1, + 0x0007ffed, 0x0007fff6, 0x0007ffee, 0x0007ffef, 0x0007fff0, 0x0007fffc, + 0x0007fffd, 0x0007ffff, 0x0007fffe, 0x0007fff7, 0x0007fff8, 0x0007fffb, + 0x0007fff9, 0x0003ffe4, 0x0007fffa, 0x0003ffe3, 0x0001ffef, 0x0001fff0, + 0x0000fff5, 0x0001ffee, 0x0000fff2, 0x0000fff3, 0x0000fff4, 0x0000fff1, + 0x00007ff6, 0x00007ff7, 0x00003ff9, 0x00003ff5, 0x00003ff7, 0x00003ff3, + 0x00003ff6, 0x00003ff2, 0x00001ff7, 0x00001ff5, 0x00000ff9, 0x00000ff7, + 0x00000ff6, 0x000007f9, 0x00000ff4, 0x000007f8, 0x000003f9, 0x000003f7, + 0x000003f5, 0x000001f8, 0x000001f7, 0x000000fa, 0x000000f8, 0x000000f6, + 0x00000079, 0x0000003a, 0x00000038, 0x0000001a, 0x0000000b, 0x00000004, + 0x00000000, 0x0000000a, 0x0000000c, 0x0000001b, 0x00000039, 0x0000003b, + 0x00000078, 0x0000007a, 0x000000f7, 0x000000f9, 0x000001f6, 0x000001f9, + 0x000003f4, 0x000003f6, 0x000003f8, 0x000007f5, 0x000007f4, 0x000007f6, + 0x000007f7, 0x00000ff5, 0x00000ff8, 0x00001ff4, 0x00001ff6, 0x00001ff8, + 0x00003ff8, 0x00003ff4, 0x0000fff0, 0x00007ff4, 0x0000fff6, 0x00007ff5, + 0x0003ffe2, 0x0007ffd9, 0x0007ffda, 0x0007ffdb, 0x0007ffdc, 0x0007ffdd, + 0x0007ffde, 0x0007ffd8, 0x0007ffd2, 0x0007ffd3, 0x0007ffd4, 0x0007ffd5, + 0x0007ffd6, 0x0007fff2, 0x0007ffdf, 0x0007ffe7, 0x0007ffe8, 0x0007ffe9, + 0x0007ffea, 0x0007ffeb, 0x0007ffe6, 0x0007ffe0, 0x0007ffe1, 0x0007ffe2, + 0x0007ffe3, 0x0007ffe4, 0x0007ffe5, 0x0007ffd7, 0x0007ffec, 0x0007fff4, + 0x0007fff3}; /* table of (0.50000...1.00000) ^0.75 */ -const FIXP_QTD FDKaacEnc_mTab_3_4[MANT_SIZE] = -{ - QTC(0x4c1bf829), QTC(0x4c3880de), QTC(0x4c550603), QTC(0x4c71879c), QTC(0x4c8e05aa), QTC(0x4caa8030), QTC(0x4cc6f72f), QTC(0x4ce36aab), - QTC(0x4cffdaa4), QTC(0x4d1c471d), QTC(0x4d38b019), QTC(0x4d55159a), QTC(0x4d7177a1), QTC(0x4d8dd631), QTC(0x4daa314b), QTC(0x4dc688f3), - QTC(0x4de2dd2a), QTC(0x4dff2df2), QTC(0x4e1b7b4d), QTC(0x4e37c53d), QTC(0x4e540bc5), QTC(0x4e704ee6), QTC(0x4e8c8ea3), QTC(0x4ea8cafd), - QTC(0x4ec503f7), QTC(0x4ee13992), QTC(0x4efd6bd0), QTC(0x4f199ab4), QTC(0x4f35c640), QTC(0x4f51ee75), QTC(0x4f6e1356), QTC(0x4f8a34e4), - QTC(0x4fa65321), QTC(0x4fc26e10), QTC(0x4fde85b2), QTC(0x4ffa9a0a), QTC(0x5016ab18), QTC(0x5032b8e0), QTC(0x504ec362), QTC(0x506acaa1), - QTC(0x5086cea0), QTC(0x50a2cf5e), QTC(0x50becce0), QTC(0x50dac725), QTC(0x50f6be31), QTC(0x5112b205), QTC(0x512ea2a3), QTC(0x514a900d), - QTC(0x51667a45), QTC(0x5182614c), QTC(0x519e4524), QTC(0x51ba25cf), QTC(0x51d60350), QTC(0x51f1dda7), QTC(0x520db4d6), QTC(0x522988e0), - QTC(0x524559c6), QTC(0x52612789), QTC(0x527cf22d), QTC(0x5298b9b1), QTC(0x52b47e19), QTC(0x52d03f65), QTC(0x52ebfd98), QTC(0x5307b8b4), - QTC(0x532370b9), QTC(0x533f25aa), QTC(0x535ad789), QTC(0x53768656), QTC(0x53923215), QTC(0x53addac6), QTC(0x53c9806b), QTC(0x53e52306), - QTC(0x5400c298), QTC(0x541c5f24), QTC(0x5437f8ab), QTC(0x54538f2e), QTC(0x546f22af), QTC(0x548ab330), QTC(0x54a640b3), QTC(0x54c1cb38), - QTC(0x54dd52c2), QTC(0x54f8d753), QTC(0x551458eb), QTC(0x552fd78d), QTC(0x554b5339), QTC(0x5566cbf3), QTC(0x558241bb), QTC(0x559db492), - QTC(0x55b9247b), QTC(0x55d49177), QTC(0x55effb87), QTC(0x560b62ad), QTC(0x5626c6eb), QTC(0x56422842), QTC(0x565d86b4), QTC(0x5678e242), - QTC(0x56943aee), QTC(0x56af90b9), QTC(0x56cae3a4), QTC(0x56e633b2), QTC(0x570180e4), QTC(0x571ccb3b), QTC(0x573812b8), QTC(0x5753575e), - QTC(0x576e992e), QTC(0x5789d829), QTC(0x57a51450), QTC(0x57c04da6), QTC(0x57db842b), QTC(0x57f6b7e1), QTC(0x5811e8c9), QTC(0x582d16e6), - QTC(0x58484238), QTC(0x58636ac0), QTC(0x587e9081), QTC(0x5899b37c), QTC(0x58b4d3b1), QTC(0x58cff123), QTC(0x58eb0bd3), QTC(0x590623c2), - QTC(0x592138f2), QTC(0x593c4b63), QTC(0x59575b19), QTC(0x59726812), QTC(0x598d7253), QTC(0x59a879da), QTC(0x59c37eab), QTC(0x59de80c6), - QTC(0x59f9802d), QTC(0x5a147ce0), QTC(0x5a2f76e2), QTC(0x5a4a6e34), QTC(0x5a6562d6), QTC(0x5a8054cb), QTC(0x5a9b4414), QTC(0x5ab630b2), - QTC(0x5ad11aa6), QTC(0x5aec01f1), QTC(0x5b06e696), QTC(0x5b21c895), QTC(0x5b3ca7ef), QTC(0x5b5784a6), QTC(0x5b725ebc), QTC(0x5b8d3631), - QTC(0x5ba80b06), QTC(0x5bc2dd3e), QTC(0x5bddacd9), QTC(0x5bf879d8), QTC(0x5c13443d), QTC(0x5c2e0c09), QTC(0x5c48d13e), QTC(0x5c6393dc), - QTC(0x5c7e53e5), QTC(0x5c99115a), QTC(0x5cb3cc3c), QTC(0x5cce848d), QTC(0x5ce93a4e), QTC(0x5d03ed80), QTC(0x5d1e9e24), QTC(0x5d394c3b), - QTC(0x5d53f7c7), QTC(0x5d6ea0c9), QTC(0x5d894742), QTC(0x5da3eb33), QTC(0x5dbe8c9e), QTC(0x5dd92b84), QTC(0x5df3c7e5), QTC(0x5e0e61c3), - QTC(0x5e28f920), QTC(0x5e438dfc), QTC(0x5e5e2059), QTC(0x5e78b037), QTC(0x5e933d99), QTC(0x5eadc87e), QTC(0x5ec850e9), QTC(0x5ee2d6da), - QTC(0x5efd5a53), QTC(0x5f17db54), QTC(0x5f3259e0), QTC(0x5f4cd5f6), QTC(0x5f674f99), QTC(0x5f81c6c8), QTC(0x5f9c3b87), QTC(0x5fb6add4), - QTC(0x5fd11db3), QTC(0x5feb8b23), QTC(0x6005f626), QTC(0x60205ebd), QTC(0x603ac4e9), QTC(0x605528ac), QTC(0x606f8a05), QTC(0x6089e8f7), - QTC(0x60a44583), QTC(0x60be9fa9), QTC(0x60d8f76b), QTC(0x60f34cca), QTC(0x610d9fc7), QTC(0x6127f062), QTC(0x61423e9e), QTC(0x615c8a7a), - QTC(0x6176d3f9), QTC(0x61911b1b), QTC(0x61ab5fe1), QTC(0x61c5a24d), QTC(0x61dfe25f), QTC(0x61fa2018), QTC(0x62145b7a), QTC(0x622e9485), - QTC(0x6248cb3b), QTC(0x6262ff9d), QTC(0x627d31ab), QTC(0x62976167), QTC(0x62b18ed1), QTC(0x62cbb9eb), QTC(0x62e5e2b6), QTC(0x63000933), - QTC(0x631a2d62), QTC(0x63344f45), QTC(0x634e6edd), QTC(0x63688c2b), QTC(0x6382a730), QTC(0x639cbfec), QTC(0x63b6d661), QTC(0x63d0ea90), - QTC(0x63eafc7a), QTC(0x64050c1f), QTC(0x641f1982), QTC(0x643924a2), QTC(0x64532d80), QTC(0x646d341f), QTC(0x6487387e), QTC(0x64a13a9e), - QTC(0x64bb3a81), QTC(0x64d53828), QTC(0x64ef3393), QTC(0x65092cc4), QTC(0x652323bb), QTC(0x653d1879), QTC(0x65570b00), QTC(0x6570fb50), - QTC(0x658ae96b), QTC(0x65a4d550), QTC(0x65bebf01), QTC(0x65d8a680), QTC(0x65f28bcc), QTC(0x660c6ee8), QTC(0x66264fd3), QTC(0x66402e8f), - QTC(0x665a0b1c), QTC(0x6673e57d), QTC(0x668dbdb0), QTC(0x66a793b8), QTC(0x66c16795), QTC(0x66db3949), QTC(0x66f508d4), QTC(0x670ed636), - QTC(0x6728a172), QTC(0x67426a87), QTC(0x675c3177), QTC(0x6775f643), QTC(0x678fb8eb), QTC(0x67a97971), QTC(0x67c337d5), QTC(0x67dcf418), - QTC(0x67f6ae3b), QTC(0x6810663f), QTC(0x682a1c25), QTC(0x6843cfed), QTC(0x685d8199), QTC(0x68773129), QTC(0x6890de9f), QTC(0x68aa89fa), - QTC(0x68c4333d), QTC(0x68ddda67), QTC(0x68f77f7a), QTC(0x69112277), QTC(0x692ac35e), QTC(0x69446230), QTC(0x695dfeee), QTC(0x6977999a), - QTC(0x69913232), QTC(0x69aac8ba), QTC(0x69c45d31), QTC(0x69ddef98), QTC(0x69f77ff0), QTC(0x6a110e3a), QTC(0x6a2a9a77), QTC(0x6a4424a8), - QTC(0x6a5daccc), QTC(0x6a7732e6), QTC(0x6a90b6f6), QTC(0x6aaa38fd), QTC(0x6ac3b8fb), QTC(0x6add36f2), QTC(0x6af6b2e2), QTC(0x6b102ccd), - QTC(0x6b29a4b2), QTC(0x6b431a92), QTC(0x6b5c8e6f), QTC(0x6b76004a), QTC(0x6b8f7022), QTC(0x6ba8ddf9), QTC(0x6bc249d0), QTC(0x6bdbb3a7), - QTC(0x6bf51b80), QTC(0x6c0e815a), QTC(0x6c27e537), QTC(0x6c414718), QTC(0x6c5aa6fd), QTC(0x6c7404e7), QTC(0x6c8d60d7), QTC(0x6ca6bace), - QTC(0x6cc012cc), QTC(0x6cd968d2), QTC(0x6cf2bce1), QTC(0x6d0c0ef9), QTC(0x6d255f1d), QTC(0x6d3ead4b), QTC(0x6d57f985), QTC(0x6d7143cc), - QTC(0x6d8a8c21), QTC(0x6da3d283), QTC(0x6dbd16f5), QTC(0x6dd65976), QTC(0x6def9a08), QTC(0x6e08d8ab), QTC(0x6e221560), QTC(0x6e3b5027), - QTC(0x6e548902), QTC(0x6e6dbff1), QTC(0x6e86f4f5), QTC(0x6ea0280e), QTC(0x6eb9593e), QTC(0x6ed28885), QTC(0x6eebb5e3), QTC(0x6f04e15a), - QTC(0x6f1e0aea), QTC(0x6f373294), QTC(0x6f505859), QTC(0x6f697c39), QTC(0x6f829e35), QTC(0x6f9bbe4e), QTC(0x6fb4dc85), QTC(0x6fcdf8d9), - QTC(0x6fe7134d), QTC(0x70002be0), QTC(0x70194293), QTC(0x70325767), QTC(0x704b6a5d), QTC(0x70647b76), QTC(0x707d8ab1), QTC(0x70969811), - QTC(0x70afa394), QTC(0x70c8ad3d), QTC(0x70e1b50c), QTC(0x70fabb01), QTC(0x7113bf1d), QTC(0x712cc161), QTC(0x7145c1ce), QTC(0x715ec064), - QTC(0x7177bd24), QTC(0x7190b80f), QTC(0x71a9b124), QTC(0x71c2a866), QTC(0x71db9dd4), QTC(0x71f49170), QTC(0x720d8339), QTC(0x72267331), - QTC(0x723f6159), QTC(0x72584db0), QTC(0x72713838), QTC(0x728a20f1), QTC(0x72a307db), QTC(0x72bbecf9), QTC(0x72d4d049), QTC(0x72edb1ce), - QTC(0x73069187), QTC(0x731f6f75), QTC(0x73384b98), QTC(0x735125f3), QTC(0x7369fe84), QTC(0x7382d54d), QTC(0x739baa4e), QTC(0x73b47d89), - QTC(0x73cd4efd), QTC(0x73e61eab), QTC(0x73feec94), QTC(0x7417b8b8), QTC(0x74308319), QTC(0x74494bb6), QTC(0x74621291), QTC(0x747ad7aa), - QTC(0x74939b02), QTC(0x74ac5c98), QTC(0x74c51c6f), QTC(0x74ddda86), QTC(0x74f696de), QTC(0x750f5178), QTC(0x75280a54), QTC(0x7540c174), - QTC(0x755976d7), QTC(0x75722a7e), QTC(0x758adc69), QTC(0x75a38c9b), QTC(0x75bc3b12), QTC(0x75d4e7cf), QTC(0x75ed92d4), QTC(0x76063c21), - QTC(0x761ee3b6), QTC(0x76378994), QTC(0x76502dbc), QTC(0x7668d02e), QTC(0x768170eb), QTC(0x769a0ff3), QTC(0x76b2ad47), QTC(0x76cb48e7), - QTC(0x76e3e2d5), QTC(0x76fc7b10), QTC(0x7715119a), QTC(0x772da673), QTC(0x7746399b), QTC(0x775ecb13), QTC(0x77775adc), QTC(0x778fe8f6), - QTC(0x77a87561), QTC(0x77c1001f), QTC(0x77d98930), QTC(0x77f21095), QTC(0x780a964d), QTC(0x78231a5b), QTC(0x783b9cbd), QTC(0x78541d75), - QTC(0x786c9c84), QTC(0x788519e9), QTC(0x789d95a6), QTC(0x78b60fbb), QTC(0x78ce8828), QTC(0x78e6feef), QTC(0x78ff740f), QTC(0x7917e78a), - QTC(0x7930595f), QTC(0x7948c990), QTC(0x7961381d), QTC(0x7979a506), QTC(0x7992104c), QTC(0x79aa79f0), QTC(0x79c2e1f1), QTC(0x79db4852), - QTC(0x79f3ad11), QTC(0x7a0c1031), QTC(0x7a2471b0), QTC(0x7a3cd191), QTC(0x7a552fd3), QTC(0x7a6d8c76), QTC(0x7a85e77d), QTC(0x7a9e40e6), - QTC(0x7ab698b2), QTC(0x7aceeee3), QTC(0x7ae74378), QTC(0x7aff9673), QTC(0x7b17e7d2), QTC(0x7b303799), QTC(0x7b4885c5), QTC(0x7b60d259), - QTC(0x7b791d55), QTC(0x7b9166b9), QTC(0x7ba9ae86), QTC(0x7bc1f4bc), QTC(0x7bda395c), QTC(0x7bf27c66), QTC(0x7c0abddb), QTC(0x7c22fdbb), - QTC(0x7c3b3c07), QTC(0x7c5378c0), QTC(0x7c6bb3e5), QTC(0x7c83ed78), QTC(0x7c9c2579), QTC(0x7cb45be9), QTC(0x7ccc90c7), QTC(0x7ce4c414), - QTC(0x7cfcf5d2), QTC(0x7d152600), QTC(0x7d2d549f), QTC(0x7d4581b0), QTC(0x7d5dad32), QTC(0x7d75d727), QTC(0x7d8dff8f), QTC(0x7da6266a), - QTC(0x7dbe4bba), QTC(0x7dd66f7d), QTC(0x7dee91b6), QTC(0x7e06b264), QTC(0x7e1ed188), QTC(0x7e36ef22), QTC(0x7e4f0b34), QTC(0x7e6725bd), - QTC(0x7e7f3ebd), QTC(0x7e975636), QTC(0x7eaf6c28), QTC(0x7ec78093), QTC(0x7edf9378), QTC(0x7ef7a4d7), QTC(0x7f0fb4b1), QTC(0x7f27c307), - QTC(0x7f3fcfd8), QTC(0x7f57db25), QTC(0x7f6fe4ef), QTC(0x7f87ed36), QTC(0x7f9ff3fb), QTC(0x7fb7f93e), QTC(0x7fcffcff), QTC(0x7fe7ff40) -}; +const FIXP_QTD FDKaacEnc_mTab_3_4[MANT_SIZE] = { + QTC(0x4c1bf829), QTC(0x4c3880de), QTC(0x4c550603), QTC(0x4c71879c), + QTC(0x4c8e05aa), QTC(0x4caa8030), QTC(0x4cc6f72f), QTC(0x4ce36aab), + QTC(0x4cffdaa4), QTC(0x4d1c471d), QTC(0x4d38b019), QTC(0x4d55159a), + QTC(0x4d7177a1), QTC(0x4d8dd631), QTC(0x4daa314b), QTC(0x4dc688f3), + QTC(0x4de2dd2a), QTC(0x4dff2df2), QTC(0x4e1b7b4d), QTC(0x4e37c53d), + QTC(0x4e540bc5), QTC(0x4e704ee6), QTC(0x4e8c8ea3), QTC(0x4ea8cafd), + QTC(0x4ec503f7), QTC(0x4ee13992), QTC(0x4efd6bd0), QTC(0x4f199ab4), + QTC(0x4f35c640), QTC(0x4f51ee75), QTC(0x4f6e1356), QTC(0x4f8a34e4), + QTC(0x4fa65321), QTC(0x4fc26e10), QTC(0x4fde85b2), QTC(0x4ffa9a0a), + QTC(0x5016ab18), QTC(0x5032b8e0), QTC(0x504ec362), QTC(0x506acaa1), + QTC(0x5086cea0), QTC(0x50a2cf5e), QTC(0x50becce0), QTC(0x50dac725), + QTC(0x50f6be31), QTC(0x5112b205), QTC(0x512ea2a3), QTC(0x514a900d), + QTC(0x51667a45), QTC(0x5182614c), QTC(0x519e4524), QTC(0x51ba25cf), + QTC(0x51d60350), QTC(0x51f1dda7), QTC(0x520db4d6), QTC(0x522988e0), + QTC(0x524559c6), QTC(0x52612789), QTC(0x527cf22d), QTC(0x5298b9b1), + QTC(0x52b47e19), QTC(0x52d03f65), QTC(0x52ebfd98), QTC(0x5307b8b4), + QTC(0x532370b9), QTC(0x533f25aa), QTC(0x535ad789), QTC(0x53768656), + QTC(0x53923215), QTC(0x53addac6), QTC(0x53c9806b), QTC(0x53e52306), + QTC(0x5400c298), QTC(0x541c5f24), QTC(0x5437f8ab), QTC(0x54538f2e), + QTC(0x546f22af), QTC(0x548ab330), QTC(0x54a640b3), QTC(0x54c1cb38), + QTC(0x54dd52c2), QTC(0x54f8d753), QTC(0x551458eb), QTC(0x552fd78d), + QTC(0x554b5339), QTC(0x5566cbf3), QTC(0x558241bb), QTC(0x559db492), + QTC(0x55b9247b), QTC(0x55d49177), QTC(0x55effb87), QTC(0x560b62ad), + QTC(0x5626c6eb), QTC(0x56422842), QTC(0x565d86b4), QTC(0x5678e242), + QTC(0x56943aee), QTC(0x56af90b9), QTC(0x56cae3a4), QTC(0x56e633b2), + QTC(0x570180e4), QTC(0x571ccb3b), QTC(0x573812b8), QTC(0x5753575e), + QTC(0x576e992e), QTC(0x5789d829), QTC(0x57a51450), QTC(0x57c04da6), + QTC(0x57db842b), QTC(0x57f6b7e1), QTC(0x5811e8c9), QTC(0x582d16e6), + QTC(0x58484238), QTC(0x58636ac0), QTC(0x587e9081), QTC(0x5899b37c), + QTC(0x58b4d3b1), QTC(0x58cff123), QTC(0x58eb0bd3), QTC(0x590623c2), + QTC(0x592138f2), QTC(0x593c4b63), QTC(0x59575b19), QTC(0x59726812), + QTC(0x598d7253), QTC(0x59a879da), QTC(0x59c37eab), QTC(0x59de80c6), + QTC(0x59f9802d), QTC(0x5a147ce0), QTC(0x5a2f76e2), QTC(0x5a4a6e34), + QTC(0x5a6562d6), QTC(0x5a8054cb), QTC(0x5a9b4414), QTC(0x5ab630b2), + QTC(0x5ad11aa6), QTC(0x5aec01f1), QTC(0x5b06e696), QTC(0x5b21c895), + QTC(0x5b3ca7ef), QTC(0x5b5784a6), QTC(0x5b725ebc), QTC(0x5b8d3631), + QTC(0x5ba80b06), QTC(0x5bc2dd3e), QTC(0x5bddacd9), QTC(0x5bf879d8), + QTC(0x5c13443d), QTC(0x5c2e0c09), QTC(0x5c48d13e), QTC(0x5c6393dc), + QTC(0x5c7e53e5), QTC(0x5c99115a), QTC(0x5cb3cc3c), QTC(0x5cce848d), + QTC(0x5ce93a4e), QTC(0x5d03ed80), QTC(0x5d1e9e24), QTC(0x5d394c3b), + QTC(0x5d53f7c7), QTC(0x5d6ea0c9), QTC(0x5d894742), QTC(0x5da3eb33), + QTC(0x5dbe8c9e), QTC(0x5dd92b84), QTC(0x5df3c7e5), QTC(0x5e0e61c3), + QTC(0x5e28f920), QTC(0x5e438dfc), QTC(0x5e5e2059), QTC(0x5e78b037), + QTC(0x5e933d99), QTC(0x5eadc87e), QTC(0x5ec850e9), QTC(0x5ee2d6da), + QTC(0x5efd5a53), QTC(0x5f17db54), QTC(0x5f3259e0), QTC(0x5f4cd5f6), + QTC(0x5f674f99), QTC(0x5f81c6c8), QTC(0x5f9c3b87), QTC(0x5fb6add4), + QTC(0x5fd11db3), QTC(0x5feb8b23), QTC(0x6005f626), QTC(0x60205ebd), + QTC(0x603ac4e9), QTC(0x605528ac), QTC(0x606f8a05), QTC(0x6089e8f7), + QTC(0x60a44583), QTC(0x60be9fa9), QTC(0x60d8f76b), QTC(0x60f34cca), + QTC(0x610d9fc7), QTC(0x6127f062), QTC(0x61423e9e), QTC(0x615c8a7a), + QTC(0x6176d3f9), QTC(0x61911b1b), QTC(0x61ab5fe1), QTC(0x61c5a24d), + QTC(0x61dfe25f), QTC(0x61fa2018), QTC(0x62145b7a), QTC(0x622e9485), + QTC(0x6248cb3b), QTC(0x6262ff9d), QTC(0x627d31ab), QTC(0x62976167), + QTC(0x62b18ed1), QTC(0x62cbb9eb), QTC(0x62e5e2b6), QTC(0x63000933), + QTC(0x631a2d62), QTC(0x63344f45), QTC(0x634e6edd), QTC(0x63688c2b), + QTC(0x6382a730), QTC(0x639cbfec), QTC(0x63b6d661), QTC(0x63d0ea90), + QTC(0x63eafc7a), QTC(0x64050c1f), QTC(0x641f1982), QTC(0x643924a2), + QTC(0x64532d80), QTC(0x646d341f), QTC(0x6487387e), QTC(0x64a13a9e), + QTC(0x64bb3a81), QTC(0x64d53828), QTC(0x64ef3393), QTC(0x65092cc4), + QTC(0x652323bb), QTC(0x653d1879), QTC(0x65570b00), QTC(0x6570fb50), + QTC(0x658ae96b), QTC(0x65a4d550), QTC(0x65bebf01), QTC(0x65d8a680), + QTC(0x65f28bcc), QTC(0x660c6ee8), QTC(0x66264fd3), QTC(0x66402e8f), + QTC(0x665a0b1c), QTC(0x6673e57d), QTC(0x668dbdb0), QTC(0x66a793b8), + QTC(0x66c16795), QTC(0x66db3949), QTC(0x66f508d4), QTC(0x670ed636), + QTC(0x6728a172), QTC(0x67426a87), QTC(0x675c3177), QTC(0x6775f643), + QTC(0x678fb8eb), QTC(0x67a97971), QTC(0x67c337d5), QTC(0x67dcf418), + QTC(0x67f6ae3b), QTC(0x6810663f), QTC(0x682a1c25), QTC(0x6843cfed), + QTC(0x685d8199), QTC(0x68773129), QTC(0x6890de9f), QTC(0x68aa89fa), + QTC(0x68c4333d), QTC(0x68ddda67), QTC(0x68f77f7a), QTC(0x69112277), + QTC(0x692ac35e), QTC(0x69446230), QTC(0x695dfeee), QTC(0x6977999a), + QTC(0x69913232), QTC(0x69aac8ba), QTC(0x69c45d31), QTC(0x69ddef98), + QTC(0x69f77ff0), QTC(0x6a110e3a), QTC(0x6a2a9a77), QTC(0x6a4424a8), + QTC(0x6a5daccc), QTC(0x6a7732e6), QTC(0x6a90b6f6), QTC(0x6aaa38fd), + QTC(0x6ac3b8fb), QTC(0x6add36f2), QTC(0x6af6b2e2), QTC(0x6b102ccd), + QTC(0x6b29a4b2), QTC(0x6b431a92), QTC(0x6b5c8e6f), QTC(0x6b76004a), + QTC(0x6b8f7022), QTC(0x6ba8ddf9), QTC(0x6bc249d0), QTC(0x6bdbb3a7), + QTC(0x6bf51b80), QTC(0x6c0e815a), QTC(0x6c27e537), QTC(0x6c414718), + QTC(0x6c5aa6fd), QTC(0x6c7404e7), QTC(0x6c8d60d7), QTC(0x6ca6bace), + QTC(0x6cc012cc), QTC(0x6cd968d2), QTC(0x6cf2bce1), QTC(0x6d0c0ef9), + QTC(0x6d255f1d), QTC(0x6d3ead4b), QTC(0x6d57f985), QTC(0x6d7143cc), + QTC(0x6d8a8c21), QTC(0x6da3d283), QTC(0x6dbd16f5), QTC(0x6dd65976), + QTC(0x6def9a08), QTC(0x6e08d8ab), QTC(0x6e221560), QTC(0x6e3b5027), + QTC(0x6e548902), QTC(0x6e6dbff1), QTC(0x6e86f4f5), QTC(0x6ea0280e), + QTC(0x6eb9593e), QTC(0x6ed28885), QTC(0x6eebb5e3), QTC(0x6f04e15a), + QTC(0x6f1e0aea), QTC(0x6f373294), QTC(0x6f505859), QTC(0x6f697c39), + QTC(0x6f829e35), QTC(0x6f9bbe4e), QTC(0x6fb4dc85), QTC(0x6fcdf8d9), + QTC(0x6fe7134d), QTC(0x70002be0), QTC(0x70194293), QTC(0x70325767), + QTC(0x704b6a5d), QTC(0x70647b76), QTC(0x707d8ab1), QTC(0x70969811), + QTC(0x70afa394), QTC(0x70c8ad3d), QTC(0x70e1b50c), QTC(0x70fabb01), + QTC(0x7113bf1d), QTC(0x712cc161), QTC(0x7145c1ce), QTC(0x715ec064), + QTC(0x7177bd24), QTC(0x7190b80f), QTC(0x71a9b124), QTC(0x71c2a866), + QTC(0x71db9dd4), QTC(0x71f49170), QTC(0x720d8339), QTC(0x72267331), + QTC(0x723f6159), QTC(0x72584db0), QTC(0x72713838), QTC(0x728a20f1), + QTC(0x72a307db), QTC(0x72bbecf9), QTC(0x72d4d049), QTC(0x72edb1ce), + QTC(0x73069187), QTC(0x731f6f75), QTC(0x73384b98), QTC(0x735125f3), + QTC(0x7369fe84), QTC(0x7382d54d), QTC(0x739baa4e), QTC(0x73b47d89), + QTC(0x73cd4efd), QTC(0x73e61eab), QTC(0x73feec94), QTC(0x7417b8b8), + QTC(0x74308319), QTC(0x74494bb6), QTC(0x74621291), QTC(0x747ad7aa), + QTC(0x74939b02), QTC(0x74ac5c98), QTC(0x74c51c6f), QTC(0x74ddda86), + QTC(0x74f696de), QTC(0x750f5178), QTC(0x75280a54), QTC(0x7540c174), + QTC(0x755976d7), QTC(0x75722a7e), QTC(0x758adc69), QTC(0x75a38c9b), + QTC(0x75bc3b12), QTC(0x75d4e7cf), QTC(0x75ed92d4), QTC(0x76063c21), + QTC(0x761ee3b6), QTC(0x76378994), QTC(0x76502dbc), QTC(0x7668d02e), + QTC(0x768170eb), QTC(0x769a0ff3), QTC(0x76b2ad47), QTC(0x76cb48e7), + QTC(0x76e3e2d5), QTC(0x76fc7b10), QTC(0x7715119a), QTC(0x772da673), + QTC(0x7746399b), QTC(0x775ecb13), QTC(0x77775adc), QTC(0x778fe8f6), + QTC(0x77a87561), QTC(0x77c1001f), QTC(0x77d98930), QTC(0x77f21095), + QTC(0x780a964d), QTC(0x78231a5b), QTC(0x783b9cbd), QTC(0x78541d75), + QTC(0x786c9c84), QTC(0x788519e9), QTC(0x789d95a6), QTC(0x78b60fbb), + QTC(0x78ce8828), QTC(0x78e6feef), QTC(0x78ff740f), QTC(0x7917e78a), + QTC(0x7930595f), QTC(0x7948c990), QTC(0x7961381d), QTC(0x7979a506), + QTC(0x7992104c), QTC(0x79aa79f0), QTC(0x79c2e1f1), QTC(0x79db4852), + QTC(0x79f3ad11), QTC(0x7a0c1031), QTC(0x7a2471b0), QTC(0x7a3cd191), + QTC(0x7a552fd3), QTC(0x7a6d8c76), QTC(0x7a85e77d), QTC(0x7a9e40e6), + QTC(0x7ab698b2), QTC(0x7aceeee3), QTC(0x7ae74378), QTC(0x7aff9673), + QTC(0x7b17e7d2), QTC(0x7b303799), QTC(0x7b4885c5), QTC(0x7b60d259), + QTC(0x7b791d55), QTC(0x7b9166b9), QTC(0x7ba9ae86), QTC(0x7bc1f4bc), + QTC(0x7bda395c), QTC(0x7bf27c66), QTC(0x7c0abddb), QTC(0x7c22fdbb), + QTC(0x7c3b3c07), QTC(0x7c5378c0), QTC(0x7c6bb3e5), QTC(0x7c83ed78), + QTC(0x7c9c2579), QTC(0x7cb45be9), QTC(0x7ccc90c7), QTC(0x7ce4c414), + QTC(0x7cfcf5d2), QTC(0x7d152600), QTC(0x7d2d549f), QTC(0x7d4581b0), + QTC(0x7d5dad32), QTC(0x7d75d727), QTC(0x7d8dff8f), QTC(0x7da6266a), + QTC(0x7dbe4bba), QTC(0x7dd66f7d), QTC(0x7dee91b6), QTC(0x7e06b264), + QTC(0x7e1ed188), QTC(0x7e36ef22), QTC(0x7e4f0b34), QTC(0x7e6725bd), + QTC(0x7e7f3ebd), QTC(0x7e975636), QTC(0x7eaf6c28), QTC(0x7ec78093), + QTC(0x7edf9378), QTC(0x7ef7a4d7), QTC(0x7f0fb4b1), QTC(0x7f27c307), + QTC(0x7f3fcfd8), QTC(0x7f57db25), QTC(0x7f6fe4ef), QTC(0x7f87ed36), + QTC(0x7f9ff3fb), QTC(0x7fb7f93e), QTC(0x7fcffcff), QTC(0x7fe7ff40)}; /* table of pow(2.0,0.25*q)/2.0, q[0..4) */ -const FIXP_QTD FDKaacEnc_quantTableQ[4] = { QTC(0x40000000), QTC(0x4c1bf7ff), QTC(0x5a82797f), QTC(0x6ba27e7f) }; +const FIXP_QTD FDKaacEnc_quantTableQ[4] = {QTC(0x40000000), QTC(0x4c1bf7ff), + QTC(0x5a82797f), QTC(0x6ba27e7f)}; /* table of pow(2.0,0.75*e)/8.0, e[0..4) */ -const FIXP_QTD FDKaacEnc_quantTableE[4] = { QTC(0x10000000), QTC(0x1ae89f99), QTC(0x2d413ccd), QTC(0x4c1bf828) }; - +const FIXP_QTD FDKaacEnc_quantTableE[4] = {QTC(0x10000000), QTC(0x1ae89f99), + QTC(0x2d413ccd), QTC(0x4c1bf828)}; /* table to count used number of bits */ -const SHORT FDKaacEnc_sideInfoTabLong[MAX_SFB_LONG + 1] = -{ - 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, - 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, - 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, - 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x000e, - 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, - 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, - 0x000e, 0x000e, 0x000e, 0x000e -}; - - -const SHORT FDKaacEnc_sideInfoTabShort[MAX_SFB_SHORT + 1] = -{ - 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x000a, - 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000d, 0x000d -}; - - - - - +const SHORT FDKaacEnc_sideInfoTabLong[] = { + 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, + 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, + 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, + 0x0009, 0x0009, 0x0009, 0x0009, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e}; + +const SHORT FDKaacEnc_sideInfoTabShort[] = { + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x000a, + 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000d, 0x000d}; /* Psy Configuration constants */ const SFB_PARAM_LONG p_FDKaacEnc_8000_long_1024 = { - 40, - { 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 16, 16, 16, - 20, 20, 20, 20, 24, 24, 24, 28, 28, 32, 36, 36, 40, 44, 48, 52, 56, 60, 64, 80 } -}; + 40, {12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 16, + 16, 16, 16, 16, 16, 16, 20, 20, 20, 20, 24, 24, 24, 28, + 28, 32, 36, 36, 40, 44, 48, 52, 56, 60, 64, 80}}; const SFB_PARAM_SHORT p_FDKaacEnc_8000_short_128 = { - 15, - { 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 16, 20, 20 } -}; + 15, {4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 16, 20, 20}}; const SFB_PARAM_LONG p_FDKaacEnc_11025_long_1024 = { - 43, - { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, - 64, 64, 64 } -}; + 43, {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, + 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64}}; const SFB_PARAM_SHORT p_FDKaacEnc_11025_short_128 = { - 15, - { 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20 } -}; + 15, {4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20}}; const SFB_PARAM_LONG p_FDKaacEnc_12000_long_1024 = { - 43, - { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, - 64, 64, 64 } -}; + 43, {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, + 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64}}; const SFB_PARAM_SHORT p_FDKaacEnc_12000_short_128 = { - 15, - { 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20 } -}; + 15, {4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20}}; const SFB_PARAM_LONG p_FDKaacEnc_16000_long_1024 = { - 43, - { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, - 64, 64, 64 } -}; + 43, {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, + 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64}}; const SFB_PARAM_SHORT p_FDKaacEnc_16000_short_128 = { - 15, - { 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20 } -}; + 15, {4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20}}; const SFB_PARAM_LONG p_FDKaacEnc_22050_long_1024 = { - 47, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24, 28, 28, 32, 36, 36, 40, 44, 48, - 52, 52, 64, 64, 64, 64, 64 } -}; + 47, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24, + 28, 28, 32, 36, 36, 40, 44, 48, 52, 52, 64, 64, 64, 64, 64}}; const SFB_PARAM_SHORT p_FDKaacEnc_22050_short_128 = { - 15, - { 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20 } -}; + 15, {4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20}}; const SFB_PARAM_LONG p_FDKaacEnc_24000_long_1024 = { - 47, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24, 28, 28, 32, 36, 36, 40, 44, 48, - 52, 52, 64, 64, 64, 64, 64 } -}; + 47, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24, + 28, 28, 32, 36, 36, 40, 44, 48, 52, 52, 64, 64, 64, 64, 64}}; const SFB_PARAM_SHORT p_FDKaacEnc_24000_short_128 = { - 15, - { 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20 } -}; + 15, {4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20}}; const SFB_PARAM_LONG p_FDKaacEnc_32000_long_1024 = { - 51, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, - 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32 } -}; + 51, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, + 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}}; const SFB_PARAM_SHORT p_FDKaacEnc_32000_short_128 = { - 14, - { 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16 } -}; + 14, {4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16}}; const SFB_PARAM_LONG p_FDKaacEnc_44100_long_1024 = { - 49, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, - 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 96 } -}; + 49, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, + 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 96}}; const SFB_PARAM_SHORT p_FDKaacEnc_44100_short_128 = { - 14, - { 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16 } -}; + 14, {4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16}}; const SFB_PARAM_LONG p_FDKaacEnc_48000_long_1024 = { - 49, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, - 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 96 } -}; + 49, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, + 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 96}}; const SFB_PARAM_SHORT p_FDKaacEnc_48000_short_128 = { - 14, - { 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16 } -}; + 14, {4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16}}; const SFB_PARAM_LONG p_FDKaacEnc_64000_long_1024 = { - 47, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 12, - 12, 16, 16, 16, 20, 24, 24, 28, 36, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40 } -}; + 47, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, + 8, 8, 12, 12, 12, 16, 16, 16, 20, 24, 24, 28, 36, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}}; const SFB_PARAM_SHORT p_FDKaacEnc_64000_short_128 = { - 12, - { 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36 } -}; + 12, {4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36}}; const SFB_PARAM_LONG p_FDKaacEnc_88200_long_1024 = { - 41, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 12, - 12, 12, 12, 12, 16, 16, 24, 28, 36, 44, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64 } -}; + 41, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 16, 16, 24, 28, + 36, 44, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}}; const SFB_PARAM_SHORT p_FDKaacEnc_88200_short_128 = { - 12, - { 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36 } -}; + 12, {4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36}}; const SFB_PARAM_LONG p_FDKaacEnc_96000_long_1024 = { - 41, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 12, - 12, 12, 12, 12, 16, 16, 24, 28, 36, 44, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64 } -}; + 41, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 16, 16, 24, 28, + 36, 44, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}}; const SFB_PARAM_SHORT p_FDKaacEnc_96000_short_128 = { - 12, - { 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36 } -}; - + 12, {4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36}}; /* TNS filter coefficients @@ -655,578 +815,1672 @@ const SFB_PARAM_SHORT p_FDKaacEnc_96000_short_128 = { /* 3 bit resolution */ -const FIXP_DBL FDKaacEnc_tnsEncCoeff3[8]= -{ - (FIXP_DBL)0x81f1d201, (FIXP_DBL)0x91261481, (FIXP_DBL)0xadb92301, (FIXP_DBL)0xd438af00, (FIXP_DBL)0x00000000, (FIXP_DBL)0x37898080, (FIXP_DBL)0x64130dff, (FIXP_DBL)0x7cca6fff -}; -const FIXP_DBL FDKaacEnc_tnsCoeff3Borders[8]={ - (FIXP_DBL)0x80000001 /*-4*/, (FIXP_DBL)0x87b826df /*-3*/, (FIXP_DBL)0x9df24154 /*-2*/, (FIXP_DBL)0xbfffffe5 /*-1*/, - (FIXP_DBL)0xe9c5e578 /* 0*/, (FIXP_DBL)0x1c7b90f0 /* 1*/, (FIXP_DBL)0x4fce83a9 /* 2*/, (FIXP_DBL)0x7352f2c3 /* 3*/ +const FIXP_LPC FDKaacEnc_tnsEncCoeff3[8] = { + FX_DBL2FXCONST_LPC(0x81f1d201), FX_DBL2FXCONST_LPC(0x91261481), + FX_DBL2FXCONST_LPC(0xadb92301), FX_DBL2FXCONST_LPC(0xd438af00), + FX_DBL2FXCONST_LPC(0x00000000), FX_DBL2FXCONST_LPC(0x37898080), + FX_DBL2FXCONST_LPC(0x64130dff), FX_DBL2FXCONST_LPC(0x7cca6fff)}; +const FIXP_LPC FDKaacEnc_tnsCoeff3Borders[8] = { + FX_DBL2FXCONST_LPC(0x80000001) /*-4*/, + FX_DBL2FXCONST_LPC(0x87b826df) /*-3*/, + FX_DBL2FXCONST_LPC(0x9df24154) /*-2*/, + FX_DBL2FXCONST_LPC(0xbfffffe5) /*-1*/, + FX_DBL2FXCONST_LPC(0xe9c5e578) /* 0*/, + FX_DBL2FXCONST_LPC(0x1c7b90f0) /* 1*/, + FX_DBL2FXCONST_LPC(0x4fce83a9) /* 2*/, + FX_DBL2FXCONST_LPC(0x7352f2c3) /* 3*/ }; /* 4 bit resolution */ -const FIXP_DBL FDKaacEnc_tnsEncCoeff4[16]= -{ - (FIXP_DBL)0x808bc881, (FIXP_DBL)0x84e2e581, (FIXP_DBL)0x8d6b4a01, (FIXP_DBL)0x99da9201, (FIXP_DBL)0xa9c45701, (FIXP_DBL)0xbc9dde81, (FIXP_DBL)0xd1c2d500, (FIXP_DBL)0xe87ae540, - (FIXP_DBL)0x00000000, (FIXP_DBL)0x1a9cd9c0, (FIXP_DBL)0x340ff240, (FIXP_DBL)0x4b3c8bff, (FIXP_DBL)0x5f1f5e7f, (FIXP_DBL)0x6ed9eb7f, (FIXP_DBL)0x79bc387f, (FIXP_DBL)0x7f4c7e7f -}; -const FIXP_DBL FDKaacEnc_tnsCoeff4Borders[16]= -{ - (FIXP_DBL)0x80000001 /*-8*/, (FIXP_DBL)0x822deff0 /*-7*/, (FIXP_DBL)0x88a4bfe6 /*-6*/, (FIXP_DBL)0x932c159d /*-5*/, - (FIXP_DBL)0xa16827c2 /*-4*/, (FIXP_DBL)0xb2dcde27 /*-3*/, (FIXP_DBL)0xc6f20b91 /*-2*/, (FIXP_DBL)0xdcf89c64 /*-1*/, - (FIXP_DBL)0xf4308ce1 /* 0*/, (FIXP_DBL)0x0d613054 /* 1*/, (FIXP_DBL)0x278dde80 /* 2*/, (FIXP_DBL)0x4000001b /* 3*/, - (FIXP_DBL)0x55a6127b /* 4*/, (FIXP_DBL)0x678dde8f /* 5*/, (FIXP_DBL)0x74ef0ed7 /* 6*/, (FIXP_DBL)0x7d33f0da /* 7*/ +const FIXP_LPC FDKaacEnc_tnsEncCoeff4[16] = { + FX_DBL2FXCONST_LPC(0x808bc881), FX_DBL2FXCONST_LPC(0x84e2e581), + FX_DBL2FXCONST_LPC(0x8d6b4a01), FX_DBL2FXCONST_LPC(0x99da9201), + FX_DBL2FXCONST_LPC(0xa9c45701), FX_DBL2FXCONST_LPC(0xbc9dde81), + FX_DBL2FXCONST_LPC(0xd1c2d500), FX_DBL2FXCONST_LPC(0xe87ae540), + FX_DBL2FXCONST_LPC(0x00000000), FX_DBL2FXCONST_LPC(0x1a9cd9c0), + FX_DBL2FXCONST_LPC(0x340ff240), FX_DBL2FXCONST_LPC(0x4b3c8bff), + FX_DBL2FXCONST_LPC(0x5f1f5e7f), FX_DBL2FXCONST_LPC(0x6ed9eb7f), + FX_DBL2FXCONST_LPC(0x79bc387f), FX_DBL2FXCONST_LPC(0x7f4c7e7f)}; +const FIXP_LPC FDKaacEnc_tnsCoeff4Borders[16] = { + FX_DBL2FXCONST_LPC(0x80000001) /*-8*/, + FX_DBL2FXCONST_LPC(0x822deff0) /*-7*/, + FX_DBL2FXCONST_LPC(0x88a4bfe6) /*-6*/, + FX_DBL2FXCONST_LPC(0x932c159d) /*-5*/, + FX_DBL2FXCONST_LPC(0xa16827c2) /*-4*/, + FX_DBL2FXCONST_LPC(0xb2dcde27) /*-3*/, + FX_DBL2FXCONST_LPC(0xc6f20b91) /*-2*/, + FX_DBL2FXCONST_LPC(0xdcf89c64) /*-1*/, + FX_DBL2FXCONST_LPC(0xf4308ce1) /* 0*/, + FX_DBL2FXCONST_LPC(0x0d613054) /* 1*/, + FX_DBL2FXCONST_LPC(0x278dde80) /* 2*/, + FX_DBL2FXCONST_LPC(0x4000001b) /* 3*/, + FX_DBL2FXCONST_LPC(0x55a6127b) /* 4*/, + FX_DBL2FXCONST_LPC(0x678dde8f) /* 5*/, + FX_DBL2FXCONST_LPC(0x74ef0ed7) /* 6*/, + FX_DBL2FXCONST_LPC(0x7d33f0da) /* 7*/ }; -const FIXP_DBL FDKaacEnc_mTab_4_3Elc[512]={ - FL2FXCONST_DBL(0.3968502629920499),FL2FXCONST_DBL(0.3978840634868335),FL2FXCONST_DBL(0.3989185359354711),FL2FXCONST_DBL(0.3999536794661432), - FL2FXCONST_DBL(0.4009894932098531),FL2FXCONST_DBL(0.4020259763004115),FL2FXCONST_DBL(0.4030631278744227),FL2FXCONST_DBL(0.4041009470712695), - FL2FXCONST_DBL(0.4051394330330996),FL2FXCONST_DBL(0.4061785849048110),FL2FXCONST_DBL(0.4072184018340380),FL2FXCONST_DBL(0.4082588829711372), - FL2FXCONST_DBL(0.4093000274691739),FL2FXCONST_DBL(0.4103418344839078),FL2FXCONST_DBL(0.4113843031737798),FL2FXCONST_DBL(0.4124274326998980), - FL2FXCONST_DBL(0.4134712222260245),FL2FXCONST_DBL(0.4145156709185620),FL2FXCONST_DBL(0.4155607779465400),FL2FXCONST_DBL(0.4166065424816022), - FL2FXCONST_DBL(0.4176529636979932),FL2FXCONST_DBL(0.4187000407725452),FL2FXCONST_DBL(0.4197477728846652),FL2FXCONST_DBL(0.4207961592163222), - FL2FXCONST_DBL(0.4218451989520345),FL2FXCONST_DBL(0.4228948912788567),FL2FXCONST_DBL(0.4239452353863673),FL2FXCONST_DBL(0.4249962304666564), - FL2FXCONST_DBL(0.4260478757143130),FL2FXCONST_DBL(0.4271001703264124),FL2FXCONST_DBL(0.4281531135025046),FL2FXCONST_DBL(0.4292067044446017), - FL2FXCONST_DBL(0.4302609423571658),FL2FXCONST_DBL(0.4313158264470970),FL2FXCONST_DBL(0.4323713559237216),FL2FXCONST_DBL(0.4334275299987803), - FL2FXCONST_DBL(0.4344843478864161),FL2FXCONST_DBL(0.4355418088031630),FL2FXCONST_DBL(0.4365999119679339),FL2FXCONST_DBL(0.4376586566020096), - FL2FXCONST_DBL(0.4387180419290272),FL2FXCONST_DBL(0.4397780671749683),FL2FXCONST_DBL(0.4408387315681480),FL2FXCONST_DBL(0.4419000343392039), - FL2FXCONST_DBL(0.4429619747210847),FL2FXCONST_DBL(0.4440245519490388),FL2FXCONST_DBL(0.4450877652606038),FL2FXCONST_DBL(0.4461516138955953), - FL2FXCONST_DBL(0.4472160970960963),FL2FXCONST_DBL(0.4482812141064458),FL2FXCONST_DBL(0.4493469641732286),FL2FXCONST_DBL(0.4504133465452648), - FL2FXCONST_DBL(0.4514803604735984),FL2FXCONST_DBL(0.4525480052114875),FL2FXCONST_DBL(0.4536162800143939),FL2FXCONST_DBL(0.4546851841399719), - FL2FXCONST_DBL(0.4557547168480591),FL2FXCONST_DBL(0.4568248774006652),FL2FXCONST_DBL(0.4578956650619623),FL2FXCONST_DBL(0.4589670790982746), - FL2FXCONST_DBL(0.4600391187780688),FL2FXCONST_DBL(0.4611117833719430),FL2FXCONST_DBL(0.4621850721526184),FL2FXCONST_DBL(0.4632589843949278), - FL2FXCONST_DBL(0.4643335193758069),FL2FXCONST_DBL(0.4654086763742842),FL2FXCONST_DBL(0.4664844546714713),FL2FXCONST_DBL(0.4675608535505532), - FL2FXCONST_DBL(0.4686378722967790),FL2FXCONST_DBL(0.4697155101974522),FL2FXCONST_DBL(0.4707937665419216),FL2FXCONST_DBL(0.4718726406215713), - FL2FXCONST_DBL(0.4729521317298118),FL2FXCONST_DBL(0.4740322391620711),FL2FXCONST_DBL(0.4751129622157845),FL2FXCONST_DBL(0.4761943001903867), - FL2FXCONST_DBL(0.4772762523873015),FL2FXCONST_DBL(0.4783588181099338),FL2FXCONST_DBL(0.4794419966636599),FL2FXCONST_DBL(0.4805257873558190), - FL2FXCONST_DBL(0.4816101894957042),FL2FXCONST_DBL(0.4826952023945537),FL2FXCONST_DBL(0.4837808253655421),FL2FXCONST_DBL(0.4848670577237714), - FL2FXCONST_DBL(0.4859538987862632),FL2FXCONST_DBL(0.4870413478719488),FL2FXCONST_DBL(0.4881294043016621),FL2FXCONST_DBL(0.4892180673981298), - FL2FXCONST_DBL(0.4903073364859640),FL2FXCONST_DBL(0.4913972108916533),FL2FXCONST_DBL(0.4924876899435545),FL2FXCONST_DBL(0.4935787729718844), - FL2FXCONST_DBL(0.4946704593087116),FL2FXCONST_DBL(0.4957627482879484),FL2FXCONST_DBL(0.4968556392453423),FL2FXCONST_DBL(0.4979491315184684), - FL2FXCONST_DBL(0.4990432244467211),FL2FXCONST_DBL(0.5001379173713062),FL2FXCONST_DBL(0.5012332096352328),FL2FXCONST_DBL(0.5023291005833056), - FL2FXCONST_DBL(0.5034255895621171),FL2FXCONST_DBL(0.5045226759200399),FL2FXCONST_DBL(0.5056203590072181),FL2FXCONST_DBL(0.5067186381755611), - FL2FXCONST_DBL(0.5078175127787346),FL2FXCONST_DBL(0.5089169821721536),FL2FXCONST_DBL(0.5100170457129749),FL2FXCONST_DBL(0.5111177027600893), - FL2FXCONST_DBL(0.5122189526741143),FL2FXCONST_DBL(0.5133207948173868),FL2FXCONST_DBL(0.5144232285539552),FL2FXCONST_DBL(0.5155262532495726), - FL2FXCONST_DBL(0.5166298682716894),FL2FXCONST_DBL(0.5177340729894460),FL2FXCONST_DBL(0.5188388667736652),FL2FXCONST_DBL(0.5199442489968457), - FL2FXCONST_DBL(0.5210502190331544),FL2FXCONST_DBL(0.5221567762584198),FL2FXCONST_DBL(0.5232639200501247),FL2FXCONST_DBL(0.5243716497873989), - FL2FXCONST_DBL(0.5254799648510130),FL2FXCONST_DBL(0.5265888646233705),FL2FXCONST_DBL(0.5276983484885021),FL2FXCONST_DBL(0.5288084158320574), - FL2FXCONST_DBL(0.5299190660412995),FL2FXCONST_DBL(0.5310302985050975),FL2FXCONST_DBL(0.5321421126139198),FL2FXCONST_DBL(0.5332545077598274), - FL2FXCONST_DBL(0.5343674833364678),FL2FXCONST_DBL(0.5354810387390675),FL2FXCONST_DBL(0.5365951733644262),FL2FXCONST_DBL(0.5377098866109097), - FL2FXCONST_DBL(0.5388251778784438),FL2FXCONST_DBL(0.5399410465685075),FL2FXCONST_DBL(0.5410574920841272),FL2FXCONST_DBL(0.5421745138298695), - FL2FXCONST_DBL(0.5432921112118353),FL2FXCONST_DBL(0.5444102836376534),FL2FXCONST_DBL(0.5455290305164744),FL2FXCONST_DBL(0.5466483512589642), - FL2FXCONST_DBL(0.5477682452772976),FL2FXCONST_DBL(0.5488887119851529),FL2FXCONST_DBL(0.5500097507977050),FL2FXCONST_DBL(0.5511313611316194), - FL2FXCONST_DBL(0.5522535424050467),FL2FXCONST_DBL(0.5533762940376158),FL2FXCONST_DBL(0.5544996154504284),FL2FXCONST_DBL(0.5556235060660528), - FL2FXCONST_DBL(0.5567479653085183),FL2FXCONST_DBL(0.5578729926033087),FL2FXCONST_DBL(0.5589985873773569),FL2FXCONST_DBL(0.5601247490590389), - FL2FXCONST_DBL(0.5612514770781683),FL2FXCONST_DBL(0.5623787708659898),FL2FXCONST_DBL(0.5635066298551742),FL2FXCONST_DBL(0.5646350534798125), - FL2FXCONST_DBL(0.5657640411754097),FL2FXCONST_DBL(0.5668935923788799),FL2FXCONST_DBL(0.5680237065285404),FL2FXCONST_DBL(0.5691543830641059), - FL2FXCONST_DBL(0.5702856214266832),FL2FXCONST_DBL(0.5714174210587655),FL2FXCONST_DBL(0.5725497814042271),FL2FXCONST_DBL(0.5736827019083177), - FL2FXCONST_DBL(0.5748161820176573),FL2FXCONST_DBL(0.5759502211802304),FL2FXCONST_DBL(0.5770848188453810),FL2FXCONST_DBL(0.5782199744638067), - FL2FXCONST_DBL(0.5793556874875542),FL2FXCONST_DBL(0.5804919573700131),FL2FXCONST_DBL(0.5816287835659116),FL2FXCONST_DBL(0.5827661655313104), - FL2FXCONST_DBL(0.5839041027235979),FL2FXCONST_DBL(0.5850425946014850),FL2FXCONST_DBL(0.5861816406250000),FL2FXCONST_DBL(0.5873212402554834), - FL2FXCONST_DBL(0.5884613929555826),FL2FXCONST_DBL(0.5896020981892474),FL2FXCONST_DBL(0.5907433554217242),FL2FXCONST_DBL(0.5918851641195517), - FL2FXCONST_DBL(0.5930275237505556),FL2FXCONST_DBL(0.5941704337838434),FL2FXCONST_DBL(0.5953138936897999),FL2FXCONST_DBL(0.5964579029400819), - FL2FXCONST_DBL(0.5976024610076139),FL2FXCONST_DBL(0.5987475673665825),FL2FXCONST_DBL(0.5998932214924321),FL2FXCONST_DBL(0.6010394228618597), - FL2FXCONST_DBL(0.6021861709528106),FL2FXCONST_DBL(0.6033334652444733),FL2FXCONST_DBL(0.6044813052172748),FL2FXCONST_DBL(0.6056296903528761), - FL2FXCONST_DBL(0.6067786201341671),FL2FXCONST_DBL(0.6079280940452625),FL2FXCONST_DBL(0.6090781115714966),FL2FXCONST_DBL(0.6102286721994192), - FL2FXCONST_DBL(0.6113797754167908),FL2FXCONST_DBL(0.6125314207125777),FL2FXCONST_DBL(0.6136836075769482),FL2FXCONST_DBL(0.6148363355012674), - FL2FXCONST_DBL(0.6159896039780929),FL2FXCONST_DBL(0.6171434125011708),FL2FXCONST_DBL(0.6182977605654305),FL2FXCONST_DBL(0.6194526476669808), - FL2FXCONST_DBL(0.6206080733031054),FL2FXCONST_DBL(0.6217640369722584),FL2FXCONST_DBL(0.6229205381740598),FL2FXCONST_DBL(0.6240775764092919), - FL2FXCONST_DBL(0.6252351511798939),FL2FXCONST_DBL(0.6263932619889586),FL2FXCONST_DBL(0.6275519083407275),FL2FXCONST_DBL(0.6287110897405869), - FL2FXCONST_DBL(0.6298708056950635),FL2FXCONST_DBL(0.6310310557118203),FL2FXCONST_DBL(0.6321918392996523),FL2FXCONST_DBL(0.6333531559684823), - FL2FXCONST_DBL(0.6345150052293571),FL2FXCONST_DBL(0.6356773865944432),FL2FXCONST_DBL(0.6368402995770224),FL2FXCONST_DBL(0.6380037436914881), - FL2FXCONST_DBL(0.6391677184533411),FL2FXCONST_DBL(0.6403322233791856),FL2FXCONST_DBL(0.6414972579867254),FL2FXCONST_DBL(0.6426628217947594), - FL2FXCONST_DBL(0.6438289143231779),FL2FXCONST_DBL(0.6449955350929588),FL2FXCONST_DBL(0.6461626836261636),FL2FXCONST_DBL(0.6473303594459330), - FL2FXCONST_DBL(0.6484985620764839),FL2FXCONST_DBL(0.6496672910431047),FL2FXCONST_DBL(0.6508365458721518),FL2FXCONST_DBL(0.6520063260910459), - FL2FXCONST_DBL(0.6531766312282679),FL2FXCONST_DBL(0.6543474608133552),FL2FXCONST_DBL(0.6555188143768979),FL2FXCONST_DBL(0.6566906914505349), - FL2FXCONST_DBL(0.6578630915669509),FL2FXCONST_DBL(0.6590360142598715),FL2FXCONST_DBL(0.6602094590640603),FL2FXCONST_DBL(0.6613834255153149), - FL2FXCONST_DBL(0.6625579131504635),FL2FXCONST_DBL(0.6637329215073610),FL2FXCONST_DBL(0.6649084501248851),FL2FXCONST_DBL(0.6660844985429335), - FL2FXCONST_DBL(0.6672610663024197),FL2FXCONST_DBL(0.6684381529452691),FL2FXCONST_DBL(0.6696157580144163),FL2FXCONST_DBL(0.6707938810538011), - FL2FXCONST_DBL(0.6719725216083646),FL2FXCONST_DBL(0.6731516792240465),FL2FXCONST_DBL(0.6743313534477807),FL2FXCONST_DBL(0.6755115438274927), - FL2FXCONST_DBL(0.6766922499120955),FL2FXCONST_DBL(0.6778734712514865),FL2FXCONST_DBL(0.6790552073965435),FL2FXCONST_DBL(0.6802374578991223), - FL2FXCONST_DBL(0.6814202223120524),FL2FXCONST_DBL(0.6826035001891340),FL2FXCONST_DBL(0.6837872910851345),FL2FXCONST_DBL(0.6849715945557853), - FL2FXCONST_DBL(0.6861564101577784),FL2FXCONST_DBL(0.6873417374487629),FL2FXCONST_DBL(0.6885275759873420),FL2FXCONST_DBL(0.6897139253330697), - FL2FXCONST_DBL(0.6909007850464473),FL2FXCONST_DBL(0.6920881546889198),FL2FXCONST_DBL(0.6932760338228737),FL2FXCONST_DBL(0.6944644220116332), - FL2FXCONST_DBL(0.6956533188194565),FL2FXCONST_DBL(0.6968427238115332),FL2FXCONST_DBL(0.6980326365539813),FL2FXCONST_DBL(0.6992230566138435), - FL2FXCONST_DBL(0.7004139835590845),FL2FXCONST_DBL(0.7016054169585869),FL2FXCONST_DBL(0.7027973563821499),FL2FXCONST_DBL(0.7039898014004843), - FL2FXCONST_DBL(0.7051827515852106),FL2FXCONST_DBL(0.7063762065088554),FL2FXCONST_DBL(0.7075701657448483),FL2FXCONST_DBL(0.7087646288675196), - FL2FXCONST_DBL(0.7099595954520960),FL2FXCONST_DBL(0.7111550650746988),FL2FXCONST_DBL(0.7123510373123402),FL2FXCONST_DBL(0.7135475117429202), - FL2FXCONST_DBL(0.7147444879452244),FL2FXCONST_DBL(0.7159419654989200),FL2FXCONST_DBL(0.7171399439845538),FL2FXCONST_DBL(0.7183384229835486), - FL2FXCONST_DBL(0.7195374020782005),FL2FXCONST_DBL(0.7207368808516762),FL2FXCONST_DBL(0.7219368588880097),FL2FXCONST_DBL(0.7231373357720997), - FL2FXCONST_DBL(0.7243383110897066),FL2FXCONST_DBL(0.7255397844274496),FL2FXCONST_DBL(0.7267417553728043),FL2FXCONST_DBL(0.7279442235140992), - FL2FXCONST_DBL(0.7291471884405130),FL2FXCONST_DBL(0.7303506497420724),FL2FXCONST_DBL(0.7315546070096487),FL2FXCONST_DBL(0.7327590598349553), - FL2FXCONST_DBL(0.7339640078105445),FL2FXCONST_DBL(0.7351694505298055),FL2FXCONST_DBL(0.7363753875869610),FL2FXCONST_DBL(0.7375818185770647), - FL2FXCONST_DBL(0.7387887430959987),FL2FXCONST_DBL(0.7399961607404706),FL2FXCONST_DBL(0.7412040711080108),FL2FXCONST_DBL(0.7424124737969701), - FL2FXCONST_DBL(0.7436213684065166),FL2FXCONST_DBL(0.7448307545366334),FL2FXCONST_DBL(0.7460406317881158),FL2FXCONST_DBL(0.7472509997625686), - FL2FXCONST_DBL(0.7484618580624036),FL2FXCONST_DBL(0.7496732062908372),FL2FXCONST_DBL(0.7508850440518872),FL2FXCONST_DBL(0.7520973709503704), - FL2FXCONST_DBL(0.7533101865919009),FL2FXCONST_DBL(0.7545234905828862),FL2FXCONST_DBL(0.7557372825305252),FL2FXCONST_DBL(0.7569515620428062), - FL2FXCONST_DBL(0.7581663287285035),FL2FXCONST_DBL(0.7593815821971756),FL2FXCONST_DBL(0.7605973220591619),FL2FXCONST_DBL(0.7618135479255810), - FL2FXCONST_DBL(0.7630302594083277),FL2FXCONST_DBL(0.7642474561200708),FL2FXCONST_DBL(0.7654651376742505),FL2FXCONST_DBL(0.7666833036850760), - FL2FXCONST_DBL(0.7679019537675227),FL2FXCONST_DBL(0.7691210875373307),FL2FXCONST_DBL(0.7703407046110011),FL2FXCONST_DBL(0.7715608046057948), - FL2FXCONST_DBL(0.7727813871397293),FL2FXCONST_DBL(0.7740024518315765),FL2FXCONST_DBL(0.7752239983008605),FL2FXCONST_DBL(0.7764460261678551), - FL2FXCONST_DBL(0.7776685350535814),FL2FXCONST_DBL(0.7788915245798054),FL2FXCONST_DBL(0.7801149943690360),FL2FXCONST_DBL(0.7813389440445223), - FL2FXCONST_DBL(0.7825633732302513),FL2FXCONST_DBL(0.7837882815509458),FL2FXCONST_DBL(0.7850136686320621),FL2FXCONST_DBL(0.7862395340997874), - FL2FXCONST_DBL(0.7874658775810378),FL2FXCONST_DBL(0.7886926987034559),FL2FXCONST_DBL(0.7899199970954088),FL2FXCONST_DBL(0.7911477723859853), - FL2FXCONST_DBL(0.7923760242049944),FL2FXCONST_DBL(0.7936047521829623),FL2FXCONST_DBL(0.7948339559511308),FL2FXCONST_DBL(0.7960636351414546), - FL2FXCONST_DBL(0.7972937893865995),FL2FXCONST_DBL(0.7985244183199399),FL2FXCONST_DBL(0.7997555215755570),FL2FXCONST_DBL(0.8009870987882359), - FL2FXCONST_DBL(0.8022191495934644),FL2FXCONST_DBL(0.8034516736274301),FL2FXCONST_DBL(0.8046846705270185),FL2FXCONST_DBL(0.8059181399298110), - FL2FXCONST_DBL(0.8071520814740822),FL2FXCONST_DBL(0.8083864947987989),FL2FXCONST_DBL(0.8096213795436166),FL2FXCONST_DBL(0.8108567353488784), - FL2FXCONST_DBL(0.8120925618556127),FL2FXCONST_DBL(0.8133288587055308),FL2FXCONST_DBL(0.8145656255410253),FL2FXCONST_DBL(0.8158028620051674), - FL2FXCONST_DBL(0.8170405677417053),FL2FXCONST_DBL(0.8182787423950622),FL2FXCONST_DBL(0.8195173856103341),FL2FXCONST_DBL(0.8207564970332875), - FL2FXCONST_DBL(0.8219960763103580),FL2FXCONST_DBL(0.8232361230886477),FL2FXCONST_DBL(0.8244766370159234),FL2FXCONST_DBL(0.8257176177406150), - FL2FXCONST_DBL(0.8269590649118125),FL2FXCONST_DBL(0.8282009781792650),FL2FXCONST_DBL(0.8294433571933784),FL2FXCONST_DBL(0.8306862016052132), - FL2FXCONST_DBL(0.8319295110664831),FL2FXCONST_DBL(0.8331732852295520),FL2FXCONST_DBL(0.8344175237474336),FL2FXCONST_DBL(0.8356622262737878), - FL2FXCONST_DBL(0.8369073924629202),FL2FXCONST_DBL(0.8381530219697793),FL2FXCONST_DBL(0.8393991144499545),FL2FXCONST_DBL(0.8406456695596752), - FL2FXCONST_DBL(0.8418926869558079),FL2FXCONST_DBL(0.8431401662958544),FL2FXCONST_DBL(0.8443881072379507),FL2FXCONST_DBL(0.8456365094408642), - FL2FXCONST_DBL(0.8468853725639923),FL2FXCONST_DBL(0.8481346962673606),FL2FXCONST_DBL(0.8493844802116208),FL2FXCONST_DBL(0.8506347240580492), - FL2FXCONST_DBL(0.8518854274685442),FL2FXCONST_DBL(0.8531365901056253),FL2FXCONST_DBL(0.8543882116324307),FL2FXCONST_DBL(0.8556402917127157), - FL2FXCONST_DBL(0.8568928300108512),FL2FXCONST_DBL(0.8581458261918209),FL2FXCONST_DBL(0.8593992799212207),FL2FXCONST_DBL(0.8606531908652563), - FL2FXCONST_DBL(0.8619075586907414),FL2FXCONST_DBL(0.8631623830650962),FL2FXCONST_DBL(0.8644176636563452),FL2FXCONST_DBL(0.8656734001331161), - FL2FXCONST_DBL(0.8669295921646375),FL2FXCONST_DBL(0.8681862394207371),FL2FXCONST_DBL(0.8694433415718407),FL2FXCONST_DBL(0.8707008982889695), - FL2FXCONST_DBL(0.8719589092437391),FL2FXCONST_DBL(0.8732173741083574),FL2FXCONST_DBL(0.8744762925556232),FL2FXCONST_DBL(0.8757356642589241), - FL2FXCONST_DBL(0.8769954888922352),FL2FXCONST_DBL(0.8782557661301171),FL2FXCONST_DBL(0.8795164956477146),FL2FXCONST_DBL(0.8807776771207545), - FL2FXCONST_DBL(0.8820393102255443),FL2FXCONST_DBL(0.8833013946389704),FL2FXCONST_DBL(0.8845639300384969),FL2FXCONST_DBL(0.8858269161021629), - FL2FXCONST_DBL(0.8870903525085819),FL2FXCONST_DBL(0.8883542389369399),FL2FXCONST_DBL(0.8896185750669933),FL2FXCONST_DBL(0.8908833605790678), - FL2FXCONST_DBL(0.8921485951540565),FL2FXCONST_DBL(0.8934142784734187),FL2FXCONST_DBL(0.8946804102191776),FL2FXCONST_DBL(0.8959469900739191), - FL2FXCONST_DBL(0.8972140177207906),FL2FXCONST_DBL(0.8984814928434985),FL2FXCONST_DBL(0.8997494151263077),FL2FXCONST_DBL(0.9010177842540390), - FL2FXCONST_DBL(0.9022865999120682),FL2FXCONST_DBL(0.9035558617863242),FL2FXCONST_DBL(0.9048255695632878),FL2FXCONST_DBL(0.9060957229299895), - FL2FXCONST_DBL(0.9073663215740092),FL2FXCONST_DBL(0.9086373651834729),FL2FXCONST_DBL(0.9099088534470528),FL2FXCONST_DBL(0.9111807860539647), - FL2FXCONST_DBL(0.9124531626939672),FL2FXCONST_DBL(0.9137259830573594),FL2FXCONST_DBL(0.9149992468349805),FL2FXCONST_DBL(0.9162729537182071), - FL2FXCONST_DBL(0.9175471033989524),FL2FXCONST_DBL(0.9188216955696648),FL2FXCONST_DBL(0.9200967299233258),FL2FXCONST_DBL(0.9213722061534494), - FL2FXCONST_DBL(0.9226481239540795),FL2FXCONST_DBL(0.9239244830197896),FL2FXCONST_DBL(0.9252012830456805),FL2FXCONST_DBL(0.9264785237273793), - FL2FXCONST_DBL(0.9277562047610376),FL2FXCONST_DBL(0.9290343258433305),FL2FXCONST_DBL(0.9303128866714547),FL2FXCONST_DBL(0.9315918869431275), - FL2FXCONST_DBL(0.9328713263565848),FL2FXCONST_DBL(0.9341512046105802),FL2FXCONST_DBL(0.9354315214043836),FL2FXCONST_DBL(0.9367122764377792), - FL2FXCONST_DBL(0.9379934694110648),FL2FXCONST_DBL(0.9392751000250497),FL2FXCONST_DBL(0.9405571679810542),FL2FXCONST_DBL(0.9418396729809072), - FL2FXCONST_DBL(0.9431226147269456),FL2FXCONST_DBL(0.9444059929220124),FL2FXCONST_DBL(0.9456898072694558),FL2FXCONST_DBL(0.9469740574731275), - FL2FXCONST_DBL(0.9482587432373810),FL2FXCONST_DBL(0.9495438642670713),FL2FXCONST_DBL(0.9508294202675522),FL2FXCONST_DBL(0.9521154109446763), - FL2FXCONST_DBL(0.9534018360047926),FL2FXCONST_DBL(0.9546886951547455),FL2FXCONST_DBL(0.9559759881018738),FL2FXCONST_DBL(0.9572637145540087), - FL2FXCONST_DBL(0.9585518742194732),FL2FXCONST_DBL(0.9598404668070802),FL2FXCONST_DBL(0.9611294920261317),FL2FXCONST_DBL(0.9624189495864168), - FL2FXCONST_DBL(0.9637088391982110),FL2FXCONST_DBL(0.9649991605722750),FL2FXCONST_DBL(0.9662899134198524),FL2FXCONST_DBL(0.9675810974526697), - FL2FXCONST_DBL(0.9688727123829343),FL2FXCONST_DBL(0.9701647579233330),FL2FXCONST_DBL(0.9714572337870316),FL2FXCONST_DBL(0.9727501396876727), - FL2FXCONST_DBL(0.9740434753393749),FL2FXCONST_DBL(0.9753372404567313),FL2FXCONST_DBL(0.9766314347548087),FL2FXCONST_DBL(0.9779260579491460), - FL2FXCONST_DBL(0.9792211097557527),FL2FXCONST_DBL(0.9805165898911081),FL2FXCONST_DBL(0.9818124980721600),FL2FXCONST_DBL(0.9831088340163232), - FL2FXCONST_DBL(0.9844055974414786),FL2FXCONST_DBL(0.9857027880659716),FL2FXCONST_DBL(0.9870004056086111),FL2FXCONST_DBL(0.9882984497886684), - FL2FXCONST_DBL(0.9895969203258759),FL2FXCONST_DBL(0.9908958169404255),FL2FXCONST_DBL(0.9921951393529680),FL2FXCONST_DBL(0.9934948872846116), - FL2FXCONST_DBL(0.9947950604569206),FL2FXCONST_DBL(0.9960956585919144),FL2FXCONST_DBL(0.9973966814120665),FL2FXCONST_DBL(0.9986981286403025) -}; - -const FIXP_DBL FDKaacEnc_specExpMantTableCombElc[4][14] = -{ - {FL2FXCONST_DBL(0.5000000000000000), FL2FXCONST_DBL(0.6299605249474366), FL2FXCONST_DBL(0.7937005259840998), FL2FXCONST_DBL(0.5000000000000000), - FL2FXCONST_DBL(0.6299605249474366), FL2FXCONST_DBL(0.7937005259840998), FL2FXCONST_DBL(0.5000000000000000), FL2FXCONST_DBL(0.6299605249474366), - FL2FXCONST_DBL(0.7937005259840998), FL2FXCONST_DBL(0.5000000000000000), FL2FXCONST_DBL(0.6299605249474366), FL2FXCONST_DBL(0.7937005259840998), - FL2FXCONST_DBL(0.5000000000000000), FL2FXCONST_DBL(0.6299605249474366)}, - - {FL2FXCONST_DBL(0.5946035575013605), FL2FXCONST_DBL(0.7491535384383408), FL2FXCONST_DBL(0.9438743126816935), FL2FXCONST_DBL(0.5946035575013605), - FL2FXCONST_DBL(0.7491535384383408), FL2FXCONST_DBL(0.9438743126816935), FL2FXCONST_DBL(0.5946035575013605), FL2FXCONST_DBL(0.7491535384383408), - FL2FXCONST_DBL(0.9438743126816935), FL2FXCONST_DBL(0.5946035575013605), FL2FXCONST_DBL(0.7491535384383408), FL2FXCONST_DBL(0.9438743126816935), - FL2FXCONST_DBL(0.5946035575013605), FL2FXCONST_DBL(0.7491535384383408)}, - - {FL2FXCONST_DBL(0.7071067811865476), FL2FXCONST_DBL(0.8908987181403393), FL2FXCONST_DBL(0.5612310241546865), FL2FXCONST_DBL(0.7071067811865476), - FL2FXCONST_DBL(0.8908987181403393), FL2FXCONST_DBL(0.5612310241546865), FL2FXCONST_DBL(0.7071067811865476), FL2FXCONST_DBL(0.8908987181403393), - FL2FXCONST_DBL(0.5612310241546865), FL2FXCONST_DBL(0.7071067811865476), FL2FXCONST_DBL(0.8908987181403393), FL2FXCONST_DBL(0.5612310241546865), - FL2FXCONST_DBL(0.7071067811865476), FL2FXCONST_DBL(0.8908987181403393)}, - - {FL2FXCONST_DBL(0.8408964152537145), FL2FXCONST_DBL(0.5297315471796477), FL2FXCONST_DBL(0.6674199270850172), FL2FXCONST_DBL(0.8408964152537145), - FL2FXCONST_DBL(0.5297315471796477), FL2FXCONST_DBL(0.6674199270850172), FL2FXCONST_DBL(0.8408964152537145), FL2FXCONST_DBL(0.5297315471796477), - FL2FXCONST_DBL(0.6674199270850172), FL2FXCONST_DBL(0.8408964152537145), FL2FXCONST_DBL(0.5297315471796477), FL2FXCONST_DBL(0.6674199270850172), - FL2FXCONST_DBL(0.8408964152537145), FL2FXCONST_DBL(0.5297315471796477)} -}; - -const UCHAR FDKaacEnc_specExpTableComb[4][14] = -{ - {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18}, - {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18}, - {1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 16, 17, 18}, - {1, 3, 4, 5, 7, 8, 9, 11, 12, 13, 15, 16, 17, 19} -}; - +const FIXP_DBL FDKaacEnc_mTab_4_3Elc[512] = { + FL2FXCONST_DBL(0.3968502629920499), FL2FXCONST_DBL(0.3978840634868335), + FL2FXCONST_DBL(0.3989185359354711), FL2FXCONST_DBL(0.3999536794661432), + FL2FXCONST_DBL(0.4009894932098531), FL2FXCONST_DBL(0.4020259763004115), + FL2FXCONST_DBL(0.4030631278744227), FL2FXCONST_DBL(0.4041009470712695), + FL2FXCONST_DBL(0.4051394330330996), FL2FXCONST_DBL(0.4061785849048110), + FL2FXCONST_DBL(0.4072184018340380), FL2FXCONST_DBL(0.4082588829711372), + FL2FXCONST_DBL(0.4093000274691739), FL2FXCONST_DBL(0.4103418344839078), + FL2FXCONST_DBL(0.4113843031737798), FL2FXCONST_DBL(0.4124274326998980), + FL2FXCONST_DBL(0.4134712222260245), FL2FXCONST_DBL(0.4145156709185620), + FL2FXCONST_DBL(0.4155607779465400), FL2FXCONST_DBL(0.4166065424816022), + FL2FXCONST_DBL(0.4176529636979932), FL2FXCONST_DBL(0.4187000407725452), + FL2FXCONST_DBL(0.4197477728846652), FL2FXCONST_DBL(0.4207961592163222), + FL2FXCONST_DBL(0.4218451989520345), FL2FXCONST_DBL(0.4228948912788567), + FL2FXCONST_DBL(0.4239452353863673), FL2FXCONST_DBL(0.4249962304666564), + FL2FXCONST_DBL(0.4260478757143130), FL2FXCONST_DBL(0.4271001703264124), + FL2FXCONST_DBL(0.4281531135025046), FL2FXCONST_DBL(0.4292067044446017), + FL2FXCONST_DBL(0.4302609423571658), FL2FXCONST_DBL(0.4313158264470970), + FL2FXCONST_DBL(0.4323713559237216), FL2FXCONST_DBL(0.4334275299987803), + FL2FXCONST_DBL(0.4344843478864161), FL2FXCONST_DBL(0.4355418088031630), + FL2FXCONST_DBL(0.4365999119679339), FL2FXCONST_DBL(0.4376586566020096), + FL2FXCONST_DBL(0.4387180419290272), FL2FXCONST_DBL(0.4397780671749683), + FL2FXCONST_DBL(0.4408387315681480), FL2FXCONST_DBL(0.4419000343392039), + FL2FXCONST_DBL(0.4429619747210847), FL2FXCONST_DBL(0.4440245519490388), + FL2FXCONST_DBL(0.4450877652606038), FL2FXCONST_DBL(0.4461516138955953), + FL2FXCONST_DBL(0.4472160970960963), FL2FXCONST_DBL(0.4482812141064458), + FL2FXCONST_DBL(0.4493469641732286), FL2FXCONST_DBL(0.4504133465452648), + FL2FXCONST_DBL(0.4514803604735984), FL2FXCONST_DBL(0.4525480052114875), + FL2FXCONST_DBL(0.4536162800143939), FL2FXCONST_DBL(0.4546851841399719), + FL2FXCONST_DBL(0.4557547168480591), FL2FXCONST_DBL(0.4568248774006652), + FL2FXCONST_DBL(0.4578956650619623), FL2FXCONST_DBL(0.4589670790982746), + FL2FXCONST_DBL(0.4600391187780688), FL2FXCONST_DBL(0.4611117833719430), + FL2FXCONST_DBL(0.4621850721526184), FL2FXCONST_DBL(0.4632589843949278), + FL2FXCONST_DBL(0.4643335193758069), FL2FXCONST_DBL(0.4654086763742842), + FL2FXCONST_DBL(0.4664844546714713), FL2FXCONST_DBL(0.4675608535505532), + FL2FXCONST_DBL(0.4686378722967790), FL2FXCONST_DBL(0.4697155101974522), + FL2FXCONST_DBL(0.4707937665419216), FL2FXCONST_DBL(0.4718726406215713), + FL2FXCONST_DBL(0.4729521317298118), FL2FXCONST_DBL(0.4740322391620711), + FL2FXCONST_DBL(0.4751129622157845), FL2FXCONST_DBL(0.4761943001903867), + FL2FXCONST_DBL(0.4772762523873015), FL2FXCONST_DBL(0.4783588181099338), + FL2FXCONST_DBL(0.4794419966636599), FL2FXCONST_DBL(0.4805257873558190), + FL2FXCONST_DBL(0.4816101894957042), FL2FXCONST_DBL(0.4826952023945537), + FL2FXCONST_DBL(0.4837808253655421), FL2FXCONST_DBL(0.4848670577237714), + FL2FXCONST_DBL(0.4859538987862632), FL2FXCONST_DBL(0.4870413478719488), + FL2FXCONST_DBL(0.4881294043016621), FL2FXCONST_DBL(0.4892180673981298), + FL2FXCONST_DBL(0.4903073364859640), FL2FXCONST_DBL(0.4913972108916533), + FL2FXCONST_DBL(0.4924876899435545), FL2FXCONST_DBL(0.4935787729718844), + FL2FXCONST_DBL(0.4946704593087116), FL2FXCONST_DBL(0.4957627482879484), + FL2FXCONST_DBL(0.4968556392453423), FL2FXCONST_DBL(0.4979491315184684), + FL2FXCONST_DBL(0.4990432244467211), FL2FXCONST_DBL(0.5001379173713062), + FL2FXCONST_DBL(0.5012332096352328), FL2FXCONST_DBL(0.5023291005833056), + FL2FXCONST_DBL(0.5034255895621171), FL2FXCONST_DBL(0.5045226759200399), + FL2FXCONST_DBL(0.5056203590072181), FL2FXCONST_DBL(0.5067186381755611), + FL2FXCONST_DBL(0.5078175127787346), FL2FXCONST_DBL(0.5089169821721536), + FL2FXCONST_DBL(0.5100170457129749), FL2FXCONST_DBL(0.5111177027600893), + FL2FXCONST_DBL(0.5122189526741143), FL2FXCONST_DBL(0.5133207948173868), + FL2FXCONST_DBL(0.5144232285539552), FL2FXCONST_DBL(0.5155262532495726), + FL2FXCONST_DBL(0.5166298682716894), FL2FXCONST_DBL(0.5177340729894460), + FL2FXCONST_DBL(0.5188388667736652), FL2FXCONST_DBL(0.5199442489968457), + FL2FXCONST_DBL(0.5210502190331544), FL2FXCONST_DBL(0.5221567762584198), + FL2FXCONST_DBL(0.5232639200501247), FL2FXCONST_DBL(0.5243716497873989), + FL2FXCONST_DBL(0.5254799648510130), FL2FXCONST_DBL(0.5265888646233705), + FL2FXCONST_DBL(0.5276983484885021), FL2FXCONST_DBL(0.5288084158320574), + FL2FXCONST_DBL(0.5299190660412995), FL2FXCONST_DBL(0.5310302985050975), + FL2FXCONST_DBL(0.5321421126139198), FL2FXCONST_DBL(0.5332545077598274), + FL2FXCONST_DBL(0.5343674833364678), FL2FXCONST_DBL(0.5354810387390675), + FL2FXCONST_DBL(0.5365951733644262), FL2FXCONST_DBL(0.5377098866109097), + FL2FXCONST_DBL(0.5388251778784438), FL2FXCONST_DBL(0.5399410465685075), + FL2FXCONST_DBL(0.5410574920841272), FL2FXCONST_DBL(0.5421745138298695), + FL2FXCONST_DBL(0.5432921112118353), FL2FXCONST_DBL(0.5444102836376534), + FL2FXCONST_DBL(0.5455290305164744), FL2FXCONST_DBL(0.5466483512589642), + FL2FXCONST_DBL(0.5477682452772976), FL2FXCONST_DBL(0.5488887119851529), + FL2FXCONST_DBL(0.5500097507977050), FL2FXCONST_DBL(0.5511313611316194), + FL2FXCONST_DBL(0.5522535424050467), FL2FXCONST_DBL(0.5533762940376158), + FL2FXCONST_DBL(0.5544996154504284), FL2FXCONST_DBL(0.5556235060660528), + FL2FXCONST_DBL(0.5567479653085183), FL2FXCONST_DBL(0.5578729926033087), + FL2FXCONST_DBL(0.5589985873773569), FL2FXCONST_DBL(0.5601247490590389), + FL2FXCONST_DBL(0.5612514770781683), FL2FXCONST_DBL(0.5623787708659898), + FL2FXCONST_DBL(0.5635066298551742), FL2FXCONST_DBL(0.5646350534798125), + FL2FXCONST_DBL(0.5657640411754097), FL2FXCONST_DBL(0.5668935923788799), + FL2FXCONST_DBL(0.5680237065285404), FL2FXCONST_DBL(0.5691543830641059), + FL2FXCONST_DBL(0.5702856214266832), FL2FXCONST_DBL(0.5714174210587655), + FL2FXCONST_DBL(0.5725497814042271), FL2FXCONST_DBL(0.5736827019083177), + FL2FXCONST_DBL(0.5748161820176573), FL2FXCONST_DBL(0.5759502211802304), + FL2FXCONST_DBL(0.5770848188453810), FL2FXCONST_DBL(0.5782199744638067), + FL2FXCONST_DBL(0.5793556874875542), FL2FXCONST_DBL(0.5804919573700131), + FL2FXCONST_DBL(0.5816287835659116), FL2FXCONST_DBL(0.5827661655313104), + FL2FXCONST_DBL(0.5839041027235979), FL2FXCONST_DBL(0.5850425946014850), + FL2FXCONST_DBL(0.5861816406250000), FL2FXCONST_DBL(0.5873212402554834), + FL2FXCONST_DBL(0.5884613929555826), FL2FXCONST_DBL(0.5896020981892474), + FL2FXCONST_DBL(0.5907433554217242), FL2FXCONST_DBL(0.5918851641195517), + FL2FXCONST_DBL(0.5930275237505556), FL2FXCONST_DBL(0.5941704337838434), + FL2FXCONST_DBL(0.5953138936897999), FL2FXCONST_DBL(0.5964579029400819), + FL2FXCONST_DBL(0.5976024610076139), FL2FXCONST_DBL(0.5987475673665825), + FL2FXCONST_DBL(0.5998932214924321), FL2FXCONST_DBL(0.6010394228618597), + FL2FXCONST_DBL(0.6021861709528106), FL2FXCONST_DBL(0.6033334652444733), + FL2FXCONST_DBL(0.6044813052172748), FL2FXCONST_DBL(0.6056296903528761), + FL2FXCONST_DBL(0.6067786201341671), FL2FXCONST_DBL(0.6079280940452625), + FL2FXCONST_DBL(0.6090781115714966), FL2FXCONST_DBL(0.6102286721994192), + FL2FXCONST_DBL(0.6113797754167908), FL2FXCONST_DBL(0.6125314207125777), + FL2FXCONST_DBL(0.6136836075769482), FL2FXCONST_DBL(0.6148363355012674), + FL2FXCONST_DBL(0.6159896039780929), FL2FXCONST_DBL(0.6171434125011708), + FL2FXCONST_DBL(0.6182977605654305), FL2FXCONST_DBL(0.6194526476669808), + FL2FXCONST_DBL(0.6206080733031054), FL2FXCONST_DBL(0.6217640369722584), + FL2FXCONST_DBL(0.6229205381740598), FL2FXCONST_DBL(0.6240775764092919), + FL2FXCONST_DBL(0.6252351511798939), FL2FXCONST_DBL(0.6263932619889586), + FL2FXCONST_DBL(0.6275519083407275), FL2FXCONST_DBL(0.6287110897405869), + FL2FXCONST_DBL(0.6298708056950635), FL2FXCONST_DBL(0.6310310557118203), + FL2FXCONST_DBL(0.6321918392996523), FL2FXCONST_DBL(0.6333531559684823), + FL2FXCONST_DBL(0.6345150052293571), FL2FXCONST_DBL(0.6356773865944432), + FL2FXCONST_DBL(0.6368402995770224), FL2FXCONST_DBL(0.6380037436914881), + FL2FXCONST_DBL(0.6391677184533411), FL2FXCONST_DBL(0.6403322233791856), + FL2FXCONST_DBL(0.6414972579867254), FL2FXCONST_DBL(0.6426628217947594), + FL2FXCONST_DBL(0.6438289143231779), FL2FXCONST_DBL(0.6449955350929588), + FL2FXCONST_DBL(0.6461626836261636), FL2FXCONST_DBL(0.6473303594459330), + FL2FXCONST_DBL(0.6484985620764839), FL2FXCONST_DBL(0.6496672910431047), + FL2FXCONST_DBL(0.6508365458721518), FL2FXCONST_DBL(0.6520063260910459), + FL2FXCONST_DBL(0.6531766312282679), FL2FXCONST_DBL(0.6543474608133552), + FL2FXCONST_DBL(0.6555188143768979), FL2FXCONST_DBL(0.6566906914505349), + FL2FXCONST_DBL(0.6578630915669509), FL2FXCONST_DBL(0.6590360142598715), + FL2FXCONST_DBL(0.6602094590640603), FL2FXCONST_DBL(0.6613834255153149), + FL2FXCONST_DBL(0.6625579131504635), FL2FXCONST_DBL(0.6637329215073610), + FL2FXCONST_DBL(0.6649084501248851), FL2FXCONST_DBL(0.6660844985429335), + FL2FXCONST_DBL(0.6672610663024197), FL2FXCONST_DBL(0.6684381529452691), + FL2FXCONST_DBL(0.6696157580144163), FL2FXCONST_DBL(0.6707938810538011), + FL2FXCONST_DBL(0.6719725216083646), FL2FXCONST_DBL(0.6731516792240465), + FL2FXCONST_DBL(0.6743313534477807), FL2FXCONST_DBL(0.6755115438274927), + FL2FXCONST_DBL(0.6766922499120955), FL2FXCONST_DBL(0.6778734712514865), + FL2FXCONST_DBL(0.6790552073965435), FL2FXCONST_DBL(0.6802374578991223), + FL2FXCONST_DBL(0.6814202223120524), FL2FXCONST_DBL(0.6826035001891340), + FL2FXCONST_DBL(0.6837872910851345), FL2FXCONST_DBL(0.6849715945557853), + FL2FXCONST_DBL(0.6861564101577784), FL2FXCONST_DBL(0.6873417374487629), + FL2FXCONST_DBL(0.6885275759873420), FL2FXCONST_DBL(0.6897139253330697), + FL2FXCONST_DBL(0.6909007850464473), FL2FXCONST_DBL(0.6920881546889198), + FL2FXCONST_DBL(0.6932760338228737), FL2FXCONST_DBL(0.6944644220116332), + FL2FXCONST_DBL(0.6956533188194565), FL2FXCONST_DBL(0.6968427238115332), + FL2FXCONST_DBL(0.6980326365539813), FL2FXCONST_DBL(0.6992230566138435), + FL2FXCONST_DBL(0.7004139835590845), FL2FXCONST_DBL(0.7016054169585869), + FL2FXCONST_DBL(0.7027973563821499), FL2FXCONST_DBL(0.7039898014004843), + FL2FXCONST_DBL(0.7051827515852106), FL2FXCONST_DBL(0.7063762065088554), + FL2FXCONST_DBL(0.7075701657448483), FL2FXCONST_DBL(0.7087646288675196), + FL2FXCONST_DBL(0.7099595954520960), FL2FXCONST_DBL(0.7111550650746988), + FL2FXCONST_DBL(0.7123510373123402), FL2FXCONST_DBL(0.7135475117429202), + FL2FXCONST_DBL(0.7147444879452244), FL2FXCONST_DBL(0.7159419654989200), + FL2FXCONST_DBL(0.7171399439845538), FL2FXCONST_DBL(0.7183384229835486), + FL2FXCONST_DBL(0.7195374020782005), FL2FXCONST_DBL(0.7207368808516762), + FL2FXCONST_DBL(0.7219368588880097), FL2FXCONST_DBL(0.7231373357720997), + FL2FXCONST_DBL(0.7243383110897066), FL2FXCONST_DBL(0.7255397844274496), + FL2FXCONST_DBL(0.7267417553728043), FL2FXCONST_DBL(0.7279442235140992), + FL2FXCONST_DBL(0.7291471884405130), FL2FXCONST_DBL(0.7303506497420724), + FL2FXCONST_DBL(0.7315546070096487), FL2FXCONST_DBL(0.7327590598349553), + FL2FXCONST_DBL(0.7339640078105445), FL2FXCONST_DBL(0.7351694505298055), + FL2FXCONST_DBL(0.7363753875869610), FL2FXCONST_DBL(0.7375818185770647), + FL2FXCONST_DBL(0.7387887430959987), FL2FXCONST_DBL(0.7399961607404706), + FL2FXCONST_DBL(0.7412040711080108), FL2FXCONST_DBL(0.7424124737969701), + FL2FXCONST_DBL(0.7436213684065166), FL2FXCONST_DBL(0.7448307545366334), + FL2FXCONST_DBL(0.7460406317881158), FL2FXCONST_DBL(0.7472509997625686), + FL2FXCONST_DBL(0.7484618580624036), FL2FXCONST_DBL(0.7496732062908372), + FL2FXCONST_DBL(0.7508850440518872), FL2FXCONST_DBL(0.7520973709503704), + FL2FXCONST_DBL(0.7533101865919009), FL2FXCONST_DBL(0.7545234905828862), + FL2FXCONST_DBL(0.7557372825305252), FL2FXCONST_DBL(0.7569515620428062), + FL2FXCONST_DBL(0.7581663287285035), FL2FXCONST_DBL(0.7593815821971756), + FL2FXCONST_DBL(0.7605973220591619), FL2FXCONST_DBL(0.7618135479255810), + FL2FXCONST_DBL(0.7630302594083277), FL2FXCONST_DBL(0.7642474561200708), + FL2FXCONST_DBL(0.7654651376742505), FL2FXCONST_DBL(0.7666833036850760), + FL2FXCONST_DBL(0.7679019537675227), FL2FXCONST_DBL(0.7691210875373307), + FL2FXCONST_DBL(0.7703407046110011), FL2FXCONST_DBL(0.7715608046057948), + FL2FXCONST_DBL(0.7727813871397293), FL2FXCONST_DBL(0.7740024518315765), + FL2FXCONST_DBL(0.7752239983008605), FL2FXCONST_DBL(0.7764460261678551), + FL2FXCONST_DBL(0.7776685350535814), FL2FXCONST_DBL(0.7788915245798054), + FL2FXCONST_DBL(0.7801149943690360), FL2FXCONST_DBL(0.7813389440445223), + FL2FXCONST_DBL(0.7825633732302513), FL2FXCONST_DBL(0.7837882815509458), + FL2FXCONST_DBL(0.7850136686320621), FL2FXCONST_DBL(0.7862395340997874), + FL2FXCONST_DBL(0.7874658775810378), FL2FXCONST_DBL(0.7886926987034559), + FL2FXCONST_DBL(0.7899199970954088), FL2FXCONST_DBL(0.7911477723859853), + FL2FXCONST_DBL(0.7923760242049944), FL2FXCONST_DBL(0.7936047521829623), + FL2FXCONST_DBL(0.7948339559511308), FL2FXCONST_DBL(0.7960636351414546), + FL2FXCONST_DBL(0.7972937893865995), FL2FXCONST_DBL(0.7985244183199399), + FL2FXCONST_DBL(0.7997555215755570), FL2FXCONST_DBL(0.8009870987882359), + FL2FXCONST_DBL(0.8022191495934644), FL2FXCONST_DBL(0.8034516736274301), + FL2FXCONST_DBL(0.8046846705270185), FL2FXCONST_DBL(0.8059181399298110), + FL2FXCONST_DBL(0.8071520814740822), FL2FXCONST_DBL(0.8083864947987989), + FL2FXCONST_DBL(0.8096213795436166), FL2FXCONST_DBL(0.8108567353488784), + FL2FXCONST_DBL(0.8120925618556127), FL2FXCONST_DBL(0.8133288587055308), + FL2FXCONST_DBL(0.8145656255410253), FL2FXCONST_DBL(0.8158028620051674), + FL2FXCONST_DBL(0.8170405677417053), FL2FXCONST_DBL(0.8182787423950622), + FL2FXCONST_DBL(0.8195173856103341), FL2FXCONST_DBL(0.8207564970332875), + FL2FXCONST_DBL(0.8219960763103580), FL2FXCONST_DBL(0.8232361230886477), + FL2FXCONST_DBL(0.8244766370159234), FL2FXCONST_DBL(0.8257176177406150), + FL2FXCONST_DBL(0.8269590649118125), FL2FXCONST_DBL(0.8282009781792650), + FL2FXCONST_DBL(0.8294433571933784), FL2FXCONST_DBL(0.8306862016052132), + FL2FXCONST_DBL(0.8319295110664831), FL2FXCONST_DBL(0.8331732852295520), + FL2FXCONST_DBL(0.8344175237474336), FL2FXCONST_DBL(0.8356622262737878), + FL2FXCONST_DBL(0.8369073924629202), FL2FXCONST_DBL(0.8381530219697793), + FL2FXCONST_DBL(0.8393991144499545), FL2FXCONST_DBL(0.8406456695596752), + FL2FXCONST_DBL(0.8418926869558079), FL2FXCONST_DBL(0.8431401662958544), + FL2FXCONST_DBL(0.8443881072379507), FL2FXCONST_DBL(0.8456365094408642), + FL2FXCONST_DBL(0.8468853725639923), FL2FXCONST_DBL(0.8481346962673606), + FL2FXCONST_DBL(0.8493844802116208), FL2FXCONST_DBL(0.8506347240580492), + FL2FXCONST_DBL(0.8518854274685442), FL2FXCONST_DBL(0.8531365901056253), + FL2FXCONST_DBL(0.8543882116324307), FL2FXCONST_DBL(0.8556402917127157), + FL2FXCONST_DBL(0.8568928300108512), FL2FXCONST_DBL(0.8581458261918209), + FL2FXCONST_DBL(0.8593992799212207), FL2FXCONST_DBL(0.8606531908652563), + FL2FXCONST_DBL(0.8619075586907414), FL2FXCONST_DBL(0.8631623830650962), + FL2FXCONST_DBL(0.8644176636563452), FL2FXCONST_DBL(0.8656734001331161), + FL2FXCONST_DBL(0.8669295921646375), FL2FXCONST_DBL(0.8681862394207371), + FL2FXCONST_DBL(0.8694433415718407), FL2FXCONST_DBL(0.8707008982889695), + FL2FXCONST_DBL(0.8719589092437391), FL2FXCONST_DBL(0.8732173741083574), + FL2FXCONST_DBL(0.8744762925556232), FL2FXCONST_DBL(0.8757356642589241), + FL2FXCONST_DBL(0.8769954888922352), FL2FXCONST_DBL(0.8782557661301171), + FL2FXCONST_DBL(0.8795164956477146), FL2FXCONST_DBL(0.8807776771207545), + FL2FXCONST_DBL(0.8820393102255443), FL2FXCONST_DBL(0.8833013946389704), + FL2FXCONST_DBL(0.8845639300384969), FL2FXCONST_DBL(0.8858269161021629), + FL2FXCONST_DBL(0.8870903525085819), FL2FXCONST_DBL(0.8883542389369399), + FL2FXCONST_DBL(0.8896185750669933), FL2FXCONST_DBL(0.8908833605790678), + FL2FXCONST_DBL(0.8921485951540565), FL2FXCONST_DBL(0.8934142784734187), + FL2FXCONST_DBL(0.8946804102191776), FL2FXCONST_DBL(0.8959469900739191), + FL2FXCONST_DBL(0.8972140177207906), FL2FXCONST_DBL(0.8984814928434985), + FL2FXCONST_DBL(0.8997494151263077), FL2FXCONST_DBL(0.9010177842540390), + FL2FXCONST_DBL(0.9022865999120682), FL2FXCONST_DBL(0.9035558617863242), + FL2FXCONST_DBL(0.9048255695632878), FL2FXCONST_DBL(0.9060957229299895), + FL2FXCONST_DBL(0.9073663215740092), FL2FXCONST_DBL(0.9086373651834729), + FL2FXCONST_DBL(0.9099088534470528), FL2FXCONST_DBL(0.9111807860539647), + FL2FXCONST_DBL(0.9124531626939672), FL2FXCONST_DBL(0.9137259830573594), + FL2FXCONST_DBL(0.9149992468349805), FL2FXCONST_DBL(0.9162729537182071), + FL2FXCONST_DBL(0.9175471033989524), FL2FXCONST_DBL(0.9188216955696648), + FL2FXCONST_DBL(0.9200967299233258), FL2FXCONST_DBL(0.9213722061534494), + FL2FXCONST_DBL(0.9226481239540795), FL2FXCONST_DBL(0.9239244830197896), + FL2FXCONST_DBL(0.9252012830456805), FL2FXCONST_DBL(0.9264785237273793), + FL2FXCONST_DBL(0.9277562047610376), FL2FXCONST_DBL(0.9290343258433305), + FL2FXCONST_DBL(0.9303128866714547), FL2FXCONST_DBL(0.9315918869431275), + FL2FXCONST_DBL(0.9328713263565848), FL2FXCONST_DBL(0.9341512046105802), + FL2FXCONST_DBL(0.9354315214043836), FL2FXCONST_DBL(0.9367122764377792), + FL2FXCONST_DBL(0.9379934694110648), FL2FXCONST_DBL(0.9392751000250497), + FL2FXCONST_DBL(0.9405571679810542), FL2FXCONST_DBL(0.9418396729809072), + FL2FXCONST_DBL(0.9431226147269456), FL2FXCONST_DBL(0.9444059929220124), + FL2FXCONST_DBL(0.9456898072694558), FL2FXCONST_DBL(0.9469740574731275), + FL2FXCONST_DBL(0.9482587432373810), FL2FXCONST_DBL(0.9495438642670713), + FL2FXCONST_DBL(0.9508294202675522), FL2FXCONST_DBL(0.9521154109446763), + FL2FXCONST_DBL(0.9534018360047926), FL2FXCONST_DBL(0.9546886951547455), + FL2FXCONST_DBL(0.9559759881018738), FL2FXCONST_DBL(0.9572637145540087), + FL2FXCONST_DBL(0.9585518742194732), FL2FXCONST_DBL(0.9598404668070802), + FL2FXCONST_DBL(0.9611294920261317), FL2FXCONST_DBL(0.9624189495864168), + FL2FXCONST_DBL(0.9637088391982110), FL2FXCONST_DBL(0.9649991605722750), + FL2FXCONST_DBL(0.9662899134198524), FL2FXCONST_DBL(0.9675810974526697), + FL2FXCONST_DBL(0.9688727123829343), FL2FXCONST_DBL(0.9701647579233330), + FL2FXCONST_DBL(0.9714572337870316), FL2FXCONST_DBL(0.9727501396876727), + FL2FXCONST_DBL(0.9740434753393749), FL2FXCONST_DBL(0.9753372404567313), + FL2FXCONST_DBL(0.9766314347548087), FL2FXCONST_DBL(0.9779260579491460), + FL2FXCONST_DBL(0.9792211097557527), FL2FXCONST_DBL(0.9805165898911081), + FL2FXCONST_DBL(0.9818124980721600), FL2FXCONST_DBL(0.9831088340163232), + FL2FXCONST_DBL(0.9844055974414786), FL2FXCONST_DBL(0.9857027880659716), + FL2FXCONST_DBL(0.9870004056086111), FL2FXCONST_DBL(0.9882984497886684), + FL2FXCONST_DBL(0.9895969203258759), FL2FXCONST_DBL(0.9908958169404255), + FL2FXCONST_DBL(0.9921951393529680), FL2FXCONST_DBL(0.9934948872846116), + FL2FXCONST_DBL(0.9947950604569206), FL2FXCONST_DBL(0.9960956585919144), + FL2FXCONST_DBL(0.9973966814120665), FL2FXCONST_DBL(0.9986981286403025)}; + +const FIXP_DBL FDKaacEnc_specExpMantTableCombElc[4][14] = { + {FL2FXCONST_DBL(0.5000000000000000), FL2FXCONST_DBL(0.6299605249474366), + FL2FXCONST_DBL(0.7937005259840998), FL2FXCONST_DBL(0.5000000000000000), + FL2FXCONST_DBL(0.6299605249474366), FL2FXCONST_DBL(0.7937005259840998), + FL2FXCONST_DBL(0.5000000000000000), FL2FXCONST_DBL(0.6299605249474366), + FL2FXCONST_DBL(0.7937005259840998), FL2FXCONST_DBL(0.5000000000000000), + FL2FXCONST_DBL(0.6299605249474366), FL2FXCONST_DBL(0.7937005259840998), + FL2FXCONST_DBL(0.5000000000000000), FL2FXCONST_DBL(0.6299605249474366)}, + + {FL2FXCONST_DBL(0.5946035575013605), FL2FXCONST_DBL(0.7491535384383408), + FL2FXCONST_DBL(0.9438743126816935), FL2FXCONST_DBL(0.5946035575013605), + FL2FXCONST_DBL(0.7491535384383408), FL2FXCONST_DBL(0.9438743126816935), + FL2FXCONST_DBL(0.5946035575013605), FL2FXCONST_DBL(0.7491535384383408), + FL2FXCONST_DBL(0.9438743126816935), FL2FXCONST_DBL(0.5946035575013605), + FL2FXCONST_DBL(0.7491535384383408), FL2FXCONST_DBL(0.9438743126816935), + FL2FXCONST_DBL(0.5946035575013605), FL2FXCONST_DBL(0.7491535384383408)}, + + {FL2FXCONST_DBL(0.7071067811865476), FL2FXCONST_DBL(0.8908987181403393), + FL2FXCONST_DBL(0.5612310241546865), FL2FXCONST_DBL(0.7071067811865476), + FL2FXCONST_DBL(0.8908987181403393), FL2FXCONST_DBL(0.5612310241546865), + FL2FXCONST_DBL(0.7071067811865476), FL2FXCONST_DBL(0.8908987181403393), + FL2FXCONST_DBL(0.5612310241546865), FL2FXCONST_DBL(0.7071067811865476), + FL2FXCONST_DBL(0.8908987181403393), FL2FXCONST_DBL(0.5612310241546865), + FL2FXCONST_DBL(0.7071067811865476), FL2FXCONST_DBL(0.8908987181403393)}, + + {FL2FXCONST_DBL(0.8408964152537145), FL2FXCONST_DBL(0.5297315471796477), + FL2FXCONST_DBL(0.6674199270850172), FL2FXCONST_DBL(0.8408964152537145), + FL2FXCONST_DBL(0.5297315471796477), FL2FXCONST_DBL(0.6674199270850172), + FL2FXCONST_DBL(0.8408964152537145), FL2FXCONST_DBL(0.5297315471796477), + FL2FXCONST_DBL(0.6674199270850172), FL2FXCONST_DBL(0.8408964152537145), + FL2FXCONST_DBL(0.5297315471796477), FL2FXCONST_DBL(0.6674199270850172), + FL2FXCONST_DBL(0.8408964152537145), FL2FXCONST_DBL(0.5297315471796477)}}; + +const UCHAR FDKaacEnc_specExpTableComb[4][14] = { + {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18}, + {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18}, + {1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 16, 17, 18}, + {1, 3, 4, 5, 7, 8, 9, 11, 12, 13, 15, 16, 17, 19}}; #define WTS0 1 #define WTS1 0 #define WTS2 -2 const FIXP_WTB ELDAnalysis512[1536] = { - /* part 0 */ - WTC0(0xfac5a770), WTC0(0xfaafbab8), WTC0(0xfa996a40), WTC0(0xfa82bbd0), WTC0(0xfa6bb538), WTC0(0xfa545c38), WTC0(0xfa3cb698), WTC0(0xfa24ca28), - WTC0(0xfa0c9ca8), WTC0(0xf9f433e8), WTC0(0xf9db9580), WTC0(0xf9c2c298), WTC0(0xf9a9b800), WTC0(0xf9907250), WTC0(0xf976ee38), WTC0(0xf95d2b88), - WTC0(0xf9432d10), WTC0(0xf928f5c0), WTC0(0xf90e8868), WTC0(0xf8f3e400), WTC0(0xf8d903a0), WTC0(0xf8bde238), WTC0(0xf8a27af0), WTC0(0xf886cde8), - WTC0(0xf86ae020), WTC0(0xf84eb6c0), WTC0(0xf83256f8), WTC0(0xf815c4b8), WTC0(0xf7f902c0), WTC0(0xf7dc13b0), WTC0(0xf7befa60), WTC0(0xf7a1ba40), - WTC0(0xf78457c0), WTC0(0xf766d780), WTC0(0xf7493d90), WTC0(0xf72b8990), WTC0(0xf70db5f0), WTC0(0xf6efbd30), WTC0(0xf6d19a20), WTC0(0xf6b352e0), - WTC0(0xf694f8c0), WTC0(0xf6769da0), WTC0(0xf6585310), WTC0(0xf63a28d0), WTC0(0xf61c2c60), WTC0(0xf5fe6b10), WTC0(0xf5e0f250), WTC0(0xf5c3ceb0), - WTC0(0xf5a70be0), WTC0(0xf58ab5a0), WTC0(0xf56ed7b0), WTC0(0xf5537e40), WTC0(0xf538b610), WTC0(0xf51e8bf0), WTC0(0xf5050c90), WTC0(0xf4ec4330), - WTC0(0xf4d439b0), WTC0(0xf4bcf9b0), WTC0(0xf4a68ce0), WTC0(0xf490fa80), WTC0(0xf47c4760), WTC0(0xf4687830), WTC0(0xf4558f00), WTC0(0xf4434fc0), - WTC0(0xf4314070), WTC0(0xf41ee450), WTC0(0xf40bc130), WTC0(0xf3f799c0), WTC0(0xf3e26d30), WTC0(0xf3cc3d70), WTC0(0xf3b50c80), WTC0(0xf39cdd60), - WTC0(0xf383b440), WTC0(0xf3699550), WTC0(0xf34e84c0), WTC0(0xf33286b0), WTC0(0xf3159f10), WTC0(0xf2f7d1b0), WTC0(0xf2d92290), WTC0(0xf2b994d0), - WTC0(0xf2992ad0), WTC0(0xf277e6d0), WTC0(0xf255cb60), WTC0(0xf232dd00), WTC0(0xf20f2240), WTC0(0xf1eaa1d0), WTC0(0xf1c56240), WTC0(0xf19f63d0), - WTC0(0xf178a0f0), WTC0(0xf15113a0), WTC0(0xf128b5c0), WTC0(0xf0ff7fd0), WTC0(0xf0d56860), WTC0(0xf0aa6610), WTC0(0xf07e6fd0), WTC0(0xf0518190), - WTC0(0xf0239cd0), WTC0(0xeff4c320), WTC0(0xefc4f720), WTC0(0xef945080), WTC0(0xef62fce0), WTC0(0xef312a40), WTC0(0xeeff05c0), WTC0(0xeecca2c0), - WTC0(0xee99faa0), WTC0(0xee6705a0), WTC0(0xee33bb60), WTC0(0xee000060), WTC0(0xedcba660), WTC0(0xed967e80), WTC0(0xed605b80), WTC0(0xed293b40), - WTC0(0xecf146a0), WTC0(0xecb8a8a0), WTC0(0xec7f8bc0), WTC0(0xec461260), WTC0(0xec0c5720), WTC0(0xebd27440), WTC0(0xeb988220), WTC0(0xeb5e7040), - WTC0(0xeb2404c0), WTC0(0xeae90440), WTC0(0xeaad33c0), WTC0(0xea7066c0), WTC0(0xea327f60), WTC0(0xe9f36000), WTC0(0xe9b2ed60), WTC0(0xe9713920), - WTC0(0xe92e81e0), WTC0(0xe8eb08c0), WTC0(0xe8a70e60), WTC0(0xe862d8e0), WTC0(0xe81eb340), WTC0(0xe7dae8a0), WTC0(0xe797c1a0), WTC0(0xe7554ca0), - WTC0(0xe7135dc0), WTC0(0xe6d1c6a0), WTC0(0xe6905720), WTC0(0xe64eb9c0), WTC0(0xe60c7300), WTC0(0xe5c90600), WTC0(0xe583f920), WTC0(0xe53d1ce0), - WTC0(0xe4f48c80), WTC0(0xe4aa6640), WTC0(0xe45ecaa0), WTC0(0xe4120be0), WTC0(0xe3c4ae60), WTC0(0xe3773860), WTC0(0xe32a2ea0), WTC0(0xe2ddeea0), - WTC0(0xe292af00), WTC0(0xe248a4a0), WTC0(0xe2000140), WTC0(0xe1b8b640), WTC0(0xe1727440), WTC0(0xe12ce900), WTC0(0xe0e7c280), WTC0(0xe0a2b420), - WTC0(0xe05d76c0), WTC0(0xe017c360), WTC0(0xdfd15440), WTC0(0xdf8a0540), WTC0(0xdf41d300), WTC0(0xdef8bb40), WTC0(0xdeaebd40), WTC0(0xde63e7c0), - WTC0(0xde185940), WTC0(0xddcc3180), WTC0(0xdd7f9000), WTC0(0xdd329e80), WTC0(0xdce58e80), WTC0(0xdc989300), WTC0(0xdc4bde40), WTC0(0xdbff96c0), - WTC0(0xdbb3d780), WTC0(0xdb68bb80), WTC0(0xdb1e5c80), WTC0(0xdad4c380), WTC0(0xda8be840), WTC0(0xda43c1c0), WTC0(0xd9fc4740), WTC0(0xd9b56640), - WTC0(0xd96f0440), WTC0(0xd9290600), WTC0(0xd8e35080), WTC0(0xd89dcd40), WTC0(0xd8586b40), WTC0(0xd8131940), WTC0(0xd7cdc640), WTC0(0xd7886180), - WTC0(0xd742dc80), WTC0(0xd6fd2780), WTC0(0xd6b73400), WTC0(0xd670fd80), WTC0(0xd62a8a40), WTC0(0xd5e3e080), WTC0(0xd59d0840), WTC0(0xd5562b80), - WTC0(0xd50f9540), WTC0(0xd4c992c0), WTC0(0xd4846f80), WTC0(0xd4405a80), WTC0(0xd3fd6580), WTC0(0xd3bba140), WTC0(0xd37b1c80), WTC0(0xd33bb780), - WTC0(0xd2fd2400), WTC0(0xd2bf1240), WTC0(0xd2813300), WTC0(0xd2435ac0), WTC0(0xd2057fc0), WTC0(0xd1c79a00), WTC0(0xd189a240), WTC0(0xd14b9dc0), - WTC0(0xd10d9e00), WTC0(0xd0cfb580), WTC0(0xd091f6c0), WTC0(0xd0548100), WTC0(0xd0177f40), WTC0(0xcfdb1cc0), WTC0(0xcf9f84c0), WTC0(0xcf64d780), - WTC0(0xcf2b2b00), WTC0(0xcef29440), WTC0(0xcebb2640), WTC0(0xce84c000), WTC0(0xce4f0bc0), WTC0(0xce19b200), WTC0(0xcde45d40), WTC0(0xcdaeedc0), - WTC0(0xcd7979c0), WTC0(0xcd4419c0), WTC0(0xcd0ee6c0), WTC0(0xccda0540), WTC0(0xcca5a500), WTC0(0xcc71f640), WTC0(0xcc3f2800), WTC0(0xcc0d4300), - WTC0(0xcbdc2a00), WTC0(0xcbabbe80), WTC0(0xcb7be200), WTC0(0xcb4c8200), WTC0(0xcb1d9800), WTC0(0xcaef1d40), WTC0(0xcac10bc0), WTC0(0xca936440), - WTC0(0xca662d00), WTC0(0xca396d40), WTC0(0xca0d2b80), WTC0(0xc9e16f80), WTC0(0xc9b63f80), WTC0(0xc98ba2c0), WTC0(0xc961a000), WTC0(0xc9383ec0), - WTC0(0xc90a0440), WTC0(0xc8e0d280), WTC0(0xc8b73b80), WTC0(0xc88d4900), WTC0(0xc86304c0), WTC0(0xc83878c0), WTC0(0xc80dae80), WTC0(0xc7e2afc0), - WTC0(0xc7b78640), WTC0(0xc78c3c40), WTC0(0xc760da80), WTC0(0xc7356640), WTC0(0xc709de40), WTC0(0xc6de41c0), WTC0(0xc6b28fc0), WTC0(0xc686bd40), - WTC0(0xc65ab600), WTC0(0xc62e6580), WTC0(0xc601b880), WTC0(0xc5d4bac0), WTC0(0xc5a79640), WTC0(0xc57a76c0), WTC0(0xc54d8780), WTC0(0xc520e840), - WTC0(0xc4f4acc0), WTC0(0xc4c8e880), WTC0(0xc49dad80), WTC0(0xc472e640), WTC0(0xc44856c0), WTC0(0xc41dc140), WTC0(0xc3f2e940), WTC0(0xc3c7bc00), - WTC0(0xc39c4f00), WTC0(0xc370b9c0), WTC0(0xc34513c0), WTC0(0xc3197940), WTC0(0xc2ee0a00), WTC0(0xc2c2e640), WTC0(0xc2982d80), WTC0(0xc26df5c0), - WTC0(0xc2444b00), WTC0(0xc21b3940), WTC0(0xc1f2cbc0), WTC0(0xc1cb05c0), WTC0(0xc1a3e340), WTC0(0xc17d5f00), WTC0(0xc15773c0), WTC0(0xc1320940), - WTC0(0xc10cf480), WTC0(0xc0e80a00), WTC0(0xc0c31f00), WTC0(0xc09e2640), WTC0(0xc0792ec0), WTC0(0xc0544940), WTC0(0xc02f86c0), WTC0(0xc00b04c0), - WTC0(0xbfe6ed01), WTC0(0xbfc36a01), WTC0(0xbfa0a581), WTC0(0xbf7eb581), WTC0(0xbf5d9a81), WTC0(0xbf3d5501), WTC0(0xbf1de601), WTC0(0xbeff4801), - WTC0(0xbee17201), WTC0(0xbec45881), WTC0(0xbea7f301), WTC0(0xbe8c3781), WTC0(0xbe712001), WTC0(0xbe56a381), WTC0(0xbe3cbc01), WTC0(0xbe236001), - WTC0(0xbe0a8581), WTC0(0xbdf22181), WTC0(0xbdda2a01), WTC0(0xbdc29a81), WTC0(0xbdab7181), WTC0(0xbd94b001), WTC0(0xbd7e5581), WTC0(0xbd686681), - WTC0(0xbd52eb01), WTC0(0xbd3deb81), WTC0(0xbd297181), WTC0(0xbd158801), WTC0(0xbd023f01), WTC0(0xbcefa601), WTC0(0xbcddcc81), WTC0(0xbcccbd01), - WTC0(0xbcbc7e01), WTC0(0xbcad1501), WTC0(0xbc9e8801), WTC0(0xbc90d481), WTC0(0xbc83f201), WTC0(0xbc77d601), WTC0(0xbc6c7781), WTC0(0xbc61c401), - WTC0(0xbc57a301), WTC0(0xbc4dfb81), WTC0(0xbc44b481), WTC0(0xbc3bbc01), WTC0(0xbc330781), WTC0(0xbc2a8c81), WTC0(0xbc224181), WTC0(0xbc1a2401), - WTC0(0xbc123b81), WTC0(0xbc0a8f01), WTC0(0xbc032601), WTC0(0xbbfc0f81), WTC0(0xbbf56181), WTC0(0xbbef3301), WTC0(0xbbe99981), WTC0(0xbbe49d01), - WTC0(0xbbe03801), WTC0(0xbbdc6481), WTC0(0xbbd91b81), WTC0(0xbbd64d01), WTC0(0xbbd3e101), WTC0(0xbbd1bd81), WTC0(0xbbcfca81), WTC0(0xbbce0601), - WTC0(0xbbcc8201), WTC0(0xbbcb5301), WTC0(0xbbca8d01), WTC0(0xbbca5081), WTC0(0xbbcaca01), WTC0(0xbbcc2681), WTC0(0xbbce9181), WTC0(0xbbd21281), - WTC0(0xbbd68c81), WTC0(0xbbdbe201), WTC0(0xbbe1f401), WTC0(0xbbe89901), WTC0(0xbbef9b81), WTC0(0xbbf6c601), WTC0(0xbbfde481), WTC0(0xbc04e381), - WTC0(0xbc0bcf81), WTC0(0xbc12b801), WTC0(0xbc19ab01), WTC0(0xbc20ae01), WTC0(0xbc27bd81), WTC0(0xbc2ed681), WTC0(0xbc35f501), WTC0(0xbc3d1801), - WTC0(0xbc444081), WTC0(0xbc4b6e81), WTC0(0xbc52a381), WTC0(0xbc59df81), WTC0(0xbc612301), WTC0(0xbc686e01), WTC0(0xbc6fc101), WTC0(0xbc771c01), - WTC0(0xbc7e7e01), WTC0(0xbc85e801), WTC0(0xbc8d5901), WTC0(0xbc94d201), WTC0(0xbc9c5281), WTC0(0xbca3db01), WTC0(0xbcab6c01), WTC0(0xbcb30601), - WTC0(0xbcbaa801), WTC0(0xbcc25181), WTC0(0xbcca0301), WTC0(0xbcd1bb81), WTC0(0xbcd97c81), WTC0(0xbce14601), WTC0(0xbce91801), WTC0(0xbcf0f381), - WTC0(0xbcf8d781), WTC0(0xbd00c381), WTC0(0xbd08b781), WTC0(0xbd10b381), WTC0(0xbd18b781), WTC0(0xbd20c401), WTC0(0xbd28d981), WTC0(0xbd30f881), - WTC0(0xbd391f81), WTC0(0xbd414f01), WTC0(0xbd498601), WTC0(0xbd51c481), WTC0(0xbd5a0b01), WTC0(0xbd625981), WTC0(0xbd6ab101), WTC0(0xbd731081), - WTC0(0xbd7b7781), WTC0(0xbd83e681), WTC0(0xbd8c5c01), WTC0(0xbd94d801), WTC0(0xbd9d5b81), WTC0(0xbda5e601), WTC0(0xbdae7881), WTC0(0xbdb71201), - WTC0(0xbdbfb281), WTC0(0xbdc85981), WTC0(0xbdd10681), WTC0(0xbdd9b981), WTC0(0xbde27201), WTC0(0xbdeb3101), WTC0(0xbdf3f701), WTC0(0xbdfcc301), - WTC0(0xbe059481), WTC0(0xbe0e6c01), WTC0(0xbe174781), WTC0(0xbe202801), WTC0(0xbe290d01), WTC0(0xbe31f701), WTC0(0xbe3ae601), WTC0(0xbe43da81), - WTC0(0xbe4cd381), WTC0(0xbe55d001), WTC0(0xbe5ed081), WTC0(0xbe67d381), WTC0(0xbe70da01), WTC0(0xbe79e481), WTC0(0xbe82f301), WTC0(0xbe8c0501), - WTC0(0xbe951a81), WTC0(0xbe9e3281), WTC0(0xbea74c81), WTC0(0xbeb06881), WTC0(0xbeb98681), WTC0(0xbec2a781), WTC0(0xbecbca81), WTC0(0xbed4f081), - WTC0(0xbede1901), WTC0(0xbee74281), WTC0(0xbef06d01), WTC0(0xbef99901), WTC0(0xbf02c581), WTC0(0xbf0bf381), WTC0(0xbf152381), WTC0(0xbf1e5501), - WTC0(0xbf278801), WTC0(0xbf30bb01), WTC0(0xbf39ee81), WTC0(0xbf432281), WTC0(0xbf4c5681), WTC0(0xbf558b01), WTC0(0xbf5ec101), WTC0(0xbf67f801), - WTC0(0xbf712f01), WTC0(0xbf7a6681), WTC0(0xbf839d81), WTC0(0xbf8cd481), WTC0(0xbf960b01), WTC0(0xbf9f4181), WTC0(0xbfa87901), WTC0(0xbfb1b101), - WTC0(0xbfbae981), WTC0(0xbfc42201), WTC0(0xbfcd5a01), WTC0(0xbfd69101), WTC0(0xbfdfc781), WTC0(0xbfe8fc01), WTC0(0xbff22f81), WTC0(0xbffb6081), - /* part 1 */ - WTC1(0x80093e01), WTC1(0x801b9b01), WTC1(0x802df701), WTC1(0x80405101), WTC1(0x8052a881), WTC1(0x8064fc81), WTC1(0x80774c81), WTC1(0x80899881), - WTC1(0x809bdf01), WTC1(0x80ae1f81), WTC1(0x80c05a01), WTC1(0x80d28d81), WTC1(0x80e4bb81), WTC1(0x80f6e481), WTC1(0x81090981), WTC1(0x811b2981), - WTC1(0x812d4481), WTC1(0x813f5981), WTC1(0x81516701), WTC1(0x81636d81), WTC1(0x81756d81), WTC1(0x81876781), WTC1(0x81995c01), WTC1(0x81ab4b01), - WTC1(0x81bd3401), WTC1(0x81cf1581), WTC1(0x81e0ee81), WTC1(0x81f2bf81), WTC1(0x82048881), WTC1(0x82164a81), WTC1(0x82280581), WTC1(0x8239b981), - WTC1(0x824b6601), WTC1(0x825d0901), WTC1(0x826ea201), WTC1(0x82803101), WTC1(0x8291b601), WTC1(0x82a33281), WTC1(0x82b4a601), WTC1(0x82c61101), - WTC1(0x82d77201), WTC1(0x82e8c801), WTC1(0x82fa1181), WTC1(0x830b4f81), WTC1(0x831c8101), WTC1(0x832da781), WTC1(0x833ec381), WTC1(0x834fd481), - WTC1(0x8360d901), WTC1(0x8371d081), WTC1(0x8382ba01), WTC1(0x83939501), WTC1(0x83a46181), WTC1(0x83b52101), WTC1(0x83c5d381), WTC1(0x83d67881), - WTC1(0x83e70f01), WTC1(0x83f79681), WTC1(0x84080d81), WTC1(0x84187401), WTC1(0x8428ca01), WTC1(0x84391081), WTC1(0x84494881), WTC1(0x84597081), - WTC1(0x84698881), WTC1(0x84798f81), WTC1(0x84898481), WTC1(0x84996701), WTC1(0x84a93801), WTC1(0x84b8f801), WTC1(0x84c8a701), WTC1(0x84d84601), - WTC1(0x84e7d381), WTC1(0x84f74e01), WTC1(0x8506b581), WTC1(0x85160981), WTC1(0x85254a81), WTC1(0x85347901), WTC1(0x85439601), WTC1(0x8552a181), - WTC1(0x85619a01), WTC1(0x85707f81), WTC1(0x857f5101), WTC1(0x858e0e01), WTC1(0x859cb781), WTC1(0x85ab4f01), WTC1(0x85b9d481), WTC1(0x85c84801), - WTC1(0x85d6a981), WTC1(0x85e4f801), WTC1(0x85f33281), WTC1(0x86015981), WTC1(0x860f6e01), WTC1(0x861d7081), WTC1(0x862b6201), WTC1(0x86394301), - WTC1(0x86471281), WTC1(0x8654d001), WTC1(0x86627b01), WTC1(0x86701381), WTC1(0x867d9a81), WTC1(0x868b1001), WTC1(0x86987581), WTC1(0x86a5ca81), - WTC1(0x86b30f01), WTC1(0x86c04381), WTC1(0x86cd6681), WTC1(0x86da7901), WTC1(0x86e77b81), WTC1(0x86f46d81), WTC1(0x87014f81), WTC1(0x870e2301), - WTC1(0x871ae981), WTC1(0x8727a381), WTC1(0x87345381), WTC1(0x8740f681), WTC1(0x874d8681), WTC1(0x8759fd01), WTC1(0x87665481), WTC1(0x87729701), - WTC1(0x877ede01), WTC1(0x878b4301), WTC1(0x8797dd81), WTC1(0x87a48b01), WTC1(0x87b0ef01), WTC1(0x87bcab81), WTC1(0x87c76201), WTC1(0x87d0ca81), - WTC1(0x87fdd781), WTC1(0x881dd301), WTC1(0x88423301), WTC1(0x886a8a81), WTC1(0x88962981), WTC1(0x88c45e81), WTC1(0x88f47901), WTC1(0x8925f101), - WTC1(0x89586901), WTC1(0x898b8301), WTC1(0x89bee581), WTC1(0x89f26101), WTC1(0x8a25f301), WTC1(0x8a599a81), WTC1(0x8a8d5801), WTC1(0x8ac13381), - WTC1(0x8af53e81), WTC1(0x8b298b81), WTC1(0x8b5e2c81), WTC1(0x8b933001), WTC1(0x8bc8a401), WTC1(0x8bfe9401), WTC1(0x8c350d01), WTC1(0x8c6c1b01), - WTC1(0x8ca3cb01), WTC1(0x8cdc2901), WTC1(0x8d154081), WTC1(0x8d4f1b01), WTC1(0x8d89be81), WTC1(0x8dc53001), WTC1(0x8e017581), WTC1(0x8e3e9481), - WTC1(0x8e7c9301), WTC1(0x8ebb7581), WTC1(0x8efb4181), WTC1(0x8f3bfb01), WTC1(0x8f7da401), WTC1(0x8fc03f01), WTC1(0x9003ce81), WTC1(0x90485401), - WTC1(0x908dd101), WTC1(0x90d44781), WTC1(0x911bb981), WTC1(0x91642781), WTC1(0x91ad9281), WTC1(0x91f7f981), WTC1(0x92435d01), WTC1(0x928fbe01), - WTC1(0x92dd1b01), WTC1(0x932b7501), WTC1(0x937acb01), WTC1(0x93cb1c81), WTC1(0x941c6901), WTC1(0x946eaf81), WTC1(0x94c1ee01), WTC1(0x95162381), - WTC1(0x956b4f81), WTC1(0x95c17081), WTC1(0x96188501), WTC1(0x96708b81), WTC1(0x96c98381), WTC1(0x97236b01), WTC1(0x977e4181), WTC1(0x97da0481), - WTC1(0x9836b201), WTC1(0x98944901), WTC1(0x98f2c601), WTC1(0x99522801), WTC1(0x99b26c81), WTC1(0x9a139101), WTC1(0x9a759301), WTC1(0x9ad87081), - WTC1(0x9b3c2801), WTC1(0x9ba0b701), WTC1(0x9c061b81), WTC1(0x9c6c5481), WTC1(0x9cd35f81), WTC1(0x9d3b3b81), WTC1(0x9da3e601), WTC1(0x9e0d5e01), - WTC1(0x9e779f81), WTC1(0x9ee2a901), WTC1(0x9f4e7801), WTC1(0x9fbb0981), WTC1(0xa0285d81), WTC1(0xa0967201), WTC1(0xa1054701), WTC1(0xa174da81), - WTC1(0xa1e52a81), WTC1(0xa2563501), WTC1(0xa2c7f801), WTC1(0xa33a7201), WTC1(0xa3ada281), WTC1(0xa4218801), WTC1(0xa4962181), WTC1(0xa50b6e81), - WTC1(0xa5816e81), WTC1(0xa5f81f81), WTC1(0xa66f8201), WTC1(0xa6e79401), WTC1(0xa7605601), WTC1(0xa7d9c681), WTC1(0xa853e501), WTC1(0xa8ceb201), - WTC1(0xa94a2c01), WTC1(0xa9c65401), WTC1(0xaa432981), WTC1(0xaac0ad01), WTC1(0xab3edf01), WTC1(0xabbdc001), WTC1(0xac3d5001), WTC1(0xacbd9081), - WTC1(0xad3e8101), WTC1(0xadc02281), WTC1(0xae427481), WTC1(0xaec57801), WTC1(0xaf492f01), WTC1(0xafcd9a81), WTC1(0xb052bc01), WTC1(0xb0d89401), - WTC1(0xb15f2381), WTC1(0xb1e66a01), WTC1(0xb26e6881), WTC1(0xb2f71f01), WTC1(0xb3808d81), WTC1(0xb40ab501), WTC1(0xb4959501), WTC1(0xb5212e81), - WTC1(0x4a6cf67f), WTC1(0x49dffeff), WTC1(0x495265ff), WTC1(0x48c4277f), WTC1(0x4835407f), WTC1(0x47a5aeff), WTC1(0x471570ff), WTC1(0x468484ff), - WTC1(0x45f2eaff), WTC1(0x4560a2ff), WTC1(0x44cdad7f), WTC1(0x443a0c7f), WTC1(0x43a5c07f), WTC1(0x4310caff), WTC1(0x427b2bff), WTC1(0x41e4e3ff), - WTC1(0x414df2ff), WTC1(0x40b6557f), WTC1(0x401e06ff), WTC1(0x3f8503c0), WTC1(0x3eeb4e00), WTC1(0x3e50ebc0), WTC1(0x3db5e680), WTC1(0x3d1a4680), - WTC1(0x3c7e10c0), WTC1(0x3be14cc0), WTC1(0x3b4402c0), WTC1(0x3aa63800), WTC1(0x3a07e840), WTC1(0x39690880), WTC1(0x38c98700), WTC1(0x38295b40), - WTC1(0x37888a80), WTC1(0x36e71d40), WTC1(0x36451d80), WTC1(0x35a29400), WTC1(0x34ff8800), WTC1(0x345c04c0), WTC1(0x33b81940), WTC1(0x3313d200), - WTC1(0x326f3800), WTC1(0x31ca5600), WTC1(0x31253840), WTC1(0x307fe8c0), WTC1(0x2fda6e40), WTC1(0x2f34ce40), WTC1(0x2e8f0e40), WTC1(0x2de92ec0), - WTC1(0x2d432780), WTC1(0x2c9cea40), WTC1(0x2bf66300), WTC1(0x2b4f88c0), WTC1(0x2aa864c0), WTC1(0x2a010240), WTC1(0x29596e40), WTC1(0x28b1ba80), - WTC1(0x2809ff40), WTC1(0x27625b80), WTC1(0x26baf580), WTC1(0x2613e7c0), WTC1(0x256d3dc0), WTC1(0x24c70300), WTC1(0x24214380), WTC1(0x237c0800), - WTC1(0x22d75400), WTC1(0x22332a80), WTC1(0x218f8cc0), WTC1(0x20ec7e40), WTC1(0x204a04c0), WTC1(0x1fa82540), WTC1(0x1f06e300), WTC1(0x1e664000), - WTC1(0x1dc63bc0), WTC1(0x1d26d3c0), WTC1(0x1c8803a0), WTC1(0x1be9cc40), WTC1(0x1b4c34c0), WTC1(0x1aaf4480), WTC1(0x1a130260), WTC1(0x197774a0), - WTC1(0x18dca260), WTC1(0x184294e0), WTC1(0x17a95840), WTC1(0x1710fd80), WTC1(0x16799ce0), WTC1(0x15e35340), WTC1(0x154e41a0), WTC1(0x14ba8360), - WTC1(0x14282be0), WTC1(0x13975100), WTC1(0x13080aa0), WTC1(0x127a6240), WTC1(0x11ee50a0), WTC1(0x1163cc80), WTC1(0x10dacb20), WTC1(0x105333a0), - WTC1(0x0fccdb30), WTC1(0x0f478f40), WTC1(0x0ec31700), WTC1(0x0e3f4e80), WTC1(0x0dbc27f0), WTC1(0x0d399000), WTC1(0x0cb76d00), WTC1(0x0c359d50), - WTC1(0x0bb3fd50), WTC1(0x0b326bd0), WTC1(0x0ab0ca80), WTC1(0x0a2f0dc0), WTC1(0x09ad40c0), WTC1(0x092b7a90), WTC1(0x08a9db80), WTC1(0x08285c80), - WTC1(0x07a6c7b8), WTC1(0x0724e4e0), WTC1(0x06a27b80), WTC1(0x061f52f8), WTC1(0x059b2ad0), WTC1(0x0515b568), WTC1(0x048ea058), WTC1(0x04066408), - WTC1(0x037e52d8), WTC1(0x02f7d3c8), WTC1(0x0274614c), WTC1(0x01f63008), WTC1(0x0180403a), WTC1(0x0115c442), WTC1(0x00ba09e2), WTC1(0x006f077c), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - /* part 2 */ - WTC2(0xfff36be1), WTC2(0xffdafbc1), WTC2(0xffc28035), WTC2(0xffa9fe8a), WTC2(0xff917c08), WTC2(0xff78fdfc), WTC2(0xff6089af), WTC2(0xff48246c), - WTC2(0xff2fd37f), WTC2(0xff179c31), WTC2(0xfeff83b6), WTC2(0xfee78d18), WTC2(0xfecfb93e), WTC2(0xfeb808f2), WTC2(0xfea07d06), WTC2(0xfe8916b4), - WTC2(0xfe71d7a0), WTC2(0xfe5ac174), WTC2(0xfe43d5d6), WTC2(0xfe2d167e), WTC2(0xfe16852e), WTC2(0xfe0023a6), WTC2(0xfde9f3f8), WTC2(0xfdd3ff7c), - WTC2(0xfdbe56c0), WTC2(0xfda90aa8), WTC2(0xfd942b78), WTC2(0xfd7fbb20), WTC2(0xfd6bad50), WTC2(0xfd57f510), WTC2(0xfd44857c), WTC2(0xfd3153fc), - WTC2(0xfd1e5840), WTC2(0xfd0b8a0c), WTC2(0xfcf8e180), WTC2(0xfce65eec), WTC2(0xfcd40ad0), WTC2(0xfcc1ee0c), WTC2(0xfcb011e8), WTC2(0xfc9e896c), - WTC2(0xfc8d716c), WTC2(0xfc7ce720), WTC2(0xfc6d072c), WTC2(0xfc5de09c), WTC2(0xfc4f74e8), WTC2(0xfc41c4e8), WTC2(0xfc34d0dc), WTC2(0xfc288a68), - WTC2(0xfc1cd49c), WTC2(0xfc1191e0), WTC2(0xfc06a4d0), WTC2(0xfbfbf3e8), WTC2(0xfbf16990), WTC2(0xfbe6f068), WTC2(0xfbdc7428), WTC2(0xfbd1fc68), - WTC2(0xfbc7ac50), WTC2(0xfbbda868), WTC2(0xfbb41500), WTC2(0xfbab1438), WTC2(0xfba2c5f8), WTC2(0xfb9b4a00), WTC2(0xfb94bfa8), WTC2(0xfb8f3b48), - WTC2(0xfb8ac638), WTC2(0xfb876970), WTC2(0xfb852d20), WTC2(0xfb840ae0), WTC2(0xfb83ed60), WTC2(0xfb84bec0), WTC2(0xfb866918), WTC2(0xfb88d4a8), - WTC2(0xfb8be810), WTC2(0xfb8f89d0), WTC2(0xfb93a080), WTC2(0xfb981418), WTC2(0xfb9ccdf0), WTC2(0xfba1b770), WTC2(0xfba6bae0), WTC2(0xfbabd5c0), - WTC2(0xfbb118d8), WTC2(0xfbb695c0), WTC2(0xfbbc5e90), WTC2(0xfbc29030), WTC2(0xfbc95268), WTC2(0xfbd0cd78), WTC2(0xfbd929c8), WTC2(0xfbe294d0), - WTC2(0xfbed4108), WTC2(0xfbf96118), WTC2(0xfc0726c8), WTC2(0xfc16b064), WTC2(0xfc280890), WTC2(0xfc3b3920), WTC2(0xfc504a98), WTC2(0xfc67271c), - WTC2(0xfc7f9a74), WTC2(0xfc996f18), WTC2(0xfcb46eb8), WTC2(0xfcd050b0), WTC2(0xfcecba24), WTC2(0xfd094f64), WTC2(0xfd25b720), WTC2(0xfd41ce40), - WTC2(0xfd5da7f8), WTC2(0xfd7959d8), WTC2(0xfd94fb74), WTC2(0xfdb0d3fc), WTC2(0xfdcd5a34), WTC2(0xfdeb06e4), WTC2(0xfe0a5184), WTC2(0xfe2b92c4), - WTC2(0xfe4f0486), WTC2(0xfe74df54), WTC2(0xfe9d5886), WTC2(0xfec85b92), WTC2(0xfef58a16), WTC2(0xff248275), WTC2(0xff54e401), WTC2(0xff866330), - WTC2(0xffb8c99b), WTC2(0xffebe1c9), WTC2(0x001f786a), WTC2(0x00538bf9), WTC2(0x00884cbc), WTC2(0x00bded23), WTC2(0x00f49f54), WTC2(0x012c8ee4), - WTC2(0x0165e0d2), WTC2(0x01a0b9d6), WTC2(0x01dd3d80), WTC2(0x021b74d4), WTC2(0x025b4e48), WTC2(0x029cb730), WTC2(0x02df9d0c), WTC2(0x0323f1a4), - WTC2(0x0369ab00), WTC2(0x03b0bf5c), WTC2(0x03f925a0), WTC2(0x0442e3d8), WTC2(0x048e0f40), WTC2(0x04dabdb0), WTC2(0x05290430), WTC2(0x0578e428), - WTC2(0x05ca4b60), WTC2(0x061d26c0), WTC2(0x067163d8), WTC2(0x06c6ff10), WTC2(0x071e03b0), WTC2(0x07767da0), WTC2(0x07d07918), WTC2(0x082c08e0), - WTC2(0x08894660), WTC2(0x08e84b70), WTC2(0x094930b0), WTC2(0x09abf8d0), WTC2(0x0a109020), WTC2(0x0a76e210), WTC2(0x0adeda50), WTC2(0x0b486b80), - WTC2(0x0bb38f00), WTC2(0x0c203e80), WTC2(0x0c8e73e0), WTC2(0x0cfe2c30), WTC2(0x0d6f6820), WTC2(0x0de22850), WTC2(0x0e566d90), WTC2(0x0ecc3dd0), - WTC2(0x0f43a3a0), WTC2(0x0fbca9f0), WTC2(0x10375b80), WTC2(0x10b3be20), WTC2(0x1131d280), WTC2(0x11b19960), WTC2(0x123313a0), WTC2(0x12b64380), - WTC2(0x133b2d00), WTC2(0x13c1d440), WTC2(0x144a3d60), WTC2(0x14d46900), WTC2(0x15605480), WTC2(0x15edfd20), WTC2(0x167d6040), WTC2(0x170e7e80), - WTC2(0x17a15b80), WTC2(0x1835fb00), WTC2(0x18cc60a0), WTC2(0x19648dc0), WTC2(0x19fe80e0), WTC2(0x1a9a38a0), WTC2(0x1b37b3e0), WTC2(0x1bd6f400), - WTC2(0x1c77fd20), WTC2(0x1d1ad400), WTC2(0x1dbf7c80), WTC2(0x1e65f820), WTC2(0x1f0e4540), WTC2(0x1fb861e0), WTC2(0x20644cc0), WTC2(0x21120640), - WTC2(0x21c19240), WTC2(0x2272f480), WTC2(0x23263000), WTC2(0x23db4580), WTC2(0x24923340), WTC2(0x254af700), WTC2(0x26058e80), WTC2(0x26c1fa00), - WTC2(0x27803d00), WTC2(0x28405a40), WTC2(0x29025500), WTC2(0x29c62d40), WTC2(0x2a8be0c0), WTC2(0x2b536cc0), WTC2(0x2c1ccf80), WTC2(0x2ce80840), - WTC2(0x2db519c0), WTC2(0x2e840600), WTC2(0x2f54cf80), WTC2(0x302775c0), WTC2(0x30fbf640), WTC2(0x31d24e00), WTC2(0x32aa7a00), WTC2(0x338479c0), - WTC2(0x34604e40), WTC2(0x353df900), WTC2(0x361d7ac0), WTC2(0x36fed200), WTC2(0x37e1fb40), WTC2(0x38c6f240), WTC2(0x39adb2c0), WTC2(0x3a963a00), - WTC2(0x3b808740), WTC2(0x3c6c9880), WTC2(0x3d5a6cc0), WTC2(0x3e4a0040), WTC2(0x3f3b4bc0), WTC2(0x402e48ff), WTC2(0x4122f17f), WTC2(0x42193f7f), - WTC2(0x43112eff), WTC2(0x440abbff), WTC2(0x4505e2ff), WTC2(0x46029e7f), WTC2(0x4700e9ff), WTC2(0x4800bfff), WTC2(0x49021bff), WTC2(0x4a050eff), - WTC2(0x4b09bc7f), WTC2(0x4c104aff), WTC2(0x4d18df7f), WTC2(0x4e23a07f), WTC2(0x4f30b2ff), WTC2(0x50403c7f), WTC2(0x515262ff), WTC2(0x52674b7f), - WTC2(0x001678b2), WTC2(0x00061a3b), WTC2(0xfffb4622), WTC2(0xfff5ea94), WTC2(0xfff5f5b9), WTC2(0xfffb55bd), WTC2(0x0005f8cb), WTC2(0x0015cd0c), - WTC2(0x002ac0ac), WTC2(0x0044c1d5), WTC2(0x0063beb2), WTC2(0x0087a56d), WTC2(0x00b06431), WTC2(0x00dde929), WTC2(0x01102280), WTC2(0x0146fe5e), - WTC2(0x01826af2), WTC2(0x01c25662), WTC2(0x0206aedc), WTC2(0x024f6288), WTC2(0x029c5f94), WTC2(0x02ed9424), WTC2(0x0342ee6c), WTC2(0x039c5c90), - WTC2(0x03f9ccbc), WTC2(0x045b2d18), WTC2(0x04c06bd8), WTC2(0x05297718), WTC2(0x05963d10), WTC2(0x0606abe8), WTC2(0x067ab1c0), WTC2(0x06f23cd0), - WTC2(0x076d3b40), WTC2(0x07eb9b38), WTC2(0x086d4ae0), WTC2(0x08f23860), WTC2(0x097a51f0), WTC2(0x0a0585b0), WTC2(0x0a93c1d0), WTC2(0x0b24f470), - WTC2(0x0bb90bc0), WTC2(0x0c4ff5f0), WTC2(0x0ce9a130), WTC2(0x0d85fb90), WTC2(0x0e24f360), WTC2(0x0ec676b0), WTC2(0x0f6a73b0), WTC2(0x1010d880), - WTC2(0x10b99360), WTC2(0x11649280), WTC2(0x1211c400), WTC2(0x12c115e0), WTC2(0x137276a0), WTC2(0x1425d420), WTC2(0x14db1ca0), WTC2(0x15923e60), - WTC2(0x164b2780), WTC2(0x1705c620), WTC2(0x17c20860), WTC2(0x187fdca0), WTC2(0x193f30e0), WTC2(0x19fff340), WTC2(0x1ac21200), WTC2(0x1b857b40), - WTC2(0x1c4a1d40), WTC2(0x1d0fe600), WTC2(0x1dd6c3e0), WTC2(0x1e9ea4e0), WTC2(0x1f677740), WTC2(0x20312940), WTC2(0x20fba8c0), WTC2(0x21c6e440), - WTC2(0x2292c9c0), WTC2(0x235f4780), WTC2(0x242c4b80), WTC2(0x24f9c400), WTC2(0x25c79f40), WTC2(0x2695cb40), WTC2(0x27643680), WTC2(0x2832cec0), - WTC2(0x29018240), WTC2(0x29d03f80), WTC2(0x2a9ef480), WTC2(0x2b6d8f00), WTC2(0x2c3bfdc0), WTC2(0x2d0a2ec0), WTC2(0x2dd81000), WTC2(0x2ea58fc0), - WTC2(0x2f729c40), WTC2(0x303f2380), WTC2(0x310b1400), WTC2(0x31d65b80), WTC2(0x32a0e840), WTC2(0x336aa8c0), WTC2(0x34338ac0), WTC2(0x34fb7cc0), - WTC2(0x35c26cc0), WTC2(0x36884900), WTC2(0x374cff80), WTC2(0x38107e80), WTC2(0x38d2b440), WTC2(0x39938ec0), WTC2(0x3a52fc40), WTC2(0x3b10eb00), - WTC2(0x3bcd4900), WTC2(0x3c880480), WTC2(0x3d410bc0), WTC2(0x3df84d00), WTC2(0x3eadb600), WTC2(0x3f613540), WTC2(0x4012b8ff), WTC2(0x40c22eff), - WTC2(0x416f85ff), WTC2(0x421aab7f), WTC2(0x42c38e7f), WTC2(0x436a1c7f), WTC2(0x440e437f), WTC2(0x44aff27f), WTC2(0x454f167f), WTC2(0x45eb9eff), - WTC2(0x468578ff), WTC2(0x471c937f), WTC2(0x47b0dc7f), WTC2(0x484241ff), WTC2(0x48d0b1ff), WTC2(0x495c1a7f), WTC2(0x49e46a7f), WTC2(0x4a698f7f), - WTC2(0x4aeb77ff), WTC2(0x4b6a11ff), WTC2(0x4be54b7f), WTC2(0x4c5d12ff), WTC2(0x4cd155ff), WTC2(0x4d4203ff), WTC2(0x4daf09ff), WTC2(0x4e18567f), - WTC2(0x4e7dd77f), WTC2(0x4edf7b7f), WTC2(0x4f3d307f), WTC2(0x4f96e47f), WTC2(0x4fec85ff), WTC2(0x503e02ff), WTC2(0x508b497f), WTC2(0x50d447ff), - WTC2(0x5118ec7f), WTC2(0x515924ff), WTC2(0x5194dfff), WTC2(0x51cc0b7f), WTC2(0x51fe95ff), WTC2(0x522c6cff), WTC2(0x52557eff), WTC2(0x5279b9ff), - WTC2(0x52990c7f), WTC2(0x52b364ff), WTC2(0x52c8b07f), WTC2(0x52d8ddff), WTC2(0x52e3db7f), WTC2(0x52e996ff), WTC2(0x52e9ff7f), WTC2(0x52e501ff), - WTC2(0x52da8cff), WTC2(0x52ca8f7f), WTC2(0x52b4f67f), WTC2(0x5299b07f), WTC2(0x5278ac7f), WTC2(0x5251d77f), WTC2(0x52251fff), WTC2(0x51f274ff), - WTC2(0x51b9c37f), WTC2(0x517af9ff), WTC2(0x5136077f), WTC2(0x50ead8ff), WTC2(0x50995cff), WTC2(0x504181ff), WTC2(0x4fe335ff), WTC2(0x4f7e677f), - WTC2(0x4f1303ff), WTC2(0x4ea0f9ff), WTC2(0x4e2837ff), WTC2(0x4da8ab7f), WTC2(0x4d2242ff), WTC2(0x4c94ecff), WTC2(0x4c0096ff), WTC2(0x4b652f7f), - WTC2(0x4ac2a4ff), WTC2(0x4a18e4ff), WTC2(0x4967ddff), WTC2(0x48af7e7f), WTC2(0x47efb3ff), WTC2(0x47286cff), WTC2(0x4659ad7f), WTC2(0x45856f7f), - WTC2(0x44afa3ff), WTC2(0x43dc507f), WTC2(0x430f657f), WTC2(0x424ad47f), WTC2(0x418e927f), WTC2(0x40da7bff), WTC2(0x402e6f7f), WTC2(0x3f8a3100), - WTC2(0x3eed6f40), WTC2(0x3e57d700), WTC2(0x3dc914c0), WTC2(0x3d40cc40), WTC2(0x3cbe98c0), WTC2(0x3c421540), WTC2(0x3bcadbc0), WTC2(0x3b588880), - WTC2(0x3aeab780), WTC2(0x3a810540), WTC2(0x3a1b0e00), WTC2(0x39b86d00), WTC2(0x3958bcc0), WTC2(0x38fb9700), WTC2(0x38a095c0), WTC2(0x38473d80), - WTC2(0x37eeff40), WTC2(0x37974b40), WTC2(0x373f9500), WTC2(0x36e7ae00), WTC2(0x368fc4c0), WTC2(0x36380b80), WTC2(0x35e0b300), WTC2(0x3589c140), - WTC2(0x35331180), WTC2(0x34dc7c80), WTC2(0x3485dc80), WTC2(0x342f1600), WTC2(0x33d81780), WTC2(0x3380d0c0), WTC2(0x33293100), WTC2(0x32d11800), - WTC2(0x32785780), WTC2(0x321ec0c0), WTC2(0x31c42680), WTC2(0x316885c0), WTC2(0x310c0580), WTC2(0x30aecec0), WTC2(0x30510940), WTC2(0x2ff2b8c0), - WTC2(0x2f93bf40), WTC2(0x2f33fc00), WTC2(0x2ed350c0), WTC2(0x2e71ba80), WTC2(0x2e0f5340), WTC2(0x2dac35c0), WTC2(0x2d487c80), WTC2(0x2ce431c0), - WTC2(0x2c7f4fc0), WTC2(0x2c19d080), WTC2(0x2bb3ad80), WTC2(0x2b4ce080), WTC2(0x2ae56340), WTC2(0x2a7d2f80), WTC2(0x2a143f00), WTC2(0x29aa8b40) -}; + /* part 0 */ + WTC0(0xfac5a770), WTC0(0xfaafbab8), WTC0(0xfa996a40), WTC0(0xfa82bbd0), + WTC0(0xfa6bb538), WTC0(0xfa545c38), WTC0(0xfa3cb698), WTC0(0xfa24ca28), + WTC0(0xfa0c9ca8), WTC0(0xf9f433e8), WTC0(0xf9db9580), WTC0(0xf9c2c298), + WTC0(0xf9a9b800), WTC0(0xf9907250), WTC0(0xf976ee38), WTC0(0xf95d2b88), + WTC0(0xf9432d10), WTC0(0xf928f5c0), WTC0(0xf90e8868), WTC0(0xf8f3e400), + WTC0(0xf8d903a0), WTC0(0xf8bde238), WTC0(0xf8a27af0), WTC0(0xf886cde8), + WTC0(0xf86ae020), WTC0(0xf84eb6c0), WTC0(0xf83256f8), WTC0(0xf815c4b8), + WTC0(0xf7f902c0), WTC0(0xf7dc13b0), WTC0(0xf7befa60), WTC0(0xf7a1ba40), + WTC0(0xf78457c0), WTC0(0xf766d780), WTC0(0xf7493d90), WTC0(0xf72b8990), + WTC0(0xf70db5f0), WTC0(0xf6efbd30), WTC0(0xf6d19a20), WTC0(0xf6b352e0), + WTC0(0xf694f8c0), WTC0(0xf6769da0), WTC0(0xf6585310), WTC0(0xf63a28d0), + WTC0(0xf61c2c60), WTC0(0xf5fe6b10), WTC0(0xf5e0f250), WTC0(0xf5c3ceb0), + WTC0(0xf5a70be0), WTC0(0xf58ab5a0), WTC0(0xf56ed7b0), WTC0(0xf5537e40), + WTC0(0xf538b610), WTC0(0xf51e8bf0), WTC0(0xf5050c90), WTC0(0xf4ec4330), + WTC0(0xf4d439b0), WTC0(0xf4bcf9b0), WTC0(0xf4a68ce0), WTC0(0xf490fa80), + WTC0(0xf47c4760), WTC0(0xf4687830), WTC0(0xf4558f00), WTC0(0xf4434fc0), + WTC0(0xf4314070), WTC0(0xf41ee450), WTC0(0xf40bc130), WTC0(0xf3f799c0), + WTC0(0xf3e26d30), WTC0(0xf3cc3d70), WTC0(0xf3b50c80), WTC0(0xf39cdd60), + WTC0(0xf383b440), WTC0(0xf3699550), WTC0(0xf34e84c0), WTC0(0xf33286b0), + WTC0(0xf3159f10), WTC0(0xf2f7d1b0), WTC0(0xf2d92290), WTC0(0xf2b994d0), + WTC0(0xf2992ad0), WTC0(0xf277e6d0), WTC0(0xf255cb60), WTC0(0xf232dd00), + WTC0(0xf20f2240), WTC0(0xf1eaa1d0), WTC0(0xf1c56240), WTC0(0xf19f63d0), + WTC0(0xf178a0f0), WTC0(0xf15113a0), WTC0(0xf128b5c0), WTC0(0xf0ff7fd0), + WTC0(0xf0d56860), WTC0(0xf0aa6610), WTC0(0xf07e6fd0), WTC0(0xf0518190), + WTC0(0xf0239cd0), WTC0(0xeff4c320), WTC0(0xefc4f720), WTC0(0xef945080), + WTC0(0xef62fce0), WTC0(0xef312a40), WTC0(0xeeff05c0), WTC0(0xeecca2c0), + WTC0(0xee99faa0), WTC0(0xee6705a0), WTC0(0xee33bb60), WTC0(0xee000060), + WTC0(0xedcba660), WTC0(0xed967e80), WTC0(0xed605b80), WTC0(0xed293b40), + WTC0(0xecf146a0), WTC0(0xecb8a8a0), WTC0(0xec7f8bc0), WTC0(0xec461260), + WTC0(0xec0c5720), WTC0(0xebd27440), WTC0(0xeb988220), WTC0(0xeb5e7040), + WTC0(0xeb2404c0), WTC0(0xeae90440), WTC0(0xeaad33c0), WTC0(0xea7066c0), + WTC0(0xea327f60), WTC0(0xe9f36000), WTC0(0xe9b2ed60), WTC0(0xe9713920), + WTC0(0xe92e81e0), WTC0(0xe8eb08c0), WTC0(0xe8a70e60), WTC0(0xe862d8e0), + WTC0(0xe81eb340), WTC0(0xe7dae8a0), WTC0(0xe797c1a0), WTC0(0xe7554ca0), + WTC0(0xe7135dc0), WTC0(0xe6d1c6a0), WTC0(0xe6905720), WTC0(0xe64eb9c0), + WTC0(0xe60c7300), WTC0(0xe5c90600), WTC0(0xe583f920), WTC0(0xe53d1ce0), + WTC0(0xe4f48c80), WTC0(0xe4aa6640), WTC0(0xe45ecaa0), WTC0(0xe4120be0), + WTC0(0xe3c4ae60), WTC0(0xe3773860), WTC0(0xe32a2ea0), WTC0(0xe2ddeea0), + WTC0(0xe292af00), WTC0(0xe248a4a0), WTC0(0xe2000140), WTC0(0xe1b8b640), + WTC0(0xe1727440), WTC0(0xe12ce900), WTC0(0xe0e7c280), WTC0(0xe0a2b420), + WTC0(0xe05d76c0), WTC0(0xe017c360), WTC0(0xdfd15440), WTC0(0xdf8a0540), + WTC0(0xdf41d300), WTC0(0xdef8bb40), WTC0(0xdeaebd40), WTC0(0xde63e7c0), + WTC0(0xde185940), WTC0(0xddcc3180), WTC0(0xdd7f9000), WTC0(0xdd329e80), + WTC0(0xdce58e80), WTC0(0xdc989300), WTC0(0xdc4bde40), WTC0(0xdbff96c0), + WTC0(0xdbb3d780), WTC0(0xdb68bb80), WTC0(0xdb1e5c80), WTC0(0xdad4c380), + WTC0(0xda8be840), WTC0(0xda43c1c0), WTC0(0xd9fc4740), WTC0(0xd9b56640), + WTC0(0xd96f0440), WTC0(0xd9290600), WTC0(0xd8e35080), WTC0(0xd89dcd40), + WTC0(0xd8586b40), WTC0(0xd8131940), WTC0(0xd7cdc640), WTC0(0xd7886180), + WTC0(0xd742dc80), WTC0(0xd6fd2780), WTC0(0xd6b73400), WTC0(0xd670fd80), + WTC0(0xd62a8a40), WTC0(0xd5e3e080), WTC0(0xd59d0840), WTC0(0xd5562b80), + WTC0(0xd50f9540), WTC0(0xd4c992c0), WTC0(0xd4846f80), WTC0(0xd4405a80), + WTC0(0xd3fd6580), WTC0(0xd3bba140), WTC0(0xd37b1c80), WTC0(0xd33bb780), + WTC0(0xd2fd2400), WTC0(0xd2bf1240), WTC0(0xd2813300), WTC0(0xd2435ac0), + WTC0(0xd2057fc0), WTC0(0xd1c79a00), WTC0(0xd189a240), WTC0(0xd14b9dc0), + WTC0(0xd10d9e00), WTC0(0xd0cfb580), WTC0(0xd091f6c0), WTC0(0xd0548100), + WTC0(0xd0177f40), WTC0(0xcfdb1cc0), WTC0(0xcf9f84c0), WTC0(0xcf64d780), + WTC0(0xcf2b2b00), WTC0(0xcef29440), WTC0(0xcebb2640), WTC0(0xce84c000), + WTC0(0xce4f0bc0), WTC0(0xce19b200), WTC0(0xcde45d40), WTC0(0xcdaeedc0), + WTC0(0xcd7979c0), WTC0(0xcd4419c0), WTC0(0xcd0ee6c0), WTC0(0xccda0540), + WTC0(0xcca5a500), WTC0(0xcc71f640), WTC0(0xcc3f2800), WTC0(0xcc0d4300), + WTC0(0xcbdc2a00), WTC0(0xcbabbe80), WTC0(0xcb7be200), WTC0(0xcb4c8200), + WTC0(0xcb1d9800), WTC0(0xcaef1d40), WTC0(0xcac10bc0), WTC0(0xca936440), + WTC0(0xca662d00), WTC0(0xca396d40), WTC0(0xca0d2b80), WTC0(0xc9e16f80), + WTC0(0xc9b63f80), WTC0(0xc98ba2c0), WTC0(0xc961a000), WTC0(0xc9383ec0), + WTC0(0xc90a0440), WTC0(0xc8e0d280), WTC0(0xc8b73b80), WTC0(0xc88d4900), + WTC0(0xc86304c0), WTC0(0xc83878c0), WTC0(0xc80dae80), WTC0(0xc7e2afc0), + WTC0(0xc7b78640), WTC0(0xc78c3c40), WTC0(0xc760da80), WTC0(0xc7356640), + WTC0(0xc709de40), WTC0(0xc6de41c0), WTC0(0xc6b28fc0), WTC0(0xc686bd40), + WTC0(0xc65ab600), WTC0(0xc62e6580), WTC0(0xc601b880), WTC0(0xc5d4bac0), + WTC0(0xc5a79640), WTC0(0xc57a76c0), WTC0(0xc54d8780), WTC0(0xc520e840), + WTC0(0xc4f4acc0), WTC0(0xc4c8e880), WTC0(0xc49dad80), WTC0(0xc472e640), + WTC0(0xc44856c0), WTC0(0xc41dc140), WTC0(0xc3f2e940), WTC0(0xc3c7bc00), + WTC0(0xc39c4f00), WTC0(0xc370b9c0), WTC0(0xc34513c0), WTC0(0xc3197940), + WTC0(0xc2ee0a00), WTC0(0xc2c2e640), WTC0(0xc2982d80), WTC0(0xc26df5c0), + WTC0(0xc2444b00), WTC0(0xc21b3940), WTC0(0xc1f2cbc0), WTC0(0xc1cb05c0), + WTC0(0xc1a3e340), WTC0(0xc17d5f00), WTC0(0xc15773c0), WTC0(0xc1320940), + WTC0(0xc10cf480), WTC0(0xc0e80a00), WTC0(0xc0c31f00), WTC0(0xc09e2640), + WTC0(0xc0792ec0), WTC0(0xc0544940), WTC0(0xc02f86c0), WTC0(0xc00b04c0), + WTC0(0xbfe6ed01), WTC0(0xbfc36a01), WTC0(0xbfa0a581), WTC0(0xbf7eb581), + WTC0(0xbf5d9a81), WTC0(0xbf3d5501), WTC0(0xbf1de601), WTC0(0xbeff4801), + WTC0(0xbee17201), WTC0(0xbec45881), WTC0(0xbea7f301), WTC0(0xbe8c3781), + WTC0(0xbe712001), WTC0(0xbe56a381), WTC0(0xbe3cbc01), WTC0(0xbe236001), + WTC0(0xbe0a8581), WTC0(0xbdf22181), WTC0(0xbdda2a01), WTC0(0xbdc29a81), + WTC0(0xbdab7181), WTC0(0xbd94b001), WTC0(0xbd7e5581), WTC0(0xbd686681), + WTC0(0xbd52eb01), WTC0(0xbd3deb81), WTC0(0xbd297181), WTC0(0xbd158801), + WTC0(0xbd023f01), WTC0(0xbcefa601), WTC0(0xbcddcc81), WTC0(0xbcccbd01), + WTC0(0xbcbc7e01), WTC0(0xbcad1501), WTC0(0xbc9e8801), WTC0(0xbc90d481), + WTC0(0xbc83f201), WTC0(0xbc77d601), WTC0(0xbc6c7781), WTC0(0xbc61c401), + WTC0(0xbc57a301), WTC0(0xbc4dfb81), WTC0(0xbc44b481), WTC0(0xbc3bbc01), + WTC0(0xbc330781), WTC0(0xbc2a8c81), WTC0(0xbc224181), WTC0(0xbc1a2401), + WTC0(0xbc123b81), WTC0(0xbc0a8f01), WTC0(0xbc032601), WTC0(0xbbfc0f81), + WTC0(0xbbf56181), WTC0(0xbbef3301), WTC0(0xbbe99981), WTC0(0xbbe49d01), + WTC0(0xbbe03801), WTC0(0xbbdc6481), WTC0(0xbbd91b81), WTC0(0xbbd64d01), + WTC0(0xbbd3e101), WTC0(0xbbd1bd81), WTC0(0xbbcfca81), WTC0(0xbbce0601), + WTC0(0xbbcc8201), WTC0(0xbbcb5301), WTC0(0xbbca8d01), WTC0(0xbbca5081), + WTC0(0xbbcaca01), WTC0(0xbbcc2681), WTC0(0xbbce9181), WTC0(0xbbd21281), + WTC0(0xbbd68c81), WTC0(0xbbdbe201), WTC0(0xbbe1f401), WTC0(0xbbe89901), + WTC0(0xbbef9b81), WTC0(0xbbf6c601), WTC0(0xbbfde481), WTC0(0xbc04e381), + WTC0(0xbc0bcf81), WTC0(0xbc12b801), WTC0(0xbc19ab01), WTC0(0xbc20ae01), + WTC0(0xbc27bd81), WTC0(0xbc2ed681), WTC0(0xbc35f501), WTC0(0xbc3d1801), + WTC0(0xbc444081), WTC0(0xbc4b6e81), WTC0(0xbc52a381), WTC0(0xbc59df81), + WTC0(0xbc612301), WTC0(0xbc686e01), WTC0(0xbc6fc101), WTC0(0xbc771c01), + WTC0(0xbc7e7e01), WTC0(0xbc85e801), WTC0(0xbc8d5901), WTC0(0xbc94d201), + WTC0(0xbc9c5281), WTC0(0xbca3db01), WTC0(0xbcab6c01), WTC0(0xbcb30601), + WTC0(0xbcbaa801), WTC0(0xbcc25181), WTC0(0xbcca0301), WTC0(0xbcd1bb81), + WTC0(0xbcd97c81), WTC0(0xbce14601), WTC0(0xbce91801), WTC0(0xbcf0f381), + WTC0(0xbcf8d781), WTC0(0xbd00c381), WTC0(0xbd08b781), WTC0(0xbd10b381), + WTC0(0xbd18b781), WTC0(0xbd20c401), WTC0(0xbd28d981), WTC0(0xbd30f881), + WTC0(0xbd391f81), WTC0(0xbd414f01), WTC0(0xbd498601), WTC0(0xbd51c481), + WTC0(0xbd5a0b01), WTC0(0xbd625981), WTC0(0xbd6ab101), WTC0(0xbd731081), + WTC0(0xbd7b7781), WTC0(0xbd83e681), WTC0(0xbd8c5c01), WTC0(0xbd94d801), + WTC0(0xbd9d5b81), WTC0(0xbda5e601), WTC0(0xbdae7881), WTC0(0xbdb71201), + WTC0(0xbdbfb281), WTC0(0xbdc85981), WTC0(0xbdd10681), WTC0(0xbdd9b981), + WTC0(0xbde27201), WTC0(0xbdeb3101), WTC0(0xbdf3f701), WTC0(0xbdfcc301), + WTC0(0xbe059481), WTC0(0xbe0e6c01), WTC0(0xbe174781), WTC0(0xbe202801), + WTC0(0xbe290d01), WTC0(0xbe31f701), WTC0(0xbe3ae601), WTC0(0xbe43da81), + WTC0(0xbe4cd381), WTC0(0xbe55d001), WTC0(0xbe5ed081), WTC0(0xbe67d381), + WTC0(0xbe70da01), WTC0(0xbe79e481), WTC0(0xbe82f301), WTC0(0xbe8c0501), + WTC0(0xbe951a81), WTC0(0xbe9e3281), WTC0(0xbea74c81), WTC0(0xbeb06881), + WTC0(0xbeb98681), WTC0(0xbec2a781), WTC0(0xbecbca81), WTC0(0xbed4f081), + WTC0(0xbede1901), WTC0(0xbee74281), WTC0(0xbef06d01), WTC0(0xbef99901), + WTC0(0xbf02c581), WTC0(0xbf0bf381), WTC0(0xbf152381), WTC0(0xbf1e5501), + WTC0(0xbf278801), WTC0(0xbf30bb01), WTC0(0xbf39ee81), WTC0(0xbf432281), + WTC0(0xbf4c5681), WTC0(0xbf558b01), WTC0(0xbf5ec101), WTC0(0xbf67f801), + WTC0(0xbf712f01), WTC0(0xbf7a6681), WTC0(0xbf839d81), WTC0(0xbf8cd481), + WTC0(0xbf960b01), WTC0(0xbf9f4181), WTC0(0xbfa87901), WTC0(0xbfb1b101), + WTC0(0xbfbae981), WTC0(0xbfc42201), WTC0(0xbfcd5a01), WTC0(0xbfd69101), + WTC0(0xbfdfc781), WTC0(0xbfe8fc01), WTC0(0xbff22f81), WTC0(0xbffb6081), + /* part 1 */ + WTC1(0x80093e01), WTC1(0x801b9b01), WTC1(0x802df701), WTC1(0x80405101), + WTC1(0x8052a881), WTC1(0x8064fc81), WTC1(0x80774c81), WTC1(0x80899881), + WTC1(0x809bdf01), WTC1(0x80ae1f81), WTC1(0x80c05a01), WTC1(0x80d28d81), + WTC1(0x80e4bb81), WTC1(0x80f6e481), WTC1(0x81090981), WTC1(0x811b2981), + WTC1(0x812d4481), WTC1(0x813f5981), WTC1(0x81516701), WTC1(0x81636d81), + WTC1(0x81756d81), WTC1(0x81876781), WTC1(0x81995c01), WTC1(0x81ab4b01), + WTC1(0x81bd3401), WTC1(0x81cf1581), WTC1(0x81e0ee81), WTC1(0x81f2bf81), + WTC1(0x82048881), WTC1(0x82164a81), WTC1(0x82280581), WTC1(0x8239b981), + WTC1(0x824b6601), WTC1(0x825d0901), WTC1(0x826ea201), WTC1(0x82803101), + WTC1(0x8291b601), WTC1(0x82a33281), WTC1(0x82b4a601), WTC1(0x82c61101), + WTC1(0x82d77201), WTC1(0x82e8c801), WTC1(0x82fa1181), WTC1(0x830b4f81), + WTC1(0x831c8101), WTC1(0x832da781), WTC1(0x833ec381), WTC1(0x834fd481), + WTC1(0x8360d901), WTC1(0x8371d081), WTC1(0x8382ba01), WTC1(0x83939501), + WTC1(0x83a46181), WTC1(0x83b52101), WTC1(0x83c5d381), WTC1(0x83d67881), + WTC1(0x83e70f01), WTC1(0x83f79681), WTC1(0x84080d81), WTC1(0x84187401), + WTC1(0x8428ca01), WTC1(0x84391081), WTC1(0x84494881), WTC1(0x84597081), + WTC1(0x84698881), WTC1(0x84798f81), WTC1(0x84898481), WTC1(0x84996701), + WTC1(0x84a93801), WTC1(0x84b8f801), WTC1(0x84c8a701), WTC1(0x84d84601), + WTC1(0x84e7d381), WTC1(0x84f74e01), WTC1(0x8506b581), WTC1(0x85160981), + WTC1(0x85254a81), WTC1(0x85347901), WTC1(0x85439601), WTC1(0x8552a181), + WTC1(0x85619a01), WTC1(0x85707f81), WTC1(0x857f5101), WTC1(0x858e0e01), + WTC1(0x859cb781), WTC1(0x85ab4f01), WTC1(0x85b9d481), WTC1(0x85c84801), + WTC1(0x85d6a981), WTC1(0x85e4f801), WTC1(0x85f33281), WTC1(0x86015981), + WTC1(0x860f6e01), WTC1(0x861d7081), WTC1(0x862b6201), WTC1(0x86394301), + WTC1(0x86471281), WTC1(0x8654d001), WTC1(0x86627b01), WTC1(0x86701381), + WTC1(0x867d9a81), WTC1(0x868b1001), WTC1(0x86987581), WTC1(0x86a5ca81), + WTC1(0x86b30f01), WTC1(0x86c04381), WTC1(0x86cd6681), WTC1(0x86da7901), + WTC1(0x86e77b81), WTC1(0x86f46d81), WTC1(0x87014f81), WTC1(0x870e2301), + WTC1(0x871ae981), WTC1(0x8727a381), WTC1(0x87345381), WTC1(0x8740f681), + WTC1(0x874d8681), WTC1(0x8759fd01), WTC1(0x87665481), WTC1(0x87729701), + WTC1(0x877ede01), WTC1(0x878b4301), WTC1(0x8797dd81), WTC1(0x87a48b01), + WTC1(0x87b0ef01), WTC1(0x87bcab81), WTC1(0x87c76201), WTC1(0x87d0ca81), + WTC1(0x87fdd781), WTC1(0x881dd301), WTC1(0x88423301), WTC1(0x886a8a81), + WTC1(0x88962981), WTC1(0x88c45e81), WTC1(0x88f47901), WTC1(0x8925f101), + WTC1(0x89586901), WTC1(0x898b8301), WTC1(0x89bee581), WTC1(0x89f26101), + WTC1(0x8a25f301), WTC1(0x8a599a81), WTC1(0x8a8d5801), WTC1(0x8ac13381), + WTC1(0x8af53e81), WTC1(0x8b298b81), WTC1(0x8b5e2c81), WTC1(0x8b933001), + WTC1(0x8bc8a401), WTC1(0x8bfe9401), WTC1(0x8c350d01), WTC1(0x8c6c1b01), + WTC1(0x8ca3cb01), WTC1(0x8cdc2901), WTC1(0x8d154081), WTC1(0x8d4f1b01), + WTC1(0x8d89be81), WTC1(0x8dc53001), WTC1(0x8e017581), WTC1(0x8e3e9481), + WTC1(0x8e7c9301), WTC1(0x8ebb7581), WTC1(0x8efb4181), WTC1(0x8f3bfb01), + WTC1(0x8f7da401), WTC1(0x8fc03f01), WTC1(0x9003ce81), WTC1(0x90485401), + WTC1(0x908dd101), WTC1(0x90d44781), WTC1(0x911bb981), WTC1(0x91642781), + WTC1(0x91ad9281), WTC1(0x91f7f981), WTC1(0x92435d01), WTC1(0x928fbe01), + WTC1(0x92dd1b01), WTC1(0x932b7501), WTC1(0x937acb01), WTC1(0x93cb1c81), + WTC1(0x941c6901), WTC1(0x946eaf81), WTC1(0x94c1ee01), WTC1(0x95162381), + WTC1(0x956b4f81), WTC1(0x95c17081), WTC1(0x96188501), WTC1(0x96708b81), + WTC1(0x96c98381), WTC1(0x97236b01), WTC1(0x977e4181), WTC1(0x97da0481), + WTC1(0x9836b201), WTC1(0x98944901), WTC1(0x98f2c601), WTC1(0x99522801), + WTC1(0x99b26c81), WTC1(0x9a139101), WTC1(0x9a759301), WTC1(0x9ad87081), + WTC1(0x9b3c2801), WTC1(0x9ba0b701), WTC1(0x9c061b81), WTC1(0x9c6c5481), + WTC1(0x9cd35f81), WTC1(0x9d3b3b81), WTC1(0x9da3e601), WTC1(0x9e0d5e01), + WTC1(0x9e779f81), WTC1(0x9ee2a901), WTC1(0x9f4e7801), WTC1(0x9fbb0981), + WTC1(0xa0285d81), WTC1(0xa0967201), WTC1(0xa1054701), WTC1(0xa174da81), + WTC1(0xa1e52a81), WTC1(0xa2563501), WTC1(0xa2c7f801), WTC1(0xa33a7201), + WTC1(0xa3ada281), WTC1(0xa4218801), WTC1(0xa4962181), WTC1(0xa50b6e81), + WTC1(0xa5816e81), WTC1(0xa5f81f81), WTC1(0xa66f8201), WTC1(0xa6e79401), + WTC1(0xa7605601), WTC1(0xa7d9c681), WTC1(0xa853e501), WTC1(0xa8ceb201), + WTC1(0xa94a2c01), WTC1(0xa9c65401), WTC1(0xaa432981), WTC1(0xaac0ad01), + WTC1(0xab3edf01), WTC1(0xabbdc001), WTC1(0xac3d5001), WTC1(0xacbd9081), + WTC1(0xad3e8101), WTC1(0xadc02281), WTC1(0xae427481), WTC1(0xaec57801), + WTC1(0xaf492f01), WTC1(0xafcd9a81), WTC1(0xb052bc01), WTC1(0xb0d89401), + WTC1(0xb15f2381), WTC1(0xb1e66a01), WTC1(0xb26e6881), WTC1(0xb2f71f01), + WTC1(0xb3808d81), WTC1(0xb40ab501), WTC1(0xb4959501), WTC1(0xb5212e81), + WTC1(0x4a6cf67f), WTC1(0x49dffeff), WTC1(0x495265ff), WTC1(0x48c4277f), + WTC1(0x4835407f), WTC1(0x47a5aeff), WTC1(0x471570ff), WTC1(0x468484ff), + WTC1(0x45f2eaff), WTC1(0x4560a2ff), WTC1(0x44cdad7f), WTC1(0x443a0c7f), + WTC1(0x43a5c07f), WTC1(0x4310caff), WTC1(0x427b2bff), WTC1(0x41e4e3ff), + WTC1(0x414df2ff), WTC1(0x40b6557f), WTC1(0x401e06ff), WTC1(0x3f8503c0), + WTC1(0x3eeb4e00), WTC1(0x3e50ebc0), WTC1(0x3db5e680), WTC1(0x3d1a4680), + WTC1(0x3c7e10c0), WTC1(0x3be14cc0), WTC1(0x3b4402c0), WTC1(0x3aa63800), + WTC1(0x3a07e840), WTC1(0x39690880), WTC1(0x38c98700), WTC1(0x38295b40), + WTC1(0x37888a80), WTC1(0x36e71d40), WTC1(0x36451d80), WTC1(0x35a29400), + WTC1(0x34ff8800), WTC1(0x345c04c0), WTC1(0x33b81940), WTC1(0x3313d200), + WTC1(0x326f3800), WTC1(0x31ca5600), WTC1(0x31253840), WTC1(0x307fe8c0), + WTC1(0x2fda6e40), WTC1(0x2f34ce40), WTC1(0x2e8f0e40), WTC1(0x2de92ec0), + WTC1(0x2d432780), WTC1(0x2c9cea40), WTC1(0x2bf66300), WTC1(0x2b4f88c0), + WTC1(0x2aa864c0), WTC1(0x2a010240), WTC1(0x29596e40), WTC1(0x28b1ba80), + WTC1(0x2809ff40), WTC1(0x27625b80), WTC1(0x26baf580), WTC1(0x2613e7c0), + WTC1(0x256d3dc0), WTC1(0x24c70300), WTC1(0x24214380), WTC1(0x237c0800), + WTC1(0x22d75400), WTC1(0x22332a80), WTC1(0x218f8cc0), WTC1(0x20ec7e40), + WTC1(0x204a04c0), WTC1(0x1fa82540), WTC1(0x1f06e300), WTC1(0x1e664000), + WTC1(0x1dc63bc0), WTC1(0x1d26d3c0), WTC1(0x1c8803a0), WTC1(0x1be9cc40), + WTC1(0x1b4c34c0), WTC1(0x1aaf4480), WTC1(0x1a130260), WTC1(0x197774a0), + WTC1(0x18dca260), WTC1(0x184294e0), WTC1(0x17a95840), WTC1(0x1710fd80), + WTC1(0x16799ce0), WTC1(0x15e35340), WTC1(0x154e41a0), WTC1(0x14ba8360), + WTC1(0x14282be0), WTC1(0x13975100), WTC1(0x13080aa0), WTC1(0x127a6240), + WTC1(0x11ee50a0), WTC1(0x1163cc80), WTC1(0x10dacb20), WTC1(0x105333a0), + WTC1(0x0fccdb30), WTC1(0x0f478f40), WTC1(0x0ec31700), WTC1(0x0e3f4e80), + WTC1(0x0dbc27f0), WTC1(0x0d399000), WTC1(0x0cb76d00), WTC1(0x0c359d50), + WTC1(0x0bb3fd50), WTC1(0x0b326bd0), WTC1(0x0ab0ca80), WTC1(0x0a2f0dc0), + WTC1(0x09ad40c0), WTC1(0x092b7a90), WTC1(0x08a9db80), WTC1(0x08285c80), + WTC1(0x07a6c7b8), WTC1(0x0724e4e0), WTC1(0x06a27b80), WTC1(0x061f52f8), + WTC1(0x059b2ad0), WTC1(0x0515b568), WTC1(0x048ea058), WTC1(0x04066408), + WTC1(0x037e52d8), WTC1(0x02f7d3c8), WTC1(0x0274614c), WTC1(0x01f63008), + WTC1(0x0180403a), WTC1(0x0115c442), WTC1(0x00ba09e2), WTC1(0x006f077c), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + /* part 2 */ + WTC2(0xfff36be1), WTC2(0xffdafbc1), WTC2(0xffc28035), WTC2(0xffa9fe8a), + WTC2(0xff917c08), WTC2(0xff78fdfc), WTC2(0xff6089af), WTC2(0xff48246c), + WTC2(0xff2fd37f), WTC2(0xff179c31), WTC2(0xfeff83b6), WTC2(0xfee78d18), + WTC2(0xfecfb93e), WTC2(0xfeb808f2), WTC2(0xfea07d06), WTC2(0xfe8916b4), + WTC2(0xfe71d7a0), WTC2(0xfe5ac174), WTC2(0xfe43d5d6), WTC2(0xfe2d167e), + WTC2(0xfe16852e), WTC2(0xfe0023a6), WTC2(0xfde9f3f8), WTC2(0xfdd3ff7c), + WTC2(0xfdbe56c0), WTC2(0xfda90aa8), WTC2(0xfd942b78), WTC2(0xfd7fbb20), + WTC2(0xfd6bad50), WTC2(0xfd57f510), WTC2(0xfd44857c), WTC2(0xfd3153fc), + WTC2(0xfd1e5840), WTC2(0xfd0b8a0c), WTC2(0xfcf8e180), WTC2(0xfce65eec), + WTC2(0xfcd40ad0), WTC2(0xfcc1ee0c), WTC2(0xfcb011e8), WTC2(0xfc9e896c), + WTC2(0xfc8d716c), WTC2(0xfc7ce720), WTC2(0xfc6d072c), WTC2(0xfc5de09c), + WTC2(0xfc4f74e8), WTC2(0xfc41c4e8), WTC2(0xfc34d0dc), WTC2(0xfc288a68), + WTC2(0xfc1cd49c), WTC2(0xfc1191e0), WTC2(0xfc06a4d0), WTC2(0xfbfbf3e8), + WTC2(0xfbf16990), WTC2(0xfbe6f068), WTC2(0xfbdc7428), WTC2(0xfbd1fc68), + WTC2(0xfbc7ac50), WTC2(0xfbbda868), WTC2(0xfbb41500), WTC2(0xfbab1438), + WTC2(0xfba2c5f8), WTC2(0xfb9b4a00), WTC2(0xfb94bfa8), WTC2(0xfb8f3b48), + WTC2(0xfb8ac638), WTC2(0xfb876970), WTC2(0xfb852d20), WTC2(0xfb840ae0), + WTC2(0xfb83ed60), WTC2(0xfb84bec0), WTC2(0xfb866918), WTC2(0xfb88d4a8), + WTC2(0xfb8be810), WTC2(0xfb8f89d0), WTC2(0xfb93a080), WTC2(0xfb981418), + WTC2(0xfb9ccdf0), WTC2(0xfba1b770), WTC2(0xfba6bae0), WTC2(0xfbabd5c0), + WTC2(0xfbb118d8), WTC2(0xfbb695c0), WTC2(0xfbbc5e90), WTC2(0xfbc29030), + WTC2(0xfbc95268), WTC2(0xfbd0cd78), WTC2(0xfbd929c8), WTC2(0xfbe294d0), + WTC2(0xfbed4108), WTC2(0xfbf96118), WTC2(0xfc0726c8), WTC2(0xfc16b064), + WTC2(0xfc280890), WTC2(0xfc3b3920), WTC2(0xfc504a98), WTC2(0xfc67271c), + WTC2(0xfc7f9a74), WTC2(0xfc996f18), WTC2(0xfcb46eb8), WTC2(0xfcd050b0), + WTC2(0xfcecba24), WTC2(0xfd094f64), WTC2(0xfd25b720), WTC2(0xfd41ce40), + WTC2(0xfd5da7f8), WTC2(0xfd7959d8), WTC2(0xfd94fb74), WTC2(0xfdb0d3fc), + WTC2(0xfdcd5a34), WTC2(0xfdeb06e4), WTC2(0xfe0a5184), WTC2(0xfe2b92c4), + WTC2(0xfe4f0486), WTC2(0xfe74df54), WTC2(0xfe9d5886), WTC2(0xfec85b92), + WTC2(0xfef58a16), WTC2(0xff248275), WTC2(0xff54e401), WTC2(0xff866330), + WTC2(0xffb8c99b), WTC2(0xffebe1c9), WTC2(0x001f786a), WTC2(0x00538bf9), + WTC2(0x00884cbc), WTC2(0x00bded23), WTC2(0x00f49f54), WTC2(0x012c8ee4), + WTC2(0x0165e0d2), WTC2(0x01a0b9d6), WTC2(0x01dd3d80), WTC2(0x021b74d4), + WTC2(0x025b4e48), WTC2(0x029cb730), WTC2(0x02df9d0c), WTC2(0x0323f1a4), + WTC2(0x0369ab00), WTC2(0x03b0bf5c), WTC2(0x03f925a0), WTC2(0x0442e3d8), + WTC2(0x048e0f40), WTC2(0x04dabdb0), WTC2(0x05290430), WTC2(0x0578e428), + WTC2(0x05ca4b60), WTC2(0x061d26c0), WTC2(0x067163d8), WTC2(0x06c6ff10), + WTC2(0x071e03b0), WTC2(0x07767da0), WTC2(0x07d07918), WTC2(0x082c08e0), + WTC2(0x08894660), WTC2(0x08e84b70), WTC2(0x094930b0), WTC2(0x09abf8d0), + WTC2(0x0a109020), WTC2(0x0a76e210), WTC2(0x0adeda50), WTC2(0x0b486b80), + WTC2(0x0bb38f00), WTC2(0x0c203e80), WTC2(0x0c8e73e0), WTC2(0x0cfe2c30), + WTC2(0x0d6f6820), WTC2(0x0de22850), WTC2(0x0e566d90), WTC2(0x0ecc3dd0), + WTC2(0x0f43a3a0), WTC2(0x0fbca9f0), WTC2(0x10375b80), WTC2(0x10b3be20), + WTC2(0x1131d280), WTC2(0x11b19960), WTC2(0x123313a0), WTC2(0x12b64380), + WTC2(0x133b2d00), WTC2(0x13c1d440), WTC2(0x144a3d60), WTC2(0x14d46900), + WTC2(0x15605480), WTC2(0x15edfd20), WTC2(0x167d6040), WTC2(0x170e7e80), + WTC2(0x17a15b80), WTC2(0x1835fb00), WTC2(0x18cc60a0), WTC2(0x19648dc0), + WTC2(0x19fe80e0), WTC2(0x1a9a38a0), WTC2(0x1b37b3e0), WTC2(0x1bd6f400), + WTC2(0x1c77fd20), WTC2(0x1d1ad400), WTC2(0x1dbf7c80), WTC2(0x1e65f820), + WTC2(0x1f0e4540), WTC2(0x1fb861e0), WTC2(0x20644cc0), WTC2(0x21120640), + WTC2(0x21c19240), WTC2(0x2272f480), WTC2(0x23263000), WTC2(0x23db4580), + WTC2(0x24923340), WTC2(0x254af700), WTC2(0x26058e80), WTC2(0x26c1fa00), + WTC2(0x27803d00), WTC2(0x28405a40), WTC2(0x29025500), WTC2(0x29c62d40), + WTC2(0x2a8be0c0), WTC2(0x2b536cc0), WTC2(0x2c1ccf80), WTC2(0x2ce80840), + WTC2(0x2db519c0), WTC2(0x2e840600), WTC2(0x2f54cf80), WTC2(0x302775c0), + WTC2(0x30fbf640), WTC2(0x31d24e00), WTC2(0x32aa7a00), WTC2(0x338479c0), + WTC2(0x34604e40), WTC2(0x353df900), WTC2(0x361d7ac0), WTC2(0x36fed200), + WTC2(0x37e1fb40), WTC2(0x38c6f240), WTC2(0x39adb2c0), WTC2(0x3a963a00), + WTC2(0x3b808740), WTC2(0x3c6c9880), WTC2(0x3d5a6cc0), WTC2(0x3e4a0040), + WTC2(0x3f3b4bc0), WTC2(0x402e48ff), WTC2(0x4122f17f), WTC2(0x42193f7f), + WTC2(0x43112eff), WTC2(0x440abbff), WTC2(0x4505e2ff), WTC2(0x46029e7f), + WTC2(0x4700e9ff), WTC2(0x4800bfff), WTC2(0x49021bff), WTC2(0x4a050eff), + WTC2(0x4b09bc7f), WTC2(0x4c104aff), WTC2(0x4d18df7f), WTC2(0x4e23a07f), + WTC2(0x4f30b2ff), WTC2(0x50403c7f), WTC2(0x515262ff), WTC2(0x52674b7f), + WTC2(0x001678b2), WTC2(0x00061a3b), WTC2(0xfffb4622), WTC2(0xfff5ea94), + WTC2(0xfff5f5b9), WTC2(0xfffb55bd), WTC2(0x0005f8cb), WTC2(0x0015cd0c), + WTC2(0x002ac0ac), WTC2(0x0044c1d5), WTC2(0x0063beb2), WTC2(0x0087a56d), + WTC2(0x00b06431), WTC2(0x00dde929), WTC2(0x01102280), WTC2(0x0146fe5e), + WTC2(0x01826af2), WTC2(0x01c25662), WTC2(0x0206aedc), WTC2(0x024f6288), + WTC2(0x029c5f94), WTC2(0x02ed9424), WTC2(0x0342ee6c), WTC2(0x039c5c90), + WTC2(0x03f9ccbc), WTC2(0x045b2d18), WTC2(0x04c06bd8), WTC2(0x05297718), + WTC2(0x05963d10), WTC2(0x0606abe8), WTC2(0x067ab1c0), WTC2(0x06f23cd0), + WTC2(0x076d3b40), WTC2(0x07eb9b38), WTC2(0x086d4ae0), WTC2(0x08f23860), + WTC2(0x097a51f0), WTC2(0x0a0585b0), WTC2(0x0a93c1d0), WTC2(0x0b24f470), + WTC2(0x0bb90bc0), WTC2(0x0c4ff5f0), WTC2(0x0ce9a130), WTC2(0x0d85fb90), + WTC2(0x0e24f360), WTC2(0x0ec676b0), WTC2(0x0f6a73b0), WTC2(0x1010d880), + WTC2(0x10b99360), WTC2(0x11649280), WTC2(0x1211c400), WTC2(0x12c115e0), + WTC2(0x137276a0), WTC2(0x1425d420), WTC2(0x14db1ca0), WTC2(0x15923e60), + WTC2(0x164b2780), WTC2(0x1705c620), WTC2(0x17c20860), WTC2(0x187fdca0), + WTC2(0x193f30e0), WTC2(0x19fff340), WTC2(0x1ac21200), WTC2(0x1b857b40), + WTC2(0x1c4a1d40), WTC2(0x1d0fe600), WTC2(0x1dd6c3e0), WTC2(0x1e9ea4e0), + WTC2(0x1f677740), WTC2(0x20312940), WTC2(0x20fba8c0), WTC2(0x21c6e440), + WTC2(0x2292c9c0), WTC2(0x235f4780), WTC2(0x242c4b80), WTC2(0x24f9c400), + WTC2(0x25c79f40), WTC2(0x2695cb40), WTC2(0x27643680), WTC2(0x2832cec0), + WTC2(0x29018240), WTC2(0x29d03f80), WTC2(0x2a9ef480), WTC2(0x2b6d8f00), + WTC2(0x2c3bfdc0), WTC2(0x2d0a2ec0), WTC2(0x2dd81000), WTC2(0x2ea58fc0), + WTC2(0x2f729c40), WTC2(0x303f2380), WTC2(0x310b1400), WTC2(0x31d65b80), + WTC2(0x32a0e840), WTC2(0x336aa8c0), WTC2(0x34338ac0), WTC2(0x34fb7cc0), + WTC2(0x35c26cc0), WTC2(0x36884900), WTC2(0x374cff80), WTC2(0x38107e80), + WTC2(0x38d2b440), WTC2(0x39938ec0), WTC2(0x3a52fc40), WTC2(0x3b10eb00), + WTC2(0x3bcd4900), WTC2(0x3c880480), WTC2(0x3d410bc0), WTC2(0x3df84d00), + WTC2(0x3eadb600), WTC2(0x3f613540), WTC2(0x4012b8ff), WTC2(0x40c22eff), + WTC2(0x416f85ff), WTC2(0x421aab7f), WTC2(0x42c38e7f), WTC2(0x436a1c7f), + WTC2(0x440e437f), WTC2(0x44aff27f), WTC2(0x454f167f), WTC2(0x45eb9eff), + WTC2(0x468578ff), WTC2(0x471c937f), WTC2(0x47b0dc7f), WTC2(0x484241ff), + WTC2(0x48d0b1ff), WTC2(0x495c1a7f), WTC2(0x49e46a7f), WTC2(0x4a698f7f), + WTC2(0x4aeb77ff), WTC2(0x4b6a11ff), WTC2(0x4be54b7f), WTC2(0x4c5d12ff), + WTC2(0x4cd155ff), WTC2(0x4d4203ff), WTC2(0x4daf09ff), WTC2(0x4e18567f), + WTC2(0x4e7dd77f), WTC2(0x4edf7b7f), WTC2(0x4f3d307f), WTC2(0x4f96e47f), + WTC2(0x4fec85ff), WTC2(0x503e02ff), WTC2(0x508b497f), WTC2(0x50d447ff), + WTC2(0x5118ec7f), WTC2(0x515924ff), WTC2(0x5194dfff), WTC2(0x51cc0b7f), + WTC2(0x51fe95ff), WTC2(0x522c6cff), WTC2(0x52557eff), WTC2(0x5279b9ff), + WTC2(0x52990c7f), WTC2(0x52b364ff), WTC2(0x52c8b07f), WTC2(0x52d8ddff), + WTC2(0x52e3db7f), WTC2(0x52e996ff), WTC2(0x52e9ff7f), WTC2(0x52e501ff), + WTC2(0x52da8cff), WTC2(0x52ca8f7f), WTC2(0x52b4f67f), WTC2(0x5299b07f), + WTC2(0x5278ac7f), WTC2(0x5251d77f), WTC2(0x52251fff), WTC2(0x51f274ff), + WTC2(0x51b9c37f), WTC2(0x517af9ff), WTC2(0x5136077f), WTC2(0x50ead8ff), + WTC2(0x50995cff), WTC2(0x504181ff), WTC2(0x4fe335ff), WTC2(0x4f7e677f), + WTC2(0x4f1303ff), WTC2(0x4ea0f9ff), WTC2(0x4e2837ff), WTC2(0x4da8ab7f), + WTC2(0x4d2242ff), WTC2(0x4c94ecff), WTC2(0x4c0096ff), WTC2(0x4b652f7f), + WTC2(0x4ac2a4ff), WTC2(0x4a18e4ff), WTC2(0x4967ddff), WTC2(0x48af7e7f), + WTC2(0x47efb3ff), WTC2(0x47286cff), WTC2(0x4659ad7f), WTC2(0x45856f7f), + WTC2(0x44afa3ff), WTC2(0x43dc507f), WTC2(0x430f657f), WTC2(0x424ad47f), + WTC2(0x418e927f), WTC2(0x40da7bff), WTC2(0x402e6f7f), WTC2(0x3f8a3100), + WTC2(0x3eed6f40), WTC2(0x3e57d700), WTC2(0x3dc914c0), WTC2(0x3d40cc40), + WTC2(0x3cbe98c0), WTC2(0x3c421540), WTC2(0x3bcadbc0), WTC2(0x3b588880), + WTC2(0x3aeab780), WTC2(0x3a810540), WTC2(0x3a1b0e00), WTC2(0x39b86d00), + WTC2(0x3958bcc0), WTC2(0x38fb9700), WTC2(0x38a095c0), WTC2(0x38473d80), + WTC2(0x37eeff40), WTC2(0x37974b40), WTC2(0x373f9500), WTC2(0x36e7ae00), + WTC2(0x368fc4c0), WTC2(0x36380b80), WTC2(0x35e0b300), WTC2(0x3589c140), + WTC2(0x35331180), WTC2(0x34dc7c80), WTC2(0x3485dc80), WTC2(0x342f1600), + WTC2(0x33d81780), WTC2(0x3380d0c0), WTC2(0x33293100), WTC2(0x32d11800), + WTC2(0x32785780), WTC2(0x321ec0c0), WTC2(0x31c42680), WTC2(0x316885c0), + WTC2(0x310c0580), WTC2(0x30aecec0), WTC2(0x30510940), WTC2(0x2ff2b8c0), + WTC2(0x2f93bf40), WTC2(0x2f33fc00), WTC2(0x2ed350c0), WTC2(0x2e71ba80), + WTC2(0x2e0f5340), WTC2(0x2dac35c0), WTC2(0x2d487c80), WTC2(0x2ce431c0), + WTC2(0x2c7f4fc0), WTC2(0x2c19d080), WTC2(0x2bb3ad80), WTC2(0x2b4ce080), + WTC2(0x2ae56340), WTC2(0x2a7d2f80), WTC2(0x2a143f00), WTC2(0x29aa8b40)}; const FIXP_WTB ELDAnalysis480[1440] = { - WTC0(0xfacfbef0), WTC0(0xfab88c18), WTC0(0xfaa0e520), WTC0(0xfa88d110), WTC0(0xfa7056e8), WTC0(0xfa577db0), WTC0(0xfa3e4c70), WTC0(0xfa24ca28), - WTC0(0xfa0afde0), WTC0(0xf9f0eea0), WTC0(0xf9d6a2c8), WTC0(0xf9bc1ab8), WTC0(0xf9a15230), WTC0(0xf9864510), WTC0(0xf96af058), WTC0(0xf94f55c0), - WTC0(0xf93378e0), WTC0(0xf9175d80), WTC0(0xf8fb0468), WTC0(0xf8de68b8), WTC0(0xf8c18438), WTC0(0xf8a450d8), WTC0(0xf886cde8), WTC0(0xf8690148), - WTC0(0xf84af148), WTC0(0xf82ca410), WTC0(0xf80e1e18), WTC0(0xf7ef62a0), WTC0(0xf7d074e0), WTC0(0xf7b15870), WTC0(0xf7921240), WTC0(0xf772a7a0), - WTC0(0xf7531e50), WTC0(0xf7337820), WTC0(0xf713afd0), WTC0(0xf6f3bea0), WTC0(0xf6d39dc0), WTC0(0xf6b352e0), WTC0(0xf692f280), WTC0(0xf6729250), - WTC0(0xf65247a0), WTC0(0xf63224c0), WTC0(0xf6123a00), WTC0(0xf5f297c0), WTC0(0xf5d34dd0), WTC0(0xf5b46b10), WTC0(0xf595fd90), WTC0(0xf5781390), - WTC0(0xf55abba0), WTC0(0xf53e0510), WTC0(0xf521ff70), WTC0(0xf506ba30), WTC0(0xf4ec4330), WTC0(0xf4d2a680), WTC0(0xf4b9efe0), WTC0(0xf4a22ac0), - WTC0(0xf48b5f70), WTC0(0xf4759310), WTC0(0xf460cde0), WTC0(0xf44cfcc0), WTC0(0xf439aff0), WTC0(0xf4264e00), WTC0(0xf4123d90), WTC0(0xf3fd1370), - WTC0(0xf3e6be00), WTC0(0xf3cf41a0), WTC0(0xf3b6a030), WTC0(0xf39cdd60), WTC0(0xf381fe00), WTC0(0xf3660760), WTC0(0xf348fe70), WTC0(0xf32ae820), - WTC0(0xf30bc940), WTC0(0xf2eba690), WTC0(0xf2ca8480), WTC0(0xf2a86670), WTC0(0xf2854f40), WTC0(0xf2614190), WTC0(0xf23c41e0), WTC0(0xf21657a0), - WTC0(0xf1ef8ae0), WTC0(0xf1c7e3e0), WTC0(0xf19f63d0), WTC0(0xf1760450), WTC0(0xf14bbdf0), WTC0(0xf1208960), WTC0(0xf0f45cd0), WTC0(0xf0c72ce0), - WTC0(0xf098ee00), WTC0(0xf06996f0), WTC0(0xf0392620), WTC0(0xf0079e10), WTC0(0xefd4ffc0), WTC0(0xefa15ca0), WTC0(0xef6ce600), WTC0(0xef37d460), - WTC0(0xef025f80), WTC0(0xeecca2c0), WTC0(0xee969760), WTC0(0xee603440), WTC0(0xee296d20), WTC0(0xedf21c00), WTC0(0xedba07e0), WTC0(0xed80f640), - WTC0(0xed46bf40), WTC0(0xed0b7b00), WTC0(0xeccf5fc0), WTC0(0xec92a120), WTC0(0xec556d60), WTC0(0xec17e700), WTC0(0xebda2d40), WTC0(0xeb9c5fa0), - WTC0(0xeb5e7040), WTC0(0xeb201b20), WTC0(0xeae117c0), WTC0(0xeaa12000), WTC0(0xea600180), WTC0(0xea1d9940), WTC0(0xe9d9c160), WTC0(0xe99468a0), - WTC0(0xe94dc040), WTC0(0xe9061940), WTC0(0xe8bdc140), WTC0(0xe8750ae0), WTC0(0xe82c4fa0), WTC0(0xe7e3ea40), WTC0(0xe79c35e0), WTC0(0xe7554ca0), - WTC0(0xe70efc00), WTC0(0xe6c90c20), WTC0(0xe6833f00), WTC0(0xe63d2300), WTC0(0xe5f620a0), WTC0(0xe5ad9dc0), WTC0(0xe5632080), WTC0(0xe5169da0), - WTC0(0xe4c83e60), WTC0(0xe4782400), WTC0(0xe4269840), WTC0(0xe3d42dc0), WTC0(0xe38188c0), WTC0(0xe32f4be0), WTC0(0xe2ddeea0), WTC0(0xe28db520), - WTC0(0xe23ee000), WTC0(0xe1f1a580), WTC0(0xe1a5e3a0), WTC0(0xe15b35a0), WTC0(0xe1113860), WTC0(0xe0c78a00), WTC0(0xe07dd0e0), WTC0(0xe033b7c0), - WTC0(0xdfe8e680), WTC0(0xdf9d1fc0), WTC0(0xdf5055c0), WTC0(0xdf0287c0), WTC0(0xdeb3b340), WTC0(0xde63e7c0), WTC0(0xde134a00), WTC0(0xddc20000), - WTC0(0xdd703180), WTC0(0xdd1e1280), WTC0(0xdccbe080), WTC0(0xdc79d980), WTC0(0xdc283600), WTC0(0xdbd71e00), WTC0(0xdb86b140), WTC0(0xdb3710c0), - WTC0(0xdae850c0), WTC0(0xda9a6bc0), WTC0(0xda4d5640), WTC0(0xda010640), WTC0(0xd9b56640), WTC0(0xd96a5700), WTC0(0xd91fb700), WTC0(0xd8d56600), - WTC0(0xd88b4a40), WTC0(0xd8414f00), WTC0(0xd7f75f80), WTC0(0xd7ad6740), WTC0(0xd76352c0), WTC0(0xd7191040), WTC0(0xd6ce8c80), WTC0(0xd683bd00), - WTC0(0xd638a5c0), WTC0(0xd5ed4f80), WTC0(0xd5a1c240), WTC0(0xd5562b80), WTC0(0xd50ae500), WTC0(0xd4c04c80), WTC0(0xd476bb40), WTC0(0xd42e62c0), - WTC0(0xd3e75680), WTC0(0xd3a1ad00), WTC0(0xd35d6780), WTC0(0xd31a4300), WTC0(0xd2d7dc00), WTC0(0xd295d080), WTC0(0xd253d8c0), WTC0(0xd211df40), - WTC0(0xd1cfdbc0), WTC0(0xd18dc480), WTC0(0xd14b9dc0), WTC0(0xd1097c80), WTC0(0xd0c77700), WTC0(0xd085a500), WTC0(0xd0442f40), WTC0(0xd0034a80), - WTC0(0xcfc32c00), WTC0(0xcf840400), WTC0(0xcf45f400), WTC0(0xcf0913c0), WTC0(0xcecd8000), WTC0(0xce932c80), WTC0(0xce59bf40), WTC0(0xce20cd40), - WTC0(0xcde7ec40), WTC0(0xcdaeedc0), WTC0(0xcd75ea00), WTC0(0xcd3cfec0), WTC0(0xcd044b40), WTC0(0xcccbff00), WTC0(0xcc945480), WTC0(0xcc5d8780), - WTC0(0xcc27c3c0), WTC0(0xcbf2fc40), WTC0(0xcbbf0a00), WTC0(0xcb8bc7c0), WTC0(0xcb591880), WTC0(0xcb26f0c0), WTC0(0xcaf54980), WTC0(0xcac41ac0), - WTC0(0xca936440), WTC0(0xca632d80), WTC0(0xca337f00), WTC0(0xca046180), WTC0(0xc9d5dd40), WTC0(0xc9a7fa80), WTC0(0xc97ac200), WTC0(0xc94e3c00), - WTC0(0xc91d1840), WTC0(0xc8f15980), WTC0(0xc8c52340), WTC0(0xc8988100), WTC0(0xc86b7f00), WTC0(0xc83e28c0), WTC0(0xc8108a80), WTC0(0xc7e2afc0), - WTC0(0xc7b4a480), WTC0(0xc7867480), WTC0(0xc7582b40), WTC0(0xc729cc80), WTC0(0xc6fb5700), WTC0(0xc6ccca40), WTC0(0xc69e2180), WTC0(0xc66f49c0), - WTC0(0xc64029c0), WTC0(0xc610a740), WTC0(0xc5e0bfc0), WTC0(0xc5b09e80), WTC0(0xc5807900), WTC0(0xc5508440), WTC0(0xc520e840), WTC0(0xc4f1bdc0), - WTC0(0xc4c31d00), WTC0(0xc4951780), WTC0(0xc4678a00), WTC0(0xc43a28c0), WTC0(0xc40ca800), WTC0(0xc3deccc0), WTC0(0xc3b09940), WTC0(0xc3822c00), - WTC0(0xc353a0c0), WTC0(0xc3251740), WTC0(0xc2f6b500), WTC0(0xc2c8a140), WTC0(0xc29b02c0), WTC0(0xc26df5c0), WTC0(0xc2418940), WTC0(0xc215cbc0), - WTC0(0xc1eaca00), WTC0(0xc1c08680), WTC0(0xc196fb00), WTC0(0xc16e22c0), WTC0(0xc145f040), WTC0(0xc11e3a80), WTC0(0xc0f6cc00), WTC0(0xc0cf6ec0), - WTC0(0xc0a802c0), WTC0(0xc0809280), WTC0(0xc0593340), WTC0(0xc031f880), WTC0(0xc00b04c0), WTC0(0xbfe48981), WTC0(0xbfbebb81), WTC0(0xbf99cb01), - WTC0(0xbf75cc81), WTC0(0xbf52c101), WTC0(0xbf30a901), WTC0(0xbf0f8301), WTC0(0xbeef4601), WTC0(0xbecfe601), WTC0(0xbeb15701), WTC0(0xbe938c81), - WTC0(0xbe767e81), WTC0(0xbe5a2301), WTC0(0xbe3e7201), WTC0(0xbe236001), WTC0(0xbe08e181), WTC0(0xbdeee981), WTC0(0xbdd56b81), WTC0(0xbdbc6381), - WTC0(0xbda3d081), WTC0(0xbd8bb281), WTC0(0xbd740b81), WTC0(0xbd5ce281), WTC0(0xbd464281), WTC0(0xbd303581), WTC0(0xbd1ac801), WTC0(0xbd060c81), - WTC0(0xbcf21601), WTC0(0xbcdef701), WTC0(0xbcccbd01), WTC0(0xbcbb7001), WTC0(0xbcab1781), WTC0(0xbc9bb901), WTC0(0xbc8d5101), WTC0(0xbc7fd301), - WTC0(0xbc733401), WTC0(0xbc676501), WTC0(0xbc5c4c81), WTC0(0xbc51cb01), WTC0(0xbc47c281), WTC0(0xbc3e1981), WTC0(0xbc34c081), WTC0(0xbc2bab01), - WTC0(0xbc22cd81), WTC0(0xbc1a2401), WTC0(0xbc11b681), WTC0(0xbc098d81), WTC0(0xbc01b381), WTC0(0xbbfa3c01), WTC0(0xbbf34281), WTC0(0xbbece281), - WTC0(0xbbe73201), WTC0(0xbbe23281), WTC0(0xbbdddb01), WTC0(0xbbda2501), WTC0(0xbbd70201), WTC0(0xbbd45601), WTC0(0xbbd20301), WTC0(0xbbcfea81), - WTC0(0xbbce0601), WTC0(0xbbcc6b01), WTC0(0xbbcb3201), WTC0(0xbbca7481), WTC0(0xbbca5d01), WTC0(0xbbcb2281), WTC0(0xbbccfc81), WTC0(0xbbd01301), - WTC0(0xbbd45881), WTC0(0xbbd9a781), WTC0(0xbbdfdb81), WTC0(0xbbe6c801), WTC0(0xbbee2f81), WTC0(0xbbf5d181), WTC0(0xbbfd6c01), WTC0(0xbc04e381), - WTC0(0xbc0c4581), WTC0(0xbc13a481), WTC0(0xbc1b1081), WTC0(0xbc228f01), WTC0(0xbc2a1a81), WTC0(0xbc31af01), WTC0(0xbc394901), WTC0(0xbc40e881), - WTC0(0xbc488e81), WTC0(0xbc503b81), WTC0(0xbc57f101), WTC0(0xbc5fae81), WTC0(0xbc677501), WTC0(0xbc6f4401), WTC0(0xbc771c01), WTC0(0xbc7efc81), - WTC0(0xbc86e581), WTC0(0xbc8ed701), WTC0(0xbc96d101), WTC0(0xbc9ed481), WTC0(0xbca6e101), WTC0(0xbcaef701), WTC0(0xbcb71701), WTC0(0xbcbf4001), - WTC0(0xbcc77181), WTC0(0xbccfac01), WTC0(0xbcd7ef01), WTC0(0xbce03b81), WTC0(0xbce89281), WTC0(0xbcf0f381), WTC0(0xbcf95e81), WTC0(0xbd01d281), - WTC0(0xbd0a4f81), WTC0(0xbd12d581), WTC0(0xbd1b6501), WTC0(0xbd23ff01), WTC0(0xbd2ca281), WTC0(0xbd355081), WTC0(0xbd3e0801), WTC0(0xbd46c801), - WTC0(0xbd4f9101), WTC0(0xbd586281), WTC0(0xbd613d81), WTC0(0xbd6a2201), WTC0(0xbd731081), WTC0(0xbd7c0781), WTC0(0xbd850701), WTC0(0xbd8e0e01), - WTC0(0xbd971c81), WTC0(0xbda03381), WTC0(0xbda95301), WTC0(0xbdb27b01), WTC0(0xbdbbab01), WTC0(0xbdc4e301), WTC0(0xbdce2181), WTC0(0xbdd76701), - WTC0(0xbde0b301), WTC0(0xbdea0681), WTC0(0xbdf36101), WTC0(0xbdfcc301), WTC0(0xbe062b81), WTC0(0xbe0f9a01), WTC0(0xbe190d81), WTC0(0xbe228681), - WTC0(0xbe2c0501), WTC0(0xbe358901), WTC0(0xbe3f1381), WTC0(0xbe48a301), WTC0(0xbe523781), WTC0(0xbe5bd001), WTC0(0xbe656c01), WTC0(0xbe6f0c01), - WTC0(0xbe78b001), WTC0(0xbe825801), WTC0(0xbe8c0501), WTC0(0xbe95b581), WTC0(0xbe9f6901), WTC0(0xbea91f01), WTC0(0xbeb2d681), WTC0(0xbebc9181), - WTC0(0xbec64e81), WTC0(0xbed00f81), WTC0(0xbed9d281), WTC0(0xbee39801), WTC0(0xbeed5f01), WTC0(0xbef72681), WTC0(0xbf00ef81), WTC0(0xbf0aba01), - WTC0(0xbf148681), WTC0(0xbf1e5501), WTC0(0xbf282501), WTC0(0xbf31f501), WTC0(0xbf3bc601), WTC0(0xbf459681), WTC0(0xbf4f6801), WTC0(0xbf593a01), - WTC0(0xbf630d81), WTC0(0xbf6ce201), WTC0(0xbf76b701), WTC0(0xbf808b81), WTC0(0xbf8a5f81), WTC0(0xbf943301), WTC0(0xbf9e0701), WTC0(0xbfa7dc01), - WTC0(0xbfb1b101), WTC0(0xbfbb8701), WTC0(0xbfc55c81), WTC0(0xbfcf3181), WTC0(0xbfd90601), WTC0(0xbfe2d901), WTC0(0xbfecaa81), WTC0(0xbff67a01), - /* part 1 */ - WTC1(0x80130981), WTC1(0x80269f81), WTC1(0x803a3381), WTC1(0x804dc481), WTC1(0x80615281), WTC1(0x8074dc01), WTC1(0x80886081), WTC1(0x809bdf01), - WTC1(0x80af5701), WTC1(0x80c2c781), WTC1(0x80d63101), WTC1(0x80e99401), WTC1(0x80fcf181), WTC1(0x81104a01), WTC1(0x81239d81), WTC1(0x8136ea01), - WTC1(0x814a2f81), WTC1(0x815d6c01), WTC1(0x8170a181), WTC1(0x8183cf81), WTC1(0x8196f781), WTC1(0x81aa1981), WTC1(0x81bd3401), WTC1(0x81d04681), - WTC1(0x81e34f81), WTC1(0x81f64f01), WTC1(0x82094581), WTC1(0x821c3401), WTC1(0x822f1b01), WTC1(0x8241fa01), WTC1(0x8254cf01), WTC1(0x82679901), - WTC1(0x827a5801), WTC1(0x828d0b01), WTC1(0x829fb401), WTC1(0x82b25301), WTC1(0x82c4e801), WTC1(0x82d77201), WTC1(0x82e9ef01), WTC1(0x82fc5f01), - WTC1(0x830ec081), WTC1(0x83211501), WTC1(0x83335c81), WTC1(0x83459881), WTC1(0x8357c701), WTC1(0x8369e781), WTC1(0x837bf801), WTC1(0x838df801), - WTC1(0x839fe801), WTC1(0x83b1c881), WTC1(0x83c39a81), WTC1(0x83d55d01), WTC1(0x83e70f01), WTC1(0x83f8b001), WTC1(0x840a3e81), WTC1(0x841bb981), - WTC1(0x842d2281), WTC1(0x843e7a81), WTC1(0x844fc081), WTC1(0x8460f581), WTC1(0x84721701), WTC1(0x84832481), WTC1(0x84941d81), WTC1(0x84a50201), - WTC1(0x84b5d301), WTC1(0x84c69101), WTC1(0x84d73c01), WTC1(0x84e7d381), WTC1(0x84f85581), WTC1(0x8508c181), WTC1(0x85191801), WTC1(0x85295881), - WTC1(0x85398481), WTC1(0x85499d01), WTC1(0x8559a081), WTC1(0x85698e81), WTC1(0x85796601), WTC1(0x85892681), WTC1(0x8598d081), WTC1(0x85a86581), - WTC1(0x85b7e601), WTC1(0x85c75201), WTC1(0x85d6a981), WTC1(0x85e5eb81), WTC1(0x85f51681), WTC1(0x86042c01), WTC1(0x86132c01), WTC1(0x86221801), - WTC1(0x8630f181), WTC1(0x863fb701), WTC1(0x864e6901), WTC1(0x865d0581), WTC1(0x866b8d81), WTC1(0x867a0081), WTC1(0x86886001), WTC1(0x8696ad01), - WTC1(0x86a4e781), WTC1(0x86b30f01), WTC1(0x86c12401), WTC1(0x86cf2601), WTC1(0x86dd1481), WTC1(0x86eaf081), WTC1(0x86f8ba81), WTC1(0x87067281), - WTC1(0x87141b01), WTC1(0x8721b481), WTC1(0x872f4201), WTC1(0x873cc201), WTC1(0x874a2f01), WTC1(0x87578181), WTC1(0x8764b101), WTC1(0x8771c601), - WTC1(0x877ede01), WTC1(0x878c1881), WTC1(0x87998f01), WTC1(0x87a70e81), WTC1(0x87b42481), WTC1(0x87c05e81), WTC1(0x87cb5101), WTC1(0x87d4ac81), - WTC1(0x87e73d81), WTC1(0x88124281), WTC1(0x88353501), WTC1(0x885f8481), WTC1(0x888d3181), WTC1(0x88be1681), WTC1(0x88f13801), WTC1(0x8925f101), - WTC1(0x895bcd01), WTC1(0x89925a81), WTC1(0x89c92f81), WTC1(0x8a001f01), WTC1(0x8a372881), WTC1(0x8a6e4a01), WTC1(0x8aa58681), WTC1(0x8adcee01), - WTC1(0x8b149701), WTC1(0x8b4c9701), WTC1(0x8b850281), WTC1(0x8bbde981), WTC1(0x8bf75b01), WTC1(0x8c316681), WTC1(0x8c6c1b01), WTC1(0x8ca78781), - WTC1(0x8ce3ba81), WTC1(0x8d20c301), WTC1(0x8d5eaa01), WTC1(0x8d9d7781), WTC1(0x8ddd3201), WTC1(0x8e1de001), WTC1(0x8e5f8881), WTC1(0x8ea23201), - WTC1(0x8ee5e301), WTC1(0x8f2aa101), WTC1(0x8f706f01), WTC1(0x8fb74f81), WTC1(0x8fff4601), WTC1(0x90485401), WTC1(0x90927b81), WTC1(0x90ddc001), - WTC1(0x912a2201), WTC1(0x9177a301), WTC1(0x91c64301), WTC1(0x92160301), WTC1(0x9266e281), WTC1(0x92b8e101), WTC1(0x930bff81), WTC1(0x93603d01), - WTC1(0x93b59901), WTC1(0x940c1281), WTC1(0x9463a881), WTC1(0x94bc5981), WTC1(0x95162381), WTC1(0x95710601), WTC1(0x95ccff01), WTC1(0x962a0c81), - WTC1(0x96882e01), WTC1(0x96e76101), WTC1(0x9747a481), WTC1(0x97a8f681), WTC1(0x980b5501), WTC1(0x986ebd81), WTC1(0x98d32d81), WTC1(0x9938a281), - WTC1(0x999f1981), WTC1(0x9a069001), WTC1(0x9a6f0381), WTC1(0x9ad87081), WTC1(0x9b42d581), WTC1(0x9bae2f81), WTC1(0x9c1a7c81), WTC1(0x9c87ba81), - WTC1(0x9cf5e701), WTC1(0x9d650081), WTC1(0x9dd50481), WTC1(0x9e45f081), WTC1(0x9eb7c101), WTC1(0x9f2a7281), WTC1(0x9f9e0301), WTC1(0xa0127081), - WTC1(0xa087b981), WTC1(0xa0fddd81), WTC1(0xa174da81), WTC1(0xa1ecae01), WTC1(0xa2655581), WTC1(0xa2dece81), WTC1(0xa3591801), WTC1(0xa3d43001), - WTC1(0xa4501601), WTC1(0xa4ccc901), WTC1(0xa54a4701), WTC1(0xa5c89001), WTC1(0xa647a301), WTC1(0xa6c77e01), WTC1(0xa7482101), WTC1(0xa7c98b01), - WTC1(0xa84bbb81), WTC1(0xa8ceb201), WTC1(0xa9526d81), WTC1(0xa9d6ef01), WTC1(0xaa5c3601), WTC1(0xaae24301), WTC1(0xab691681), WTC1(0xabf0b181), - WTC1(0xac791401), WTC1(0xad023f01), WTC1(0xad8c3301), WTC1(0xae16f001), WTC1(0xaea27681), WTC1(0xaf2ec901), WTC1(0xafbbe801), WTC1(0xb049d601), - WTC1(0xb0d89401), WTC1(0xb1682281), WTC1(0xb1f88181), WTC1(0xb289b181), WTC1(0xb31bb301), WTC1(0xb3ae8601), WTC1(0xb4422b81), WTC1(0xb4d6a381), - WTC1(0x4a5a327f), WTC1(0x49c4adff), WTC1(0x492e637f), WTC1(0x48974f7f), WTC1(0x47ff6d7f), WTC1(0x4766baff), WTC1(0x46cd35ff), WTC1(0x4632dd7f), - WTC1(0x4597b0ff), WTC1(0x44fbb1ff), WTC1(0x445eeaff), WTC1(0x43c165ff), WTC1(0x4323227f), WTC1(0x4284277f), WTC1(0x41e48aff), WTC1(0x4144557f), - WTC1(0x40a3867f), WTC1(0x4001f5ff), WTC1(0x3f5f5d80), WTC1(0x3ebbad00), WTC1(0x3e16ee40), WTC1(0x3d713d00), WTC1(0x3ccab700), WTC1(0x3c236500), - WTC1(0x3b7b5800), WTC1(0x3ad2ecc0), WTC1(0x3a2a6540), WTC1(0x3981b7c0), WTC1(0x38d8ba00), WTC1(0x382f01c0), WTC1(0x37846240), WTC1(0x36d8eb00), - WTC1(0x362c9ec0), WTC1(0x357f7a00), WTC1(0x34d18340), WTC1(0x3422c900), WTC1(0x33736c40), WTC1(0x32c39040), WTC1(0x32134280), WTC1(0x31629280), - WTC1(0x30b1a000), WTC1(0x30008380), WTC1(0x2f4f4240), WTC1(0x2e9df180), WTC1(0x2decc780), WTC1(0x2d3bd640), WTC1(0x2c8b0cc0), WTC1(0x2bda3080), - WTC1(0x2b28ec80), WTC1(0x2a773500), WTC1(0x29c51b40), WTC1(0x291293c0), WTC1(0x285f9280), WTC1(0x27ac35c0), WTC1(0x26f8ab40), WTC1(0x26454c00), - WTC1(0x25925600), WTC1(0x24dfd580), WTC1(0x242ddd40), WTC1(0x237c87c0), WTC1(0x22cbe240), WTC1(0x221bef40), WTC1(0x216cb040), WTC1(0x20be2800), - WTC1(0x20105c80), WTC1(0x1f6352a0), WTC1(0x1eb71240), WTC1(0x1e0ba140), WTC1(0x1d60fe40), WTC1(0x1cb723e0), WTC1(0x1c0e0300), WTC1(0x1b6596c0), - WTC1(0x1abde8a0), WTC1(0x1a16fbe0), WTC1(0x1970c680), WTC1(0x18cb4840), WTC1(0x18268e20), WTC1(0x1782a0c0), WTC1(0x16df8960), WTC1(0x163d6300), - WTC1(0x159c52c0), WTC1(0x14fc87e0), WTC1(0x145e2c80), WTC1(0x13c15b60), WTC1(0x13263240), WTC1(0x128cd9a0), WTC1(0x11f562a0), WTC1(0x115fc1c0), - WTC1(0x10cbf160), WTC1(0x1039f200), WTC1(0x0fa9a080), WTC1(0x0f1abd90), WTC1(0x0e8d01d0), WTC1(0x0e003330), WTC1(0x0d743590), WTC1(0x0ce8ef40), - WTC1(0x0c5e1900), WTC1(0x0bd35d70), WTC1(0x0b488eb0), WTC1(0x0abd8410), WTC1(0x0a320a00), WTC1(0x09a60e70), WTC1(0x0919ab00), WTC1(0x088d0de0), - WTC1(0x080065e0), WTC1(0x07739710), WTC1(0x06e65808), WTC1(0x06588348), WTC1(0x05ca0ae0), WTC1(0x053aaaf8), WTC1(0x04a9faf0), WTC1(0x0417f698), - WTC1(0x03859ff4), WTC1(0x02f49be4), WTC1(0x0266b668), WTC1(0x01de554e), WTC1(0x015f50ca), WTC1(0x00eb7e5d), WTC1(0x00904f24), WTC1(0x00212889), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - /* part 2 */ - WTC2(0xfffece02), WTC2(0xffe4c3df), WTC2(0xffcaaa55), WTC2(0xffb087d1), WTC2(0xff9662bf), WTC2(0xff7c418b), WTC2(0xff622aa0), WTC2(0xff48246c), - WTC2(0xff2e355a), WTC2(0xff1463db), WTC2(0xfefab608), WTC2(0xfee12f0a), WTC2(0xfec7cfd2), WTC2(0xfeae995a), WTC2(0xfe958cc4), WTC2(0xfe7cabce), - WTC2(0xfe63f882), WTC2(0xfe4b74e0), WTC2(0xfe3322f6), WTC2(0xfe1b04dc), WTC2(0xfe031ccc), WTC2(0xfdeb6cf0), WTC2(0xfdd3ff7c), WTC2(0xfdbce834), - WTC2(0xfda63bb8), WTC2(0xfd900c68), WTC2(0xfd7a590c), WTC2(0xfd6511b4), WTC2(0xfd5026c0), WTC2(0xfd3b8954), WTC2(0xfd272df0), WTC2(0xfd130adc), - WTC2(0xfcff15ac), WTC2(0xfceb4a68), WTC2(0xfcd7b110), WTC2(0xfcc454d0), WTC2(0xfcb14064), WTC2(0xfc9e896c), WTC2(0xfc8c5264), WTC2(0xfc7abef0), - WTC2(0xfc69f078), WTC2(0xfc59f5e8), WTC2(0xfc4acfec), WTC2(0xfc3c8060), WTC2(0xfc2f0264), WTC2(0xfc223b7c), WTC2(0xfc160714), WTC2(0xfc0a4150), - WTC2(0xfbfec920), WTC2(0xfbf38320), WTC2(0xfbe855d0), WTC2(0xfbdd2740), WTC2(0xfbd1fc68), WTC2(0xfbc6fea0), WTC2(0xfbbc5a48), WTC2(0xfbb23b48), - WTC2(0xfba8ca78), WTC2(0xfba02e50), WTC2(0xfb988de0), WTC2(0xfb920b40), WTC2(0xfb8cb870), WTC2(0xfb889f68), WTC2(0xfb85cbe8), WTC2(0xfb843dd0), - WTC2(0xfb83df78), WTC2(0xfb8495d0), WTC2(0xfb864660), WTC2(0xfb88d4a8), WTC2(0xfb8c21e8), WTC2(0xfb900f28), WTC2(0xfb947dc0), WTC2(0xfb9950c0), - WTC2(0xfb9e6d08), WTC2(0xfba3b658), WTC2(0xfba91908), WTC2(0xfbae9e08), WTC2(0xfbb45bd0), WTC2(0xfbba66f8), WTC2(0xfbc0dcf0), WTC2(0xfbc7ead8), - WTC2(0xfbcfc200), WTC2(0xfbd89330), WTC2(0xfbe294d0), WTC2(0xfbee03d0), WTC2(0xfbfb1de8), WTC2(0xfc0a1da4), WTC2(0xfc1b22e0), WTC2(0xfc2e38f0), - WTC2(0xfc436d48), WTC2(0xfc5abf7c), WTC2(0xfc74024c), WTC2(0xfc8ef2e8), WTC2(0xfcab51ac), WTC2(0xfcc8d024), WTC2(0xfce704f0), WTC2(0xfd0580cc), - WTC2(0xfd23d4d0), WTC2(0xfd41ce40), WTC2(0xfd5f81b0), WTC2(0xfd7d08f0), WTC2(0xfd9a8560), WTC2(0xfdb85938), WTC2(0xfdd71798), WTC2(0xfdf753b8), - WTC2(0xfe1993ee), WTC2(0xfe3e30f8), WTC2(0xfe656cba), WTC2(0xfe8f8fdc), WTC2(0xfebca8a4), WTC2(0xfeec590e), WTC2(0xff1e285c), WTC2(0xff51a0b7), - WTC2(0xff866330), WTC2(0xffbc2cbb), WTC2(0xfff2bbff), WTC2(0x0029d79d), WTC2(0x00618a22), WTC2(0x009a1185), WTC2(0x00d3aa8c), WTC2(0x010e8ff6), - WTC2(0x014af29e), WTC2(0x0188fe56), WTC2(0x01c8e108), WTC2(0x020ab3c4), WTC2(0x024e68a8), WTC2(0x0293e824), WTC2(0x02db1bc8), WTC2(0x0323f1a4), - WTC2(0x036e5d6c), WTC2(0x03ba5320), WTC2(0x0407c938), WTC2(0x0456cad0), WTC2(0x04a77288), WTC2(0x04f9db88), WTC2(0x054e1888), WTC2(0x05a41ef0), - WTC2(0x05fbd6e0), WTC2(0x065528c0), WTC2(0x06b00838), WTC2(0x070c7ee0), WTC2(0x076a9bb0), WTC2(0x07ca6d10), WTC2(0x082c08e0), WTC2(0x088f8da0), - WTC2(0x08f51ac0), WTC2(0x095ccc20), WTC2(0x09c69f70), WTC2(0x0a327b40), WTC2(0x0aa046d0), WTC2(0x0b0febb0), WTC2(0x0b815dd0), WTC2(0x0bf49600), - WTC2(0x0c698c50), WTC2(0x0ce03ba0), WTC2(0x0d58a380), WTC2(0x0dd2c510), WTC2(0x0e4ea110), WTC2(0x0ecc3dd0), WTC2(0x0f4ba800), WTC2(0x0fcced10), - WTC2(0x10501960), WTC2(0x10d532a0), WTC2(0x115c39c0), WTC2(0x11e52fa0), WTC2(0x12701560), WTC2(0x12fcef20), WTC2(0x138bc200), WTC2(0x141c9300), - WTC2(0x14af64a0), WTC2(0x154434e0), WTC2(0x15db0020), WTC2(0x1673c360), WTC2(0x170e7e80), WTC2(0x17ab35e0), WTC2(0x1849ee40), WTC2(0x18eaaba0), - WTC2(0x198d6f00), WTC2(0x1a3236a0), WTC2(0x1ad90080), WTC2(0x1b81cc60), WTC2(0x1c2c9da0), WTC2(0x1cd97980), WTC2(0x1d8865c0), WTC2(0x1e396540), - WTC2(0x1eec7700), WTC2(0x1fa198c0), WTC2(0x2058c840), WTC2(0x21120640), WTC2(0x21cd5700), WTC2(0x228abec0), WTC2(0x234a4180), WTC2(0x240bdf80), - WTC2(0x24cf95c0), WTC2(0x259561c0), WTC2(0x265d4200), WTC2(0x27273840), WTC2(0x27f348c0), WTC2(0x28c17700), WTC2(0x2991c500), WTC2(0x2a643080), - WTC2(0x2b38b680), WTC2(0x2c0f53c0), WTC2(0x2ce80840), WTC2(0x2dc2d680), WTC2(0x2e9fc100), WTC2(0x2f7ecac0), WTC2(0x305ff280), WTC2(0x314334c0), - WTC2(0x32288e00), WTC2(0x330ffb80), WTC2(0x33f97d80), WTC2(0x34e515c0), WTC2(0x35d2c5c0), WTC2(0x36c28d00), WTC2(0x37b467c0), WTC2(0x38a85080), - WTC2(0x399e4240), WTC2(0x3a963a00), WTC2(0x3b903600), WTC2(0x3c8c3480), WTC2(0x3d8a3380), WTC2(0x3e8a2dc0), WTC2(0x3f8c1b40), WTC2(0x408ff2ff), - WTC2(0x4195ae7f), WTC2(0x429d477f), WTC2(0x43a6b87f), WTC2(0x44b1fdff), WTC2(0x45bf11ff), WTC2(0x46cdee7f), WTC2(0x47de8cff), WTC2(0x48f0e77f), - WTC2(0x4a050eff), WTC2(0x4b1b2dff), WTC2(0x4c3372ff), WTC2(0x4d4e0bff), WTC2(0x4e6b257f), WTC2(0x4f8aedff), WTC2(0x50ad92ff), WTC2(0x51d341ff), - WTC2(0x002006a9), WTC2(0x000bfb36), WTC2(0xfffe45ac), WTC2(0xfff6d064), WTC2(0xfff585bc), WTC2(0xfffa500d), WTC2(0x000519b4), WTC2(0x0015cd0c), - WTC2(0x002c5470), WTC2(0x00489a3b), WTC2(0x006a88c8), WTC2(0x00920a74), WTC2(0x00bf0999), WTC2(0x00f17092), WTC2(0x012929bc), WTC2(0x01661f70), - WTC2(0x01a83c0c), WTC2(0x01ef69e8), WTC2(0x023b9364), WTC2(0x028ca2d4), WTC2(0x02e2829c), WTC2(0x033d1d10), WTC2(0x039c5c90), WTC2(0x04002b78), - WTC2(0x04687418), WTC2(0x04d520e0), WTC2(0x05461c18), WTC2(0x05bb5020), WTC2(0x0634a758), WTC2(0x06b20c20), WTC2(0x073368c8), WTC2(0x07b8a7b0), - WTC2(0x0841b340), WTC2(0x08ce75b0), WTC2(0x095ed980), WTC2(0x09f2c900), WTC2(0x0a8a2e80), WTC2(0x0b24f470), WTC2(0x0bc30510), WTC2(0x0c644ad0), - WTC2(0x0d08b010), WTC2(0x0db01f10), WTC2(0x0e5a8250), WTC2(0x0f07c400), WTC2(0x0fb7cea0), WTC2(0x106a8c80), WTC2(0x111fe800), WTC2(0x11d7cb60), - WTC2(0x12922120), WTC2(0x134ed3a0), WTC2(0x140dcd00), WTC2(0x14cef7e0), WTC2(0x15923e60), WTC2(0x16578b00), WTC2(0x171ec820), WTC2(0x17e7e020), - WTC2(0x18b2bd20), WTC2(0x197f49c0), WTC2(0x1a4d7040), WTC2(0x1b1d1b00), WTC2(0x1bee3460), WTC2(0x1cc0a6a0), WTC2(0x1d945c40), WTC2(0x1e693f80), - WTC2(0x1f3f3ac0), WTC2(0x20163880), WTC2(0x20ee22c0), WTC2(0x21c6e440), WTC2(0x22a06740), WTC2(0x237a9600), WTC2(0x24555ac0), WTC2(0x2530a040), - WTC2(0x260c5080), WTC2(0x26e85600), WTC2(0x27c49b00), WTC2(0x28a10a00), WTC2(0x297d8d80), WTC2(0x2a5a0f80), WTC2(0x2b367a80), WTC2(0x2c12b8c0), - WTC2(0x2ceeb500), WTC2(0x2dca5940), WTC2(0x2ea58fc0), WTC2(0x2f804340), WTC2(0x305a5dc0), WTC2(0x3133ca00), WTC2(0x320c7200), WTC2(0x32e44000), - WTC2(0x33bb1ec0), WTC2(0x3490f880), WTC2(0x3565b7c0), WTC2(0x36394640), WTC2(0x370b8f00), WTC2(0x37dc7c00), WTC2(0x38abf7c0), WTC2(0x3979ecc0), - WTC2(0x3a464500), WTC2(0x3b10eb00), WTC2(0x3bd9c940), WTC2(0x3ca0c9c0), WTC2(0x3d65d740), WTC2(0x3e28dc00), WTC2(0x3ee9c240), WTC2(0x3fa87480), - WTC2(0x4064dcff), WTC2(0x411ee67f), WTC2(0x41d67a7f), WTC2(0x428b847f), WTC2(0x433ded7f), WTC2(0x43eda0ff), WTC2(0x449a887f), WTC2(0x45448f7f), - WTC2(0x45eb9eff), WTC2(0x468fa1ff), WTC2(0x473082ff), WTC2(0x47ce2c7f), WTC2(0x4868887f), WTC2(0x48ff80ff), WTC2(0x499300ff), WTC2(0x4a22f2ff), - WTC2(0x4aaf407f), WTC2(0x4b37d47f), WTC2(0x4bbc997f), WTC2(0x4c3d78ff), WTC2(0x4cba5e7f), WTC2(0x4d33337f), WTC2(0x4da7e27f), WTC2(0x4e18567f), - WTC2(0x4e8478ff), WTC2(0x4eec347f), WTC2(0x4f4f737f), WTC2(0x4fae20ff), WTC2(0x500825ff), WTC2(0x505d6dff), WTC2(0x50ade37f), WTC2(0x50f96f7f), - WTC2(0x513ffdff), WTC2(0x518177ff), WTC2(0x51bdc87f), WTC2(0x51f4d9ff), WTC2(0x5226967f), WTC2(0x5252e87f), WTC2(0x5279b9ff), WTC2(0x529af5ff), - WTC2(0x52b6867f), WTC2(0x52cc55ff), WTC2(0x52dc4eff), WTC2(0x52e65aff), WTC2(0x52ea657f), WTC2(0x52e857ff), WTC2(0x52e01d7f), WTC2(0x52d19fff), - WTC2(0x52bcc9ff), WTC2(0x52a1857f), WTC2(0x527fbd7f), WTC2(0x52575b7f), WTC2(0x52284a7f), WTC2(0x51f274ff), WTC2(0x51b5c47f), WTC2(0x5172247f), - WTC2(0x51277dff), WTC2(0x50d5bc7f), WTC2(0x507cc9ff), WTC2(0x501c90ff), WTC2(0x4fb4fb7f), WTC2(0x4f45f3ff), WTC2(0x4ecf64ff), WTC2(0x4e5138ff), - WTC2(0x4dcb597f), WTC2(0x4d3db1ff), WTC2(0x4ca82bff), WTC2(0x4c0ab27f), WTC2(0x4b652f7f), WTC2(0x4ab78d7f), WTC2(0x4a01b67f), WTC2(0x4943957f), - WTC2(0x487d12ff), WTC2(0x47ae1f7f), WTC2(0x46d68f7f), WTC2(0x45f7187f), WTC2(0x4513597f), WTC2(0x4430467f), WTC2(0x4352d2ff), WTC2(0x427e6bff), - WTC2(0x41b390ff), WTC2(0x40f2077f), WTC2(0x4039a87f), WTC2(0x3f8a3100), WTC2(0x3ee33e00), WTC2(0x3e446ac0), WTC2(0x3dad5180), WTC2(0x3d1d7fc0), - WTC2(0x3c947b00), WTC2(0x3c11c7c0), WTC2(0x3b94ebc0), WTC2(0x3b1d6dc0), WTC2(0x3aaad480), WTC2(0x3a3ca740), WTC2(0x39d26c40), WTC2(0x396ba8c0), - WTC2(0x3907e080), WTC2(0x38a69800), WTC2(0x38473d80), WTC2(0x37e923c0), WTC2(0x378b9b80), WTC2(0x372e0380), WTC2(0x36d03a80), WTC2(0x36727f00), - WTC2(0x36150e40), WTC2(0x35b81540), WTC2(0x355b8000), WTC2(0x34ff1dc0), WTC2(0x34a2bfc0), WTC2(0x34463e80), WTC2(0x33e982c0), WTC2(0x338c7880), - WTC2(0x332f0bc0), WTC2(0x32d11800), WTC2(0x327265c0), WTC2(0x3212bbc0), WTC2(0x31b1e740), WTC2(0x314fef00), WTC2(0x30ed0540), WTC2(0x30895c80), - WTC2(0x30251880), WTC2(0x2fc02880), WTC2(0x2f5a6480), WTC2(0x2ef3a480), WTC2(0x2e8bd640), WTC2(0x2e231100), WTC2(0x2db97680), WTC2(0x2d4f2700), - WTC2(0x2ce431c0), WTC2(0x2c789080), WTC2(0x2c0c3bc0), WTC2(0x2b9f2bc0), WTC2(0x2b315940), WTC2(0x2ac2bc00), WTC2(0x2a534cc0), WTC2(0x29e303c0) + WTC0(0xfacfbef0), WTC0(0xfab88c18), WTC0(0xfaa0e520), WTC0(0xfa88d110), + WTC0(0xfa7056e8), WTC0(0xfa577db0), WTC0(0xfa3e4c70), WTC0(0xfa24ca28), + WTC0(0xfa0afde0), WTC0(0xf9f0eea0), WTC0(0xf9d6a2c8), WTC0(0xf9bc1ab8), + WTC0(0xf9a15230), WTC0(0xf9864510), WTC0(0xf96af058), WTC0(0xf94f55c0), + WTC0(0xf93378e0), WTC0(0xf9175d80), WTC0(0xf8fb0468), WTC0(0xf8de68b8), + WTC0(0xf8c18438), WTC0(0xf8a450d8), WTC0(0xf886cde8), WTC0(0xf8690148), + WTC0(0xf84af148), WTC0(0xf82ca410), WTC0(0xf80e1e18), WTC0(0xf7ef62a0), + WTC0(0xf7d074e0), WTC0(0xf7b15870), WTC0(0xf7921240), WTC0(0xf772a7a0), + WTC0(0xf7531e50), WTC0(0xf7337820), WTC0(0xf713afd0), WTC0(0xf6f3bea0), + WTC0(0xf6d39dc0), WTC0(0xf6b352e0), WTC0(0xf692f280), WTC0(0xf6729250), + WTC0(0xf65247a0), WTC0(0xf63224c0), WTC0(0xf6123a00), WTC0(0xf5f297c0), + WTC0(0xf5d34dd0), WTC0(0xf5b46b10), WTC0(0xf595fd90), WTC0(0xf5781390), + WTC0(0xf55abba0), WTC0(0xf53e0510), WTC0(0xf521ff70), WTC0(0xf506ba30), + WTC0(0xf4ec4330), WTC0(0xf4d2a680), WTC0(0xf4b9efe0), WTC0(0xf4a22ac0), + WTC0(0xf48b5f70), WTC0(0xf4759310), WTC0(0xf460cde0), WTC0(0xf44cfcc0), + WTC0(0xf439aff0), WTC0(0xf4264e00), WTC0(0xf4123d90), WTC0(0xf3fd1370), + WTC0(0xf3e6be00), WTC0(0xf3cf41a0), WTC0(0xf3b6a030), WTC0(0xf39cdd60), + WTC0(0xf381fe00), WTC0(0xf3660760), WTC0(0xf348fe70), WTC0(0xf32ae820), + WTC0(0xf30bc940), WTC0(0xf2eba690), WTC0(0xf2ca8480), WTC0(0xf2a86670), + WTC0(0xf2854f40), WTC0(0xf2614190), WTC0(0xf23c41e0), WTC0(0xf21657a0), + WTC0(0xf1ef8ae0), WTC0(0xf1c7e3e0), WTC0(0xf19f63d0), WTC0(0xf1760450), + WTC0(0xf14bbdf0), WTC0(0xf1208960), WTC0(0xf0f45cd0), WTC0(0xf0c72ce0), + WTC0(0xf098ee00), WTC0(0xf06996f0), WTC0(0xf0392620), WTC0(0xf0079e10), + WTC0(0xefd4ffc0), WTC0(0xefa15ca0), WTC0(0xef6ce600), WTC0(0xef37d460), + WTC0(0xef025f80), WTC0(0xeecca2c0), WTC0(0xee969760), WTC0(0xee603440), + WTC0(0xee296d20), WTC0(0xedf21c00), WTC0(0xedba07e0), WTC0(0xed80f640), + WTC0(0xed46bf40), WTC0(0xed0b7b00), WTC0(0xeccf5fc0), WTC0(0xec92a120), + WTC0(0xec556d60), WTC0(0xec17e700), WTC0(0xebda2d40), WTC0(0xeb9c5fa0), + WTC0(0xeb5e7040), WTC0(0xeb201b20), WTC0(0xeae117c0), WTC0(0xeaa12000), + WTC0(0xea600180), WTC0(0xea1d9940), WTC0(0xe9d9c160), WTC0(0xe99468a0), + WTC0(0xe94dc040), WTC0(0xe9061940), WTC0(0xe8bdc140), WTC0(0xe8750ae0), + WTC0(0xe82c4fa0), WTC0(0xe7e3ea40), WTC0(0xe79c35e0), WTC0(0xe7554ca0), + WTC0(0xe70efc00), WTC0(0xe6c90c20), WTC0(0xe6833f00), WTC0(0xe63d2300), + WTC0(0xe5f620a0), WTC0(0xe5ad9dc0), WTC0(0xe5632080), WTC0(0xe5169da0), + WTC0(0xe4c83e60), WTC0(0xe4782400), WTC0(0xe4269840), WTC0(0xe3d42dc0), + WTC0(0xe38188c0), WTC0(0xe32f4be0), WTC0(0xe2ddeea0), WTC0(0xe28db520), + WTC0(0xe23ee000), WTC0(0xe1f1a580), WTC0(0xe1a5e3a0), WTC0(0xe15b35a0), + WTC0(0xe1113860), WTC0(0xe0c78a00), WTC0(0xe07dd0e0), WTC0(0xe033b7c0), + WTC0(0xdfe8e680), WTC0(0xdf9d1fc0), WTC0(0xdf5055c0), WTC0(0xdf0287c0), + WTC0(0xdeb3b340), WTC0(0xde63e7c0), WTC0(0xde134a00), WTC0(0xddc20000), + WTC0(0xdd703180), WTC0(0xdd1e1280), WTC0(0xdccbe080), WTC0(0xdc79d980), + WTC0(0xdc283600), WTC0(0xdbd71e00), WTC0(0xdb86b140), WTC0(0xdb3710c0), + WTC0(0xdae850c0), WTC0(0xda9a6bc0), WTC0(0xda4d5640), WTC0(0xda010640), + WTC0(0xd9b56640), WTC0(0xd96a5700), WTC0(0xd91fb700), WTC0(0xd8d56600), + WTC0(0xd88b4a40), WTC0(0xd8414f00), WTC0(0xd7f75f80), WTC0(0xd7ad6740), + WTC0(0xd76352c0), WTC0(0xd7191040), WTC0(0xd6ce8c80), WTC0(0xd683bd00), + WTC0(0xd638a5c0), WTC0(0xd5ed4f80), WTC0(0xd5a1c240), WTC0(0xd5562b80), + WTC0(0xd50ae500), WTC0(0xd4c04c80), WTC0(0xd476bb40), WTC0(0xd42e62c0), + WTC0(0xd3e75680), WTC0(0xd3a1ad00), WTC0(0xd35d6780), WTC0(0xd31a4300), + WTC0(0xd2d7dc00), WTC0(0xd295d080), WTC0(0xd253d8c0), WTC0(0xd211df40), + WTC0(0xd1cfdbc0), WTC0(0xd18dc480), WTC0(0xd14b9dc0), WTC0(0xd1097c80), + WTC0(0xd0c77700), WTC0(0xd085a500), WTC0(0xd0442f40), WTC0(0xd0034a80), + WTC0(0xcfc32c00), WTC0(0xcf840400), WTC0(0xcf45f400), WTC0(0xcf0913c0), + WTC0(0xcecd8000), WTC0(0xce932c80), WTC0(0xce59bf40), WTC0(0xce20cd40), + WTC0(0xcde7ec40), WTC0(0xcdaeedc0), WTC0(0xcd75ea00), WTC0(0xcd3cfec0), + WTC0(0xcd044b40), WTC0(0xcccbff00), WTC0(0xcc945480), WTC0(0xcc5d8780), + WTC0(0xcc27c3c0), WTC0(0xcbf2fc40), WTC0(0xcbbf0a00), WTC0(0xcb8bc7c0), + WTC0(0xcb591880), WTC0(0xcb26f0c0), WTC0(0xcaf54980), WTC0(0xcac41ac0), + WTC0(0xca936440), WTC0(0xca632d80), WTC0(0xca337f00), WTC0(0xca046180), + WTC0(0xc9d5dd40), WTC0(0xc9a7fa80), WTC0(0xc97ac200), WTC0(0xc94e3c00), + WTC0(0xc91d1840), WTC0(0xc8f15980), WTC0(0xc8c52340), WTC0(0xc8988100), + WTC0(0xc86b7f00), WTC0(0xc83e28c0), WTC0(0xc8108a80), WTC0(0xc7e2afc0), + WTC0(0xc7b4a480), WTC0(0xc7867480), WTC0(0xc7582b40), WTC0(0xc729cc80), + WTC0(0xc6fb5700), WTC0(0xc6ccca40), WTC0(0xc69e2180), WTC0(0xc66f49c0), + WTC0(0xc64029c0), WTC0(0xc610a740), WTC0(0xc5e0bfc0), WTC0(0xc5b09e80), + WTC0(0xc5807900), WTC0(0xc5508440), WTC0(0xc520e840), WTC0(0xc4f1bdc0), + WTC0(0xc4c31d00), WTC0(0xc4951780), WTC0(0xc4678a00), WTC0(0xc43a28c0), + WTC0(0xc40ca800), WTC0(0xc3deccc0), WTC0(0xc3b09940), WTC0(0xc3822c00), + WTC0(0xc353a0c0), WTC0(0xc3251740), WTC0(0xc2f6b500), WTC0(0xc2c8a140), + WTC0(0xc29b02c0), WTC0(0xc26df5c0), WTC0(0xc2418940), WTC0(0xc215cbc0), + WTC0(0xc1eaca00), WTC0(0xc1c08680), WTC0(0xc196fb00), WTC0(0xc16e22c0), + WTC0(0xc145f040), WTC0(0xc11e3a80), WTC0(0xc0f6cc00), WTC0(0xc0cf6ec0), + WTC0(0xc0a802c0), WTC0(0xc0809280), WTC0(0xc0593340), WTC0(0xc031f880), + WTC0(0xc00b04c0), WTC0(0xbfe48981), WTC0(0xbfbebb81), WTC0(0xbf99cb01), + WTC0(0xbf75cc81), WTC0(0xbf52c101), WTC0(0xbf30a901), WTC0(0xbf0f8301), + WTC0(0xbeef4601), WTC0(0xbecfe601), WTC0(0xbeb15701), WTC0(0xbe938c81), + WTC0(0xbe767e81), WTC0(0xbe5a2301), WTC0(0xbe3e7201), WTC0(0xbe236001), + WTC0(0xbe08e181), WTC0(0xbdeee981), WTC0(0xbdd56b81), WTC0(0xbdbc6381), + WTC0(0xbda3d081), WTC0(0xbd8bb281), WTC0(0xbd740b81), WTC0(0xbd5ce281), + WTC0(0xbd464281), WTC0(0xbd303581), WTC0(0xbd1ac801), WTC0(0xbd060c81), + WTC0(0xbcf21601), WTC0(0xbcdef701), WTC0(0xbcccbd01), WTC0(0xbcbb7001), + WTC0(0xbcab1781), WTC0(0xbc9bb901), WTC0(0xbc8d5101), WTC0(0xbc7fd301), + WTC0(0xbc733401), WTC0(0xbc676501), WTC0(0xbc5c4c81), WTC0(0xbc51cb01), + WTC0(0xbc47c281), WTC0(0xbc3e1981), WTC0(0xbc34c081), WTC0(0xbc2bab01), + WTC0(0xbc22cd81), WTC0(0xbc1a2401), WTC0(0xbc11b681), WTC0(0xbc098d81), + WTC0(0xbc01b381), WTC0(0xbbfa3c01), WTC0(0xbbf34281), WTC0(0xbbece281), + WTC0(0xbbe73201), WTC0(0xbbe23281), WTC0(0xbbdddb01), WTC0(0xbbda2501), + WTC0(0xbbd70201), WTC0(0xbbd45601), WTC0(0xbbd20301), WTC0(0xbbcfea81), + WTC0(0xbbce0601), WTC0(0xbbcc6b01), WTC0(0xbbcb3201), WTC0(0xbbca7481), + WTC0(0xbbca5d01), WTC0(0xbbcb2281), WTC0(0xbbccfc81), WTC0(0xbbd01301), + WTC0(0xbbd45881), WTC0(0xbbd9a781), WTC0(0xbbdfdb81), WTC0(0xbbe6c801), + WTC0(0xbbee2f81), WTC0(0xbbf5d181), WTC0(0xbbfd6c01), WTC0(0xbc04e381), + WTC0(0xbc0c4581), WTC0(0xbc13a481), WTC0(0xbc1b1081), WTC0(0xbc228f01), + WTC0(0xbc2a1a81), WTC0(0xbc31af01), WTC0(0xbc394901), WTC0(0xbc40e881), + WTC0(0xbc488e81), WTC0(0xbc503b81), WTC0(0xbc57f101), WTC0(0xbc5fae81), + WTC0(0xbc677501), WTC0(0xbc6f4401), WTC0(0xbc771c01), WTC0(0xbc7efc81), + WTC0(0xbc86e581), WTC0(0xbc8ed701), WTC0(0xbc96d101), WTC0(0xbc9ed481), + WTC0(0xbca6e101), WTC0(0xbcaef701), WTC0(0xbcb71701), WTC0(0xbcbf4001), + WTC0(0xbcc77181), WTC0(0xbccfac01), WTC0(0xbcd7ef01), WTC0(0xbce03b81), + WTC0(0xbce89281), WTC0(0xbcf0f381), WTC0(0xbcf95e81), WTC0(0xbd01d281), + WTC0(0xbd0a4f81), WTC0(0xbd12d581), WTC0(0xbd1b6501), WTC0(0xbd23ff01), + WTC0(0xbd2ca281), WTC0(0xbd355081), WTC0(0xbd3e0801), WTC0(0xbd46c801), + WTC0(0xbd4f9101), WTC0(0xbd586281), WTC0(0xbd613d81), WTC0(0xbd6a2201), + WTC0(0xbd731081), WTC0(0xbd7c0781), WTC0(0xbd850701), WTC0(0xbd8e0e01), + WTC0(0xbd971c81), WTC0(0xbda03381), WTC0(0xbda95301), WTC0(0xbdb27b01), + WTC0(0xbdbbab01), WTC0(0xbdc4e301), WTC0(0xbdce2181), WTC0(0xbdd76701), + WTC0(0xbde0b301), WTC0(0xbdea0681), WTC0(0xbdf36101), WTC0(0xbdfcc301), + WTC0(0xbe062b81), WTC0(0xbe0f9a01), WTC0(0xbe190d81), WTC0(0xbe228681), + WTC0(0xbe2c0501), WTC0(0xbe358901), WTC0(0xbe3f1381), WTC0(0xbe48a301), + WTC0(0xbe523781), WTC0(0xbe5bd001), WTC0(0xbe656c01), WTC0(0xbe6f0c01), + WTC0(0xbe78b001), WTC0(0xbe825801), WTC0(0xbe8c0501), WTC0(0xbe95b581), + WTC0(0xbe9f6901), WTC0(0xbea91f01), WTC0(0xbeb2d681), WTC0(0xbebc9181), + WTC0(0xbec64e81), WTC0(0xbed00f81), WTC0(0xbed9d281), WTC0(0xbee39801), + WTC0(0xbeed5f01), WTC0(0xbef72681), WTC0(0xbf00ef81), WTC0(0xbf0aba01), + WTC0(0xbf148681), WTC0(0xbf1e5501), WTC0(0xbf282501), WTC0(0xbf31f501), + WTC0(0xbf3bc601), WTC0(0xbf459681), WTC0(0xbf4f6801), WTC0(0xbf593a01), + WTC0(0xbf630d81), WTC0(0xbf6ce201), WTC0(0xbf76b701), WTC0(0xbf808b81), + WTC0(0xbf8a5f81), WTC0(0xbf943301), WTC0(0xbf9e0701), WTC0(0xbfa7dc01), + WTC0(0xbfb1b101), WTC0(0xbfbb8701), WTC0(0xbfc55c81), WTC0(0xbfcf3181), + WTC0(0xbfd90601), WTC0(0xbfe2d901), WTC0(0xbfecaa81), WTC0(0xbff67a01), + /* part 1 */ + WTC1(0x80130981), WTC1(0x80269f81), WTC1(0x803a3381), WTC1(0x804dc481), + WTC1(0x80615281), WTC1(0x8074dc01), WTC1(0x80886081), WTC1(0x809bdf01), + WTC1(0x80af5701), WTC1(0x80c2c781), WTC1(0x80d63101), WTC1(0x80e99401), + WTC1(0x80fcf181), WTC1(0x81104a01), WTC1(0x81239d81), WTC1(0x8136ea01), + WTC1(0x814a2f81), WTC1(0x815d6c01), WTC1(0x8170a181), WTC1(0x8183cf81), + WTC1(0x8196f781), WTC1(0x81aa1981), WTC1(0x81bd3401), WTC1(0x81d04681), + WTC1(0x81e34f81), WTC1(0x81f64f01), WTC1(0x82094581), WTC1(0x821c3401), + WTC1(0x822f1b01), WTC1(0x8241fa01), WTC1(0x8254cf01), WTC1(0x82679901), + WTC1(0x827a5801), WTC1(0x828d0b01), WTC1(0x829fb401), WTC1(0x82b25301), + WTC1(0x82c4e801), WTC1(0x82d77201), WTC1(0x82e9ef01), WTC1(0x82fc5f01), + WTC1(0x830ec081), WTC1(0x83211501), WTC1(0x83335c81), WTC1(0x83459881), + WTC1(0x8357c701), WTC1(0x8369e781), WTC1(0x837bf801), WTC1(0x838df801), + WTC1(0x839fe801), WTC1(0x83b1c881), WTC1(0x83c39a81), WTC1(0x83d55d01), + WTC1(0x83e70f01), WTC1(0x83f8b001), WTC1(0x840a3e81), WTC1(0x841bb981), + WTC1(0x842d2281), WTC1(0x843e7a81), WTC1(0x844fc081), WTC1(0x8460f581), + WTC1(0x84721701), WTC1(0x84832481), WTC1(0x84941d81), WTC1(0x84a50201), + WTC1(0x84b5d301), WTC1(0x84c69101), WTC1(0x84d73c01), WTC1(0x84e7d381), + WTC1(0x84f85581), WTC1(0x8508c181), WTC1(0x85191801), WTC1(0x85295881), + WTC1(0x85398481), WTC1(0x85499d01), WTC1(0x8559a081), WTC1(0x85698e81), + WTC1(0x85796601), WTC1(0x85892681), WTC1(0x8598d081), WTC1(0x85a86581), + WTC1(0x85b7e601), WTC1(0x85c75201), WTC1(0x85d6a981), WTC1(0x85e5eb81), + WTC1(0x85f51681), WTC1(0x86042c01), WTC1(0x86132c01), WTC1(0x86221801), + WTC1(0x8630f181), WTC1(0x863fb701), WTC1(0x864e6901), WTC1(0x865d0581), + WTC1(0x866b8d81), WTC1(0x867a0081), WTC1(0x86886001), WTC1(0x8696ad01), + WTC1(0x86a4e781), WTC1(0x86b30f01), WTC1(0x86c12401), WTC1(0x86cf2601), + WTC1(0x86dd1481), WTC1(0x86eaf081), WTC1(0x86f8ba81), WTC1(0x87067281), + WTC1(0x87141b01), WTC1(0x8721b481), WTC1(0x872f4201), WTC1(0x873cc201), + WTC1(0x874a2f01), WTC1(0x87578181), WTC1(0x8764b101), WTC1(0x8771c601), + WTC1(0x877ede01), WTC1(0x878c1881), WTC1(0x87998f01), WTC1(0x87a70e81), + WTC1(0x87b42481), WTC1(0x87c05e81), WTC1(0x87cb5101), WTC1(0x87d4ac81), + WTC1(0x87e73d81), WTC1(0x88124281), WTC1(0x88353501), WTC1(0x885f8481), + WTC1(0x888d3181), WTC1(0x88be1681), WTC1(0x88f13801), WTC1(0x8925f101), + WTC1(0x895bcd01), WTC1(0x89925a81), WTC1(0x89c92f81), WTC1(0x8a001f01), + WTC1(0x8a372881), WTC1(0x8a6e4a01), WTC1(0x8aa58681), WTC1(0x8adcee01), + WTC1(0x8b149701), WTC1(0x8b4c9701), WTC1(0x8b850281), WTC1(0x8bbde981), + WTC1(0x8bf75b01), WTC1(0x8c316681), WTC1(0x8c6c1b01), WTC1(0x8ca78781), + WTC1(0x8ce3ba81), WTC1(0x8d20c301), WTC1(0x8d5eaa01), WTC1(0x8d9d7781), + WTC1(0x8ddd3201), WTC1(0x8e1de001), WTC1(0x8e5f8881), WTC1(0x8ea23201), + WTC1(0x8ee5e301), WTC1(0x8f2aa101), WTC1(0x8f706f01), WTC1(0x8fb74f81), + WTC1(0x8fff4601), WTC1(0x90485401), WTC1(0x90927b81), WTC1(0x90ddc001), + WTC1(0x912a2201), WTC1(0x9177a301), WTC1(0x91c64301), WTC1(0x92160301), + WTC1(0x9266e281), WTC1(0x92b8e101), WTC1(0x930bff81), WTC1(0x93603d01), + WTC1(0x93b59901), WTC1(0x940c1281), WTC1(0x9463a881), WTC1(0x94bc5981), + WTC1(0x95162381), WTC1(0x95710601), WTC1(0x95ccff01), WTC1(0x962a0c81), + WTC1(0x96882e01), WTC1(0x96e76101), WTC1(0x9747a481), WTC1(0x97a8f681), + WTC1(0x980b5501), WTC1(0x986ebd81), WTC1(0x98d32d81), WTC1(0x9938a281), + WTC1(0x999f1981), WTC1(0x9a069001), WTC1(0x9a6f0381), WTC1(0x9ad87081), + WTC1(0x9b42d581), WTC1(0x9bae2f81), WTC1(0x9c1a7c81), WTC1(0x9c87ba81), + WTC1(0x9cf5e701), WTC1(0x9d650081), WTC1(0x9dd50481), WTC1(0x9e45f081), + WTC1(0x9eb7c101), WTC1(0x9f2a7281), WTC1(0x9f9e0301), WTC1(0xa0127081), + WTC1(0xa087b981), WTC1(0xa0fddd81), WTC1(0xa174da81), WTC1(0xa1ecae01), + WTC1(0xa2655581), WTC1(0xa2dece81), WTC1(0xa3591801), WTC1(0xa3d43001), + WTC1(0xa4501601), WTC1(0xa4ccc901), WTC1(0xa54a4701), WTC1(0xa5c89001), + WTC1(0xa647a301), WTC1(0xa6c77e01), WTC1(0xa7482101), WTC1(0xa7c98b01), + WTC1(0xa84bbb81), WTC1(0xa8ceb201), WTC1(0xa9526d81), WTC1(0xa9d6ef01), + WTC1(0xaa5c3601), WTC1(0xaae24301), WTC1(0xab691681), WTC1(0xabf0b181), + WTC1(0xac791401), WTC1(0xad023f01), WTC1(0xad8c3301), WTC1(0xae16f001), + WTC1(0xaea27681), WTC1(0xaf2ec901), WTC1(0xafbbe801), WTC1(0xb049d601), + WTC1(0xb0d89401), WTC1(0xb1682281), WTC1(0xb1f88181), WTC1(0xb289b181), + WTC1(0xb31bb301), WTC1(0xb3ae8601), WTC1(0xb4422b81), WTC1(0xb4d6a381), + WTC1(0x4a5a327f), WTC1(0x49c4adff), WTC1(0x492e637f), WTC1(0x48974f7f), + WTC1(0x47ff6d7f), WTC1(0x4766baff), WTC1(0x46cd35ff), WTC1(0x4632dd7f), + WTC1(0x4597b0ff), WTC1(0x44fbb1ff), WTC1(0x445eeaff), WTC1(0x43c165ff), + WTC1(0x4323227f), WTC1(0x4284277f), WTC1(0x41e48aff), WTC1(0x4144557f), + WTC1(0x40a3867f), WTC1(0x4001f5ff), WTC1(0x3f5f5d80), WTC1(0x3ebbad00), + WTC1(0x3e16ee40), WTC1(0x3d713d00), WTC1(0x3ccab700), WTC1(0x3c236500), + WTC1(0x3b7b5800), WTC1(0x3ad2ecc0), WTC1(0x3a2a6540), WTC1(0x3981b7c0), + WTC1(0x38d8ba00), WTC1(0x382f01c0), WTC1(0x37846240), WTC1(0x36d8eb00), + WTC1(0x362c9ec0), WTC1(0x357f7a00), WTC1(0x34d18340), WTC1(0x3422c900), + WTC1(0x33736c40), WTC1(0x32c39040), WTC1(0x32134280), WTC1(0x31629280), + WTC1(0x30b1a000), WTC1(0x30008380), WTC1(0x2f4f4240), WTC1(0x2e9df180), + WTC1(0x2decc780), WTC1(0x2d3bd640), WTC1(0x2c8b0cc0), WTC1(0x2bda3080), + WTC1(0x2b28ec80), WTC1(0x2a773500), WTC1(0x29c51b40), WTC1(0x291293c0), + WTC1(0x285f9280), WTC1(0x27ac35c0), WTC1(0x26f8ab40), WTC1(0x26454c00), + WTC1(0x25925600), WTC1(0x24dfd580), WTC1(0x242ddd40), WTC1(0x237c87c0), + WTC1(0x22cbe240), WTC1(0x221bef40), WTC1(0x216cb040), WTC1(0x20be2800), + WTC1(0x20105c80), WTC1(0x1f6352a0), WTC1(0x1eb71240), WTC1(0x1e0ba140), + WTC1(0x1d60fe40), WTC1(0x1cb723e0), WTC1(0x1c0e0300), WTC1(0x1b6596c0), + WTC1(0x1abde8a0), WTC1(0x1a16fbe0), WTC1(0x1970c680), WTC1(0x18cb4840), + WTC1(0x18268e20), WTC1(0x1782a0c0), WTC1(0x16df8960), WTC1(0x163d6300), + WTC1(0x159c52c0), WTC1(0x14fc87e0), WTC1(0x145e2c80), WTC1(0x13c15b60), + WTC1(0x13263240), WTC1(0x128cd9a0), WTC1(0x11f562a0), WTC1(0x115fc1c0), + WTC1(0x10cbf160), WTC1(0x1039f200), WTC1(0x0fa9a080), WTC1(0x0f1abd90), + WTC1(0x0e8d01d0), WTC1(0x0e003330), WTC1(0x0d743590), WTC1(0x0ce8ef40), + WTC1(0x0c5e1900), WTC1(0x0bd35d70), WTC1(0x0b488eb0), WTC1(0x0abd8410), + WTC1(0x0a320a00), WTC1(0x09a60e70), WTC1(0x0919ab00), WTC1(0x088d0de0), + WTC1(0x080065e0), WTC1(0x07739710), WTC1(0x06e65808), WTC1(0x06588348), + WTC1(0x05ca0ae0), WTC1(0x053aaaf8), WTC1(0x04a9faf0), WTC1(0x0417f698), + WTC1(0x03859ff4), WTC1(0x02f49be4), WTC1(0x0266b668), WTC1(0x01de554e), + WTC1(0x015f50ca), WTC1(0x00eb7e5d), WTC1(0x00904f24), WTC1(0x00212889), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + /* part 2 */ + WTC2(0xfffece02), WTC2(0xffe4c3df), WTC2(0xffcaaa55), WTC2(0xffb087d1), + WTC2(0xff9662bf), WTC2(0xff7c418b), WTC2(0xff622aa0), WTC2(0xff48246c), + WTC2(0xff2e355a), WTC2(0xff1463db), WTC2(0xfefab608), WTC2(0xfee12f0a), + WTC2(0xfec7cfd2), WTC2(0xfeae995a), WTC2(0xfe958cc4), WTC2(0xfe7cabce), + WTC2(0xfe63f882), WTC2(0xfe4b74e0), WTC2(0xfe3322f6), WTC2(0xfe1b04dc), + WTC2(0xfe031ccc), WTC2(0xfdeb6cf0), WTC2(0xfdd3ff7c), WTC2(0xfdbce834), + WTC2(0xfda63bb8), WTC2(0xfd900c68), WTC2(0xfd7a590c), WTC2(0xfd6511b4), + WTC2(0xfd5026c0), WTC2(0xfd3b8954), WTC2(0xfd272df0), WTC2(0xfd130adc), + WTC2(0xfcff15ac), WTC2(0xfceb4a68), WTC2(0xfcd7b110), WTC2(0xfcc454d0), + WTC2(0xfcb14064), WTC2(0xfc9e896c), WTC2(0xfc8c5264), WTC2(0xfc7abef0), + WTC2(0xfc69f078), WTC2(0xfc59f5e8), WTC2(0xfc4acfec), WTC2(0xfc3c8060), + WTC2(0xfc2f0264), WTC2(0xfc223b7c), WTC2(0xfc160714), WTC2(0xfc0a4150), + WTC2(0xfbfec920), WTC2(0xfbf38320), WTC2(0xfbe855d0), WTC2(0xfbdd2740), + WTC2(0xfbd1fc68), WTC2(0xfbc6fea0), WTC2(0xfbbc5a48), WTC2(0xfbb23b48), + WTC2(0xfba8ca78), WTC2(0xfba02e50), WTC2(0xfb988de0), WTC2(0xfb920b40), + WTC2(0xfb8cb870), WTC2(0xfb889f68), WTC2(0xfb85cbe8), WTC2(0xfb843dd0), + WTC2(0xfb83df78), WTC2(0xfb8495d0), WTC2(0xfb864660), WTC2(0xfb88d4a8), + WTC2(0xfb8c21e8), WTC2(0xfb900f28), WTC2(0xfb947dc0), WTC2(0xfb9950c0), + WTC2(0xfb9e6d08), WTC2(0xfba3b658), WTC2(0xfba91908), WTC2(0xfbae9e08), + WTC2(0xfbb45bd0), WTC2(0xfbba66f8), WTC2(0xfbc0dcf0), WTC2(0xfbc7ead8), + WTC2(0xfbcfc200), WTC2(0xfbd89330), WTC2(0xfbe294d0), WTC2(0xfbee03d0), + WTC2(0xfbfb1de8), WTC2(0xfc0a1da4), WTC2(0xfc1b22e0), WTC2(0xfc2e38f0), + WTC2(0xfc436d48), WTC2(0xfc5abf7c), WTC2(0xfc74024c), WTC2(0xfc8ef2e8), + WTC2(0xfcab51ac), WTC2(0xfcc8d024), WTC2(0xfce704f0), WTC2(0xfd0580cc), + WTC2(0xfd23d4d0), WTC2(0xfd41ce40), WTC2(0xfd5f81b0), WTC2(0xfd7d08f0), + WTC2(0xfd9a8560), WTC2(0xfdb85938), WTC2(0xfdd71798), WTC2(0xfdf753b8), + WTC2(0xfe1993ee), WTC2(0xfe3e30f8), WTC2(0xfe656cba), WTC2(0xfe8f8fdc), + WTC2(0xfebca8a4), WTC2(0xfeec590e), WTC2(0xff1e285c), WTC2(0xff51a0b7), + WTC2(0xff866330), WTC2(0xffbc2cbb), WTC2(0xfff2bbff), WTC2(0x0029d79d), + WTC2(0x00618a22), WTC2(0x009a1185), WTC2(0x00d3aa8c), WTC2(0x010e8ff6), + WTC2(0x014af29e), WTC2(0x0188fe56), WTC2(0x01c8e108), WTC2(0x020ab3c4), + WTC2(0x024e68a8), WTC2(0x0293e824), WTC2(0x02db1bc8), WTC2(0x0323f1a4), + WTC2(0x036e5d6c), WTC2(0x03ba5320), WTC2(0x0407c938), WTC2(0x0456cad0), + WTC2(0x04a77288), WTC2(0x04f9db88), WTC2(0x054e1888), WTC2(0x05a41ef0), + WTC2(0x05fbd6e0), WTC2(0x065528c0), WTC2(0x06b00838), WTC2(0x070c7ee0), + WTC2(0x076a9bb0), WTC2(0x07ca6d10), WTC2(0x082c08e0), WTC2(0x088f8da0), + WTC2(0x08f51ac0), WTC2(0x095ccc20), WTC2(0x09c69f70), WTC2(0x0a327b40), + WTC2(0x0aa046d0), WTC2(0x0b0febb0), WTC2(0x0b815dd0), WTC2(0x0bf49600), + WTC2(0x0c698c50), WTC2(0x0ce03ba0), WTC2(0x0d58a380), WTC2(0x0dd2c510), + WTC2(0x0e4ea110), WTC2(0x0ecc3dd0), WTC2(0x0f4ba800), WTC2(0x0fcced10), + WTC2(0x10501960), WTC2(0x10d532a0), WTC2(0x115c39c0), WTC2(0x11e52fa0), + WTC2(0x12701560), WTC2(0x12fcef20), WTC2(0x138bc200), WTC2(0x141c9300), + WTC2(0x14af64a0), WTC2(0x154434e0), WTC2(0x15db0020), WTC2(0x1673c360), + WTC2(0x170e7e80), WTC2(0x17ab35e0), WTC2(0x1849ee40), WTC2(0x18eaaba0), + WTC2(0x198d6f00), WTC2(0x1a3236a0), WTC2(0x1ad90080), WTC2(0x1b81cc60), + WTC2(0x1c2c9da0), WTC2(0x1cd97980), WTC2(0x1d8865c0), WTC2(0x1e396540), + WTC2(0x1eec7700), WTC2(0x1fa198c0), WTC2(0x2058c840), WTC2(0x21120640), + WTC2(0x21cd5700), WTC2(0x228abec0), WTC2(0x234a4180), WTC2(0x240bdf80), + WTC2(0x24cf95c0), WTC2(0x259561c0), WTC2(0x265d4200), WTC2(0x27273840), + WTC2(0x27f348c0), WTC2(0x28c17700), WTC2(0x2991c500), WTC2(0x2a643080), + WTC2(0x2b38b680), WTC2(0x2c0f53c0), WTC2(0x2ce80840), WTC2(0x2dc2d680), + WTC2(0x2e9fc100), WTC2(0x2f7ecac0), WTC2(0x305ff280), WTC2(0x314334c0), + WTC2(0x32288e00), WTC2(0x330ffb80), WTC2(0x33f97d80), WTC2(0x34e515c0), + WTC2(0x35d2c5c0), WTC2(0x36c28d00), WTC2(0x37b467c0), WTC2(0x38a85080), + WTC2(0x399e4240), WTC2(0x3a963a00), WTC2(0x3b903600), WTC2(0x3c8c3480), + WTC2(0x3d8a3380), WTC2(0x3e8a2dc0), WTC2(0x3f8c1b40), WTC2(0x408ff2ff), + WTC2(0x4195ae7f), WTC2(0x429d477f), WTC2(0x43a6b87f), WTC2(0x44b1fdff), + WTC2(0x45bf11ff), WTC2(0x46cdee7f), WTC2(0x47de8cff), WTC2(0x48f0e77f), + WTC2(0x4a050eff), WTC2(0x4b1b2dff), WTC2(0x4c3372ff), WTC2(0x4d4e0bff), + WTC2(0x4e6b257f), WTC2(0x4f8aedff), WTC2(0x50ad92ff), WTC2(0x51d341ff), + WTC2(0x002006a9), WTC2(0x000bfb36), WTC2(0xfffe45ac), WTC2(0xfff6d064), + WTC2(0xfff585bc), WTC2(0xfffa500d), WTC2(0x000519b4), WTC2(0x0015cd0c), + WTC2(0x002c5470), WTC2(0x00489a3b), WTC2(0x006a88c8), WTC2(0x00920a74), + WTC2(0x00bf0999), WTC2(0x00f17092), WTC2(0x012929bc), WTC2(0x01661f70), + WTC2(0x01a83c0c), WTC2(0x01ef69e8), WTC2(0x023b9364), WTC2(0x028ca2d4), + WTC2(0x02e2829c), WTC2(0x033d1d10), WTC2(0x039c5c90), WTC2(0x04002b78), + WTC2(0x04687418), WTC2(0x04d520e0), WTC2(0x05461c18), WTC2(0x05bb5020), + WTC2(0x0634a758), WTC2(0x06b20c20), WTC2(0x073368c8), WTC2(0x07b8a7b0), + WTC2(0x0841b340), WTC2(0x08ce75b0), WTC2(0x095ed980), WTC2(0x09f2c900), + WTC2(0x0a8a2e80), WTC2(0x0b24f470), WTC2(0x0bc30510), WTC2(0x0c644ad0), + WTC2(0x0d08b010), WTC2(0x0db01f10), WTC2(0x0e5a8250), WTC2(0x0f07c400), + WTC2(0x0fb7cea0), WTC2(0x106a8c80), WTC2(0x111fe800), WTC2(0x11d7cb60), + WTC2(0x12922120), WTC2(0x134ed3a0), WTC2(0x140dcd00), WTC2(0x14cef7e0), + WTC2(0x15923e60), WTC2(0x16578b00), WTC2(0x171ec820), WTC2(0x17e7e020), + WTC2(0x18b2bd20), WTC2(0x197f49c0), WTC2(0x1a4d7040), WTC2(0x1b1d1b00), + WTC2(0x1bee3460), WTC2(0x1cc0a6a0), WTC2(0x1d945c40), WTC2(0x1e693f80), + WTC2(0x1f3f3ac0), WTC2(0x20163880), WTC2(0x20ee22c0), WTC2(0x21c6e440), + WTC2(0x22a06740), WTC2(0x237a9600), WTC2(0x24555ac0), WTC2(0x2530a040), + WTC2(0x260c5080), WTC2(0x26e85600), WTC2(0x27c49b00), WTC2(0x28a10a00), + WTC2(0x297d8d80), WTC2(0x2a5a0f80), WTC2(0x2b367a80), WTC2(0x2c12b8c0), + WTC2(0x2ceeb500), WTC2(0x2dca5940), WTC2(0x2ea58fc0), WTC2(0x2f804340), + WTC2(0x305a5dc0), WTC2(0x3133ca00), WTC2(0x320c7200), WTC2(0x32e44000), + WTC2(0x33bb1ec0), WTC2(0x3490f880), WTC2(0x3565b7c0), WTC2(0x36394640), + WTC2(0x370b8f00), WTC2(0x37dc7c00), WTC2(0x38abf7c0), WTC2(0x3979ecc0), + WTC2(0x3a464500), WTC2(0x3b10eb00), WTC2(0x3bd9c940), WTC2(0x3ca0c9c0), + WTC2(0x3d65d740), WTC2(0x3e28dc00), WTC2(0x3ee9c240), WTC2(0x3fa87480), + WTC2(0x4064dcff), WTC2(0x411ee67f), WTC2(0x41d67a7f), WTC2(0x428b847f), + WTC2(0x433ded7f), WTC2(0x43eda0ff), WTC2(0x449a887f), WTC2(0x45448f7f), + WTC2(0x45eb9eff), WTC2(0x468fa1ff), WTC2(0x473082ff), WTC2(0x47ce2c7f), + WTC2(0x4868887f), WTC2(0x48ff80ff), WTC2(0x499300ff), WTC2(0x4a22f2ff), + WTC2(0x4aaf407f), WTC2(0x4b37d47f), WTC2(0x4bbc997f), WTC2(0x4c3d78ff), + WTC2(0x4cba5e7f), WTC2(0x4d33337f), WTC2(0x4da7e27f), WTC2(0x4e18567f), + WTC2(0x4e8478ff), WTC2(0x4eec347f), WTC2(0x4f4f737f), WTC2(0x4fae20ff), + WTC2(0x500825ff), WTC2(0x505d6dff), WTC2(0x50ade37f), WTC2(0x50f96f7f), + WTC2(0x513ffdff), WTC2(0x518177ff), WTC2(0x51bdc87f), WTC2(0x51f4d9ff), + WTC2(0x5226967f), WTC2(0x5252e87f), WTC2(0x5279b9ff), WTC2(0x529af5ff), + WTC2(0x52b6867f), WTC2(0x52cc55ff), WTC2(0x52dc4eff), WTC2(0x52e65aff), + WTC2(0x52ea657f), WTC2(0x52e857ff), WTC2(0x52e01d7f), WTC2(0x52d19fff), + WTC2(0x52bcc9ff), WTC2(0x52a1857f), WTC2(0x527fbd7f), WTC2(0x52575b7f), + WTC2(0x52284a7f), WTC2(0x51f274ff), WTC2(0x51b5c47f), WTC2(0x5172247f), + WTC2(0x51277dff), WTC2(0x50d5bc7f), WTC2(0x507cc9ff), WTC2(0x501c90ff), + WTC2(0x4fb4fb7f), WTC2(0x4f45f3ff), WTC2(0x4ecf64ff), WTC2(0x4e5138ff), + WTC2(0x4dcb597f), WTC2(0x4d3db1ff), WTC2(0x4ca82bff), WTC2(0x4c0ab27f), + WTC2(0x4b652f7f), WTC2(0x4ab78d7f), WTC2(0x4a01b67f), WTC2(0x4943957f), + WTC2(0x487d12ff), WTC2(0x47ae1f7f), WTC2(0x46d68f7f), WTC2(0x45f7187f), + WTC2(0x4513597f), WTC2(0x4430467f), WTC2(0x4352d2ff), WTC2(0x427e6bff), + WTC2(0x41b390ff), WTC2(0x40f2077f), WTC2(0x4039a87f), WTC2(0x3f8a3100), + WTC2(0x3ee33e00), WTC2(0x3e446ac0), WTC2(0x3dad5180), WTC2(0x3d1d7fc0), + WTC2(0x3c947b00), WTC2(0x3c11c7c0), WTC2(0x3b94ebc0), WTC2(0x3b1d6dc0), + WTC2(0x3aaad480), WTC2(0x3a3ca740), WTC2(0x39d26c40), WTC2(0x396ba8c0), + WTC2(0x3907e080), WTC2(0x38a69800), WTC2(0x38473d80), WTC2(0x37e923c0), + WTC2(0x378b9b80), WTC2(0x372e0380), WTC2(0x36d03a80), WTC2(0x36727f00), + WTC2(0x36150e40), WTC2(0x35b81540), WTC2(0x355b8000), WTC2(0x34ff1dc0), + WTC2(0x34a2bfc0), WTC2(0x34463e80), WTC2(0x33e982c0), WTC2(0x338c7880), + WTC2(0x332f0bc0), WTC2(0x32d11800), WTC2(0x327265c0), WTC2(0x3212bbc0), + WTC2(0x31b1e740), WTC2(0x314fef00), WTC2(0x30ed0540), WTC2(0x30895c80), + WTC2(0x30251880), WTC2(0x2fc02880), WTC2(0x2f5a6480), WTC2(0x2ef3a480), + WTC2(0x2e8bd640), WTC2(0x2e231100), WTC2(0x2db97680), WTC2(0x2d4f2700), + WTC2(0x2ce431c0), WTC2(0x2c789080), WTC2(0x2c0c3bc0), WTC2(0x2b9f2bc0), + WTC2(0x2b315940), WTC2(0x2ac2bc00), WTC2(0x2a534cc0), WTC2(0x29e303c0)}; + +const FIXP_WTB ELDAnalysis256[768] = { + WTC(0xfababde8), WTC(0xfa8e1e6a), WTC(0xfa6012a9), WTC(0xfa30c8dd), + WTC(0xfa006f4b), WTC(0xf9cf32c4), WTC(0xf99d1cc8), WTC(0xf96a148d), + WTC(0xf936184d), WTC(0xf9013d5b), WTC(0xf8cb7b67), WTC(0xf894ace0), + WTC(0xf85cd28e), WTC(0xf82413f8), WTC(0xf7ea90af), WTC(0xf7b05ee6), + WTC(0xf7759b0b), WTC(0xf73a671f), WTC(0xf6febea3), WTC(0xf6c27a0e), + WTC(0xf685ca33), WTC(0xf6493907), WTC(0xf60d437b), WTC(0xf5d2551f), + WTC(0xf598d273), WTC(0xf561199e), WTC(0xf52b8c6f), WTC(0xf4f8907d), + WTC(0xf4c87fdf), WTC(0xf49ba806), WTC(0xf4724286), WTC(0xf44c6127), + WTC(0xf4282435), WTC(0xf401ceae), WTC(0xf3d775a1), WTC(0xf3a91477), + WTC(0xf376c33f), WTC(0xf340a328), WTC(0xf306d4d6), WTC(0xf2c9775c), + WTC(0xf288a3ed), WTC(0xf2446e2a), WTC(0xf1fcfa45), WTC(0xf1b27b2d), + WTC(0xf164f3f4), WTC(0xf114365c), WTC(0xf0c00532), WTC(0xf06817a9), + WTC(0xf00c4ea4), WTC(0xefacbc7f), WTC(0xef4a205f), WTC(0xeee5dc33), + WTC(0xee808a0d), WTC(0xee19eeb2), WTC(0xedb12f6e), WTC(0xed44e8eb), + WTC(0xecd50a13), WTC(0xec62d8dd), WTC(0xebef68b2), WTC(0xeb7b805c), + WTC(0xeb069af4), WTC(0xea8eef1c), WTC(0xea131c86), WTC(0xe99234c6), + WTC(0xe90cd9c2), WTC(0xe884f65b), WTC(0xe7fcbd6d), WTC(0xe7767300), + WTC(0xe6f289d0), WTC(0xe66f958a), WTC(0xe5eae99f), WTC(0xe560c403), + WTC(0xe4cfaaa1), WTC(0xe43887dc), WTC(0xe39dedc4), WTC(0xe303f190), + WTC(0xe26d7f5d), WTC(0xe1dc34ff), WTC(0xe14f9ced), WTC(0xe0c53cd0), + WTC(0xe03ab085), WTC(0xdfadc948), WTC(0xdf1d640c), WTC(0xde896bb6), + WTC(0xddf256ad), WTC(0xdd591e3d), WTC(0xdcbf0aec), WTC(0xdc25ab0a), + WTC(0xdb8e334c), WTC(0xdaf97794), WTC(0xda67bed9), WTC(0xd9d8c524), + WTC(0xd94bfa62), WTC(0xd8c089b5), WTC(0xd835c151), WTC(0xd7ab1704), + WTC(0xd7200906), WTC(0xd69420dc), WTC(0xd6073c0d), WTC(0xd5799615), + WTC(0xd4ec7c87), WTC(0xd46241c9), WTC(0xd3dc5bde), WTC(0xd35b4a79), + WTC(0xd2de1032), WTC(0xd26246f5), WTC(0xd1e68ed2), WTC(0xd16aa0a4), + WTC(0xd0eea5d2), WTC(0xd073302b), WTC(0xcff93749), WTC(0xcf820f45), + WTC(0xcf0ebb30), WTC(0xce9fd702), WTC(0xce34596c), WTC(0xcdc9a803), + WTC(0xcd5ec5d6), WTC(0xccf468ec), WTC(0xcc8bb41e), WTC(0xcc2619cc), + WTC(0xcbc3e090), WTC(0xcb6422f5), WTC(0xcb064d2f), WTC(0xcaaa2a6d), + WTC(0xca4fbdc9), WTC(0xc9f73c43), WTC(0xc9a0dc9b), WTC(0xc94cdd02), + WTC(0xc8f578a4), WTC(0xc8a24d15), WTC(0xc84dc71f), WTC(0xc7f83516), + WTC(0xc7a1e4b9), WTC(0xc74b22b1), WTC(0xc6f41284), WTC(0xc69cabc1), + WTC(0xc644986d), WTC(0xc5eb4167), WTC(0xc5910312), WTC(0xc5372c7f), + WTC(0xc4deba2e), WTC(0xc4883eca), WTC(0xc43310f0), WTC(0xc3dd5c5a), + WTC(0xc3868802), WTC(0xc32f431d), WTC(0xc2d86c9e), WTC(0xc28300a6), + WTC(0xc22fae33), WTC(0xc1ded3f7), WTC(0xc1908d7d), WTC(0xc144b0ed), + WTC(0xc0fa7cee), WTC(0xc0b0a3b5), WTC(0xc066b8d3), WTC(0xc01d3b32), + WTC(0xbfd5161c), WTC(0xbf8f92af), WTC(0xbf4d5cea), WTC(0xbf0e7d5e), + WTC(0xbed2ce3a), WTC(0xbe9a0062), WTC(0xbe63cec2), WTC(0xbe2ffd2f), + WTC(0xbdfe4565), WTC(0xbdce5568), WTC(0xbda003df), WTC(0xbd735018), + WTC(0xbd485b2c), WTC(0xbd1f69bd), WTC(0xbcf8db7c), WTC(0xbcd52b0a), + WTC(0xbcb4ae4a), WTC(0xbc979382), WTC(0xbc7dcbab), WTC(0xbc6709dc), + WTC(0xbc52c1b1), WTC(0xbc402f2b), WTC(0xbc2ec37b), WTC(0xbc1e2cb3), + WTC(0xbc0e5d5f), WTC(0xbbff8f23), WTC(0xbbf238d2), WTC(0xbbe707d4), + WTC(0xbbde3c63), WTC(0xbbd7a658), WTC(0xbbd2c7f0), WTC(0xbbcee18b), + WTC(0xbbcbdebb), WTC(0xbbca5ab1), WTC(0xbbcb5622), WTC(0xbbd032e4), + WTC(0xbbd91d4d), WTC(0xbbe53757), WTC(0xbbf32f54), WTC(0xbc016781), + WTC(0xbc0f433a), WTC(0xbc1d2aa4), WTC(0xbc2b4912), WTC(0xbc3985df), + WTC(0xbc47d6b9), WTC(0xbc564099), WTC(0xbc64c78a), WTC(0xbc736d96), + WTC(0xbc823210), WTC(0xbc911484), WTC(0xbca015b8), WTC(0xbcaf37eb), + WTC(0xbcbe7bc3), WTC(0xbccdde4d), WTC(0xbcdd6037), WTC(0xbced049a), + WTC(0xbcfccc81), WTC(0xbd0cb482), WTC(0xbd1cbcaa), WTC(0xbd2ce7ea), + WTC(0xbd3d363b), WTC(0xbd4da445), WTC(0xbd5e312d), WTC(0xbd6edfd1), + WTC(0xbd7fae14), WTC(0xbd90991b), WTC(0xbda19fcf), WTC(0xbdb2c464), + WTC(0xbdc4053b), WTC(0xbdd55f4b), WTC(0xbde6d0a0), WTC(0xbdf85c51), + WTC(0xbe09ffa3), WTC(0xbe1bb724), WTC(0xbe2d8160), WTC(0xbe3f5f98), + WTC(0xbe515144), WTC(0xbe6351a9), WTC(0xbe755ebd), WTC(0xbe877b8e), + WTC(0xbe99a63d), WTC(0xbeabda45), WTC(0xbebe16b0), WTC(0xbed05d1c), + WTC(0xbee2ada9), WTC(0xbef502e2), WTC(0xbf075c40), WTC(0xbf19bc0b), + WTC(0xbf2c217f), WTC(0xbf3e887a), WTC(0xbf50f09d), WTC(0xbf635c77), + WTC(0xbf75cac0), WTC(0xbf883905), WTC(0xbf9aa62b), WTC(0xbfad14f1), + WTC(0xbfbf85c7), WTC(0xbfd1f592), WTC(0xbfe461fc), WTC(0xbff6c86a), + WTC(0x80126c8d), WTC(0x80372448), WTC(0x805bd2fd), WTC(0x80807315), + WTC(0x80a4fffa), WTC(0x80c9748d), WTC(0x80edd08b), WTC(0x81121a23), + WTC(0x81364fde), WTC(0x815a6b16), WTC(0x817e6b36), WTC(0x81a25433), + WTC(0x81c625c8), WTC(0x81e9d801), WTC(0x820d6a5c), WTC(0x8230e060), + WTC(0x825438c0), WTC(0x82776ac7), WTC(0x829a7555), WTC(0x82bd5ca3), + WTC(0x82e01e80), WTC(0x8302b200), WTC(0x83251590), WTC(0x83474d79), + WTC(0x8369566f), WTC(0x838b2957), WTC(0x83acc2d9), WTC(0x83ce27c1), + WTC(0x83ef54b9), WTC(0x841042d1), WTC(0x8430ef15), WTC(0x84515e84), + WTC(0x84718e32), WTC(0x84917804), WTC(0x84b11a25), WTC(0x84d0788d), + WTC(0x84ef9322), WTC(0x850e61ec), WTC(0x852ce400), WTC(0x854b1e0a), + WTC(0x85690f2c), WTC(0x8586b207), WTC(0x85a4057b), WTC(0x85c1107d), + WTC(0x85ddd335), WTC(0x85fa485e), WTC(0x86167172), WTC(0x8632549d), + WTC(0x864df388), WTC(0x8669497e), WTC(0x86845757), WTC(0x869f2218), + WTC(0x86b9ab5a), WTC(0x86d3f1bf), WTC(0x86edf68f), WTC(0x8707baf1), + WTC(0x872147e0), WTC(0x873aa6fc), WTC(0x8753c571), WTC(0x876c76e6), + WTC(0x87850ab7), WTC(0x879e373b), WTC(0x87b6ea37), WTC(0x87cc4188), + WTC(0x880d4300), WTC(0x8855e9ff), WTC(0x88acfca0), WTC(0x890d0f94), + WTC(0x8971e7d5), WTC(0x89d8a0c1), WTC(0x8a3fc425), WTC(0x8aa74105), + WTC(0x8b0f5b93), WTC(0x8b78a107), WTC(0x8be38bb3), WTC(0x8c508092), + WTC(0x8cbfe384), WTC(0x8d3214f1), WTC(0x8da75d21), WTC(0x8e1fe96c), + WTC(0x8e9be76a), WTC(0x8f1b806c), WTC(0x8f9ed314), WTC(0x9025f26a), + WTC(0x90b0ecea), WTC(0x913fd0eb), WTC(0x91d2a684), WTC(0x92696dea), + WTC(0x93042868), WTC(0x93a2d456), WTC(0x94456d20), WTC(0x94ebe9e5), + WTC(0x95964178), WTC(0x96446a05), WTC(0x96f65958), WTC(0x97ac059a), + WTC(0x98656089), WTC(0x99225a80), WTC(0x99e2e2e8), WTC(0x9aa6e666), + WTC(0x9b6e54b8), WTC(0x9c391d99), WTC(0x9d07338a), WTC(0x9dd8888d), + WTC(0x9ead0b5c), WTC(0x9f84a871), WTC(0xa05f4fb3), WTC(0xa13cf913), + WTC(0xa21d9891), WTC(0xa3011e27), WTC(0xa3e77eb4), WTC(0xa4d0b190), + WTC(0xa5bcb0d7), WTC(0xa6ab750c), WTC(0xa79cf884), WTC(0xa89135cb), + WTC(0xa9882a44), WTC(0xaa81d578), WTC(0xab7e39a6), WTC(0xac7d5a36), + WTC(0xad7f3ba5), WTC(0xae83dfed), WTC(0xaf8b4e16), WTC(0xb095911c), + WTC(0xb1a2afd1), WTC(0xb2b2ac9f), WTC(0xb3c58807), WTC(0xb4db4d5e), + WTC(0x4a268ead), WTC(0x490b5ba7), WTC(0x47ed8d30), WTC(0x46cd10c5), + WTC(0x45a9dcc1), WTC(0x4483f267), WTC(0x435b5aeb), WTC(0x42301d12), + WTC(0x41023a15), WTC(0x3fd19bf1), WTC(0x3e9e31e1), WTC(0x3d682986), + WTC(0x3c2fc001), WTC(0x3af52d8f), WTC(0x39b88b7d), WTC(0x38798642), + WTC(0x3737e6d3), WTC(0x35f3e98a), WTC(0x34add45c), WTC(0x33660083), + WTC(0x321ccf3a), WTC(0x30d2963e), WTC(0x2f87a28f), WTC(0x2e3c22cd), + WTC(0x2cf010e5), WTC(0x2ba2ffe5), WTC(0x2a54ba93), WTC(0x290596f5), + WTC(0x27b62806), WTC(0x266762b8), WTC(0x251a11b1), WTC(0x23ce94f9), + WTC(0x22852ddb), WTC(0x213df340), WTC(0x1ff90185), WTC(0x1eb67d94), + WTC(0x1d767485), WTC(0x1c38d477), WTC(0x1afda747), WTC(0x19c5248b), + WTC(0x188f8259), WTC(0x175d0d40), WTC(0x162e5320), WTC(0x150436cd), + WTC(0x13df8d3f), WTC(0x12c102f1), WTC(0x11a8dd65), WTC(0x1096d490), + WTC(0x0f8a1755), WTC(0x0e811dcd), WTC(0x0d7acb9a), WTC(0x0c767d00), + WTC(0x0b7334d9), WTC(0x0a6fef31), WTC(0x096c5a87), WTC(0x08691adb), + WTC(0x0765e395), WTC(0x06610309), WTC(0x0558a0d2), WTC(0x044a946c), + WTC(0x033acb52), WTC(0x0234706f), WTC(0x014939dc), WTC(0x00928577), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0xffe73593), WTC(0xffb63fcf), WTC(0xff853c1f), WTC(0xff5454d7), + WTC(0xff23b44b), WTC(0xfef38417), WTC(0xfec3dc9a), WTC(0xfe94c511), + WTC(0xfe664753), WTC(0xfe387086), WTC(0xfe0b4e63), WTC(0xfddef15c), + WTC(0xfdb3a3f6), WTC(0xfd89e611), WTC(0xfd61c750), WTC(0xfd3ae585), + WTC(0xfd14ec09), WTC(0xfcef9b06), WTC(0xfccaf509), WTC(0xfca74180), + WTC(0xfc8518a3), WTC(0xfc655c7a), WTC(0xfc488545), WTC(0xfc2e9998), + WTC(0xfc1726bb), WTC(0xfc01463f), WTC(0xfbec2c64), WTC(0xfbd735ce), + WTC(0xfbc29e8e), WTC(0xfbaf8042), WTC(0xfb9eeba0), WTC(0xfb91dc05), + WTC(0xfb88f420), WTC(0xfb8479eb), WTC(0xfb84398b), WTC(0xfb87884b), + WTC(0xfb8da8bf), WTC(0xfb95d020), WTC(0xfb9f3e49), WTC(0xfba9448a), + WTC(0xfbb3cf10), WTC(0xfbbf67e7), WTC(0xfbccf65d), WTC(0xfbddba58), + WTC(0xfbf31f46), WTC(0xfc0eb236), WTC(0xfc3164f0), WTC(0xfc5b8269), + WTC(0xfc8c5bcd), WTC(0xfcc248ee), WTC(0xfcfb056c), WTC(0xfd33cc26), + WTC(0xfd6b84ee), WTC(0xfda2d9e7), WTC(0xfddc03fb), WTC(0xfe1aaf57), + WTC(0xfe61a0af), WTC(0xfeb28df7), WTC(0xff0cd343), WTC(0xff6d8388), + WTC(0xffd24331), WTC(0x00396fe3), WTC(0x00a2fb3e), WTC(0x01107050), + WTC(0x01831900), WTC(0x01fc2377), WTC(0x027bd1fc), WTC(0x03019a2d), + WTC(0x038d0a88), WTC(0x041dd88f), WTC(0x04b43495), WTC(0x0550c1ef), + WTC(0x05f38bd6), WTC(0x069c0523), WTC(0x074a114e), WTC(0x07fe0ceb), + WTC(0x08b88e33), WTC(0x097a5965), WTC(0x0a438318), WTC(0x0b137046), + WTC(0x0be9b5ab), WTC(0x0cc61fa9), WTC(0x0da897b2), WTC(0x0e9123b3), + WTC(0x0f7ff200), WTC(0x10755696), WTC(0x11717f94), WTC(0x127474a0), + WTC(0x137e489d), WTC(0x148f1b02), WTC(0x15a6f15e), WTC(0x16c5b7c9), + WTC(0x17eb72b1), WTC(0x19183e51), WTC(0x1a4c2444), WTC(0x1b871b1c), + WTC(0x1cc92e92), WTC(0x1e127ffc), WTC(0x1f6319b9), WTC(0x20baef78), + WTC(0x221a0861), WTC(0x23807f94), WTC(0x24ee5a89), WTC(0x2663898d), + WTC(0x27e0101e), WTC(0x2964058d), WTC(0x2aef6bcf), WTC(0x2c8230fc), + WTC(0x2e1c545b), WTC(0x2fbde72b), WTC(0x3166e76f), WTC(0x33173f5d), + WTC(0x34cee8c3), WTC(0x368debe1), WTC(0x38543d4f), WTC(0x3a21bd94), + WTC(0x3bf6576f), WTC(0x3dd1ff07), WTC(0x3fb4948e), WTC(0x419de414), + WTC(0x438dc202), WTC(0x45840e7d), WTC(0x4780a435), WTC(0x4983609f), + WTC(0x4b8cc548), WTC(0x4d9df796), WTC(0x4fb81f46), WTC(0x51dc8690), + WTC(0x000d970d), WTC(0xfff7ea67), WTC(0xfff7fc3d), WTC(0x000d3de2), + WTC(0x003720ad), WTC(0x007515f1), WTC(0x00c68f04), WTC(0x012afd3b), + WTC(0x01a1d1ec), WTC(0x022a7e69), WTC(0x02c47408), WTC(0x036f2420), + WTC(0x042a0001), WTC(0x04f47905), WTC(0x05ce007e), WTC(0x06b607be), + WTC(0x07ac0028), WTC(0x08af5b01), WTC(0x09bf89a7), WTC(0x0adbfd6d), + WTC(0x0c042798), WTC(0x0d377997), WTC(0x0e7564b5), WTC(0x0fbd5a3a), + WTC(0x110ecb85), WTC(0x126929fb), WTC(0x13cbe6e6), WTC(0x15367376), + WTC(0x16a8413f), WTC(0x1820c15f), WTC(0x199f6568), WTC(0x1b239e6b), + WTC(0x1cacdde2), WTC(0x1e3a951a), WTC(0x1fcc356f), WTC(0x2161301f), + WTC(0x22f8f6b7), WTC(0x2492fa4a), WTC(0x262eac3f), WTC(0x27cb7e20), + WTC(0x2968e0c4), WTC(0x2b064625), WTC(0x2ca31f1a), WTC(0x2e3edd2a), + WTC(0x2fd8f19f), WTC(0x3170ce00), WTC(0x3305e32c), WTC(0x3497a2df), + WTC(0x36257e78), WTC(0x37aee70b), WTC(0x39334e05), WTC(0x3ab22498), + WTC(0x3c2adc2c), WTC(0x3d9ce645), WTC(0x3f07b3ef), WTC(0x406ab6ca), + WTC(0x41c56001), WTC(0x4317214a), WTC(0x445f6b34), WTC(0x459daf5d), + WTC(0x46d15f56), WTC(0x47f9ed71), WTC(0x4916d11f), WTC(0x4a275770), + WTC(0x4b2b2fff), WTC(0x4c219eae), WTC(0x4d0a20cb), WTC(0x4de4288e), + WTC(0x4eaf263d), WTC(0x4f6a8bb8), WTC(0x5015ca33), WTC(0x50b052dd), + WTC(0x51399757), WTC(0x51b108c6), WTC(0x5216190a), WTC(0x5268387c), + WTC(0x52a6d933), WTC(0x52d16c19), WTC(0x52e7628b), WTC(0x52e82ea3), + WTC(0x52d3407d), WTC(0x52a80a28), WTC(0x5265fd43), WTC(0x520c8a1d), + WTC(0x519b22c8), WTC(0x511138e0), WTC(0x506e3c82), WTC(0x4fb1a037), + WTC(0x4edad4e3), WTC(0x4de94c2d), WTC(0x4cdc76d8), WTC(0x4bb3c683), + WTC(0x4a6eacd2), WTC(0x490c9abe), WTC(0x478d04f1), WTC(0x45f00420), + WTC(0x4445673f), WTC(0x42ac0d2e), WTC(0x41338364), WTC(0x3fdb5b58), + WTC(0x3ea1c30f), WTC(0x3d842780), WTC(0x3c7fa763), WTC(0x3b911b96), + WTC(0x3ab560bf), WTC(0x39e95908), WTC(0x3929debb), WTC(0x3873bd4d), + WTC(0x37c31db2), WTC(0x3713a59c), WTC(0x3663deb2), WTC(0x35b52f23), + WTC(0x3507c61e), WTC(0x345a7f42), WTC(0x33ac7e0c), WTC(0x32fd366f), + WTC(0x324baa28), WTC(0x319674e9), WTC(0x30dd7e1a), WTC(0x3021f3e8), + WTC(0x2f63f903), WTC(0x2ea2a1aa), WTC(0x2dddd97b), WTC(0x2d166985), + WTC(0x2c4ca42f), WTC(0x2b805cca), WTC(0x2ab162aa), WTC(0x29df7b17), }; +const FIXP_WTB ELDAnalysis240[720] = { + WTC(0xfab9477b), WTC(0xfa899344), WTC(0xfa5845dd), WTC(0xfa259762), + WTC(0xf9f1c005), WTC(0xf9bcefe6), WTC(0xf9871e8b), WTC(0xf9503397), + WTC(0xf9183f47), WTC(0xf8df4eac), WTC(0xf8a53ba7), WTC(0xf869f0be), + WTC(0xf82d9759), WTC(0xf7f0593e), WTC(0xf7b2520a), WTC(0xf773a37c), + WTC(0xf73475ce), WTC(0xf6f4bedd), WTC(0xf6b455a8), WTC(0xf6739525), + WTC(0xf6332510), WTC(0xf5f3938b), WTC(0xf5b56073), WTC(0xf57900bd), + WTC(0xf53ee82d), WTC(0xf5079149), WTC(0xf4d36ffc), WTC(0xf4a2e526), + WTC(0xf4763d91), WTC(0xf44d9872), WTC(0xf426eaed), WTC(0xf3fdc161), + WTC(0xf3d001ff), WTC(0xf39dafcc), WTC(0xf366eb43), WTC(0xf32bdcdc), + WTC(0xf2ecab80), WTC(0xf2a97b34), WTC(0xf26265ae), WTC(0xf2178a6f), + WTC(0xf1c92458), WTC(0xf17752b9), WTC(0xf121e6ac), WTC(0xf0c89a63), + WTC(0xf06b15ef), WTC(0xf0092e86), WTC(0xefa2fd42), WTC(0xef397ebc), + WTC(0xeece51c6), WTC(0xee61e8b6), WTC(0xedf3d92e), WTC(0xed82c330), + WTC(0xed0d58bb), WTC(0xec94891b), WTC(0xec19d435), WTC(0xeb9e4e4e), + WTC(0xeb221000), WTC(0xeaa32422), WTC(0xea1fb440), WTC(0xe99695d2), + WTC(0xe90859ab), WTC(0xe8775114), WTC(0xe7e62b37), WTC(0xe7578147), + WTC(0xe6cb3ac1), WTC(0xe63f5696), WTC(0xe5afe916), WTC(0xe519090f), + WTC(0xe47aab0d), WTC(0xe3d6c2d0), WTC(0xe331dae7), WTC(0xe29031e1), + WTC(0xe1f40926), WTC(0xe15d87d2), WTC(0xe0c9d727), WTC(0xe0360ad5), + WTC(0xdf9f81af), WTC(0xdf04f9f9), WTC(0xde66697f), WTC(0xddc48ca1), + WTC(0xdd20a42a), WTC(0xdc7c6853), WTC(0xdbd9a476), WTC(0xdb398a8c), + WTC(0xda9cd7c2), WTC(0xda0365cf), WTC(0xd96cad85), WTC(0xd8d7b7a3), + WTC(0xd8439e8c), WTC(0xd7afb73d), WTC(0xd71b6347), WTC(0xd686149a), + WTC(0xd5efab2c), WTC(0xd558877e), WTC(0xd4c29dbc), WTC(0xd430a0aa), + WTC(0xd3a3d490), WTC(0xd31c588f), WTC(0xd297e075), WTC(0xd213ef33), + WTC(0xd18fd566), WTC(0xd10b8d3f), WTC(0xd087b250), WTC(0xd0054ef2), + WTC(0xcf85f94a), WTC(0xcf0af5f7), WTC(0xce94faf5), WTC(0xce229409), + WTC(0xcdb0b5f8), WTC(0xcd3ec554), WTC(0xcccdbf58), WTC(0xcc5f39d5), + WTC(0xcbf49ef5), WTC(0xcb8d5f73), WTC(0xcb28801c), WTC(0xcac5a265), + WTC(0xca64ad2e), WTC(0xca05d7fd), WTC(0xc9a96602), WTC(0xc94f9f79), + WTC(0xc8f2b954), WTC(0xc899e795), WTC(0xc83f94aa), WTC(0xc7e41f63), + WTC(0xc787e69f), WTC(0xc72b3fd0), WTC(0xc6ce3f0f), WTC(0xc670c175), + WTC(0xc61224cf), WTC(0xc5b21fec), WTC(0xc55202a4), WTC(0xc4f3353a), + WTC(0xc4968597), WTC(0xc43b93f2), WTC(0xc3e03d26), WTC(0xc383a011), + WTC(0xc3268aed), WTC(0xc2ca1039), WTC(0xc26f5bcc), WTC(0xc21726c9), + WTC(0xc1c1d5b2), WTC(0xc16f66ba), WTC(0xc11f76d9), WTC(0xc0d0a9f6), + WTC(0xc081cddb), WTC(0xc0333180), WTC(0xbfe5bb54), WTC(0xbf9aee90), + WTC(0xbf53d587), WTC(0xbf108855), WTC(0xbed0de05), WTC(0xbe9477d7), + WTC(0xbe5b030f), WTC(0xbe243642), WTC(0xbdefb72f), WTC(0xbdbd29df), + WTC(0xbd8c71ab), WTC(0xbd5d99cb), WTC(0xbd30e375), WTC(0xbd06afcc), + WTC(0xbcdf8c7f), WTC(0xbcbbf704), WTC(0xbc9c307e), WTC(0xbc803b86), + WTC(0xbc67c0c7), WTC(0xbc521d3d), WTC(0xbc3e6561), WTC(0xbc2bf2cb), + WTC(0xbc1a6872), WTC(0xbc09ce15), WTC(0xbbfa764f), WTC(0xbbed1356), + WTC(0xbbe257fa), WTC(0xbbda4099), WTC(0xbbd46a31), WTC(0xbbcffa76), + WTC(0xbbcc766d), WTC(0xbbca782f), WTC(0xbbcb16c7), WTC(0xbbcff77c), + WTC(0xbbd978e6), WTC(0xbbe68e5f), WTC(0xbbf593ed), WTC(0xbc04a834), + WTC(0xbc136941), WTC(0xbc2252c3), WTC(0xbc31723d), WTC(0xbc40ab92), + WTC(0xbc4ffe2d), WTC(0xbc5f7072), WTC(0xbc6f0520), WTC(0xbc7ebd23), + WTC(0xbc8e9746), WTC(0xbc9e942f), WTC(0xbcaeb633), WTC(0xbcbefe8b), + WTC(0xbccf69bb), WTC(0xbcdff92e), WTC(0xbcf0b04f), WTC(0xbd018ebd), + WTC(0xbd129192), WTC(0xbd23b9b8), WTC(0xbd350afb), WTC(0xbd46820e), + WTC(0xbd581bfc), WTC(0xbd69db11), WTC(0xbd7bbf57), WTC(0xbd8dc584), + WTC(0xbd9feaad), WTC(0xbdb231a4), WTC(0xbdc498ea), WTC(0xbdd71cd1), + WTC(0xbde9bb57), WTC(0xbdfc77d9), WTC(0xbe0f4e93), WTC(0xbe223ae5), + WTC(0xbe353cf5), WTC(0xbe485689), WTC(0xbe5b8329), WTC(0xbe6ebe88), + WTC(0xbe820afd), WTC(0xbe956811), WTC(0xbea8d109), WTC(0xbebc4352), + WTC(0xbecfc0fb), WTC(0xbee34a07), WTC(0xbef6d884), WTC(0xbf0a6bb1), + WTC(0xbf1e0685), WTC(0xbf31a685), WTC(0xbf45483c), WTC(0xbf58eb6b), + WTC(0xbf6c9376), WTC(0xbf803c90), WTC(0xbf93e4b9), WTC(0xbfa78d05), + WTC(0xbfbb3830), WTC(0xbfcee339), WTC(0xbfe28aa9), WTC(0xbff62b89), + WTC(0x8013a5f4), WTC(0x803acfd6), WTC(0x8061eec7), WTC(0x8088fc73), + WTC(0x80aff270), WTC(0x80d6cbe5), WTC(0x80fd8c2a), WTC(0x812437a8), + WTC(0x814ac94f), WTC(0x81713adc), WTC(0x81979098), WTC(0x81bdccb7), + WTC(0x81e3e738), WTC(0x8209dd04), WTC(0x822fb23a), WTC(0x825565bb), + WTC(0x827aed94), WTC(0x82a04909), WTC(0x82c57c85), WTC(0x82ea831c), + WTC(0x830f539d), WTC(0x8333eeba), WTC(0x8358585a), WTC(0x837c882e), + WTC(0x83a07742), WTC(0x83c428a5), WTC(0x83e79c4c), WTC(0x840aca65), + WTC(0x842dad81), WTC(0x84504ac0), WTC(0x84729fb1), WTC(0x8494a4f1), + WTC(0x84b65932), WTC(0x84d7c0f8), WTC(0x84f8d936), WTC(0x85199a59), + WTC(0x853a05a1), WTC(0x855a2023), WTC(0x8579e46e), WTC(0x85994d55), + WTC(0x85b86190), WTC(0x85d723e6), WTC(0x85f58fa9), WTC(0x8613a3ce), + WTC(0x863167b5), WTC(0x864eddfe), WTC(0x866c0138), WTC(0x8688d2e4), + WTC(0x86a55901), WTC(0x86c19497), WTC(0x86dd8390), WTC(0x86f9288f), + WTC(0x871487e0), WTC(0x872fadd0), WTC(0x874a9a1e), WTC(0x876519d0), + WTC(0x877f471e), WTC(0x8799fb36), WTC(0x87b48b97), WTC(0x87cba021), + WTC(0x880f67ae), WTC(0x885e0f91), WTC(0x88bc84cd), WTC(0x89244640), + WTC(0x8990a45d), WTC(0x89fe6766), WTC(0x8a6c9065), WTC(0x8adb31e6), + WTC(0x8b4ad5b3), WTC(0x8bbc2068), WTC(0x8c2f93ff), WTC(0x8ca5a922), + WTC(0x8d1ed72d), WTC(0x8d9b7ddb), WTC(0x8e1bd6cc), WTC(0x8ea01924), + WTC(0x8f287716), WTC(0x8fb5143e), WTC(0x9046074e), WTC(0x90db612b), + WTC(0x91753263), WTC(0x92138094), WTC(0x92b64cf3), WTC(0x935d96c9), + WTC(0x94095a56), WTC(0x94b98fd4), WTC(0x956e2a87), WTC(0x96271ff6), + WTC(0x96e46309), WTC(0x97a5e80d), WTC(0x986b9e55), WTC(0x993572af), + WTC(0x9a0350ce), WTC(0x9ad52154), WTC(0x9baad10f), WTC(0x9c844cdd), + WTC(0x9d618437), WTC(0x9e4265b2), WTC(0x9f26d9ad), WTC(0xa00ec9b0), + WTC(0xa0fa2916), WTC(0xa1e8ec20), WTC(0xa2daffa4), WTC(0xa3d05468), + WTC(0xa4c8e007), WTC(0xa5c49ae4), WTC(0xa6c37c24), WTC(0xa7c57d03), + WTC(0xa8ca9750), WTC(0xa9d2c7f2), WTC(0xaade0f6f), WTC(0xabec7177), + WTC(0xacfdf2b1), WTC(0xae129740), WTC(0xaf2a6321), WTC(0xb04563a6), + WTC(0xb163a2e6), WTC(0xb28524c4), WTC(0xb3a9eaf7), WTC(0xb4d1ff1b), + WTC(0x4a1d2880), WTC(0x48eee56e), WTC(0x47bda882), WTC(0x46895c79), + WTC(0x4551f8a1), WTC(0x4417817b), WTC(0x42da023d), WTC(0x419980ca), + WTC(0x4055f463), WTC(0x3f0f3b51), WTC(0x3dc56e18), WTC(0x3c78d943), + WTC(0x3b29bf3d), WTC(0x39d84ea0), WTC(0x3884337d), WTC(0x372d2371), + WTC(0x35d364ea), WTC(0x34774cef), WTC(0x33194d3a), WTC(0x31b9d586), + WTC(0x30594fcf), WTC(0x2ef80b63), WTC(0x2d9630d5), WTC(0x2c337c00), + WTC(0x2acf6a9e), WTC(0x296a3205), WTC(0x28046825), WTC(0x269f1752), + WTC(0x253b5314), WTC(0x23d9993f), WTC(0x227a3c77), WTC(0x211d59a0), + WTC(0x1fc314fd), WTC(0x1e6b9834), WTC(0x1d16eb58), WTC(0x1bc4f82e), + WTC(0x1a75e481), WTC(0x1929f389), WTC(0x17e16ee3), WTC(0x169cd758), + WTC(0x155d1ae5), WTC(0x14235182), WTC(0x12f051de), WTC(0x11c4993b), + WTC(0x109fdf4c), WTC(0x0f81351c), WTC(0x0e66c5e6), WTC(0x0d4f4b16), + WTC(0x0c39f013), WTC(0x0b25765d), WTC(0x0a10c51e), WTC(0x08fbee35), + WTC(0x07e7986f), WTC(0x06d25fe7), WTC(0x05ba1b52), WTC(0x049c33b7), + WTC(0x0379ceb9), WTC(0x025ee7c7), WTC(0x015edc1c), WTC(0x00978deb), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0xffe59474), WTC(0xffb158f8), WTC(0xff7d1275), WTC(0xff48f44c), + WTC(0xff1531e3), WTC(0xfee1faa9), WTC(0xfeaf626e), WTC(0xfe7d7227), + WTC(0xfe4c383f), WTC(0xfe1bc4ff), WTC(0xfdec297f), WTC(0xfdbd9f6c), + WTC(0xfd90bbf0), WTC(0xfd65ba73), WTC(0xfd3c2d32), WTC(0xfd13ab35), + WTC(0xfcebe811), WTC(0xfcc4eeae), WTC(0xfc9f1d64), WTC(0xfc7b48b0), + WTC(0xfc5a7282), WTC(0xfc3cef9b), WTC(0xfc229f4c), WTC(0xfc0a9e29), + WTC(0xfbf3dccb), WTC(0xfbdd80c3), WTC(0xfbc7556c), WTC(0xfbb289cf), + WTC(0xfba06f99), WTC(0xfb923aca), WTC(0xfb88bb57), WTC(0xfb84457f), + WTC(0xfb848c2e), WTC(0xfb88bd28), WTC(0xfb8feda1), WTC(0xfb9928eb), + WTC(0xfba38b9e), WTC(0xfbae711c), WTC(0xfbba3538), WTC(0xfbc7af9d), + WTC(0xfbd8485e), WTC(0xfbeda238), WTC(0xfc099de4), WTC(0xfc2d981f), + WTC(0xfc59fd0d), WTC(0xfc8e1583), WTC(0xfcc7e0d7), WTC(0xfd048d03), + WTC(0xfd40dfaf), WTC(0xfd7c1d35), WTC(0xfdb767cc), WTC(0xfdf64a9f), + WTC(0xfe3d0242), WTC(0xfe8e3316), WTC(0xfeead2b9), WTC(0xff4fff8c), + WTC(0xffba7b11), WTC(0x00281cae), WTC(0x009847d1), WTC(0x010cb653), + WTC(0x01870639), WTC(0x02089db5), WTC(0x0291b571), WTC(0x0321a4c1), + WTC(0x03b7eda0), WTC(0x04544c7f), WTC(0x04f74134), WTC(0x05a16810), + WTC(0x06525829), WTC(0x070994d4), WTC(0x07c767ba), WTC(0x088c69b8), + WTC(0x09598634), WTC(0x0a2f14ca), WTC(0x0b0c677b), WTC(0x0bf0f576), + WTC(0x0cdc7f73), WTC(0x0dceed54), WTC(0x0ec84a00), WTC(0x0fc8db86), + WTC(0x10d10278), WTC(0x11e0e05e), WTC(0x12f880cc), WTC(0x1418049b), + WTC(0x153f86b3), WTC(0x166ef5a3), WTC(0x17a64878), WTC(0x18e59dde), + WTC(0x1a2d088b), WTC(0x1b7c7e41), WTC(0x1cd40ab7), WTC(0x1e33d542), + WTC(0x1f9be7a5), WTC(0x210c344f), WTC(0x2284cb85), WTC(0x2405ca48), + WTC(0x258f2b7f), WTC(0x2720e063), WTC(0x28bafd49), WTC(0x2a5d950c), + WTC(0x2c0896e4), WTC(0x2dbbf7d4), WTC(0x2f77ca28), WTC(0x313c1273), + WTC(0x3308b7e4), WTC(0x34ddb0ec), WTC(0x36bb06b7), WTC(0x38a0a935), + WTC(0x3a8e7270), WTC(0x3c844ca9), WTC(0x3e82267e), WTC(0x4087ccfa), + WTC(0x42950352), WTC(0x44a99ce7), WTC(0x46c57093), WTC(0x48e84dbe), + WTC(0x4b127506), WTC(0x4d452d29), WTC(0x4f81e066), WTC(0x51ca11c4), + WTC(0x000c82e8), WTC(0xfff6f40c), WTC(0xfffa1260), WTC(0x001530bf), + WTC(0x0047a202), WTC(0x0090b903), WTC(0x00efc89f), WTC(0x016423af), + WTC(0x01ed1d0e), WTC(0x028a0796), WTC(0x033a3620), WTC(0x03fcfb89), + WTC(0x04d1aaaa), WTC(0x05b7965c), WTC(0x06ae1179), WTC(0x07b46ee8), + WTC(0x08ca0173), WTC(0x09ee1c00), WTC(0x0b201162), WTC(0x0c5f346e), + WTC(0x0daad808), WTC(0x0f024f17), WTC(0x1064ec4b), WTC(0x11d202c4), + WTC(0x1348e514), WTC(0x14c8e62f), WTC(0x1651590a), WTC(0x17e19051), + WTC(0x1978df27), WTC(0x1b169812), WTC(0x1cba0e15), WTC(0x1e629407), + WTC(0x200f7cd4), WTC(0x21c01b29), WTC(0x2373c228), WTC(0x2529c453), + WTC(0x26e174b9), WTC(0x289a262f), WTC(0x2a532bba), WTC(0x2c0bd7b2), + WTC(0x2dc37d92), WTC(0x2f796fce), WTC(0x312d017a), WTC(0x32dd8513), + WTC(0x348a4dde), WTC(0x3632aeb3), WTC(0x37d5fa29), WTC(0x39738334), + WTC(0x3b0a9c99), WTC(0x3c9a9926), WTC(0x3e22cc21), WTC(0x3fa287dc), + WTC(0x41191f89), WTC(0x4285e5fc), WTC(0x43e82e02), WTC(0x453f4a40), + WTC(0x468a8dd9), WTC(0x47c94c23), WTC(0x48fadc7c), WTC(0x4a1e75f9), + WTC(0x4b339ecf), WTC(0x4c3981b1), WTC(0x4d2f7cd3), WTC(0x4e14e381), + WTC(0x4ee90804), WTC(0x4fab3d6a), WTC(0x505ad6bd), WTC(0x50f726a3), + WTC(0x517f7fea), WTC(0x51f335fd), WTC(0x52519b0f), WTC(0x529a01f2), + WTC(0x52cbbe31), WTC(0x52e621d9), WTC(0x52e880aa), WTC(0x52d22c7a), + WTC(0x52a278a5), WTC(0x5258b880), WTC(0x51f43e1d), WTC(0x51745c38), + WTC(0x50d8669e), WTC(0x501faf0e), WTC(0x4f49897e), WTC(0x4e554804), + WTC(0x4d423d9e), WTC(0x4c0fbd8b), WTC(0x4abd1a4d), WTC(0x4949a698), + WTC(0x47b4b7f9), WTC(0x45fe2b6d), WTC(0x44375019), WTC(0x4284e96e), + WTC(0x40f7efa2), WTC(0x3f8f8b33), WTC(0x3e494311), WTC(0x3d21e35b), + WTC(0x3c15c621), WTC(0x3b2115f3), WTC(0x3a4008aa), WTC(0x396ed2a6), + WTC(0x38a99a1d), WTC(0x37ec1177), WTC(0x3730f154), WTC(0x36756c15), + WTC(0x35bafb0d), WTC(0x35020093), WTC(0x34492381), WTC(0x338f6226), + WTC(0x32d40a34), WTC(0x3215bd73), WTC(0x315302ce), WTC(0x308c7c41), + WTC(0x2fc3532f), WTC(0x2ef6de8f), WTC(0x2e265a7f), WTC(0x2d527bfd), + WTC(0x2c7bf035), WTC(0x2ba2975b), WTC(0x2ac63552), WTC(0x29e686ca), +}; +const FIXP_WTB ELDAnalysis128[384] = { + WTC(0xfaa49e98), WTC(0xfa48929f), WTC(0xf9e7eb39), WTC(0xf983b829), + WTC(0xf91bc5cb), WTC(0xf8b0376f), WTC(0xf8408d62), WTC(0xf7cd8c1e), + WTC(0xf7580da3), WTC(0xf6e0b0dc), WTC(0xf667753c), WTC(0xf5efa4cf), + WTC(0xf57cb6de), WTC(0xf511b62b), WTC(0xf4b1a860), WTC(0xf45ee8f8), + WTC(0xf415710d), WTC(0xf3c0c4f3), WTC(0xf35c2af9), WTC(0xf2e89620), + WTC(0xf266f3cb), WTC(0xf1d819bf), WTC(0xf13cff2f), WTC(0xf09489d2), + WTC(0xefdcfa80), WTC(0xef182059), WTC(0xee4d6c60), WTC(0xed7b8da7), + WTC(0xec9c27b1), WTC(0xebb57d0d), WTC(0xeacb3918), WTC(0xe9d35591), + WTC(0xe8c9176e), WTC(0xe7b93e42), WTC(0xe6b10e47), WTC(0xe5a6b875), + WTC(0xe484c345), WTC(0xe3509f1b), WTC(0xe224254c), WTC(0xe10a4e18), + WTC(0xdff4a668), WTC(0xded3d881), WTC(0xdda5ed98), WTC(0xdc722d13), + WTC(0xdb437360), WTC(0xda1fefed), WTC(0xd90623b2), WTC(0xd7f070f5), + WTC(0xd6da361b), WTC(0xd5c0786f), WTC(0xd4a6e188), WTC(0xd39b37b4), + WTC(0xd2a01ff2), WTC(0xd1a8a05c), WTC(0xd0b0cf47), WTC(0xcfbd3527), + WTC(0xced6b8d7), WTC(0xcdff0a66), WTC(0xcd2978a4), WTC(0xcc587183), + WTC(0xcb93bfdb), WTC(0xcad80773), WTC(0xca233c2b), WTC(0xc9768b5e), + WTC(0xc8cc130c), WTC(0xc8231acd), WTC(0xc7768de4), WTC(0xc6c86bdf), + WTC(0xc6181aa1), WTC(0xc563f6ce), WTC(0xc4b33a2a), WTC(0xc4085fcf), + WTC(0xc35ae72e), WTC(0xc2ad7adf), WTC(0xc206ed94), WTC(0xc16a5744), + WTC(0xc0d59625), WTC(0xc041e21b), WTC(0xbfb1ee05), WTC(0xbf2d82ea), + WTC(0xbeb60fe9), WTC(0xbe499da8), WTC(0xbde61891), WTC(0xbd8975b6), + WTC(0xbd339d36), WTC(0xbce6a08b), WTC(0xbca5b2f9), WTC(0xbc721002), + WTC(0xbc494d41), WTC(0xbc266160), WTC(0xbc06d14f), WTC(0xbbec52c7), + WTC(0xbbdaaf79), WTC(0xbbd0be99), WTC(0xbbcae139), WTC(0xbbcd359c), + WTC(0xbbded5d3), WTC(0xbbfa58cf), WTC(0xbc162f9d), WTC(0xbc326534), + WTC(0xbc4f081c), WTC(0xbc6c1678), WTC(0xbc899f93), WTC(0xbca7a263), + WTC(0xbcc62954), WTC(0xbce52ddc), WTC(0xbd04bc7f), WTC(0xbd24cd8f), + WTC(0xbd456998), WTC(0xbd668428), WTC(0xbd88207c), WTC(0xbdaa2e4b), + WTC(0xbdccaf3e), WTC(0xbdef932c), WTC(0xbe12d936), WTC(0xbe366dd6), + WTC(0xbe5a4fd9), WTC(0xbe7e6b49), WTC(0xbea2bf3f), WTC(0xbec738b5), + WTC(0xbeebd791), WTC(0xbf108b49), WTC(0xbf3554aa), WTC(0xbf5a25cf), + WTC(0xbf7f020b), WTC(0xbfa3dd25), WTC(0xbfc8be1e), WTC(0xbfed95f6), + WTC(0x8024c933), WTC(0x806e24fb), WTC(0x80b73d96), WTC(0x80fff78c), + WTC(0x8148612f), WTC(0x8190626e), WTC(0x81d8030a), WTC(0x821f28e1), + WTC(0x8265d6be), WTC(0x82abed56), WTC(0x82f16e40), WTC(0x833636d2), + WTC(0x837a470a), WTC(0x83bd7be6), WTC(0x83ffd415), WTC(0x84412e66), + WTC(0x84818c4f), WTC(0x84c0d18c), WTC(0x84ff0429), WTC(0x853c09a5), + WTC(0x8577eacf), WTC(0x85b29402), WTC(0x85ec17bf), WTC(0x86246b50), + WTC(0x865ba7d7), WTC(0x8691c4c0), WTC(0x86c6d72a), WTC(0x86fae06c), + WTC(0x872dfcd1), WTC(0x87602c6a), WTC(0x87918a27), WTC(0x87c22ef8), + WTC(0x882f7c20), WTC(0x88dc38ab), WTC(0x89a52f47), WTC(0x8a737635), + WTC(0x8b43d08d), WTC(0x8c19be9f), WTC(0x8cf89ce7), WTC(0x8de337e9), + WTC(0x8edb3e02), WTC(0x8fe1e815), WTC(0x90f7e107), WTC(0x921d8b95), + WTC(0x9353008c), WTC(0x94982fd7), WTC(0x95ecdc6d), WTC(0x9750b87f), + WTC(0x98c36ad6), WTC(0x9a447674), WTC(0x9bd34e9c), WTC(0x9d6f76fa), + WTC(0x9f18780d), WTC(0xa0cdc487), WTC(0xa28eff8e), WTC(0xa45bbe4b), + WTC(0xa633baaf), WTC(0xa816bff0), WTC(0xaa04a90d), WTC(0xabfd7205), + WTC(0xae01356b), WTC(0xb0101477), WTC(0xb22a5244), WTC(0xb4500b02), + WTC(0x499946f3), WTC(0x475da5af), WTC(0x45173dce), WTC(0x42c610ad), + WTC(0x406a44b0), WTC(0x3e037ce8), WTC(0x3b92b806), WTC(0x39195cd0), + WTC(0x36962f17), WTC(0x340a1b28), WTC(0x3177cde6), WTC(0x2ee1f20d), + WTC(0x2c49b0d6), WTC(0x29ad3d74), WTC(0x270e9ec1), WTC(0x2474132f), + WTC(0x21e14a01), WTC(0x1f57704e), WTC(0x1cd758ce), WTC(0x1a610d48), + WTC(0x17f5db88), WTC(0x1598a188), WTC(0x134f7a40), WTC(0x111f1ca0), + WTC(0x0f053b83), WTC(0x0cf871db), WTC(0x0af19e60), WTC(0x08eaa56d), + WTC(0x06e3c473), WTC(0x04d25cc9), WTC(0x02b59b4d), WTC(0x00e5bc4c), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0xffcebf14), WTC(0xff6cc249), WTC(0xff0b8bda), WTC(0xfeac3e5f), + WTC(0xfe4f4638), WTC(0xfdf5052f), WTC(0xfd9e8cf4), WTC(0xfd4e34ea), + WTC(0xfd023142), WTC(0xfcb8f6f7), WTC(0xfc74e090), WTC(0xfc3b33e8), + WTC(0xfc0c1254), WTC(0xfbe1b2eb), WTC(0xfbb8ce73), WTC(0xfb97e511), + WTC(0xfb86273d), WTC(0xfb857a3e), WTC(0xfb918813), WTC(0xfba43692), + WTC(0xfbb96f24), WTC(0xfbd4dcc3), WTC(0xfc000cd5), WTC(0xfc458653), + WTC(0xfca6cd98), WTC(0xfd178c8e), WTC(0xfd872979), WTC(0xfdfa721e), + WTC(0xfe88c77c), WTC(0xff3c8b5c), WTC(0x00059ebc), WTC(0x00d91db0), + WTC(0x01bec555), WTC(0x02bdfb80), WTC(0x03d4c846), WTC(0x0501ad53), + WTC(0x064719b2), WTC(0x07a34a2b), WTC(0x0918814b), WTC(0x0aaaaa6b), + WTC(0x0c5728b9), WTC(0x0e1c1a0f), WTC(0x0ff9ccd1), WTC(0x11f21ffb), + WTC(0x1405d073), WTC(0x1635776b), WTC(0x1880f4e5), WTC(0x1ae8bdcb), + WTC(0x1d6cede3), WTC(0x200e1d93), WTC(0x22cc56fd), WTC(0x25a80858), + WTC(0x28a11bdd), WTC(0x2bb7e363), WTC(0x2eec2f0f), WTC(0x323e298d), + WTC(0x35ad7f0b), WTC(0x393a1989), WTC(0x3ce34a65), WTC(0x40a8683d), + WTC(0x44881c94), WTC(0x48813cb3), WTC(0x4c94523d), WTC(0x50c8eff0), + WTC(0x00000000), WTC(0x00000000), WTC(0x0053a1ea), WTC(0x00f67066), + WTC(0x01e3f61b), WTC(0x0317bdaf), WTC(0x048d51ca), WTC(0x06403d11), + WTC(0x082c0a34), WTC(0x0a4c43d2), WTC(0x0c9c748e), WTC(0x0f182718), + WTC(0x11bae616), WTC(0x14803c1b), WTC(0x1763b3e6), WTC(0x1a60d832), + WTC(0x1d73336b), WTC(0x20965068), WTC(0x23c5b9d6), WTC(0x26fcfa1a), + WTC(0x2a379c30), WTC(0x2d712a75), WTC(0x30a52fba), WTC(0x33cf36a9), + WTC(0x36eaca15), WTC(0x39f3743b), WTC(0x3ce4bfc2), WTC(0x3fba37b8), + WTC(0x426f6671), WTC(0x44ffd6e8), WTC(0x47671326), WTC(0x49a0b2d0), + WTC(0x4ba81be1), WTC(0x4d78fd1e), WTC(0x4f0ed503), WTC(0x50652e28), + WTC(0x51779351), WTC(0x52418fbe), WTC(0x52bead75), WTC(0x52ea76cc), + WTC(0x52c07793), WTC(0x523c3918), WTC(0x5159470e), WTC(0x50132b36), + WTC(0x4e657128), WTC(0x4c4ba31d), WTC(0x49c14b60), WTC(0x46c1e9e4), + WTC(0x4374e179), WTC(0x408377b1), WTC(0x3e0fa0aa), WTC(0x3c05d584), + WTC(0x3a4d9888), WTC(0x38cdd8fa), WTC(0x376b75c4), WTC(0x360c51a7), + WTC(0x34b12fdc), WTC(0x33550d9f), WTC(0x31f1955c), WTC(0x307ffcb2), + WTC(0x2f03c44d), WTC(0x2d7a6b86), WTC(0x2be6d3d4), WTC(0x2a48d219), +}; + +const FIXP_WTB ELDAnalysis120[360] = { + WTC(0xfaa1a40a), WTC(0xfa3f173d), WTC(0xf9d7760c), WTC(0xf96bcc12), + WTC(0xf8fbe82c), WTC(0xf887bb26), WTC(0xf80f131a), WTC(0xf7930d03), + WTC(0xf714aeaf), WTC(0xf693f5a1), WTC(0xf613385b), WTC(0xf596ef0e), + WTC(0xf522dcc4), WTC(0xf4bab1f6), WTC(0xf461700c), WTC(0xf412e1fe), + WTC(0xf3b769b1), WTC(0xf349eaca), WTC(0xf2cb9164), WTC(0xf23d6d7b), + WTC(0xf1a0ab28), WTC(0xf0f5c20f), WTC(0xf03aadd9), WTC(0xef6e8c66), + WTC(0xee984910), WTC(0xedbbcbf8), WTC(0xecd1435b), WTC(0xebdc1b77), + WTC(0xeae31338), WTC(0xe9dbea9a), WTC(0xe8c005ea), WTC(0xe79e7068), + WTC(0xe6856dce), WTC(0xe5657c79), WTC(0xe42928e9), WTC(0xe2e0756e), + WTC(0xe1a83cf5), WTC(0xe0801fab), WTC(0xdf52bfeb), WTC(0xde15d1b1), + WTC(0xdcce71ba), WTC(0xdb8931bf), WTC(0xda4fbbe8), WTC(0xd9220a98), + WTC(0xd7f9af0c), WTC(0xd6d0e1df), WTC(0xd5a41f15), WTC(0xd4790330), + WTC(0xd35f84b8), WTC(0xd255e881), WTC(0xd14daf00), WTC(0xd04638e2), + WTC(0xcf47dff7), WTC(0xce5b8850), WTC(0xcd77b1d6), WTC(0xcc960ec0), + WTC(0xcbc0a6a4), WTC(0xcaf6d4f7), WTC(0xca34fa7d), WTC(0xc97c26c0), + WTC(0xc8c6868a), WTC(0xc811f873), WTC(0xc7599db8), WTC(0xc69f9780), + WTC(0xc5e24043), WTC(0xc5226384), WTC(0xc468f547), WTC(0xc3b20be9), + WTC(0xc2f826f0), WTC(0xc242ea02), WTC(0xc19844ae), WTC(0xc0f80714), + WTC(0xc05a6da1), WTC(0xbfbfe6d3), WTC(0xbf31b5b4), WTC(0xbeb24843), + WTC(0xbe3f4cb4), WTC(0xbdd63599), WTC(0xbd74c6b2), WTC(0xbd1b7128), + WTC(0xbccd4b41), WTC(0xbc8dc08e), WTC(0xbc5ca2bd), WTC(0xbc3509f1), + WTC(0xbc11f904), WTC(0xbbf37848), WTC(0xbbddfb6b), WTC(0xbbd214ea), + WTC(0xbbcb3a11), WTC(0xbbcce581), WTC(0xbbdfa6ba), WTC(0xbbfd2fa5), + WTC(0xbc1ad516), WTC(0xbc390c16), WTC(0xbc57b323), WTC(0xbc76dd1f), + WTC(0xbc969172), WTC(0xbcb6d611), WTC(0xbcd7ac8e), WTC(0xbcf91af9), + WTC(0xbd1b20bd), WTC(0xbd3dc1f5), WTC(0xbd60f678), WTC(0xbd84bec7), + WTC(0xbda909c0), WTC(0xbdcdd76e), WTC(0xbdf3161c), WTC(0xbe18c1e5), + WTC(0xbe3ec6c5), WTC(0xbe651f19), WTC(0xbe8bb78b), WTC(0xbeb288e1), + WTC(0xbed9848b), WTC(0xbf00a16f), WTC(0xbf27d681), WTC(0xbf4f1958), + WTC(0xbf76680e), WTC(0xbf9db85c), WTC(0xbfc50e09), WTC(0xbfec5bdf), + WTC(0x80273bdb), WTC(0x807577de), WTC(0x80c3630d), WTC(0x8110e4cb), + WTC(0x815e05da), WTC(0x81aab20f), WTC(0x81f6e68e), WTC(0x824290d0), + WTC(0x828da04c), WTC(0x82d8061f), WTC(0x8321a740), WTC(0x836a77f9), + WTC(0x83b2574f), WTC(0x83f93cc1), WTC(0x843f04a6), WTC(0x8483acd1), + WTC(0x84c71639), WTC(0x850944da), WTC(0x854a1d3a), WTC(0x8589a437), + WTC(0x85c7ccf9), WTC(0x8604a42f), WTC(0x86402cfb), WTC(0x867a740d), + WTC(0x86b37ff2), WTC(0x86eb5f6f), WTC(0x87222109), WTC(0x8757eb5f), + WTC(0x878c8341), WTC(0x87c0be51), WTC(0x88345fca), WTC(0x88ef97fb), + WTC(0x89c778c5), WTC(0x8aa3cc20), WTC(0x8b833d56), WTC(0x8c6a42a9), + WTC(0x8d5cb787), WTC(0x8e5d7787), WTC(0x8f6e3c5b), WTC(0x90902640), + WTC(0x91c3ca28), WTC(0x9309622d), WTC(0x9460e7d0), WTC(0x95ca1ad2), + WTC(0x97449dff), WTC(0x98d00612), WTC(0x9a6bbc19), WTC(0x9c17164d), + WTC(0x9dd180fc), WTC(0x9f9a6304), WTC(0xa1711f56), WTC(0xa355425e), + WTC(0xa5465846), WTC(0xa744190f), WTC(0xa94e4ca9), WTC(0xab64dcf0), + WTC(0xad87e068), WTC(0xafb77bfa), WTC(0xb1f3fb2b), WTC(0xb43d885c), + WTC(0x49866451), WTC(0x4723e56b), WTC(0x44b51e8d), WTC(0x423a2180), + WTC(0x3fb2fe0f), WTC(0x3d1f78f2), WTC(0x3a8153b7), WTC(0x37d906ff), + WTC(0x35259e7e), WTC(0x3269ba18), WTC(0x2fa8c1ea), WTC(0x2ce4fbab), + WTC(0x2a1cebd5), WTC(0x27519ac1), WTC(0x248a2de9), WTC(0x21cb7a79), + WTC(0x1f16fc13), WTC(0x1c6d9a50), WTC(0x19cf83c1), WTC(0x173e9943), + WTC(0x14bf6a71), WTC(0x12598f74), WTC(0x100fe27f), WTC(0x0ddab46a), + WTC(0x0bafab9d), WTC(0x09864fc7), WTC(0x075d3ac8), WTC(0x052c0fc2), + WTC(0x02ea842b), WTC(0x00f21d19), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0xffcb7b4d), WTC(0xff62fb20), WTC(0xfefb82e2), WTC(0xfe965482), + WTC(0xfe33e4bf), WTC(0xfdd4b9b5), WTC(0xfd7b04ec), WTC(0xfd27cfe4), + WTC(0xfcd84cfd), WTC(0xfc8ce1d4), WTC(0xfc4b45e1), WTC(0xfc1666da), + WTC(0xfbe8af26), WTC(0xfbbcad9e), WTC(0xfb98c6ad), WTC(0xfb85dd87), + WTC(0xfb86355b), WTC(0xfb94589b), WTC(0xfba8ed8a), WTC(0xfbc0a735), + WTC(0xfbe23f8d), WTC(0xfc1a92c4), WTC(0xfc73315f), WTC(0xfce611a1), + WTC(0xfd5e94d9), WTC(0xfdd61cab), WTC(0xfe6427fd), WTC(0xff1c92da), + WTC(0xfff10542), WTC(0x00d1d58a), WTC(0x01c6daab), WTC(0x02d8dbc3), + WTC(0x040557a6), WTC(0x054b6f91), WTC(0x06ad2b2b), WTC(0x0828f4c5), + WTC(0x09c348d1), WTC(0x0b7dcb56), WTC(0x0d54d98e), WTC(0x0f47a599), + WTC(0x1157fa1b), WTC(0x138743ae), WTC(0x15d6423f), WTC(0x1844f0ae), + WTC(0x1ad3c273), WTC(0x1d82e65c), WTC(0x205306e1), WTC(0x23443d5c), + WTC(0x2656fae8), WTC(0x298b3a5a), WTC(0x2ce13a7d), WTC(0x3058e0e3), + WTC(0x33f22950), WTC(0x37acd0b2), WTC(0x3b885e6b), WTC(0x3f840412), + WTC(0x439e65ee), WTC(0x47d6014e), WTC(0x4c2aa857), WTC(0x50a46876), + WTC(0xfffe9b02), WTC(0x0004ac61), WTC(0x0069639d), WTC(0x0127578b), + WTC(0x02391efe), WTC(0x039950cc), WTC(0x054283bf), WTC(0x072f4eba), + WTC(0x095a488c), WTC(0x0bbe0802), WTC(0x0e5523f9), WTC(0x111a332e), + WTC(0x1407cca2), WTC(0x171886f5), WTC(0x1a46f927), WTC(0x1d8db9e1), + WTC(0x20e7600d), WTC(0x244e82a3), WTC(0x27bdb846), WTC(0x2b2f97a8), + WTC(0x2e9eb7ea), WTC(0x3205afd1), WTC(0x355f161c), WTC(0x38a581d7), + WTC(0x3bd3894a), WTC(0x3ee3c398), WTC(0x41d0c7ae), WTC(0x44952cb8), + WTC(0x472b8856), WTC(0x498e7eee), WTC(0x4bb88245), WTC(0x4da44d9f), + WTC(0x4f4c6b7d), WTC(0x50ab7298), WTC(0x51bbfa11), WTC(0x527898fb), + WTC(0x52dbe5f2), WTC(0x52e07778), WTC(0x5280e51f), WTC(0x51b7c4f1), + WTC(0x507fadc7), WTC(0x4ed336dd), WTC(0x4cacf749), WTC(0x4a078534), + WTC(0x46dd6dcc), WTC(0x43599e22), WTC(0x403f48da), WTC(0x3db1ed89), + WTC(0x3b98bd24), WTC(0x39d5b003), WTC(0x384a3292), WTC(0x36d328ff), + WTC(0x355e63a6), WTC(0x33ec69d8), WTC(0x32755ebd), WTC(0x30f01fce), + WTC(0x2f5d9646), WTC(0x2dbcc615), WTC(0x2c0fa145), WTC(0x2a56ce53), +}; diff --git a/libAACenc/src/aacEnc_rom.h b/libAACenc/src/aacEnc_rom.h index 862417f..fd50cab 100644 --- a/libAACenc/src/aacEnc_rom.h +++ b/libAACenc/src/aacEnc_rom.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,39 +90,42 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/****************************************************************************** + Author(s): M. Lohwasser, M. Gayer - Initial authors: M. Lohwasser, M. Gayer - Contents/description: + Description: + +*******************************************************************************/ -******************************************************************************/ /*! \file - \brief Memory layout + \brief Memory layout \author Markus Lohwasser */ -#ifndef AAC_ENC_ROM_H -#define AAC_ENC_ROM_H +#ifndef AACENC_ROM_H +#define AACENC_ROM_H #include "common_fix.h" #include "psy_const.h" #include "psy_configuration.h" #include "FDK_tools_rom.h" +#include "FDK_lpc.h" /* Huffman Tables */ -extern const ULONG FDKaacEnc_huff_ltab1_2[3][3][3][3]; -extern const ULONG FDKaacEnc_huff_ltab3_4[3][3][3][3]; -extern const ULONG FDKaacEnc_huff_ltab5_6[9][9]; -extern const ULONG FDKaacEnc_huff_ltab7_8[8][8]; -extern const ULONG FDKaacEnc_huff_ltab9_10[13][13]; -extern const UCHAR FDKaacEnc_huff_ltab11[17][17]; -extern const UCHAR FDKaacEnc_huff_ltabscf[121]; +extern const ULONG FDKaacEnc_huff_ltab1_2[3][3][3][3]; +extern const ULONG FDKaacEnc_huff_ltab3_4[3][3][3][3]; +extern const ULONG FDKaacEnc_huff_ltab5_6[9][9]; +extern const ULONG FDKaacEnc_huff_ltab7_8[8][8]; +extern const ULONG FDKaacEnc_huff_ltab9_10[13][13]; +extern const UCHAR FDKaacEnc_huff_ltab11[17][17]; +extern const UCHAR FDKaacEnc_huff_ltabscf[121]; extern const USHORT FDKaacEnc_huff_ctab1[3][3][3][3]; extern const USHORT FDKaacEnc_huff_ctab2[3][3][3][3]; extern const USHORT FDKaacEnc_huff_ctab3[3][3][3][3]; @@ -123,13 +137,13 @@ extern const USHORT FDKaacEnc_huff_ctab8[8][8]; extern const USHORT FDKaacEnc_huff_ctab9[13][13]; extern const USHORT FDKaacEnc_huff_ctab10[13][13]; extern const USHORT FDKaacEnc_huff_ctab11[21][17]; -extern const ULONG FDKaacEnc_huff_ctabscf[121]; +extern const ULONG FDKaacEnc_huff_ctabscf[121]; /* quantizer */ #define MANT_DIGITS 9 -#define MANT_SIZE (1<>shift)) / (samplingRate>>shift); + return (bitRate * (frameLength >> shift)) / (samplingRate >> shift); } -INT FDKaacEnc_CalcBitrate( - const INT bitsPerFrame, - const INT frameLength, - const INT samplingRate - ) -{ - int shift = 0; - while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength - && (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate) - { - shift++; - } - - return (bitsPerFrame * (samplingRate>>shift)) / ( frameLength>>shift) ; +INT FDKaacEnc_CalcBitrate(const INT bitsPerFrame, const INT frameLength, + const INT samplingRate) { + int shift = 0; + while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength && + (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate) { + shift++; + } + return (bitsPerFrame * (samplingRate >> shift)) / (frameLength >> shift); } -static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(INT bitRate, - INT framelength, - INT ancillaryRate, - INT *ancillaryBitsPerFrame, - INT sampleRate); - -INT FDKaacEnc_LimitBitrate( - HANDLE_TRANSPORTENC hTpEnc, - INT coreSamplingRate, - INT frameLength, - INT nChannels, - INT nChannelsEff, - INT bitRate, - INT averageBits, - INT *pAverageBitsPerFrame, - INT bitrateMode, - INT nSubFrames - ) -{ - INT transportBits, prevBitRate, averageBitsPerFrame, shift = 0, iter=0; - - while ( (frameLength & ~((1<<(shift+1))-1)) == frameLength - && (coreSamplingRate & ~((1<<(shift+1))-1)) == coreSamplingRate ) - { - shift ++; +static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary( + INT bitRate, INT framelength, INT ancillaryRate, INT *ancillaryBitsPerFrame, + INT sampleRate); + +INT FDKaacEnc_LimitBitrate(HANDLE_TRANSPORTENC hTpEnc, AUDIO_OBJECT_TYPE aot, + INT coreSamplingRate, INT frameLength, INT nChannels, + INT nChannelsEff, INT bitRate, INT averageBits, + INT *pAverageBitsPerFrame, + AACENC_BITRATE_MODE bitrateMode, INT nSubFrames) { + INT transportBits, prevBitRate, averageBitsPerFrame, minBitrate = 0, iter = 0; + INT minBitsPerFrame = 40 * nChannels; + if (isLowDelay(aot)) { + minBitrate = 8000 * nChannelsEff; } do { prevBitRate = bitRate; - averageBitsPerFrame = (bitRate*(frameLength>>shift)) / (coreSamplingRate>>shift) / nSubFrames; + averageBitsPerFrame = + FDKaacEnc_CalcBitsPerFrame(bitRate, frameLength, coreSamplingRate) / + nSubFrames; if (pAverageBitsPerFrame != NULL) { *pAverageBitsPerFrame = averageBitsPerFrame; @@ -182,32 +173,34 @@ INT FDKaacEnc_LimitBitrate( transportBits = 208; } - bitRate = FDKmax(bitRate, ((((40 * nChannels) + transportBits) * (coreSamplingRate)) / frameLength) ); + bitRate = fMax(bitRate, + fMax(minBitrate, + FDKaacEnc_CalcBitrate((minBitsPerFrame + transportBits), + frameLength, coreSamplingRate))); FDK_ASSERT(bitRate >= 0); - bitRate = FDKmin(bitRate, ((nChannelsEff * MIN_BUFSIZE_PER_EFF_CHAN)*(coreSamplingRate>>shift)) / (frameLength>>shift)) ; + bitRate = fMin(bitRate, FDKaacEnc_CalcBitrate( + (nChannelsEff * MIN_BUFSIZE_PER_EFF_CHAN), + frameLength, coreSamplingRate)); FDK_ASSERT(bitRate >= 0); - } while (prevBitRate != bitRate && iter++ < 3) ; + } while (prevBitRate != bitRate && iter++ < 3); return bitRate; } - -typedef struct -{ +typedef struct { AACENC_BITRATE_MODE bitrateMode; int chanBitrate[2]; /* mono/stereo settings */ } CONFIG_TAB_ENTRY_VBR; static const CONFIG_TAB_ENTRY_VBR configTabVBR[] = { - {AACENC_BR_MODE_CBR, { 0, 0}} , - {AACENC_BR_MODE_VBR_1, { 32000, 20000}} , - {AACENC_BR_MODE_VBR_2, { 40000, 32000}} , - {AACENC_BR_MODE_VBR_3, { 56000, 48000}} , - {AACENC_BR_MODE_VBR_4, { 72000, 64000}} , - {AACENC_BR_MODE_VBR_5, {112000, 96000}} -}; + {AACENC_BR_MODE_CBR, {0, 0}}, + {AACENC_BR_MODE_VBR_1, {32000, 20000}}, + {AACENC_BR_MODE_VBR_2, {40000, 32000}}, + {AACENC_BR_MODE_VBR_3, {56000, 48000}}, + {AACENC_BR_MODE_VBR_4, {72000, 64000}}, + {AACENC_BR_MODE_VBR_5, {112000, 96000}}}; /*----------------------------------------------------------------------------- @@ -218,30 +211,30 @@ static const CONFIG_TAB_ENTRY_VBR configTabVBR[] = { returns: vbr bitrate ------------------------------------------------------------------------------*/ -INT FDKaacEnc_GetVBRBitrate(INT bitrateMode, CHANNEL_MODE channelMode) -{ +INT FDKaacEnc_GetVBRBitrate(AACENC_BITRATE_MODE bitrateMode, + CHANNEL_MODE channelMode) { INT bitrate = 0; INT monoStereoMode = 0; /* default mono */ - if (FDKaacEnc_GetMonoStereoMode(channelMode)==EL_MODE_STEREO) { - monoStereoMode = 1; + if (FDKaacEnc_GetMonoStereoMode(channelMode) == EL_MODE_STEREO) { + monoStereoMode = 1; } - switch((AACENC_BITRATE_MODE)bitrateMode){ - case AACENC_BR_MODE_VBR_1: - case AACENC_BR_MODE_VBR_2: - case AACENC_BR_MODE_VBR_3: - case AACENC_BR_MODE_VBR_4: - case AACENC_BR_MODE_VBR_5: - bitrate = configTabVBR[bitrateMode].chanBitrate[monoStereoMode]; - break; - case AACENC_BR_MODE_INVALID: - case AACENC_BR_MODE_CBR: - case AACENC_BR_MODE_SFR: - case AACENC_BR_MODE_FF: - default: - bitrate = 0; - break; + switch (bitrateMode) { + case AACENC_BR_MODE_VBR_1: + case AACENC_BR_MODE_VBR_2: + case AACENC_BR_MODE_VBR_3: + case AACENC_BR_MODE_VBR_4: + case AACENC_BR_MODE_VBR_5: + bitrate = configTabVBR[bitrateMode].chanBitrate[monoStereoMode]; + break; + case AACENC_BR_MODE_INVALID: + case AACENC_BR_MODE_CBR: + case AACENC_BR_MODE_SFR: + case AACENC_BR_MODE_FF: + default: + bitrate = 0; + break; } /* convert channel bitrate to overall bitrate*/ @@ -257,38 +250,39 @@ INT FDKaacEnc_GetVBRBitrate(INT bitrateMode, CHANNEL_MODE channelMode) * * \return Corrected bitreservoir level used in transport library. */ -static INT FDKaacEnc_EncBitresToTpBitres( - const HANDLE_AAC_ENC hAacEnc - ) -{ - INT transporBitreservoir = 0; +static INT FDKaacEnc_EncBitresToTpBitres(const HANDLE_AAC_ENC hAacEnc) { + INT transportBitreservoir = 0; switch (hAacEnc->bitrateMode) { case AACENC_BR_MODE_CBR: - transporBitreservoir = hAacEnc->qcKernel->bitResTot; /* encoder bitreservoir level */ + transportBitreservoir = + hAacEnc->qcKernel->bitResTot; /* encoder bitreservoir level */ break; case AACENC_BR_MODE_VBR_1: case AACENC_BR_MODE_VBR_2: case AACENC_BR_MODE_VBR_3: case AACENC_BR_MODE_VBR_4: case AACENC_BR_MODE_VBR_5: - transporBitreservoir = FDK_INT_MAX; /* signal variable bitrate */ + transportBitreservoir = FDK_INT_MAX; /* signal variable bitrate */ break; - case AACENC_BR_MODE_FF: case AACENC_BR_MODE_SFR: - transporBitreservoir = 0; /* super framing and fixed framing */ - break; /* without bitreservoir signaling */ + transportBitreservoir = 0; /* super framing and fixed framing */ + break; /* without bitreservoir signaling */ default: case AACENC_BR_MODE_INVALID: - transporBitreservoir = 0; /* invalid configuration*/ - FDK_ASSERT(0); + transportBitreservoir = 0; /* invalid configuration*/ } - if (hAacEnc->config->audioMuxVersion==2) { - transporBitreservoir = MIN_BUFSIZE_PER_EFF_CHAN * hAacEnc->channelMapping.nChannelsEff; + if (hAacEnc->config->audioMuxVersion == 2) { + transportBitreservoir = + MIN_BUFSIZE_PER_EFF_CHAN * hAacEnc->channelMapping.nChannelsEff; } - return transporBitreservoir; + return transportBitreservoir; +} + +INT FDKaacEnc_GetBitReservoirState(const HANDLE_AAC_ENC hAacEncoder) { + return FDKaacEnc_EncBitresToTpBitres(hAacEncoder); } /*----------------------------------------------------------------------------- @@ -298,40 +292,39 @@ static INT FDKaacEnc_EncBitresToTpBitres( returns: --- ------------------------------------------------------------------------------*/ -void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config) -{ - /* make thepre initialization of the structs flexible */ - FDKmemclear(config, sizeof(AACENC_CONFIG)); - - /* default ancillary */ - config->anc_Rate = 0; /* no ancillary data */ - config->ancDataBitRate = 0; /* no additional consumed bitrate */ - - /* default configurations */ - config->bitRate = -1; /* bitrate must be set*/ - config->averageBits = -1; /* instead of bitrate/s we can configure bits/superframe */ - config->bitrateMode = 0; - config->bandWidth = 0; /* get bandwidth from table */ - config->useTns = TNS_ENABLE_MASK; /* tns enabled completly */ - config->usePns = 1; /* depending on channelBitrate this might be set to 0 later */ - config->useIS = 1; /* Intensity Stereo Configuration */ - config->framelength = -1; /* Framesize not configured */ - config->syntaxFlags = 0; /* default syntax with no specialities */ - config->epConfig = -1; /* no ER syntax -> no additional error protection */ - config->nSubFrames = 1; /* default, no sub frames */ - config->channelOrder = CH_ORDER_MPEG; /* Use MPEG channel ordering. */ - config->channelMode = MODE_UNKNOWN; - config->minBitsPerFrame = -1; /* minum number of bits in each AU */ - config->maxBitsPerFrame = -1; /* minum number of bits in each AU */ - config->bitreservoir = -1; /* default, uninitialized value */ - config->audioMuxVersion = -1; /* audio mux version not configured */ - - /* init tabs in fixpoint_math */ - InitLdInt(); - InitInvSqrtTab(); +void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config) { + /* make the preinitialization of the structs flexible */ + FDKmemclear(config, sizeof(AACENC_CONFIG)); + + /* default ancillary */ + config->anc_Rate = 0; /* no ancillary data */ + config->ancDataBitRate = 0; /* no additional consumed bitrate */ + + /* default configurations */ + config->bitRate = -1; /* bitrate must be set*/ + config->averageBits = + -1; /* instead of bitrate/s we can configure bits/superframe */ + config->bitrateMode = + AACENC_BR_MODE_CBR; /* set bitrate mode to constant bitrate */ + config->bandWidth = 0; /* get bandwidth from table */ + config->useTns = TNS_ENABLE_MASK; /* tns enabled completly */ + config->usePns = + 1; /* depending on channelBitrate this might be set to 0 later */ + config->useIS = 1; /* Intensity Stereo Configuration */ + config->useMS = 1; /* MS Stereo tool */ + config->framelength = -1; /* Framesize not configured */ + config->syntaxFlags = 0; /* default syntax with no specialities */ + config->epConfig = -1; /* no ER syntax -> no additional error protection */ + config->nSubFrames = 1; /* default, no sub frames */ + config->channelOrder = CH_ORDER_MPEG; /* Use MPEG channel ordering. */ + config->channelMode = MODE_UNKNOWN; + config->minBitsPerFrame = -1; /* minum number of bits in each AU */ + config->maxBitsPerFrame = -1; /* minum number of bits in each AU */ + config->audioMuxVersion = -1; /* audio mux version not configured */ + config->downscaleFactor = + 1; /* downscale factor for ELD reduced delay mode, 1 is normal ELD */ } - /*--------------------------------------------------------------------------- functionname: FDKaacEnc_Open @@ -339,16 +332,13 @@ void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config) returns: error code ---------------------------------------------------------------------------*/ -AAC_ENCODER_ERROR FDKaacEnc_Open(HANDLE_AAC_ENC *phAacEnc, - const INT nElements, - const INT nChannels, - const INT nSubFrames) -{ +AAC_ENCODER_ERROR FDKaacEnc_Open(HANDLE_AAC_ENC *phAacEnc, const INT nElements, + const INT nChannels, const INT nSubFrames) { AAC_ENCODER_ERROR ErrorStatus; - AAC_ENC *hAacEnc = NULL; - UCHAR *dynamicRAM = NULL; + AAC_ENC *hAacEnc = NULL; + UCHAR *dynamicRAM = NULL; - if (phAacEnc==NULL) { + if (phAacEnc == NULL) { return AAC_ENC_INVALID_HANDLE; } @@ -360,82 +350,65 @@ AAC_ENCODER_ERROR FDKaacEnc_Open(HANDLE_AAC_ENC *phAacEnc, } FDKmemclear(hAacEnc, sizeof(AAC_ENC)); - hAacEnc->dynamic_RAM = GetAACdynamic_RAM(); - dynamicRAM = (UCHAR*)hAacEnc->dynamic_RAM; + if (NULL == (hAacEnc->dynamic_RAM = GetAACdynamic_RAM())) { + ErrorStatus = AAC_ENC_NO_MEMORY; + goto bail; + } + dynamicRAM = (UCHAR *)hAacEnc->dynamic_RAM; /* allocate the Psy aud Psy Out structure */ - ErrorStatus = FDKaacEnc_PsyNew(&hAacEnc->psyKernel, - nElements, - nChannels - ,dynamicRAM - ); - if (ErrorStatus != AAC_ENC_OK) - goto bail; - - ErrorStatus = FDKaacEnc_PsyOutNew(hAacEnc->psyOut, - nElements, - nChannels, - nSubFrames - ,dynamicRAM - ); - if (ErrorStatus != AAC_ENC_OK) - goto bail; + ErrorStatus = + FDKaacEnc_PsyNew(&hAacEnc->psyKernel, nElements, nChannels, dynamicRAM); + if (ErrorStatus != AAC_ENC_OK) goto bail; + + ErrorStatus = FDKaacEnc_PsyOutNew(hAacEnc->psyOut, nElements, nChannels, + nSubFrames, dynamicRAM); + if (ErrorStatus != AAC_ENC_OK) goto bail; /* allocate the Q&C Out structure */ - ErrorStatus = FDKaacEnc_QCOutNew(hAacEnc->qcOut, - nElements, - nChannels, - nSubFrames - ,dynamicRAM - ); - if (ErrorStatus != AAC_ENC_OK) - goto bail; + ErrorStatus = FDKaacEnc_QCOutNew(hAacEnc->qcOut, nElements, nChannels, + nSubFrames, dynamicRAM); + if (ErrorStatus != AAC_ENC_OK) goto bail; /* allocate the Q&C kernel */ - ErrorStatus = FDKaacEnc_QCNew(&hAacEnc->qcKernel, - nElements - ,dynamicRAM - ); - if (ErrorStatus != AAC_ENC_OK) - goto bail; + ErrorStatus = FDKaacEnc_QCNew(&hAacEnc->qcKernel, nElements, dynamicRAM); + if (ErrorStatus != AAC_ENC_OK) goto bail; hAacEnc->maxChannels = nChannels; hAacEnc->maxElements = nElements; - hAacEnc->maxFrames = nSubFrames; + hAacEnc->maxFrames = nSubFrames; bail: *phAacEnc = hAacEnc; return ErrorStatus; } - -AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc, - AACENC_CONFIG *config, /* pre-initialized config struct */ - HANDLE_TRANSPORTENC hTpEnc, - ULONG initFlags) -{ +AAC_ENCODER_ERROR FDKaacEnc_Initialize( + HANDLE_AAC_ENC hAacEnc, + AACENC_CONFIG *config, /* pre-initialized config struct */ + HANDLE_TRANSPORTENC hTpEnc, ULONG initFlags) { AAC_ENCODER_ERROR ErrorStatus; - INT psyBitrate, tnsMask; //INT profile = 1; - CHANNEL_MAPPING *cm = NULL; + INT psyBitrate, tnsMask; // INT profile = 1; + CHANNEL_MAPPING *cm = NULL; - INT qmbfac, qbw; + INT mbfac_e, qbw; FIXP_DBL mbfac, bw_ratio; QC_INIT qcInit; INT averageBitsPerFrame = 0; + int bitresMin = 0; /* the bitreservoir is always big for AAC-LC */ + const CHANNEL_MODE prevChannelMode = hAacEnc->encoderMode; - if (config==NULL) - return AAC_ENC_INVALID_HANDLE; + if (config == NULL) return AAC_ENC_INVALID_HANDLE; /******************* sanity checks *******************/ /* check config structure */ - if (config->nChannels < 1 || config->nChannels > (8)) { + if (config->nChannels < 1 || config->nChannels > (8)) { return AAC_ENC_UNSUPPORTED_CHANNELCONFIG; } /* check sample rate */ - switch (config->sampleRate) - { + switch (config->sampleRate) { case 8000: case 11025: case 12000: @@ -454,52 +427,44 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc, } /* bitrate has to be set */ - if (config->bitRate==-1) { - return AAC_ENC_UNSUPPORTED_BITRATE; + if (config->bitRate == -1) { + return AAC_ENC_UNSUPPORTED_BITRATE; } /* check bit rate */ if (FDKaacEnc_LimitBitrate( - hTpEnc, - config->sampleRate, - config->framelength, - config->nChannels, - FDKaacEnc_GetChannelModeConfiguration(config->channelMode)->nChannelsEff, - config->bitRate, - config->averageBits, - &averageBitsPerFrame, - config->bitrateMode, - config->nSubFrames - ) != config->bitRate - && !((config->bitrateMode>=1) && (config->bitrateMode<=5)) - ) - { + hTpEnc, config->audioObjectType, config->sampleRate, + config->framelength, config->nChannels, + FDKaacEnc_GetChannelModeConfiguration(config->channelMode) + ->nChannelsEff, + config->bitRate, config->averageBits, &averageBitsPerFrame, + config->bitrateMode, config->nSubFrames) != config->bitRate && + !(AACENC_BR_MODE_IS_VBR(config->bitrateMode))) { return AAC_ENC_UNSUPPORTED_BITRATE; } if (config->syntaxFlags & AC_ER_VCB11) { - return AAC_ENC_UNSUPPORTED_ER_FORMAT; + return AAC_ENC_UNSUPPORTED_ER_FORMAT; } if (config->syntaxFlags & AC_ER_HCR) { - return AAC_ENC_UNSUPPORTED_ER_FORMAT; + return AAC_ENC_UNSUPPORTED_ER_FORMAT; } /* check frame length */ - switch (config->framelength) - { + switch (config->framelength) { case 1024: - if ( config->audioObjectType == AOT_ER_AAC_LD - || config->audioObjectType == AOT_ER_AAC_ELD ) - { + if (isLowDelay(config->audioObjectType)) { return AAC_ENC_INVALID_FRAME_LENGTH; } break; + case 128: + case 256: case 512: + case 120: + case 240: case 480: - if ( config->audioObjectType != AOT_ER_AAC_LD - && config->audioObjectType != AOT_ER_AAC_ELD ) - { + if (!isLowDelay(config->audioObjectType)) { return AAC_ENC_INVALID_FRAME_LENGTH; } break; @@ -508,189 +473,241 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc, } if (config->anc_Rate != 0) { - - ErrorStatus = FDKaacEnc_InitCheckAncillary(config->bitRate, - config->framelength, - config->anc_Rate, - &hAacEnc->ancillaryBitsPerFrame, - config->sampleRate); - if (ErrorStatus != AAC_ENC_OK) - goto bail; - - - /* update estimated consumed bitrate */ - config->ancDataBitRate += ( (hAacEnc->ancillaryBitsPerFrame * config->sampleRate) / config->framelength ); - + ErrorStatus = FDKaacEnc_InitCheckAncillary( + config->bitRate, config->framelength, config->anc_Rate, + &hAacEnc->ancillaryBitsPerFrame, config->sampleRate); + if (ErrorStatus != AAC_ENC_OK) goto bail; + + /* update estimated consumed bitrate */ + config->ancDataBitRate += + FDKaacEnc_CalcBitrate(hAacEnc->ancillaryBitsPerFrame, + config->framelength, config->sampleRate); } /* maximal allowed DSE bytes in frame */ - { - /* fixpoint calculation*/ - INT q_res, encBitrate, sc; - FIXP_DBL tmp = fDivNorm(config->framelength, config->sampleRate, &q_res); - encBitrate = (config->bitRate/*-config->ancDataBitRate*/)- (INT)(config->nChannels*8000); - sc = CountLeadingBits(encBitrate); - config->maxAncBytesPerAU = FDKmin( (256), FDKmax(0,(INT)(fMultDiv2(tmp, (FIXP_DBL)(encBitrate<>(-q_res+sc-1+3))) ); - } + config->maxAncBytesPerAU = + fMin((256), fMax(0, FDKaacEnc_CalcBitsPerFrame( + (config->bitRate - (config->nChannels * 8000)), + config->framelength, config->sampleRate) >> + 3)); /* bind config to hAacEnc->config */ hAacEnc->config = config; /* set hAacEnc->bitrateMode */ - hAacEnc->bitrateMode = (AACENC_BITRATE_MODE)config->bitrateMode; + hAacEnc->bitrateMode = config->bitrateMode; hAacEnc->encoderMode = config->channelMode; - ErrorStatus = FDKaacEnc_InitChannelMapping(hAacEnc->encoderMode, config->channelOrder, &hAacEnc->channelMapping); - if (ErrorStatus != AAC_ENC_OK) - goto bail; + ErrorStatus = FDKaacEnc_InitChannelMapping( + hAacEnc->encoderMode, config->channelOrder, &hAacEnc->channelMapping); + if (ErrorStatus != AAC_ENC_OK) goto bail; cm = &hAacEnc->channelMapping; - ErrorStatus = FDKaacEnc_DetermineBandWidth(&hAacEnc->config->bandWidth, - config->bandWidth, - config->bitRate - config->ancDataBitRate, - hAacEnc->bitrateMode, - config->sampleRate, - config->framelength, - cm, - hAacEnc->encoderMode); - if (ErrorStatus != AAC_ENC_OK) - goto bail; + ErrorStatus = FDKaacEnc_DetermineBandWidth( + config->bandWidth, config->bitRate - config->ancDataBitRate, + hAacEnc->bitrateMode, config->sampleRate, config->framelength, cm, + hAacEnc->encoderMode, &hAacEnc->config->bandWidth); + if (ErrorStatus != AAC_ENC_OK) goto bail; hAacEnc->bandwidth90dB = (INT)hAacEnc->config->bandWidth; tnsMask = config->useTns ? TNS_ENABLE_MASK : 0x0; psyBitrate = config->bitRate - config->ancDataBitRate; - ErrorStatus = FDKaacEnc_psyInit(hAacEnc->psyKernel, - hAacEnc->psyOut, - hAacEnc->maxFrames, - hAacEnc->maxChannels, - config->audioObjectType, - cm); - if (ErrorStatus != AAC_ENC_OK) - goto bail; + if ((hAacEnc->encoderMode != prevChannelMode) || (initFlags != 0)) { + /* Reinitialize psych states in case of channel configuration change ore if + * full reset requested. */ + ErrorStatus = FDKaacEnc_psyInit(hAacEnc->psyKernel, hAacEnc->psyOut, + hAacEnc->maxFrames, hAacEnc->maxChannels, + config->audioObjectType, cm); + if (ErrorStatus != AAC_ENC_OK) goto bail; + } - ErrorStatus = FDKaacEnc_psyMainInit(hAacEnc->psyKernel, - config->audioObjectType, - cm, - config->sampleRate, - config->framelength, - psyBitrate, - tnsMask, - hAacEnc->bandwidth90dB, - config->usePns, - config->useIS, - config->syntaxFlags, - initFlags); - if (ErrorStatus != AAC_ENC_OK) - goto bail; + ErrorStatus = FDKaacEnc_psyMainInit( + hAacEnc->psyKernel, config->audioObjectType, cm, config->sampleRate, + config->framelength, psyBitrate, tnsMask, hAacEnc->bandwidth90dB, + config->usePns, config->useIS, config->useMS, config->syntaxFlags, + initFlags); + if (ErrorStatus != AAC_ENC_OK) goto bail; ErrorStatus = FDKaacEnc_QCOutInit(hAacEnc->qcOut, hAacEnc->maxFrames, cm); - if (ErrorStatus != AAC_ENC_OK) - goto bail; - - - - qcInit.channelMapping = &hAacEnc->channelMapping; - qcInit.sceCpe = 0; + if (ErrorStatus != AAC_ENC_OK) goto bail; + + qcInit.channelMapping = &hAacEnc->channelMapping; + qcInit.sceCpe = 0; + + if (AACENC_BR_MODE_IS_VBR(config->bitrateMode)) { + qcInit.averageBits = (averageBitsPerFrame + 7) & ~7; + qcInit.bitRes = MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff; + qcInit.maxBits = MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff; + qcInit.maxBits = (config->maxBitsPerFrame != -1) + ? fixMin(qcInit.maxBits, config->maxBitsPerFrame) + : qcInit.maxBits; + qcInit.maxBits = fixMax(qcInit.maxBits, (averageBitsPerFrame + 7) & ~7); + qcInit.minBits = + (config->minBitsPerFrame != -1) ? config->minBitsPerFrame : 0; + qcInit.minBits = fixMin(qcInit.minBits, averageBitsPerFrame & ~7); + } else { + INT bitreservoir = -1; /* default bitrservoir size*/ + if (isLowDelay(config->audioObjectType)) { + INT brPerChannel = config->bitRate / config->nChannels; + brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel)); + + /* bitreservoir = + * (maxBitRes-minBitRes)/(maxBitRate-minBitrate)*(bitRate-minBitrate)+minBitRes; + */ + FIXP_DBL slope = fDivNorm( + (brPerChannel - BITRATE_MIN_LD), + BITRATE_MAX_LD - BITRATE_MIN_LD); /* calc slope for interpolation */ + bitreservoir = fMultI(slope, (INT)(BITRES_MAX_LD - BITRES_MIN_LD)) + + BITRES_MIN_LD; /* interpolate */ + bitreservoir = bitreservoir & ~7; /* align to bytes */ + bitresMin = BITRES_MIN_LD; + } - if ((config->bitrateMode>=1) && (config->bitrateMode<=5)) { - qcInit.averageBits = (averageBitsPerFrame+7)&~7; - qcInit.bitRes = MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff; - qcInit.maxBits = MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff; - qcInit.maxBits = (config->maxBitsPerFrame!=-1) ? fixMin(qcInit.maxBits, config->maxBitsPerFrame) : qcInit.maxBits; - qcInit.maxBits = fixMax(qcInit.maxBits, (averageBitsPerFrame+7)&~7); - qcInit.minBits = (config->minBitsPerFrame!=-1) ? config->minBitsPerFrame : 0; - qcInit.minBits = fixMin(qcInit.minBits, averageBitsPerFrame&~7); - } - else - { - int maxBitres; - qcInit.averageBits = (averageBitsPerFrame+7)&~7; - maxBitres = (MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff) - qcInit.averageBits; - qcInit.bitRes = (config->bitreservoir!=-1) ? FDKmin(config->bitreservoir, maxBitres) : maxBitres; - - qcInit.maxBits = fixMin(MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff, ((averageBitsPerFrame+7)&~7)+qcInit.bitRes); - qcInit.maxBits = (config->maxBitsPerFrame!=-1) ? fixMin(qcInit.maxBits, config->maxBitsPerFrame) : qcInit.maxBits; - qcInit.maxBits = fixMin(MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff, fixMax(qcInit.maxBits, (averageBitsPerFrame+7+8)&~7)); - - qcInit.minBits = fixMax(0, ((averageBitsPerFrame-1)&~7)-qcInit.bitRes-transportEnc_GetStaticBits(hTpEnc, ((averageBitsPerFrame+7)&~7)+qcInit.bitRes)); - qcInit.minBits = (config->minBitsPerFrame!=-1) ? fixMax(qcInit.minBits, config->minBitsPerFrame) : qcInit.minBits; - qcInit.minBits = fixMin(qcInit.minBits, (averageBitsPerFrame - transportEnc_GetStaticBits(hTpEnc, qcInit.maxBits))&~7); + int maxBitres; + qcInit.averageBits = (averageBitsPerFrame + 7) & ~7; + maxBitres = + (MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff) - qcInit.averageBits; + qcInit.bitRes = + (bitreservoir != -1) ? fMin(bitreservoir, maxBitres) : maxBitres; + + qcInit.maxBits = fixMin(MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff, + ((averageBitsPerFrame + 7) & ~7) + qcInit.bitRes); + qcInit.maxBits = (config->maxBitsPerFrame != -1) + ? fixMin(qcInit.maxBits, config->maxBitsPerFrame) + : qcInit.maxBits; + qcInit.maxBits = + fixMin(MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff, + fixMax(qcInit.maxBits, (averageBitsPerFrame + 7 + 8) & ~7)); + + qcInit.minBits = fixMax( + 0, ((averageBitsPerFrame - 1) & ~7) - qcInit.bitRes - + transportEnc_GetStaticBits( + hTpEnc, ((averageBitsPerFrame + 7) & ~7) + qcInit.bitRes)); + qcInit.minBits = (config->minBitsPerFrame != -1) + ? fixMax(qcInit.minBits, config->minBitsPerFrame) + : qcInit.minBits; + qcInit.minBits = fixMin( + qcInit.minBits, (averageBitsPerFrame - + transportEnc_GetStaticBits(hTpEnc, qcInit.maxBits)) & + ~7); } - qcInit.sampleRate = config->sampleRate; - qcInit.advancedBitsToPe = isLowDelay(config->audioObjectType) ? 1 : 0 ; - qcInit.nSubFrames = config->nSubFrames; + qcInit.sampleRate = config->sampleRate; + qcInit.isLowDelay = isLowDelay(config->audioObjectType) ? 1 : 0; + qcInit.nSubFrames = config->nSubFrames; qcInit.padding.paddingRest = config->sampleRate; - /* Calc meanPe: qcInit.meanPe = 10.0f * FRAME_LEN_LONG * hAacEnc->bandwidth90dB/(config->sampleRate/2.0f); */ - bw_ratio = fDivNorm((FIXP_DBL)(10*config->framelength*hAacEnc->bandwidth90dB), (FIXP_DBL)(config->sampleRate), &qbw); - qcInit.meanPe = FDKmax((INT)scaleValue(bw_ratio, qbw+1-(DFRACT_BITS-1)), 1); - - /* Calc maxBitFac */ - mbfac = fDivNorm((MIN_BUFSIZE_PER_EFF_CHAN-744)*cm->nChannelsEff, qcInit.averageBits/qcInit.nSubFrames, &qmbfac); - qmbfac = DFRACT_BITS-1-qmbfac; - qcInit.maxBitFac = (qmbfac > 24) ? (mbfac >> (qmbfac - 24)):(mbfac << (24 - qmbfac)); - - switch(config->bitrateMode){ - case AACENC_BR_MODE_CBR: - qcInit.bitrateMode = QCDATA_BR_MODE_CBR; - break; - case AACENC_BR_MODE_VBR_1: - qcInit.bitrateMode = QCDATA_BR_MODE_VBR_1; - break; - case AACENC_BR_MODE_VBR_2: - qcInit.bitrateMode = QCDATA_BR_MODE_VBR_2; - break; - case AACENC_BR_MODE_VBR_3: - qcInit.bitrateMode = QCDATA_BR_MODE_VBR_3; - break; - case AACENC_BR_MODE_VBR_4: - qcInit.bitrateMode = QCDATA_BR_MODE_VBR_4; - break; - case AACENC_BR_MODE_VBR_5: - qcInit.bitrateMode = QCDATA_BR_MODE_VBR_5; - break; - case AACENC_BR_MODE_SFR: - qcInit.bitrateMode = QCDATA_BR_MODE_SFR; - break; - case AACENC_BR_MODE_FF: - qcInit.bitrateMode = QCDATA_BR_MODE_FF; - break; - default: - ErrorStatus = AAC_ENC_UNSUPPORTED_BITRATE_MODE; - goto bail; + if (qcInit.bitRes >= bitresMin * config->nChannels) { + qcInit.bitResMode = AACENC_BR_MODE_FULL; /* full bitreservoir */ + } else if (qcInit.bitRes > 0) { + qcInit.bitResMode = AACENC_BR_MODE_REDUCED; /* reduced bitreservoir */ + } else { + qcInit.bitResMode = AACENC_BR_MODE_DISABLED; /* disabled bitreservoir */ } - qcInit.invQuant = (config->useRequant)?2:0; + /* Configure bitrate distribution strategy. */ + switch (config->channelMode) { + case MODE_1_2: + case MODE_1_2_1: + case MODE_1_2_2: + case MODE_1_2_2_1: + case MODE_6_1: + case MODE_1_2_2_2_1: + case MODE_7_1_BACK: + case MODE_7_1_TOP_FRONT: + case MODE_7_1_REAR_SURROUND: + case MODE_7_1_FRONT_CENTER: + qcInit.bitDistributionMode = 0; /* over all elements bitrate estimation */ + break; + case MODE_1: + case MODE_2: + default: /* all non mpeg defined channel modes */ + qcInit.bitDistributionMode = 1; /* element-wise bit bitrate estimation */ + } /* config->channelMode */ + + /* Calc meanPe: qcInit.meanPe = 10.0f * FRAME_LEN_LONG * + * hAacEnc->bandwidth90dB/(config->sampleRate/2.0f); */ + bw_ratio = + fDivNorm((FIXP_DBL)(10 * config->framelength * hAacEnc->bandwidth90dB), + (FIXP_DBL)(config->sampleRate), &qbw); + qcInit.meanPe = + fMax((INT)scaleValue(bw_ratio, qbw + 1 - (DFRACT_BITS - 1)), 1); + + /* Calc maxBitFac, scale it to 24 bit accuracy */ + mbfac = fDivNorm(qcInit.maxBits, qcInit.averageBits / qcInit.nSubFrames, + &mbfac_e); + qcInit.maxBitFac = scaleValue(mbfac, -(DFRACT_BITS - 1 - 24 - mbfac_e)); + + switch (config->bitrateMode) { + case AACENC_BR_MODE_CBR: + qcInit.bitrateMode = QCDATA_BR_MODE_CBR; + break; + case AACENC_BR_MODE_VBR_1: + qcInit.bitrateMode = QCDATA_BR_MODE_VBR_1; + break; + case AACENC_BR_MODE_VBR_2: + qcInit.bitrateMode = QCDATA_BR_MODE_VBR_2; + break; + case AACENC_BR_MODE_VBR_3: + qcInit.bitrateMode = QCDATA_BR_MODE_VBR_3; + break; + case AACENC_BR_MODE_VBR_4: + qcInit.bitrateMode = QCDATA_BR_MODE_VBR_4; + break; + case AACENC_BR_MODE_VBR_5: + qcInit.bitrateMode = QCDATA_BR_MODE_VBR_5; + break; + case AACENC_BR_MODE_SFR: + qcInit.bitrateMode = QCDATA_BR_MODE_SFR; + break; + case AACENC_BR_MODE_FF: + qcInit.bitrateMode = QCDATA_BR_MODE_FF; + break; + default: + ErrorStatus = AAC_ENC_UNSUPPORTED_BITRATE_MODE; + goto bail; + } - /* maxIterations should be set to the maximum number of requantization iterations that are - * allowed before the crash recovery functionality is activated. This setting should be adjusted - * to the processing power available, i.e. to the processing power headroom in one frame that is - * still left after normal encoding without requantization. Please note that if activated this - * functionality is used most likely only in cases where the encoder is operating beyond - * recommended settings, i.e. the audio quality is suboptimal anyway. Activating the crash - * recovery does not further reduce audio quality significantly in these cases. */ - if ( (config->audioObjectType == AOT_ER_AAC_LD) || (config->audioObjectType == AOT_ER_AAC_ELD) ) { + qcInit.invQuant = (config->useRequant) ? 2 : 0; + + /* maxIterations should be set to the maximum number of requantization + * iterations that are allowed before the crash recovery functionality is + * activated. This setting should be adjusted to the processing power + * available, i.e. to the processing power headroom in one frame that is still + * left after normal encoding without requantization. Please note that if + * activated this functionality is used most likely only in cases where the + * encoder is operating beyond recommended settings, i.e. the audio quality is + * suboptimal anyway. Activating the crash recovery does not further reduce + * audio quality significantly in these cases. */ + if (isLowDelay(config->audioObjectType)) { qcInit.maxIterations = 2; - } - else - { + } else { qcInit.maxIterations = 5; } qcInit.bitrate = config->bitRate - config->ancDataBitRate; - qcInit.staticBits = transportEnc_GetStaticBits(hTpEnc, qcInit.averageBits/qcInit.nSubFrames); + qcInit.staticBits = transportEnc_GetStaticBits( + hTpEnc, qcInit.averageBits / qcInit.nSubFrames); - ErrorStatus = FDKaacEnc_QCInit(hAacEnc->qcKernel, &qcInit); - if (ErrorStatus != AAC_ENC_OK) - goto bail; + ErrorStatus = FDKaacEnc_QCInit(hAacEnc->qcKernel, &qcInit, initFlags); + if (ErrorStatus != AAC_ENC_OK) goto bail; - hAacEnc->aot = hAacEnc->config->audioObjectType; + /* Map virtual aot's to intern aot used in bitstream writer. */ + switch (hAacEnc->config->audioObjectType) { + case AOT_MP2_AAC_LC: + hAacEnc->aot = AOT_AAC_LC; + break; + case AOT_MP2_SBR: + hAacEnc->aot = AOT_SBR; + break; + default: + hAacEnc->aot = hAacEnc->config->audioObjectType; + } /* common things */ @@ -701,7 +718,6 @@ bail: return ErrorStatus; } - /*--------------------------------------------------------------------------- functionname: FDKaacEnc_EncodeFrame @@ -709,277 +725,235 @@ bail: returns: error code ---------------------------------------------------------------------------*/ -AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame( HANDLE_AAC_ENC hAacEnc, /* encoder handle */ - HANDLE_TRANSPORTENC hTpEnc, - INT_PCM* RESTRICT inputBuffer, - INT* nOutBytes, - AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS] - ) -{ - AAC_ENCODER_ERROR ErrorStatus; - int el, n, c=0; - UCHAR extPayloadUsed[MAX_TOTAL_EXT_PAYLOADS]; - - CHANNEL_MAPPING *cm = &hAacEnc->channelMapping; - - - - PSY_OUT *psyOut = hAacEnc->psyOut[c]; - QC_OUT *qcOut = hAacEnc->qcOut[c]; - - FDKmemclear(extPayloadUsed, MAX_TOTAL_EXT_PAYLOADS * sizeof(UCHAR)); - - qcOut->elementExtBits = 0; /* sum up all extended bit of each element */ - qcOut->staticBits = 0; /* sum up side info bits of each element */ - qcOut->totalNoRedPe = 0; /* sum up PE */ - - /* advance psychoacoustics */ - for (el=0; elnElements; el++) { - ELEMENT_INFO elInfo = cm->elInfo[el]; - - if ( (elInfo.elType == ID_SCE) - || (elInfo.elType == ID_CPE) - || (elInfo.elType == ID_LFE) ) - { - int ch; - - /* update pointer!*/ - for(ch=0;chpsyOutElement[el]->psyOutChannel[ch]; - QC_OUT_CHANNEL *qcOutChan = qcOut->qcElement[el]->qcOutChannel[ch]; - - psyOutChan->mdctSpectrum = qcOutChan->mdctSpectrum; - psyOutChan->sfbSpreadEnergy = qcOutChan->sfbSpreadEnergy; - psyOutChan->sfbEnergy = qcOutChan->sfbEnergy; - psyOutChan->sfbEnergyLdData = qcOutChan->sfbEnergyLdData; - psyOutChan->sfbMinSnrLdData = qcOutChan->sfbMinSnrLdData; - psyOutChan->sfbThresholdLdData = qcOutChan->sfbThresholdLdData; - - } - - FDKaacEnc_psyMain(elInfo.nChannelsInEl, - hAacEnc->psyKernel->psyElement[el], - hAacEnc->psyKernel->psyDynamic, - hAacEnc->psyKernel->psyConf, - psyOut->psyOutElement[el], - inputBuffer, - cm->elInfo[el].ChannelIndex, - cm->nChannels - - ); - - /* FormFactor, Pe and staticBitDemand calculation */ - ErrorStatus = FDKaacEnc_QCMainPrepare(&elInfo, - hAacEnc->qcKernel->hAdjThr->adjThrStateElem[el], - psyOut->psyOutElement[el], - qcOut->qcElement[el], - hAacEnc->aot, - hAacEnc->config->syntaxFlags, - hAacEnc->config->epConfig); - - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; - - /*-------------------------------------------- */ - - qcOut->qcElement[el]->extBitsUsed = 0; - qcOut->qcElement[el]->nExtensions = 0; - /* reset extension payload */ - FDKmemclear(&qcOut->qcElement[el]->extension, (1)*sizeof(QC_OUT_EXTENSION)); - - for ( n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++ ) { - if ( !extPayloadUsed[n] - && (extPayload[n].associatedChElement == el) - && (extPayload[n].dataSize > 0) - && (extPayload[n].pData != NULL) ) - { - int idx = qcOut->qcElement[el]->nExtensions++; - - qcOut->qcElement[el]->extension[idx].type = extPayload[n].dataType; /* Perform a sanity check on the type? */ - qcOut->qcElement[el]->extension[idx].nPayloadBits = extPayload[n].dataSize; - qcOut->qcElement[el]->extension[idx].pPayload = extPayload[n].pData; - /* Now ask the bitstream encoder how many bits we need to encode the data with the current bitstream syntax: */ - qcOut->qcElement[el]->extBitsUsed += - FDKaacEnc_writeExtensionData( NULL, - &qcOut->qcElement[el]->extension[idx], - 0, 0, - hAacEnc->config->syntaxFlags, - hAacEnc->aot, - hAacEnc->config->epConfig ); - extPayloadUsed[n] = 1; - } - } - - /* sum up extension and static bits for all channel elements */ - qcOut->elementExtBits += qcOut->qcElement[el]->extBitsUsed; - qcOut->staticBits += qcOut->qcElement[el]->staticBitsUsed; - - /* sum up pe */ - qcOut->totalNoRedPe += qcOut->qcElement[el]->peData.pe; +AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame( + HANDLE_AAC_ENC hAacEnc, /* encoder handle */ + HANDLE_TRANSPORTENC hTpEnc, INT_PCM *RESTRICT inputBuffer, + const UINT inputBufferBufSize, INT *nOutBytes, + AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS]) { + AAC_ENCODER_ERROR ErrorStatus; + int el, n, c = 0; + UCHAR extPayloadUsed[MAX_TOTAL_EXT_PAYLOADS]; + + CHANNEL_MAPPING *cm = &hAacEnc->channelMapping; + + PSY_OUT *psyOut = hAacEnc->psyOut[c]; + QC_OUT *qcOut = hAacEnc->qcOut[c]; + + FDKmemclear(extPayloadUsed, MAX_TOTAL_EXT_PAYLOADS * sizeof(UCHAR)); + + qcOut->elementExtBits = 0; /* sum up all extended bit of each element */ + qcOut->staticBits = 0; /* sum up side info bits of each element */ + qcOut->totalNoRedPe = 0; /* sum up PE */ + + /* advance psychoacoustics */ + for (el = 0; el < cm->nElements; el++) { + ELEMENT_INFO elInfo = cm->elInfo[el]; + + if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || + (elInfo.elType == ID_LFE)) { + int ch; + + /* update pointer!*/ + for (ch = 0; ch < elInfo.nChannelsInEl; ch++) { + PSY_OUT_CHANNEL *psyOutChan = + psyOut->psyOutElement[el]->psyOutChannel[ch]; + QC_OUT_CHANNEL *qcOutChan = qcOut->qcElement[el]->qcOutChannel[ch]; + + psyOutChan->mdctSpectrum = qcOutChan->mdctSpectrum; + psyOutChan->sfbSpreadEnergy = qcOutChan->sfbSpreadEnergy; + psyOutChan->sfbEnergy = qcOutChan->sfbEnergy; + psyOutChan->sfbEnergyLdData = qcOutChan->sfbEnergyLdData; + psyOutChan->sfbMinSnrLdData = qcOutChan->sfbMinSnrLdData; + psyOutChan->sfbThresholdLdData = qcOutChan->sfbThresholdLdData; + } + + ErrorStatus = FDKaacEnc_psyMain( + elInfo.nChannelsInEl, hAacEnc->psyKernel->psyElement[el], + hAacEnc->psyKernel->psyDynamic, hAacEnc->psyKernel->psyConf, + psyOut->psyOutElement[el], inputBuffer, inputBufferBufSize, + cm->elInfo[el].ChannelIndex, cm->nChannels); + + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; + + /* FormFactor, Pe and staticBitDemand calculation */ + ErrorStatus = FDKaacEnc_QCMainPrepare( + &elInfo, hAacEnc->qcKernel->hAdjThr->adjThrStateElem[el], + psyOut->psyOutElement[el], qcOut->qcElement[el], hAacEnc->aot, + hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig); + + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; + + /*-------------------------------------------- */ + + qcOut->qcElement[el]->extBitsUsed = 0; + qcOut->qcElement[el]->nExtensions = 0; + /* reset extension payload */ + FDKmemclear(&qcOut->qcElement[el]->extension, + (1) * sizeof(QC_OUT_EXTENSION)); + + for (n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++) { + if (!extPayloadUsed[n] && (extPayload[n].associatedChElement == el) && + (extPayload[n].dataSize > 0) && (extPayload[n].pData != NULL)) { + int idx = qcOut->qcElement[el]->nExtensions++; + + qcOut->qcElement[el]->extension[idx].type = + extPayload[n].dataType; /* Perform a sanity check on the type? */ + qcOut->qcElement[el]->extension[idx].nPayloadBits = + extPayload[n].dataSize; + qcOut->qcElement[el]->extension[idx].pPayload = extPayload[n].pData; + /* Now ask the bitstream encoder how many bits we need to encode the + * data with the current bitstream syntax: */ + qcOut->qcElement[el]->extBitsUsed += FDKaacEnc_writeExtensionData( + NULL, &qcOut->qcElement[el]->extension[idx], 0, 0, + hAacEnc->config->syntaxFlags, hAacEnc->aot, + hAacEnc->config->epConfig); + extPayloadUsed[n] = 1; } + } + + /* sum up extension and static bits for all channel elements */ + qcOut->elementExtBits += qcOut->qcElement[el]->extBitsUsed; + qcOut->staticBits += qcOut->qcElement[el]->staticBitsUsed; + + /* sum up pe */ + qcOut->totalNoRedPe += qcOut->qcElement[el]->peData.pe; } + } - qcOut->nExtensions = 0; - qcOut->globalExtBits = 0; - - /* reset extension payload */ - FDKmemclear(&qcOut->extension, (2+2)*sizeof(QC_OUT_EXTENSION)); - - /* Add extension payload not assigned to an channel element - (Ancillary data is the only supported type up to now) */ - for ( n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++ ) { - if ( !extPayloadUsed[n] - && (extPayload[n].associatedChElement == -1) - && (extPayload[n].pData != NULL) ) - { - UINT payloadBits = 0; - - if (extPayload[n].dataType == EXT_DATA_ELEMENT) { - if (hAacEnc->ancillaryBitsPerFrame) { - /* granted frame dse bitrate */ - payloadBits = hAacEnc->ancillaryBitsPerFrame; - } - else { - /* write anc data if bitrate constraint fulfilled */ - if ((extPayload[n].dataSize>>3) <= hAacEnc->config->maxAncBytesPerAU) { - payloadBits = extPayload[n].dataSize; - } - } - payloadBits = fixMin( extPayload[n].dataSize, payloadBits ); - } else { - payloadBits = extPayload[n].dataSize; - } - - if (payloadBits > 0) - { - int idx = qcOut->nExtensions++; - - qcOut->extension[idx].type = extPayload[n].dataType; /* Perform a sanity check on the type? */ - qcOut->extension[idx].nPayloadBits = payloadBits; - qcOut->extension[idx].pPayload = extPayload[n].pData; - /* Now ask the bitstream encoder how many bits we need to encode the data with the current bitstream syntax: */ - qcOut->globalExtBits += FDKaacEnc_writeExtensionData( NULL, - &qcOut->extension[idx], - 0, 0, - hAacEnc->config->syntaxFlags, - hAacEnc->aot, - hAacEnc->config->epConfig ); - if (extPayload[n].dataType == EXT_DATA_ELEMENT) { - /* substract the processed bits */ - extPayload[n].dataSize -= payloadBits; - } - extPayloadUsed[n] = 1; - } + qcOut->nExtensions = 0; + qcOut->globalExtBits = 0; + + /* reset extension payload */ + FDKmemclear(&qcOut->extension, (2 + 2) * sizeof(QC_OUT_EXTENSION)); + + /* Add extension payload not assigned to an channel element + (Ancillary data is the only supported type up to now) */ + for (n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++) { + if (!extPayloadUsed[n] && (extPayload[n].associatedChElement == -1) && + (extPayload[n].pData != NULL)) { + UINT payloadBits = 0; + + if (extPayload[n].dataType == EXT_DATA_ELEMENT) { + if (hAacEnc->ancillaryBitsPerFrame) { + /* granted frame dse bitrate */ + payloadBits = hAacEnc->ancillaryBitsPerFrame; + } else { + /* write anc data if bitrate constraint fulfilled */ + if ((extPayload[n].dataSize >> 3) <= + hAacEnc->config->maxAncBytesPerAU) { + payloadBits = extPayload[n].dataSize; + } } - } + payloadBits = fixMin(extPayload[n].dataSize, payloadBits); + } else { + payloadBits = extPayload[n].dataSize; + } - if (!(hAacEnc->config->syntaxFlags & (AC_SCALABLE|AC_ER))) { - qcOut->globalExtBits += EL_ID_BITS; /* add bits for ID_END */ + if (payloadBits > 0) { + int idx = qcOut->nExtensions++; + + qcOut->extension[idx].type = + extPayload[n].dataType; /* Perform a sanity check on the type? */ + qcOut->extension[idx].nPayloadBits = payloadBits; + qcOut->extension[idx].pPayload = extPayload[n].pData; + /* Now ask the bitstream encoder how many bits we need to encode the + * data with the current bitstream syntax: */ + qcOut->globalExtBits += FDKaacEnc_writeExtensionData( + NULL, &qcOut->extension[idx], 0, 0, hAacEnc->config->syntaxFlags, + hAacEnc->aot, hAacEnc->config->epConfig); + if (extPayload[n].dataType == EXT_DATA_ELEMENT) { + /* substract the processed bits */ + extPayload[n].dataSize -= payloadBits; + } + extPayloadUsed[n] = 1; + } } + } + + if (!(hAacEnc->config->syntaxFlags & (AC_SCALABLE | AC_ER))) { + qcOut->globalExtBits += EL_ID_BITS; /* add bits for ID_END */ + } + + /* build bitstream all nSubFrames */ + { + INT totalBits = 0; /* Total AU bits */ + ; + INT avgTotalBits = 0; - /* build bitstream all nSubFrames */ + /*-------------------------------------------- */ + /* Get average total bits */ + /*-------------------------------------------- */ { - INT totalBits = 0; /* Total AU bits */; - INT avgTotalBits = 0; - - /*-------------------------------------------- */ - /* Get average total bits */ - /*-------------------------------------------- */ - { - /* frame wise bitrate adaption */ - FDKaacEnc_AdjustBitrate(hAacEnc->qcKernel, - cm, - &avgTotalBits, - hAacEnc->config->bitRate, - hAacEnc->config->sampleRate, - hAacEnc->config->framelength); - - /* adjust super frame bitrate */ - avgTotalBits *= hAacEnc->config->nSubFrames; - } + /* frame wise bitrate adaption */ + FDKaacEnc_AdjustBitrate( + hAacEnc->qcKernel, cm, &avgTotalBits, hAacEnc->config->bitRate, + hAacEnc->config->sampleRate, hAacEnc->config->framelength); + + /* adjust super frame bitrate */ + avgTotalBits *= hAacEnc->config->nSubFrames; + } - /* Make first estimate of transport header overhead. - Take maximum possible frame size into account to prevent bitreservoir underrun. */ - hAacEnc->qcKernel->globHdrBits = transportEnc_GetStaticBits(hTpEnc, avgTotalBits + hAacEnc->qcKernel->bitResTot); - - - /*-------------------------------------------- */ - /*-------------------------------------------- */ - /*-------------------------------------------- */ - - ErrorStatus = FDKaacEnc_QCMain(hAacEnc->qcKernel, - hAacEnc->psyOut, - hAacEnc->qcOut, - avgTotalBits, - cm - ,hAacEnc->aot, - hAacEnc->config->syntaxFlags, - hAacEnc->config->epConfig); - - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; - /*-------------------------------------------- */ - - /*-------------------------------------------- */ - ErrorStatus = FDKaacEnc_updateFillBits(cm, - hAacEnc->qcKernel, - hAacEnc->qcKernel->elementBits, - hAacEnc->qcOut); - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; - - /*-------------------------------------------- */ - ErrorStatus = FDKaacEnc_FinalizeBitConsumption(cm, - hAacEnc->qcKernel, - qcOut, - qcOut->qcElement, - hTpEnc, - hAacEnc->aot, - hAacEnc->config->syntaxFlags, - hAacEnc->config->epConfig); - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; - /*-------------------------------------------- */ - totalBits += qcOut->totalBits; - - - /*-------------------------------------------- */ - FDKaacEnc_updateBitres(cm, - hAacEnc->qcKernel, - hAacEnc->qcOut); - - /*-------------------------------------------- */ - - /* for ( all sub frames ) ... */ - /* write bitstream header */ - transportEnc_WriteAccessUnit( - hTpEnc, - totalBits, - FDKaacEnc_EncBitresToTpBitres(hAacEnc), - cm->nChannelsEff); - - /* write bitstream */ - ErrorStatus = FDKaacEnc_WriteBitstream( - hTpEnc, - cm, - qcOut, - psyOut, - hAacEnc->qcKernel, - hAacEnc->aot, - hAacEnc->config->syntaxFlags, - hAacEnc->config->epConfig); - - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; - - /* transportEnc_EndAccessUnit() is being called inside FDKaacEnc_WriteBitstream() */ - transportEnc_GetFrame(hTpEnc, nOutBytes); - - } /* -end- if (curFrame==hAacEnc->qcKernel->nSubFrames) */ + /* Make first estimate of transport header overhead. + Take maximum possible frame size into account to prevent bitreservoir + underrun. */ + hAacEnc->qcKernel->globHdrBits = transportEnc_GetStaticBits( + hTpEnc, avgTotalBits + hAacEnc->qcKernel->bitResTot); + /*-------------------------------------------- */ + /*-------------------------------------------- */ + /*-------------------------------------------- */ + + ErrorStatus = FDKaacEnc_QCMain( + hAacEnc->qcKernel, hAacEnc->psyOut, hAacEnc->qcOut, avgTotalBits, cm, + hAacEnc->aot, hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig); + + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; + /*-------------------------------------------- */ + + /*-------------------------------------------- */ + ErrorStatus = FDKaacEnc_updateFillBits( + cm, hAacEnc->qcKernel, hAacEnc->qcKernel->elementBits, hAacEnc->qcOut); + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; /*-------------------------------------------- */ - return AAC_ENC_OK; + ErrorStatus = FDKaacEnc_FinalizeBitConsumption( + cm, hAacEnc->qcKernel, qcOut, qcOut->qcElement, hTpEnc, hAacEnc->aot, + hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig); + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; + /*-------------------------------------------- */ + totalBits += qcOut->totalBits; + + /*-------------------------------------------- */ + FDKaacEnc_updateBitres(cm, hAacEnc->qcKernel, hAacEnc->qcOut); + + /*-------------------------------------------- */ + + /* for ( all sub frames ) ... */ + /* write bitstream header */ + if (TRANSPORTENC_OK != + transportEnc_WriteAccessUnit(hTpEnc, totalBits, + FDKaacEnc_EncBitresToTpBitres(hAacEnc), + cm->nChannelsEff)) { + return AAC_ENC_UNKNOWN; + } + + /* write bitstream */ + ErrorStatus = FDKaacEnc_WriteBitstream( + hTpEnc, cm, qcOut, psyOut, hAacEnc->qcKernel, hAacEnc->aot, + hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig); + + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; + + /* transportEnc_EndAccessUnit() is being called inside + * FDKaacEnc_WriteBitstream() */ + if (TRANSPORTENC_OK != transportEnc_GetFrame(hTpEnc, nOutBytes)) { + return AAC_ENC_UNKNOWN; + } + + } /* -end- if (curFrame==hAacEnc->qcKernel->nSubFrames) */ + + /*-------------------------------------------- */ + return AAC_ENC_OK; } /*--------------------------------------------------------------------------- @@ -990,29 +964,27 @@ AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame( HANDLE_AAC_ENC hAacEnc, ---------------------------------------------------------------------------*/ -void FDKaacEnc_Close( HANDLE_AAC_ENC* phAacEnc) /* encoder handle */ +void FDKaacEnc_Close(HANDLE_AAC_ENC *phAacEnc) /* encoder handle */ { - if (*phAacEnc == NULL) { - return; - } - AAC_ENC *hAacEnc = (AAC_ENC*)*phAacEnc; + if (*phAacEnc == NULL) { + return; + } + AAC_ENC *hAacEnc = (AAC_ENC *)*phAacEnc; - if (hAacEnc->dynamic_RAM != NULL) - FreeAACdynamic_RAM(&hAacEnc->dynamic_RAM); + if (hAacEnc->dynamic_RAM != NULL) FreeAACdynamic_RAM(&hAacEnc->dynamic_RAM); - FDKaacEnc_PsyClose(&hAacEnc->psyKernel,hAacEnc->psyOut); + FDKaacEnc_PsyClose(&hAacEnc->psyKernel, hAacEnc->psyOut); - FDKaacEnc_QCClose(&hAacEnc->qcKernel, hAacEnc->qcOut); + FDKaacEnc_QCClose(&hAacEnc->qcKernel, hAacEnc->qcOut); - FreeRam_aacEnc_AacEncoder(phAacEnc); + FreeRam_aacEnc_AacEncoder(phAacEnc); } - /* The following functions are in this source file only for convenience and */ /* need not be visible outside of a possible encoder library. */ /* basic defines for ancillary data */ -#define MAX_ANCRATE 19200 /* ancillary rate >= 19200 isn't valid */ +#define MAX_ANCRATE 19200 /* ancillary rate >= 19200 isn't valid */ /*--------------------------------------------------------------------------- @@ -1021,42 +993,33 @@ void FDKaacEnc_Close( HANDLE_AAC_ENC* phAacEnc) /* encoder handle */ return: if success or NULL if error ---------------------------------------------------------------------------*/ -static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(INT bitRate, - INT framelength, - INT ancillaryRate, - INT *ancillaryBitsPerFrame, - INT sampleRate) -{ - INT diffToByteAlign; - +static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary( + INT bitRate, INT framelength, INT ancillaryRate, INT *ancillaryBitsPerFrame, + INT sampleRate) { /* don't use negative ancillary rates */ - if ( ancillaryRate < -1 ) - return AAC_ENC_UNSUPPORTED_ANC_BITRATE; + if (ancillaryRate < -1) return AAC_ENC_UNSUPPORTED_ANC_BITRATE; /* check if ancillary rate is ok */ - if ( (ancillaryRate != (-1)) && (ancillaryRate != 0) ) { + if ((ancillaryRate != (-1)) && (ancillaryRate != 0)) { /* ancRate <= 15% of bitrate && ancRate < 19200 */ - if ( ( ancillaryRate >= MAX_ANCRATE ) || - ( (ancillaryRate * 20) > (bitRate * 3) ) ) { + if ((ancillaryRate >= MAX_ANCRATE) || + ((ancillaryRate * 20) > (bitRate * 3))) { return AAC_ENC_UNSUPPORTED_ANC_BITRATE; } - } - else if (ancillaryRate == -1) { + } else if (ancillaryRate == -1) { /* if no special ancRate is requested but a ancillary file is stated, then generate a ancillary rate matching to the bitrate */ if (bitRate >= (MAX_ANCRATE * 10)) { /* ancillary rate is 19199 */ ancillaryRate = (MAX_ANCRATE - 1); - } - else { /* 10% of bitrate */ + } else { /* 10% of bitrate */ ancillaryRate = bitRate / 10; } } /* make ancillaryBitsPerFrame byte align */ - *ancillaryBitsPerFrame = (ancillaryRate * framelength ) / sampleRate; - diffToByteAlign = *ancillaryBitsPerFrame % 8; - *ancillaryBitsPerFrame = *ancillaryBitsPerFrame - diffToByteAlign; + *ancillaryBitsPerFrame = + FDKaacEnc_CalcBitsPerFrame(ancillaryRate, framelength, sampleRate) & ~0x7; return AAC_ENC_OK; } diff --git a/libAACenc/src/aacenc.h b/libAACenc/src/aacenc.h index 79524b5..0e0d8c1 100644 --- a/libAACenc/src/aacenc.h +++ b/libAACenc/src/aacenc.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,17 +90,18 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/************************* Fast MPEG AAC Audio Encoder ********************** + Author(s): M. Schug / A. Groeschel - Initial author: M. Schug / A. Groeschel - contents/description: fast aac coder interface library functions + Description: fast aac coder interface library functions -******************************************************************************/ +*******************************************************************************/ -#ifndef _aacenc_h_ -#define _aacenc_h_ +#ifndef AACENC_H +#define AACENC_H #include "common_fix.h" #include "FDK_audio.h" @@ -98,10 +110,7 @@ amm-info@iis.fraunhofer.de #include "sbr_encoder.h" -#define BITRES_MAX_LD 4000 -#define BITRES_MIN_LD 500 -#define BITRATE_MAX_LD 70000 /* Max assumed bitrate for bitres calculation */ -#define BITRATE_MIN_LD 12000 /* Min assumed bitrate for bitres calculation */ +#define MIN_BUFSIZE_PER_EFF_CHAN 6144 #ifdef __cplusplus extern "C" { @@ -111,192 +120,218 @@ extern "C" { * AAC-LC error codes. */ typedef enum { - AAC_ENC_OK = 0x0000, /*!< All fine. */ + AAC_ENC_OK = 0x0000, /*!< All fine. */ - AAC_ENC_UNKNOWN = 0x0002, /*!< Error condition is of unknown reason, or from another module. */ + AAC_ENC_UNKNOWN = 0x0002, /*!< Error condition is of unknown reason, or from + another module. */ /* initialization errors */ - aac_enc_init_error_start = 0x2000, - AAC_ENC_INVALID_HANDLE = 0x2020, /*!< The handle passed to the function call was invalid (probably NULL). */ - AAC_ENC_INVALID_FRAME_LENGTH = 0x2080, /*!< Invalid frame length. */ - AAC_ENC_INVALID_N_CHANNELS = 0x20e0, /*!< Invalid amount of audio input channels. */ - AAC_ENC_INVALID_SFB_TABLE = 0x2140, /*!< Internal encoder error. */ - - AAC_ENC_UNSUPPORTED_AOT = 0x3000, /*!< The Audio Object Type (AOT) is not supported. */ - AAC_ENC_UNSUPPORTED_BITRATE = 0x3020, /*!< The chosen bitrate is not supported. */ - AAC_ENC_UNSUPPORTED_BITRATE_MODE = 0x3028, /*!< Unsupported bit rate mode (CBR or VBR). */ - AAC_ENC_UNSUPPORTED_ANC_BITRATE = 0x3040, /*!< Unsupported ancillay bitrate. */ - AAC_ENC_UNSUPPORTED_ANC_MODE = 0x3060, - AAC_ENC_UNSUPPORTED_TRANSPORT_TYPE = 0x3080, /*!< The bitstream format is not supported. */ - AAC_ENC_UNSUPPORTED_ER_FORMAT = 0x30a0, /*!< The error resilience tool format is not supported. */ - AAC_ENC_UNSUPPORTED_EPCONFIG = 0x30c0, /*!< The error protection format is not supported. */ - AAC_ENC_UNSUPPORTED_CHANNELCONFIG = 0x30e0, /*!< The channel configuration (either number or arrangement) is not supported. */ - AAC_ENC_UNSUPPORTED_SAMPLINGRATE = 0x3100, /*!< Sample rate of audio input is not supported. */ - AAC_ENC_NO_MEMORY = 0x3120, /*!< Could not allocate memory. */ - AAC_ENC_PE_INIT_TABLE_NOT_FOUND = 0x3140, /*!< Internal encoder error. */ + aac_enc_init_error_start = 0x2000, + AAC_ENC_INVALID_HANDLE = 0x2020, /*!< The handle passed to the function call + was invalid (probably NULL). */ + AAC_ENC_INVALID_FRAME_LENGTH = + 0x2080, /*!< Invalid frame length (must be 1024 or 960). */ + AAC_ENC_INVALID_N_CHANNELS = + 0x20e0, /*!< Invalid amount of audio input channels. */ + AAC_ENC_INVALID_SFB_TABLE = 0x2140, /*!< Internal encoder error. */ + + AAC_ENC_UNSUPPORTED_AOT = + 0x3000, /*!< The Audio Object Type (AOT) is not supported. */ + AAC_ENC_UNSUPPORTED_FILTERBANK = + 0x3010, /*!< Filterbank type is not supported. */ + AAC_ENC_UNSUPPORTED_BITRATE = + 0x3020, /*!< The chosen bitrate is not supported. */ + AAC_ENC_UNSUPPORTED_BITRATE_MODE = + 0x3028, /*!< Unsupported bit rate mode (CBR or VBR). */ + AAC_ENC_UNSUPPORTED_ANC_BITRATE = + 0x3040, /*!< Unsupported ancillay bitrate. */ + AAC_ENC_UNSUPPORTED_ANC_MODE = 0x3060, + AAC_ENC_UNSUPPORTED_TRANSPORT_TYPE = + 0x3080, /*!< The bitstream format is not supported. */ + AAC_ENC_UNSUPPORTED_ER_FORMAT = + 0x30a0, /*!< The error resilience tool format is not supported. */ + AAC_ENC_UNSUPPORTED_EPCONFIG = + 0x30c0, /*!< The error protection format is not supported. */ + AAC_ENC_UNSUPPORTED_CHANNELCONFIG = + 0x30e0, /*!< The channel configuration (either number or arrangement) is + not supported. */ + AAC_ENC_UNSUPPORTED_SAMPLINGRATE = + 0x3100, /*!< Sample rate of audio input is not supported. */ + AAC_ENC_NO_MEMORY = 0x3120, /*!< Could not allocate memory. */ + AAC_ENC_PE_INIT_TABLE_NOT_FOUND = 0x3140, /*!< Internal encoder error. */ aac_enc_init_error_end, /* encode errors */ - aac_enc_error_start = 0x4000, - AAC_ENC_QUANT_ERROR = 0x4020, /*!< Too many bits used in quantization. */ - AAC_ENC_WRITTEN_BITS_ERROR = 0x4040, /*!< Unexpected number of written bits, differs to - calculated number of bits. */ - AAC_ENC_PNS_TABLE_ERROR = 0x4060, /*!< PNS level out of range. */ - AAC_ENC_GLOBAL_GAIN_TOO_HIGH = 0x4080, /*!< Internal quantizer error. */ - AAC_ENC_BITRES_TOO_LOW = 0x40a0, /*!< Too few bits in bit reservoir. */ - AAC_ENC_BITRES_TOO_HIGH = 0x40a1, /*!< Too many bits in bit reservoir. */ - AAC_ENC_INVALID_CHANNEL_BITRATE = 0x4100, - AAC_ENC_INVALID_ELEMENTINFO_TYPE = 0x4120, /*!< Internal encoder error. */ - - AAC_ENC_WRITE_SCAL_ERROR = 0x41e0, /*!< Error writing scalefacData. */ - AAC_ENC_WRITE_SEC_ERROR = 0x4200, /*!< Error writing sectionData. */ - AAC_ENC_WRITE_SPEC_ERROR = 0x4220, /*!< Error writing spectralData. */ + aac_enc_error_start = 0x4000, + AAC_ENC_QUANT_ERROR = 0x4020, /*!< Too many bits used in quantization. */ + AAC_ENC_WRITTEN_BITS_ERROR = + 0x4040, /*!< Unexpected number of written bits, differs to + calculated number of bits. */ + AAC_ENC_PNS_TABLE_ERROR = 0x4060, /*!< PNS level out of range. */ + AAC_ENC_GLOBAL_GAIN_TOO_HIGH = 0x4080, /*!< Internal quantizer error. */ + AAC_ENC_BITRES_TOO_LOW = 0x40a0, /*!< Too few bits in bit reservoir. */ + AAC_ENC_BITRES_TOO_HIGH = 0x40a1, /*!< Too many bits in bit reservoir. */ + AAC_ENC_INVALID_CHANNEL_BITRATE = 0x4100, + AAC_ENC_INVALID_ELEMENTINFO_TYPE = 0x4120, /*!< Internal encoder error. */ + + AAC_ENC_WRITE_SCAL_ERROR = 0x41e0, /*!< Error writing scalefacData. */ + AAC_ENC_WRITE_SEC_ERROR = 0x4200, /*!< Error writing sectionData. */ + AAC_ENC_WRITE_SPEC_ERROR = 0x4220, /*!< Error writing spectralData. */ aac_enc_error_end } AAC_ENCODER_ERROR; /*-------------------------- defines --------------------------------------*/ -#define ANC_DATA_BUFFERSIZE 1024 /* ancBuffer size */ - -#define MAX_TOTAL_EXT_PAYLOADS (((8) * (1)) + (2+2)) +#define ANC_DATA_BUFFERSIZE 1024 /* ancBuffer size */ +#define MAX_TOTAL_EXT_PAYLOADS ((((8)) * (1)) + (2 + 2)) typedef enum { - AACENC_BR_MODE_INVALID = -1, /*!< Invalid bitrate mode. */ - AACENC_BR_MODE_CBR = 0, /*!< Constant bitrate mode. */ - AACENC_BR_MODE_VBR_1 = 1, /*!< Variable bitrate mode, about 32 kbps/channel. */ - AACENC_BR_MODE_VBR_2 = 2, /*!< Variable bitrate mode, about 40 kbps/channel. */ - AACENC_BR_MODE_VBR_3 = 3, /*!< Variable bitrate mode, about 48-56 kbps/channel. */ - AACENC_BR_MODE_VBR_4 = 4, /*!< Variable bitrate mode, about 64 kbps/channel. */ - AACENC_BR_MODE_VBR_5 = 5, /*!< Variable bitrate mode, about 80-96 kbps/channel. */ - AACENC_BR_MODE_FF = 6, /*!< Fixed frame mode. */ - AACENC_BR_MODE_SFR = 7 /*!< Superframe mode. */ + AACENC_BR_MODE_INVALID = -1, /*!< Invalid bitrate mode. */ + AACENC_BR_MODE_CBR = 0, /*!< Constant bitrate mode. */ + AACENC_BR_MODE_VBR_1 = 1, /*!< Variable bitrate mode, very low bitrate. */ + AACENC_BR_MODE_VBR_2 = 2, /*!< Variable bitrate mode, low bitrate. */ + AACENC_BR_MODE_VBR_3 = 3, /*!< Variable bitrate mode, medium bitrate. */ + AACENC_BR_MODE_VBR_4 = 4, /*!< Variable bitrate mode, high bitrate. */ + AACENC_BR_MODE_VBR_5 = 5, /*!< Variable bitrate mode, very high bitrate. */ + AACENC_BR_MODE_FF = 6, /*!< Fixed frame mode. */ + AACENC_BR_MODE_SFR = 7 /*!< Superframe mode. */ } AACENC_BITRATE_MODE; +#define AACENC_BR_MODE_IS_VBR(brMode) ((brMode >= 1) && (brMode <= 5)) + typedef enum { - CH_ORDER_MPEG = 0, /*!< MPEG channel ordering (e. g. 5.1: C, L, R, SL, SR, LFE) */ - CH_ORDER_WAV /*!< WAV fileformat channel ordering (e. g. 5.1: L, R, C, LFE, SL, SR) */ + CH_ORDER_MPEG = + 0, /*!< MPEG channel ordering (e. g. 5.1: C, L, R, SL, SR, LFE) */ + CH_ORDER_WAV /*!< WAV fileformat channel ordering (e. g. 5.1: L, R, C, LFE, + SL, SR) */ } CHANNEL_ORDER; /*-------------------- structure definitions ------------------------------*/ struct AACENC_CONFIG { - INT sampleRate; /* encoder sample rate */ - INT bitRate; /* encoder bit rate in bits/sec */ - INT ancDataBitRate; /* additional bits consumed by anc data or sbr have to be consiedered while configuration */ + INT sampleRate; /* encoder sample rate */ + INT bitRate; /* encoder bit rate in bits/sec */ + INT ancDataBitRate; /* additional bits consumed by anc data or sbr have to be + consiedered while configuration */ + + INT nSubFrames; /* number of frames in super frame (not ADTS/LATM subframes !) + */ + AUDIO_OBJECT_TYPE audioObjectType; /* Audio Object Type */ - INT nSubFrames; /* number of frames in super frame (not ADTS/LATM subframes !) */ - AUDIO_OBJECT_TYPE audioObjectType; /* Audio Object Type */ + INT averageBits; /* encoder bit rate in bits/superframe */ + AACENC_BITRATE_MODE bitrateMode; /* encoder bitrate mode (CBR/VBR) */ + INT nChannels; /* number of channels to process */ + CHANNEL_ORDER channelOrder; /* input Channel ordering scheme. */ + INT bandWidth; /* targeted audio bandwidth in Hz */ + CHANNEL_MODE channelMode; /* encoder channel mode configuration */ + INT framelength; /* used frame size */ - INT averageBits; /* encoder bit rate in bits/superframe */ - INT bitrateMode; /* encoder bitrate mode (CBR/VBR) */ - INT nChannels; /* number of channels to process */ - CHANNEL_ORDER channelOrder; /* Input Channel ordering scheme. */ - INT bandWidth; /* targeted audio bandwidth in Hz */ - CHANNEL_MODE channelMode; /* encoder channel mode configuration */ - INT framelength; /* used frame size */ + UINT syntaxFlags; /* bitstreams syntax configuration */ + SCHAR epConfig; /* error protection configuration */ - UINT syntaxFlags; /* bitstreams syntax configuration */ - SCHAR epConfig; /* error protection configuration */ + INT anc_Rate; /* ancillary rate, 0 (disabled), -1 (default) else desired rate + */ + UINT maxAncBytesPerAU; + INT minBitsPerFrame; /* minimum number of bits in AU */ + INT maxBitsPerFrame; /* maximum number of bits in AU */ - INT anc_Rate; /* ancillary rate, 0 (disabled), -1 (default) else desired rate */ - UINT maxAncBytesPerAU; - INT minBitsPerFrame; /* minimum number of bits in AU */ - INT maxBitsPerFrame; /* maximum number of bits in AU */ - INT bitreservoir; /* size of bitreservoir */ + INT audioMuxVersion; /* audio mux version in loas/latm transport format */ - INT audioMuxVersion; /* audio mux version in loas/latm transport format */ + UINT sbrRatio; /* sbr sampling rate ratio: dual- or single-rate */ - UINT sbrRatio; /* sbr sampling rate ratio: dual- or single-rate */ + UCHAR useTns; /* flag: use temporal noise shaping */ + UCHAR usePns; /* flag: use perceptual noise substitution */ + UCHAR useIS; /* flag: use intensity coding */ + UCHAR useMS; /* flag: use ms stereo tool */ - UCHAR useTns; /* flag: use temporal noise shaping */ - UCHAR usePns; /* flag: use perceptual noise substitution */ - UCHAR useIS; /* flag: use intensity coding */ + UCHAR useRequant; /* flag: use afterburner */ - UCHAR useRequant; /* flag: use afterburner */ + UINT downscaleFactor; }; typedef struct { - UCHAR *pData; /* pointer to extension payload data */ - UINT dataSize; /* extension payload data size in bits */ - EXT_PAYLOAD_TYPE dataType; /* extension payload data type */ - INT associatedChElement; /* number of the channel element the data is assigned to */ + UCHAR *pData; /* pointer to extension payload data */ + UINT dataSize; /* extension payload data size in bits */ + EXT_PAYLOAD_TYPE dataType; /* extension payload data type */ + INT associatedChElement; /* number of the channel element the data is assigned + to */ } AACENC_EXT_PAYLOAD; typedef struct AAC_ENC *HANDLE_AAC_ENC; /** - * \brief Calculate framesize in bits for given bit rate, frame length and sampling rate. + * \brief Calculate framesize in bits for given bit rate, frame length and + * sampling rate. * * \param bitRate Ttarget bitrate in bits per second. * \param frameLength Number of audio samples in one frame. * \param samplingRate Sampling rate in Hz. * * \return Framesize in bits per frame. -*/ -INT FDKaacEnc_CalcBitsPerFrame( - const INT bitRate, - const INT frameLength, - const INT samplingRate - ); + */ +INT FDKaacEnc_CalcBitsPerFrame(const INT bitRate, const INT frameLength, + const INT samplingRate); /** - * \brief Calculate bitrate in bits per second for given framesize, frame length and sampling rate. + * \brief Calculate bitrate in bits per second for given framesize, frame length + * and sampling rate. * - * \param bitsPerFrame Framesize in bits per frame. + * \param bitsPerFrame Framesize in bits per frame * \param frameLength Number of audio samples in one frame. * \param samplingRate Sampling rate in Hz. * * \return Bitrate in bits per second. -*/ -INT FDKaacEnc_CalcBitrate( - const INT bitsPerFrame, - const INT frameLength, - const INT samplingRate - ); + */ +INT FDKaacEnc_CalcBitrate(const INT bitsPerFrame, const INT frameLength, + const INT samplingRate); /** * \brief Limit given bit rate to a valid value * \param hTpEnc transport encoder handle + * \param aot audio object type * \param coreSamplingRate the sample rate to be used for the AAC encoder * \param frameLength the frameLength to be used for the AAC encoder * \param nChannels number of total channels * \param nChannelsEff number of effective channels - * \param bitRate the initial bit rate value for which the closest valid bit rate value is searched for - * \param averageBits average bits per frame for fixed framing. Set to -1 if not available. + * \param bitRate the initial bit rate value for which the closest valid bit + * rate value is searched for + * \param averageBits average bits per frame for fixed framing. Set to -1 if not + * available. * \param optional pointer where the current bits per frame are stored into. * \param bitrateMode the current bit rate mode - * \param nSubFrames number of sub frames for super framing (not transport frames). + * \param nSubFrames number of sub frames for super framing (not transport + * frames). * \return a valid bit rate value as close as possible or identical to bitRate */ -INT FDKaacEnc_LimitBitrate( - HANDLE_TRANSPORTENC hTpEnc, - INT coreSamplingRate, - INT frameLength, - INT nChannels, - INT nChannelsEff, - INT bitRate, - INT averageBits, - INT *pAverageBitsPerFrame, - INT bitrateMode, - INT nSubFrames - ); - - /*----------------------------------------------------------------------------- - - functionname: FDKaacEnc_GetVBRBitrate - description: Get VBR bitrate from vbr quality - input params: int vbrQuality (VBR0, VBR1, VBR2) - channelMode - returns: vbr bitrate +INT FDKaacEnc_LimitBitrate(HANDLE_TRANSPORTENC hTpEnc, AUDIO_OBJECT_TYPE aot, + INT coreSamplingRate, INT frameLength, INT nChannels, + INT nChannelsEff, INT bitRate, INT averageBits, + INT *pAverageBitsPerFrame, + AACENC_BITRATE_MODE bitrateMode, INT nSubFrames); - ------------------------------------------------------------------------------*/ - INT FDKaacEnc_GetVBRBitrate(INT bitrateMode, CHANNEL_MODE channelMode); +/** + * \brief Get current state of the bit reservoir + * \param hAacEncoder encoder handle + * \return bit reservoir state in bits + */ +INT FDKaacEnc_GetBitReservoirState(const HANDLE_AAC_ENC hAacEncoder); + +/*----------------------------------------------------------------------------- + + functionname: FDKaacEnc_GetVBRBitrate + description: Get VBR bitrate from vbr quality + input params: int vbrQuality (VBR0, VBR1, VBR2) + channelMode + returns: vbr bitrate +------------------------------------------------------------------------------*/ +INT FDKaacEnc_GetVBRBitrate(AACENC_BITRATE_MODE bitrateMode, + CHANNEL_MODE channelMode); /*----------------------------------------------------------------------------- @@ -305,26 +340,27 @@ INT FDKaacEnc_LimitBitrate( returns: --- ------------------------------------------------------------------------------*/ -void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config); +void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config); /*--------------------------------------------------------------------------- - functionname:FDKaacEnc_Open + functionname:FDKaacEnc_Open description: allocate and initialize a new encoder instance returns: 0 if success ---------------------------------------------------------------------------*/ -AAC_ENCODER_ERROR FDKaacEnc_Open(HANDLE_AAC_ENC *phAacEnc, /* pointer to an encoder handle, initialized on return */ - const INT nElements, /* number of maximal elements in instance to support */ - const INT nChannels, /* number of maximal channels in instance to support */ - const INT nSubFrames); /* support superframing in instance */ - - -AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEncoder, /* pointer to an encoder handle, initialized on return */ - AACENC_CONFIG *config, /* pre-initialized config struct */ - HANDLE_TRANSPORTENC hTpEnc, - ULONG initFlags); - +AAC_ENCODER_ERROR FDKaacEnc_Open( + HANDLE_AAC_ENC + *phAacEnc, /* pointer to an encoder handle, initialized on return */ + const INT nElements, /* number of maximal elements in instance to support */ + const INT nChannels, /* number of maximal channels in instance to support */ + const INT nSubFrames); /* support superframing in instance */ + +AAC_ENCODER_ERROR FDKaacEnc_Initialize( + HANDLE_AAC_ENC + hAacEncoder, /* pointer to an encoder handle, initialized on return */ + AACENC_CONFIG *config, /* pre-initialized config struct */ + HANDLE_TRANSPORTENC hTpEnc, ULONG initFlags); /*--------------------------------------------------------------------------- @@ -334,12 +370,11 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEncoder, /* poin ---------------------------------------------------------------------------*/ -AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame( HANDLE_AAC_ENC hAacEnc, /* encoder handle */ - HANDLE_TRANSPORTENC hTpEnc, - INT_PCM* inputBuffer, - INT* numOutBytes, - AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS] - ); +AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame( + HANDLE_AAC_ENC hAacEnc, /* encoder handle */ + HANDLE_TRANSPORTENC hTpEnc, INT_PCM *inputBuffer, + const UINT inputBufferBufSize, INT *numOutBytes, + AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS]); /*--------------------------------------------------------------------------- @@ -349,11 +384,10 @@ AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame( HANDLE_AAC_ENC hAacEnc, / ---------------------------------------------------------------------------*/ -void FDKaacEnc_Close( HANDLE_AAC_ENC* phAacEnc); /* encoder handle */ +void FDKaacEnc_Close(HANDLE_AAC_ENC *phAacEnc); /* encoder handle */ #ifdef __cplusplus } #endif -#endif /* _aacenc_h_ */ - +#endif /* AACENC_H */ diff --git a/libAACenc/src/aacenc_lib.cpp b/libAACenc/src/aacenc_lib.cpp index 64445b9..11db3da 100644 --- a/libAACenc/src/aacenc_lib.cpp +++ b/libAACenc/src/aacenc_lib.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/**************************** MPEG-4 HE-AAC Encoder ************************* +/**************************** AAC encoder library ****************************** - Initial author: M. Lohwasser - contents/description: FDK HE-AAC Encoder interface library functions + Author(s): M. Lohwasser -****************************************************************************/ + Description: FDK HE-AAC Encoder interface library functions + +*******************************************************************************/ #include "aacenc_lib.h" #include "FDK_audio.h" @@ -96,9 +108,9 @@ amm-info@iis.fraunhofer.de #include "FDK_core.h" /* FDK_tools versioning info */ /* Encoder library info */ -#define AACENCODER_LIB_VL0 3 -#define AACENCODER_LIB_VL1 4 -#define AACENCODER_LIB_VL2 22 +#define AACENCODER_LIB_VL0 4 +#define AACENCODER_LIB_VL1 0 +#define AACENCODER_LIB_VL2 0 #define AACENCODER_LIB_TITLE "AAC Encoder" #ifdef __ANDROID__ #define AACENCODER_LIB_BUILD_DATE "" @@ -108,9 +120,10 @@ amm-info@iis.fraunhofer.de #define AACENCODER_LIB_BUILD_TIME __TIME__ #endif +#include "pcm_utils.h" #include "sbr_encoder.h" -#include "../src/sbr_ram.h" +#include "../src/sbrenc_ram.h" #include "channel_map.h" #include "psy_const.h" @@ -119,260 +132,297 @@ amm-info@iis.fraunhofer.de #include "tpenc_lib.h" #include "metadata_main.h" - -#define SBL(fl) (fl/8) /*!< Short block length (hardcoded to 8 short blocks per long block) */ -#define BSLA(fl) (4*SBL(fl)+SBL(fl)/2) /*!< AAC block switching look-ahead */ -#define DELAY_AAC(fl) (fl+BSLA(fl)) /*!< MDCT + blockswitching */ -#define DELAY_AACELD(fl) ((fl)/2) /*!< ELD FB delay (no framing delay included) */ - -#define INPUTBUFFER_SIZE (1537+100+2048) - -#define DEFAULT_HEADER_PERIOD_REPETITION_RATE 10 /*!< Default header repetition rate used in transport library and for SBR header. */ +#include "mps_main.h" +#include "sacenc_lib.h" + +#define SBL(fl) \ + (fl / \ + 8) /*!< Short block length (hardcoded to 8 short blocks per long block) */ +#define BSLA(fl) \ + (4 * SBL(fl) + SBL(fl) / 2) /*!< AAC block switching look-ahead */ +#define DELAY_AAC(fl) (fl + BSLA(fl)) /*!< MDCT + blockswitching */ +#define DELAY_AACLD(fl) (fl) /*!< MDCT delay (no framing delay included) */ +#define DELAY_AACELD(fl) \ + ((fl) / 2) /*!< ELD FB delay (no framing delay included) */ + +#define MAX_DS_DELAY (100) /*!< Maximum downsampler delay in SBR. */ +#define INPUTBUFFER_SIZE \ + (2 * (1024) + MAX_DS_DELAY + 1537) /*!< Audio input samples + downsampler \ + delay + sbr/aac delay compensation */ + +#define DEFAULT_HEADER_PERIOD_REPETITION_RATE \ + 10 /*!< Default header repetition rate used in transport library and for SBR \ + header. */ //////////////////////////////////////////////////////////////////////////////////// /** * Flags to characterize encoder modules to be supported in present instance. */ enum { - ENC_MODE_FLAG_AAC = 0x0001, - ENC_MODE_FLAG_SBR = 0x0002, - ENC_MODE_FLAG_PS = 0x0004, - ENC_MODE_FLAG_SAC = 0x0008, - ENC_MODE_FLAG_META = 0x0010 + ENC_MODE_FLAG_AAC = 0x0001, + ENC_MODE_FLAG_SBR = 0x0002, + ENC_MODE_FLAG_PS = 0x0004, + ENC_MODE_FLAG_SAC = 0x0008, + ENC_MODE_FLAG_META = 0x0010 }; //////////////////////////////////////////////////////////////////////////////////// typedef struct { - AUDIO_OBJECT_TYPE userAOT; /*!< Audio Object Type. */ - UINT userSamplerate; /*!< Sampling frequency. */ - UINT nChannels; /*!< will be set via channelMode. */ - CHANNEL_MODE userChannelMode; - UINT userBitrate; - UINT userBitrateMode; - UINT userBandwidth; - UINT userAfterburner; - UINT userFramelength; - UINT userAncDataRate; - UINT userPeakBitrate; - - UCHAR userTns; /*!< Use TNS coding. */ - UCHAR userPns; /*!< Use PNS coding. */ - UCHAR userIntensity; /*!< Use Intensity coding. */ - - TRANSPORT_TYPE userTpType; /*!< Transport type */ - UCHAR userTpSignaling; /*!< Extension AOT signaling mode. */ - UCHAR userTpNsubFrames; /*!< Number of sub frames in a transport frame for LOAS/LATM or ADTS (default 1). */ - UCHAR userTpAmxv; /*!< AudioMuxVersion to be used for LATM (default 0). */ - UCHAR userTpProtection; - UCHAR userTpHeaderPeriod; /*!< Parameter used to configure LATM/LOAS SMC rate. Moreover this parameters is - used to configure repetition rate of PCE in raw_data_block. */ - - UCHAR userErTools; /*!< Use VCB11, HCR and/or RVLC ER tool. */ - UINT userPceAdditions; /*!< Configure additional bits in PCE. */ - - UCHAR userMetaDataMode; /*!< Meta data library configuration. */ - - UCHAR userSbrEnabled; /*!< Enable SBR for ELD. */ - UINT userSbrRatio; /*!< SBR sampling rate ratio. Dual- or single-rate. */ + AUDIO_OBJECT_TYPE userAOT; /*!< Audio Object Type. */ + UINT userSamplerate; /*!< Sampling frequency. */ + UINT nChannels; /*!< will be set via channelMode. */ + CHANNEL_MODE userChannelMode; + UINT userBitrate; + UINT userBitrateMode; + UINT userBandwidth; + UINT userAfterburner; + UINT userFramelength; + UINT userAncDataRate; + UINT userPeakBitrate; + + UCHAR userTns; /*!< Use TNS coding. */ + UCHAR userPns; /*!< Use PNS coding. */ + UCHAR userIntensity; /*!< Use Intensity coding. */ + + TRANSPORT_TYPE userTpType; /*!< Transport type */ + UCHAR userTpSignaling; /*!< Extension AOT signaling mode. */ + UCHAR userTpNsubFrames; /*!< Number of sub frames in a transport frame for + LOAS/LATM or ADTS (default 1). */ + UCHAR userTpAmxv; /*!< AudioMuxVersion to be used for LATM (default 0). */ + UCHAR userTpProtection; + UCHAR userTpHeaderPeriod; /*!< Parameter used to configure LATM/LOAS SMC rate. + Moreover this parameters is used to configure + repetition rate of PCE in raw_data_block. */ + + UCHAR userErTools; /*!< Use VCB11, HCR and/or RVLC ER tool. */ + UINT userPceAdditions; /*!< Configure additional bits in PCE. */ + + UCHAR userMetaDataMode; /*!< Meta data library configuration. */ + + UCHAR userSbrEnabled; /*!< Enable SBR for ELD. */ + UINT userSbrRatio; /*!< SBR sampling rate ratio. Dual- or single-rate. */ + + UINT userDownscaleFactor; } USER_PARAM; +/** + * SBR extenxion payload struct provides buffers to be filled in SBR encoder + * library. + */ +typedef struct { + UCHAR data[(1)][(8)][MAX_PAYLOAD_SIZE]; /*!< extension payload data buffer */ + UINT dataSize[(1)][(8)]; /*!< extension payload data size in bits */ +} SBRENC_EXT_PAYLOAD; + //////////////////////////////////////////////////////////////////////////////////// /**************************************************************************** Structure Definitions ****************************************************************************/ -typedef struct AACENC_CONFIG *HANDLE_AACENC_CONFIG; - - -struct AACENCODER -{ - USER_PARAM extParam; - CODER_CONFIG coderConfig; +typedef struct AACENC_CONFIG *HANDLE_AACENC_CONFIG; - /* AAC */ - AACENC_CONFIG aacConfig; - HANDLE_AAC_ENC hAacEnc; +struct AACENCODER { + USER_PARAM extParam; + CODER_CONFIG coderConfig; - /* SBR */ - HANDLE_SBR_ENCODER hEnvEnc; + /* AAC */ + AACENC_CONFIG aacConfig; + HANDLE_AAC_ENC hAacEnc; - /* Meta Data */ - HANDLE_FDK_METADATA_ENCODER hMetadataEnc; - INT metaDataAllowed; /* Signal whether chosen configuration allows metadata. Necessary for delay - compensation. Metadata mode is a separate parameter. */ + /* SBR */ + HANDLE_SBR_ENCODER hEnvEnc; /* SBR encoder */ + SBRENC_EXT_PAYLOAD *pSbrPayload; /* SBR extension payload */ - /* Transport */ - HANDLE_TRANSPORTENC hTpEnc; + /* Meta Data */ + HANDLE_FDK_METADATA_ENCODER hMetadataEnc; + INT metaDataAllowed; /* Signal whether chosen configuration allows metadata. + Necessary for delay compensation. Metadata mode is a + separate parameter. */ - /* Output */ - UCHAR *outBuffer; /* Internal bitstream buffer */ - INT outBufferInBytes; /* Size of internal bitstream buffer*/ + HANDLE_MPS_ENCODER hMpsEnc; - /* Input */ - INT_PCM *inputBuffer; /* Internal input buffer. Input source for AAC encoder */ - INT inputBufferOffset; /* Where to write new input samples. */ + /* Transport */ + HANDLE_TRANSPORTENC hTpEnc; - INT nSamplesToRead; /* number of input samples neeeded for encoding one frame */ - INT nSamplesRead; /* number of input samples already in input buffer */ - INT nZerosAppended; /* appended zeros at end of file*/ - INT nDelay; /* encoder delay */ + INT_PCM + *inputBuffer; /* Internal input buffer. Input source for AAC encoder */ + UCHAR *outBuffer; /* Internal bitstream buffer */ - AACENC_EXT_PAYLOAD extPayload [MAX_TOTAL_EXT_PAYLOADS]; - /* Extension payload */ - UCHAR extPayloadData [(1)][(8)][MAX_PAYLOAD_SIZE]; - UINT extPayloadSize [(1)][(8)]; /* payload sizes in bits */ + INT inputBufferSize; /* Size of internal input buffer */ + INT inputBufferSizePerChannel; /* Size of internal input buffer per channel */ + INT outBufferInBytes; /* Size of internal bitstream buffer*/ - ULONG InitFlags; /* internal status to treggier re-initialization */ + INT inputBufferOffset; /* Where to write new input samples. */ + INT nSamplesToRead; /* number of input samples neeeded for encoding one frame + */ + INT nSamplesRead; /* number of input samples already in input buffer */ + INT nZerosAppended; /* appended zeros at end of file*/ + INT nDelay; /* codec delay */ + INT nDelayCore; /* codec delay, w/o the SBR decoder delay */ - /* Memory allocation info. */ - INT nMaxAacElements; - INT nMaxAacChannels; - INT nMaxSbrElements; - INT nMaxSbrChannels; - UINT nMaxSubFrames; + AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS]; - UINT encoder_modis; + ULONG InitFlags; /* internal status to treggier re-initialization */ - /* Capability flags */ - UINT CAPF_tpEnc; + /* Memory allocation info. */ + INT nMaxAacElements; + INT nMaxAacChannels; + INT nMaxSbrElements; + INT nMaxSbrChannels; -} ; + UINT encoder_modis; -typedef struct -{ - ULONG samplingRate; /*!< Encoder output sampling rate. */ - ULONG bitrateRange; /*!< Lower bitrate range for config entry. */ + /* Capability flags */ + UINT CAPF_tpEnc; +}; - UCHAR lowDelaySbr; /*!< 0: ELD sbr off, - 1: ELD sbr on */ +typedef struct { + /* input */ + ULONG nChannels; /*!< Number of audio channels. */ + ULONG samplingRate; /*!< Encoder output sampling rate. */ + ULONG bitrateRange; /*!< Lower bitrate range for config entry. */ - UCHAR downsampledSbr; /*!< 0: ELD with dualrate sbr, - 1: ELD with downsampled sbr */ + /* output*/ + UCHAR sbrMode; /*!< 0: ELD sbr off, + 1: ELD with downsampled sbr, + 2: ELD with dualrate sbr. */ + CHANNEL_MODE chMode; /*!< Channel mode. */ } ELD_SBR_CONFIGURATOR; /** * \brief This table defines ELD/SBR default configurations. */ -static const ELD_SBR_CONFIGURATOR eldSbrAutoConfigTab[] = -{ - { 48000, 0, 1, 0 }, - { 48000, 64001, 0, 0 }, +static const ELD_SBR_CONFIGURATOR eldSbrAutoConfigTab[] = { + {1, 48000, 0, 2, MODE_1}, {1, 48000, 64000, 0, MODE_1}, + + {1, 44100, 0, 2, MODE_1}, {1, 44100, 64000, 0, MODE_1}, + + {1, 32000, 0, 2, MODE_1}, {1, 32000, 28000, 1, MODE_1}, + {1, 32000, 56000, 0, MODE_1}, + + {1, 24000, 0, 1, MODE_1}, {1, 24000, 40000, 0, MODE_1}, + + {1, 16000, 0, 1, MODE_1}, {1, 16000, 28000, 0, MODE_1}, + + {1, 15999, 0, 0, MODE_1}, + + {2, 48000, 0, 2, MODE_2}, {2, 48000, 44000, 2, MODE_2}, + {2, 48000, 128000, 0, MODE_2}, - { 44100, 0, 1, 0 }, - { 44100, 64001, 0, 0 }, + {2, 44100, 0, 2, MODE_2}, {2, 44100, 44000, 2, MODE_2}, + {2, 44100, 128000, 0, MODE_2}, - { 32000, 0, 1, 0 }, - { 32000, 28000, 1, 1 }, - { 32000, 56000, 0, 0 }, + {2, 32000, 0, 2, MODE_2}, {2, 32000, 32000, 2, MODE_2}, + {2, 32000, 68000, 1, MODE_2}, {2, 32000, 96000, 0, MODE_2}, - { 24000, 0, 1, 1 }, - { 24000, 40000, 0, 0 }, + {2, 24000, 0, 1, MODE_2}, {2, 24000, 48000, 1, MODE_2}, + {2, 24000, 80000, 0, MODE_2}, - { 16000, 0, 1, 1 }, - { 16000, 28000, 0, 0 } + {2, 16000, 0, 1, MODE_2}, {2, 16000, 32000, 1, MODE_2}, + {2, 16000, 64000, 0, MODE_2}, + + {2, 15999, 0, 0, MODE_2} }; /* * \brief Configure SBR for ELD configuration. * - * This function finds default SBR configuration for ELD based on sampling rate and channel bitrate. - * Outputparameters are SBR on/off, and SBR ratio. + * This function finds default SBR configuration for ELD based on number of + * channels, sampling rate and bitrate. * + * \param nChannels Number of audio channels. * \param samplingRate Audio signal sampling rate. - * \param channelMode Channel configuration to be used. - * \param totalBitrate Overall bitrate. - * \param eldSbr Pointer to eldSbr parameter, filled on return. - * \param eldSbrRatio Pointer to eldSbrRatio parameter, filled on return. + * \param bitrate Encoder bitrate. * - * \return - AACENC_OK, all fine. - * - AACENC_INVALID_CONFIG, on failure. + * \return - pointer to eld sbr configuration. + * - NULL, on failure. */ -static AACENC_ERROR eldSbrConfigurator( - const ULONG samplingRate, - const CHANNEL_MODE channelMode, - const ULONG totalBitrate, - UINT * const eldSbr, - UINT * const eldSbrRatio - ) -{ - AACENC_ERROR err = AACENC_OK; - int i, cfgIdx = -1; - const ULONG channelBitrate = totalBitrate / FDKaacEnc_GetChannelModeConfiguration(channelMode)->nChannelsEff; - - for (i=0; i<(int)(sizeof(eldSbrAutoConfigTab)/sizeof(ELD_SBR_CONFIGURATOR)); i++) { - if ( (samplingRate <= eldSbrAutoConfigTab[i].samplingRate) - && (channelBitrate >= eldSbrAutoConfigTab[i].bitrateRange) ) - { - cfgIdx = i; - } - } - - if (cfgIdx != -1) { - *eldSbr = (eldSbrAutoConfigTab[cfgIdx].lowDelaySbr==0) ? 0 : 1; - *eldSbrRatio = (eldSbrAutoConfigTab[cfgIdx].downsampledSbr==0) ? 2 : 1; - } - else { - err = AACENC_INVALID_CONFIG; /* no default configuration for eld-sbr available. */ +static const ELD_SBR_CONFIGURATOR *eldSbrConfigurator(const ULONG nChannels, + const ULONG samplingRate, + const ULONG bitrate) { + int i; + const ELD_SBR_CONFIGURATOR *pSetup = NULL; + + for (i = 0; + i < (int)(sizeof(eldSbrAutoConfigTab) / sizeof(ELD_SBR_CONFIGURATOR)); + i++) { + if ((nChannels == eldSbrAutoConfigTab[i].nChannels) && + (samplingRate <= eldSbrAutoConfigTab[i].samplingRate) && + (bitrate >= eldSbrAutoConfigTab[i].bitrateRange)) { + pSetup = &eldSbrAutoConfigTab[i]; } + } - return err; + return pSetup; } -static inline INT isSbrActive(const HANDLE_AACENC_CONFIG hAacConfig) -{ - INT sbrUsed = 0; +static inline INT isSbrActive(const HANDLE_AACENC_CONFIG hAacConfig) { + INT sbrUsed = 0; - if ( (hAacConfig->audioObjectType==AOT_SBR) || (hAacConfig->audioObjectType==AOT_PS) ) - { - sbrUsed = 1; - } - if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD && (hAacConfig->syntaxFlags & AC_SBR_PRESENT)) - { - sbrUsed = 1; - } + /* Note: Even if implicit signalling was selected, The AOT itself here is not + * AOT_AAC_LC */ + if ((hAacConfig->audioObjectType == AOT_SBR) || + (hAacConfig->audioObjectType == AOT_PS) || + (hAacConfig->audioObjectType == AOT_MP2_SBR)) { + sbrUsed = 1; + } + if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD && + (hAacConfig->syntaxFlags & AC_SBR_PRESENT)) { + sbrUsed = 1; + } - return ( sbrUsed ); + return (sbrUsed); } -static inline INT isPsActive(const AUDIO_OBJECT_TYPE audioObjectType) -{ - INT psUsed = 0; +static inline INT isPsActive(const AUDIO_OBJECT_TYPE audioObjectType) { + INT psUsed = 0; - if ( (audioObjectType==AOT_PS) ) - { - psUsed = 1; - } + if (audioObjectType == AOT_PS) { + psUsed = 1; + } - return ( psUsed ); + return (psUsed); +} + +static CHANNEL_MODE GetCoreChannelMode( + const CHANNEL_MODE channelMode, const AUDIO_OBJECT_TYPE audioObjectType) { + CHANNEL_MODE mappedChannelMode = channelMode; + if ((isPsActive(audioObjectType) && (channelMode == MODE_2)) || + (channelMode == MODE_212)) { + mappedChannelMode = MODE_1; + } + return mappedChannelMode; } static SBR_PS_SIGNALING getSbrSignalingMode( - const AUDIO_OBJECT_TYPE audioObjectType, - const TRANSPORT_TYPE transportType, - const UCHAR transportSignaling, - const UINT sbrRatio - ) + const AUDIO_OBJECT_TYPE audioObjectType, const TRANSPORT_TYPE transportType, + const UCHAR transportSignaling, const UINT sbrRatio) { SBR_PS_SIGNALING sbrSignaling; - if (transportType==TT_UNKNOWN || sbrRatio==0) { + if (transportType == TT_UNKNOWN || sbrRatio == 0) { sbrSignaling = SIG_UNKNOWN; /* Needed parameters have not been set */ return sbrSignaling; } else { - sbrSignaling = SIG_IMPLICIT; /* default: implicit signaling */ + sbrSignaling = + SIG_EXPLICIT_HIERARCHICAL; /* default: explicit hierarchical signaling + */ } - if ( (audioObjectType==AOT_AAC_LC) || (audioObjectType==AOT_SBR) || (audioObjectType==AOT_PS) ) { + if ((audioObjectType == AOT_AAC_LC) || (audioObjectType == AOT_SBR) || + (audioObjectType == AOT_PS) || (audioObjectType == AOT_MP2_AAC_LC) || + (audioObjectType == AOT_MP2_SBR)) { switch (transportType) { case TT_MP4_ADIF: case TT_MP4_ADTS: - sbrSignaling = SIG_IMPLICIT; /* For MPEG-2 transport types, only implicit signaling is possible */ + sbrSignaling = SIG_IMPLICIT; /* For MPEG-2 transport types, only + implicit signaling is possible */ break; case TT_MP4_RAW: @@ -380,16 +430,13 @@ static SBR_PS_SIGNALING getSbrSignalingMode( case TT_MP4_LATM_MCP0: case TT_MP4_LOAS: default: - if ( transportSignaling==0xFF ) { + if (transportSignaling == 0xFF) { /* Defaults */ - if ( sbrRatio==1 ) { - sbrSignaling = SIG_EXPLICIT_HIERARCHICAL; /* For downsampled SBR, explicit signaling is mandatory */ - } else { - sbrSignaling = SIG_IMPLICIT; /* For dual-rate SBR, implicit signaling is default */ - } + sbrSignaling = SIG_EXPLICIT_HIERARCHICAL; } else { /* User set parameters */ - /* Attention: Backward compatible explicit signaling does only work with AMV1 for LATM/LOAS */ + /* Attention: Backward compatible explicit signaling does only work + * with AMV1 for LATM/LOAS */ sbrSignaling = (SBR_PS_SIGNALING)transportSignaling; } break; @@ -403,78 +450,90 @@ static SBR_PS_SIGNALING getSbrSignalingMode( Allocate Encoder ****************************************************************************/ -H_ALLOC_MEM (_AacEncoder, AACENCODER) -C_ALLOC_MEM (_AacEncoder, AACENCODER, 1) - - - +H_ALLOC_MEM(_AacEncoder, AACENCODER) +C_ALLOC_MEM(_AacEncoder, struct AACENCODER, 1) /* * Map Encoder specific config structures to CODER_CONFIG. */ -static void FDKaacEnc_MapConfig( - CODER_CONFIG *const cc, - const USER_PARAM *const extCfg, - const SBR_PS_SIGNALING sbrSignaling, - const HANDLE_AACENC_CONFIG hAacConfig - ) -{ +static void FDKaacEnc_MapConfig(CODER_CONFIG *const cc, + const USER_PARAM *const extCfg, + const SBR_PS_SIGNALING sbrSignaling, + const HANDLE_AACENC_CONFIG hAacConfig) { AUDIO_OBJECT_TYPE transport_AOT = AOT_NULL_OBJECT; FDKmemclear(cc, sizeof(CODER_CONFIG)); cc->flags = 0; - transport_AOT = hAacConfig->audioObjectType; + cc->samplesPerFrame = hAacConfig->framelength; + cc->samplingRate = hAacConfig->sampleRate; + cc->extSamplingRate = extCfg->userSamplerate; + + /* Map virtual aot to transport aot. */ + switch (hAacConfig->audioObjectType) { + case AOT_MP2_AAC_LC: + transport_AOT = AOT_AAC_LC; + break; + case AOT_MP2_SBR: + transport_AOT = AOT_SBR; + cc->flags |= CC_SBR; + break; + default: + transport_AOT = hAacConfig->audioObjectType; + } if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) { cc->flags |= (hAacConfig->syntaxFlags & AC_SBR_PRESENT) ? CC_SBR : 0; + cc->flags |= (hAacConfig->syntaxFlags & AC_LD_MPS) ? CC_SAC : 0; } /* transport type is usually AAC-LC. */ - if ( (transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS) ) { - cc->aot = AOT_AAC_LC; - } - else { - cc->aot = transport_AOT; + if ((transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS)) { + cc->aot = AOT_AAC_LC; + } else { + cc->aot = transport_AOT; } /* Configure extension aot. */ - if (sbrSignaling==SIG_IMPLICIT) { - cc->extAOT = AOT_NULL_OBJECT; /* implicit */ - } - else { - if ( (sbrSignaling==SIG_EXPLICIT_BW_COMPATIBLE) && ( (transport_AOT==AOT_SBR) || (transport_AOT==AOT_PS) ) ) { - cc->extAOT = AOT_SBR; /* explicit backward compatible */ - } - else { - cc->extAOT = transport_AOT; /* explicit hierarchical */ + if (sbrSignaling == SIG_IMPLICIT) { + cc->extAOT = AOT_NULL_OBJECT; /* implicit */ + } else { + if ((sbrSignaling == SIG_EXPLICIT_BW_COMPATIBLE) && + ((transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS))) { + cc->extAOT = AOT_SBR; /* explicit backward compatible */ + } else { + cc->extAOT = transport_AOT; /* explicit hierarchical */ } } - if ( (transport_AOT==AOT_SBR) || (transport_AOT==AOT_PS) ) { - cc->sbrPresent=1; - if (transport_AOT==AOT_PS) { - cc->psPresent=1; + if ((transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS)) { + cc->sbrPresent = 1; + if (transport_AOT == AOT_PS) { + cc->psPresent = 1; } } - cc->sbrSignaling = sbrSignaling; + cc->sbrSignaling = sbrSignaling; - cc->extSamplingRate = extCfg->userSamplerate; - cc->bitRate = hAacConfig->bitRate; - cc->noChannels = hAacConfig->nChannels; - cc->flags |= CC_IS_BASELAYER; - cc->channelMode = hAacConfig->channelMode; + if (hAacConfig->downscaleFactor > 1) { + cc->downscaleSamplingRate = cc->samplingRate; + cc->samplingRate *= hAacConfig->downscaleFactor; + cc->extSamplingRate *= hAacConfig->downscaleFactor; + } + + cc->bitRate = hAacConfig->bitRate; + cc->noChannels = hAacConfig->nChannels; + cc->flags |= CC_IS_BASELAYER; + cc->channelMode = hAacConfig->channelMode; cc->nSubFrames = (hAacConfig->nSubFrames > 1 && extCfg->userTpNsubFrames == 1) - ? hAacConfig->nSubFrames - : extCfg->userTpNsubFrames; + ? hAacConfig->nSubFrames + : extCfg->userTpNsubFrames; - cc->flags |= (extCfg->userTpProtection) ? CC_PROTECTION : 0; + cc->flags |= (extCfg->userTpProtection) ? CC_PROTECTION : 0; - if (extCfg->userTpHeaderPeriod!=0xFF) { - cc->headerPeriod = extCfg->userTpHeaderPeriod; - } - else { /* auto-mode */ + if (extCfg->userTpHeaderPeriod != 0xFF) { + cc->headerPeriod = extCfg->userTpHeaderPeriod; + } else { /* auto-mode */ switch (extCfg->userTpType) { case TT_MP4_ADTS: case TT_MP4_LOAS: @@ -486,27 +545,65 @@ static void FDKaacEnc_MapConfig( } } - cc->samplesPerFrame = hAacConfig->framelength; - cc->samplingRate = hAacConfig->sampleRate; - /* Mpeg-4 signaling for transport library. */ - cc->flags |= CC_MPEG_ID; + switch (hAacConfig->audioObjectType) { + case AOT_MP2_AAC_LC: + case AOT_MP2_SBR: + cc->flags &= ~CC_MPEG_ID; /* Required for ADTS. */ + cc->extAOT = AOT_NULL_OBJECT; + break; + default: + cc->flags |= CC_MPEG_ID; + } /* ER-tools signaling. */ - cc->flags |= (hAacConfig->syntaxFlags & AC_ER_VCB11) ? CC_VCB11 : 0; - cc->flags |= (hAacConfig->syntaxFlags & AC_ER_HCR) ? CC_HCR : 0; - cc->flags |= (hAacConfig->syntaxFlags & AC_ER_RVLC) ? CC_RVLC : 0; + cc->flags |= (hAacConfig->syntaxFlags & AC_ER_VCB11) ? CC_VCB11 : 0; + cc->flags |= (hAacConfig->syntaxFlags & AC_ER_HCR) ? CC_HCR : 0; + cc->flags |= (hAacConfig->syntaxFlags & AC_ER_RVLC) ? CC_RVLC : 0; /* Matrix mixdown coefficient configuration. */ - if ( (extCfg->userPceAdditions&0x1) && (hAacConfig->epConfig==-1) - && ((cc->channelMode==MODE_1_2_2)||(cc->channelMode==MODE_1_2_2_1)) ) - { - cc->matrixMixdownA = ((extCfg->userPceAdditions>>1)&0x3)+1; - cc->flags |= (extCfg->userPceAdditions>>3)&0x1 ? CC_PSEUDO_SURROUND : 0; - } - else { + if ((extCfg->userPceAdditions & 0x1) && (hAacConfig->epConfig == -1) && + ((cc->channelMode == MODE_1_2_2) || (cc->channelMode == MODE_1_2_2_1))) { + cc->matrixMixdownA = ((extCfg->userPceAdditions >> 1) & 0x3) + 1; + cc->flags |= (extCfg->userPceAdditions >> 3) & 0x1 ? CC_PSEUDO_SURROUND : 0; + } else { cc->matrixMixdownA = 0; } + + cc->channelConfigZero = 0; +} + +/* + * Validate prefilled pointers within buffer descriptor. + * + * \param pBufDesc Pointer to buffer descriptor + + * \return - AACENC_OK, all fine. + * - AACENC_INVALID_HANDLE, on missing pointer initializiation. + * - AACENC_UNSUPPORTED_PARAMETER, on incorrect buffer descriptor + initialization. + */ +static AACENC_ERROR validateBufDesc(const AACENC_BufDesc *pBufDesc) { + AACENC_ERROR err = AACENC_OK; + + if (pBufDesc != NULL) { + int i; + if ((pBufDesc->bufferIdentifiers == NULL) || (pBufDesc->bufSizes == NULL) || + (pBufDesc->bufElSizes == NULL) || (pBufDesc->bufs == NULL)) { + err = AACENC_UNSUPPORTED_PARAMETER; + goto bail; + } + for (i = 0; i < pBufDesc->numBufs; i++) { + if (pBufDesc->bufs[i] == NULL) { + err = AACENC_UNSUPPORTED_PARAMETER; + goto bail; + } + } + } else { + err = AACENC_INVALID_HANDLE; + } +bail: + return err; } /* @@ -518,195 +615,172 @@ static void FDKaacEnc_MapConfig( * \return - Buffer descriptor index. * -1, if there is no entry available. */ -static INT getBufDescIdx( - const AACENC_BufDesc *pBufDesc, - const AACENC_BufferIdentifier identifier -) -{ - INT i, idx = -1; - - for (i=0; inumBufs; i++) { - if ( (AACENC_BufferIdentifier)pBufDesc->bufferIdentifiers[i] == identifier ) { +static INT getBufDescIdx(const AACENC_BufDesc *pBufDesc, + const AACENC_BufferIdentifier identifier) { + INT i, idx = -1; + + if (pBufDesc != NULL) { + for (i = 0; i < pBufDesc->numBufs; i++) { + if ((AACENC_BufferIdentifier)pBufDesc->bufferIdentifiers[i] == + identifier) { idx = i; break; } } - return idx; + } + return idx; } - /**************************************************************************** Function Declarations ****************************************************************************/ AAC_ENCODER_ERROR aacEncDefaultConfig(HANDLE_AACENC_CONFIG hAacConfig, - USER_PARAM *config) -{ - /* make reasonable default settings */ - FDKaacEnc_AacInitDefaultConfig (hAacConfig); - - /* clear configuration structure and copy default settings */ - FDKmemclear(config, sizeof(USER_PARAM)); - - /* copy encoder configuration settings */ - config->nChannels = hAacConfig->nChannels; - config->userAOT = hAacConfig->audioObjectType = AOT_AAC_LC; - config->userSamplerate = hAacConfig->sampleRate; - config->userChannelMode = hAacConfig->channelMode; - config->userBitrate = hAacConfig->bitRate; - config->userBitrateMode = hAacConfig->bitrateMode; - config->userPeakBitrate = (UINT)-1; - config->userBandwidth = hAacConfig->bandWidth; - config->userTns = hAacConfig->useTns; - config->userPns = hAacConfig->usePns; - config->userIntensity = hAacConfig->useIS; - config->userAfterburner = hAacConfig->useRequant; - config->userFramelength = (UINT)-1; - - if (hAacConfig->syntaxFlags & AC_ER_VCB11) { - config->userErTools |= 0x01; - } - if (hAacConfig->syntaxFlags & AC_ER_HCR) { - config->userErTools |= 0x02; - } - - /* initialize transport parameters */ - config->userTpType = TT_UNKNOWN; - config->userTpAmxv = 0; - config->userTpSignaling = 0xFF; /* choose signaling automatically */ - config->userTpNsubFrames = 1; - config->userTpProtection = 0; /* not crc protected*/ - config->userTpHeaderPeriod = 0xFF; /* header period in auto mode */ - config->userPceAdditions = 0; /* no matrix mixdown coefficient */ - config->userMetaDataMode = 0; /* do not embed any meta data info */ - - config->userAncDataRate = 0; - - /* SBR rate is set to 0 here, which means it should be set automatically - in FDKaacEnc_AdjustEncSettings() if the user did not set a rate - expilicitely. */ - config->userSbrRatio = 0; - - /* SBR enable set to -1 means to inquire ELD audio configurator for reasonable configuration. */ - config->userSbrEnabled = -1; - - return AAC_ENC_OK; + USER_PARAM *config) { + /* make reasonable default settings */ + FDKaacEnc_AacInitDefaultConfig(hAacConfig); + + /* clear configuration structure and copy default settings */ + FDKmemclear(config, sizeof(USER_PARAM)); + + /* copy encoder configuration settings */ + config->nChannels = hAacConfig->nChannels; + config->userAOT = hAacConfig->audioObjectType = AOT_AAC_LC; + config->userSamplerate = hAacConfig->sampleRate; + config->userChannelMode = hAacConfig->channelMode; + config->userBitrate = hAacConfig->bitRate; + config->userBitrateMode = hAacConfig->bitrateMode; + config->userPeakBitrate = (UINT)-1; + config->userBandwidth = hAacConfig->bandWidth; + config->userTns = hAacConfig->useTns; + config->userPns = hAacConfig->usePns; + config->userIntensity = hAacConfig->useIS; + config->userAfterburner = hAacConfig->useRequant; + config->userFramelength = (UINT)-1; + + config->userDownscaleFactor = 1; + + /* initialize transport parameters */ + config->userTpType = TT_UNKNOWN; + config->userTpAmxv = 0; + config->userTpSignaling = 0xFF; /* choose signaling automatically */ + config->userTpNsubFrames = 1; + config->userTpProtection = 0; /* not crc protected*/ + config->userTpHeaderPeriod = 0xFF; /* header period in auto mode */ + config->userPceAdditions = 0; /* no matrix mixdown coefficient */ + config->userMetaDataMode = 0; /* do not embed any meta data info */ + + config->userAncDataRate = 0; + + /* SBR rate is set to 0 here, which means it should be set automatically + in FDKaacEnc_AdjustEncSettings() if the user did not set a rate + expilicitely. */ + config->userSbrRatio = 0; + + /* SBR enable set to -1 means to inquire ELD audio configurator for reasonable + * configuration. */ + config->userSbrEnabled = (UCHAR)-1; + + return AAC_ENC_OK; } -static -void aacEncDistributeSbrBits(CHANNEL_MAPPING *channelMapping, SBR_ELEMENT_INFO *sbrElInfo, INT bitRate) -{ +static void aacEncDistributeSbrBits(CHANNEL_MAPPING *channelMapping, + SBR_ELEMENT_INFO *sbrElInfo, INT bitRate) { INT codebits = bitRate; int el; /* Copy Element info */ - for (el=0; elnElements; el++) { - sbrElInfo[el].ChannelIndex[0] = channelMapping->elInfo[el].ChannelIndex[0]; - sbrElInfo[el].ChannelIndex[1] = channelMapping->elInfo[el].ChannelIndex[1]; - sbrElInfo[el].elType = channelMapping->elInfo[el].elType; - sbrElInfo[el].bitRate = (INT)(fMultNorm(channelMapping->elInfo[el].relativeBits, (FIXP_DBL)bitRate)); - sbrElInfo[el].instanceTag = channelMapping->elInfo[el].instanceTag; - sbrElInfo[el].nChannelsInEl = channelMapping->elInfo[el].nChannelsInEl; - - codebits -= sbrElInfo[el].bitRate; + for (el = 0; el < channelMapping->nElements; el++) { + sbrElInfo[el].ChannelIndex[0] = channelMapping->elInfo[el].ChannelIndex[0]; + sbrElInfo[el].ChannelIndex[1] = channelMapping->elInfo[el].ChannelIndex[1]; + sbrElInfo[el].elType = channelMapping->elInfo[el].elType; + sbrElInfo[el].bitRate = + fMultIfloor(channelMapping->elInfo[el].relativeBits, bitRate); + sbrElInfo[el].instanceTag = channelMapping->elInfo[el].instanceTag; + sbrElInfo[el].nChannelsInEl = channelMapping->elInfo[el].nChannelsInEl; + sbrElInfo[el].fParametricStereo = 0; + sbrElInfo[el].fDualMono = 0; + + codebits -= sbrElInfo[el].bitRate; } sbrElInfo[0].bitRate += codebits; } - -static -INT aacEncoder_LimitBitrate( - const HANDLE_TRANSPORTENC hTpEnc, - const INT samplingRate, - const INT frameLength, - const INT nChannels, - const CHANNEL_MODE channelMode, - INT bitRate, - const INT nSubFrames, - const INT sbrActive, - const INT sbrDownSampleRate, - const AUDIO_OBJECT_TYPE aot - ) -{ +static INT aacEncoder_LimitBitrate(const HANDLE_TRANSPORTENC hTpEnc, + const INT samplingRate, + const INT frameLength, const INT nChannels, + const CHANNEL_MODE channelMode, INT bitRate, + const INT nSubFrames, const INT sbrActive, + const INT sbrDownSampleRate, + const UINT syntaxFlags, + const AUDIO_OBJECT_TYPE aot) { INT coreSamplingRate; CHANNEL_MAPPING cm; FDKaacEnc_InitChannelMapping(channelMode, CH_ORDER_MPEG, &cm); if (sbrActive) { - coreSamplingRate = samplingRate >> (sbrEncoder_IsSingleRatePossible(aot) ? (sbrDownSampleRate-1):1); + coreSamplingRate = + samplingRate >> + (sbrEncoder_IsSingleRatePossible(aot) ? (sbrDownSampleRate - 1) : 1); } else { coreSamplingRate = samplingRate; } - /* Consider bandwidth channel bit rate limit (see bandwidth.cpp: GetBandwidthEntry()) */ - if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) { - bitRate = FDKmin(360000*nChannels, bitRate); - bitRate = FDKmax(8000*nChannels, bitRate); - } - - if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) { - bitRate = FDKmin(576000*nChannels, bitRate); - /*bitRate = FDKmax(0*nChannels, bitRate);*/ - } - - /* Limit bit rate in respect to the core coder */ - bitRate = FDKaacEnc_LimitBitrate( - hTpEnc, - coreSamplingRate, - frameLength, - nChannels, - cm.nChannelsEff, - bitRate, - -1, - NULL, - -1, - nSubFrames - ); + bitRate = FDKaacEnc_LimitBitrate(hTpEnc, aot, coreSamplingRate, frameLength, + nChannels, cm.nChannelsEff, bitRate, -1, + NULL, AACENC_BR_MODE_INVALID, nSubFrames); /* Limit bit rate in respect to available SBR modes if active */ - if (sbrActive) - { + if (sbrActive) { int numIterations = 0; INT initialBitrate, adjustedBitrate; - initialBitrate = adjustedBitrate = bitRate; + adjustedBitrate = bitRate; - /* Find total bitrate which provides valid configuration for each SBR element. */ + /* Find total bitrate which provides valid configuration for each SBR + * element. */ do { int e; - SBR_ELEMENT_INFO sbrElInfo[(8)]; - FDK_ASSERT(cm.nElements <= (8)); + SBR_ELEMENT_INFO sbrElInfo[((8))]; + FDK_ASSERT(cm.nElements <= ((8))); initialBitrate = adjustedBitrate; /* Get bit rate for each SBR element */ aacEncDistributeSbrBits(&cm, sbrElInfo, initialBitrate); - for (e=0; e sbrBitRateOut) { - adjustedBitrate = fMin(initialBitrate, (INT)fDivNorm((FIXP_DBL)(sbrBitRateOut-8), cm.elInfo[e].relativeBits)); + adjustedBitrate = fMin(initialBitrate, + (INT)fDivNorm((FIXP_DBL)(sbrBitRateOut - 8), + cm.elInfo[e].relativeBits)); break; } @@ -716,17 +790,56 @@ INT aacEncoder_LimitBitrate( numIterations++; /* restrict iteration to worst case of num elements */ - } while ( (initialBitrate!=adjustedBitrate) && (numIterations<=cm.nElements) ); + } while ((initialBitrate != adjustedBitrate) && + (numIterations <= cm.nElements)); /* Unequal bitrates mean that no reasonable bitrate configuration found. */ - bitRate = (initialBitrate==adjustedBitrate) ? adjustedBitrate : 0; + bitRate = (initialBitrate == adjustedBitrate) ? adjustedBitrate : 0; } - FDK_ASSERT(bitRate > 0); + /* Limit bit rate in respect to available MPS modes if active */ + if ((aot == AOT_ER_AAC_ELD) && (syntaxFlags & AC_LD_MPS) && + (channelMode == MODE_1)) { + bitRate = FDK_MpegsEnc_GetClosestBitRate( + aot, MODE_212, samplingRate, (sbrActive) ? sbrDownSampleRate : 0, + bitRate); + } return bitRate; } +/* + * \brief Get CBR bitrate + * + * \hAacConfig Internal encoder config + * \return Bitrate + */ +static INT FDKaacEnc_GetCBRBitrate(const HANDLE_AACENC_CONFIG hAacConfig, + const INT userSbrRatio) { + INT bitrate = FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode) + ->nChannelsEff * + hAacConfig->sampleRate; + + if (isPsActive(hAacConfig->audioObjectType)) { + bitrate = 1 * bitrate; /* 0.5 bit per sample */ + } else if (isSbrActive(hAacConfig)) { + if ((userSbrRatio == 2) || + ((userSbrRatio == 0) && + (hAacConfig->audioObjectType != AOT_ER_AAC_ELD))) { + bitrate = (bitrate + (bitrate >> 2)) >> 1; /* 0.625 bits per sample */ + } + if ((userSbrRatio == 1) || + ((userSbrRatio == 0) && + (hAacConfig->audioObjectType == AOT_ER_AAC_ELD))) { + bitrate = (bitrate + (bitrate >> 3)); /* 1.125 bits per sample */ + } + } else { + bitrate = bitrate + (bitrate >> 1); /* 1.5 bits per sample */ + } + + return bitrate; +} + /* * \brief Consistency check of given USER_PARAM struct and * copy back configuration from public struct into internal @@ -734,271 +847,365 @@ INT aacEncoder_LimitBitrate( * * \hAacEncoder Internal encoder config which is to be updated * \param config User provided config (public struct) - * \return ´returns always AAC_ENC_OK + * \return returns always AAC_ENC_OK */ -static -AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder, - USER_PARAM *config) -{ - AACENC_ERROR err = AACENC_OK; - - /* Get struct pointers. */ - HANDLE_AACENC_CONFIG hAacConfig = &hAacEncoder->aacConfig; - - hAacConfig->nChannels = config->nChannels; - - /* Encoder settings update. */ - hAacConfig->sampleRate = config->userSamplerate; - hAacConfig->useTns = config->userTns; - hAacConfig->usePns = config->userPns; - hAacConfig->useIS = config->userIntensity; - hAacConfig->bitRate = config->userBitrate; - hAacConfig->channelMode = config->userChannelMode; - hAacConfig->bitrateMode = config->userBitrateMode; - hAacConfig->bandWidth = config->userBandwidth; - hAacConfig->useRequant = config->userAfterburner; - - hAacConfig->audioObjectType = config->userAOT; - hAacConfig->anc_Rate = config->userAncDataRate; - hAacConfig->syntaxFlags = 0; - hAacConfig->epConfig = -1; - - if (config->userTpType==TT_MP4_LATM_MCP1 || config->userTpType==TT_MP4_LATM_MCP0 || config->userTpType==TT_MP4_LOAS) { - hAacConfig->audioMuxVersion = config->userTpAmxv; - } - else { - hAacConfig->audioMuxVersion = -1; - } +static AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder, + USER_PARAM *config) { + AACENC_ERROR err = AACENC_OK; + + /* Get struct pointers. */ + HANDLE_AACENC_CONFIG hAacConfig = &hAacEncoder->aacConfig; + + /* Encoder settings update. */ + hAacConfig->sampleRate = config->userSamplerate; + if (config->userDownscaleFactor > 1) { + hAacConfig->useTns = 0; + hAacConfig->usePns = 0; + hAacConfig->useIS = 0; + } else { + hAacConfig->useTns = config->userTns; + hAacConfig->usePns = config->userPns; + hAacConfig->useIS = config->userIntensity; + } - /* Adapt internal AOT when necessary. */ - switch ( hAacConfig->audioObjectType ) { - case AOT_AAC_LC: - case AOT_SBR: - case AOT_PS: - config->userTpType = (config->userTpType!=TT_UNKNOWN) ? config->userTpType : TT_MP4_ADTS; - hAacConfig->framelength = (config->userFramelength!=(UINT)-1) ? config->userFramelength : 1024; - if (hAacConfig->framelength != 1024) { - return AACENC_INVALID_CONFIG; - } - break; - case AOT_ER_AAC_LD: - hAacConfig->epConfig = 0; - hAacConfig->syntaxFlags |= AC_ER|AC_LD; - hAacConfig->syntaxFlags |= ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0); - hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0); - hAacConfig->syntaxFlags |= ((config->userErTools & 0x4) ? AC_ER_RVLC : 0); - config->userTpType = (config->userTpType!=TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS; - hAacConfig->framelength = (config->userFramelength!=(UINT)-1) ? config->userFramelength : 512; - if (hAacConfig->framelength != 512 && hAacConfig->framelength != 480) { - return AACENC_INVALID_CONFIG; - } - break; - case AOT_ER_AAC_ELD: - hAacConfig->epConfig = 0; - hAacConfig->syntaxFlags |= AC_ER|AC_ELD; - hAacConfig->syntaxFlags |= ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0); - hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0); - hAacConfig->syntaxFlags |= ((config->userErTools & 0x4) ? AC_ER_RVLC : 0); - hAacConfig->syntaxFlags |= ((config->userSbrEnabled==1) ? AC_SBR_PRESENT : 0); - config->userTpType = (config->userTpType!=TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS; - hAacConfig->framelength = (config->userFramelength!=(UINT)-1) ? config->userFramelength : 512; - if (hAacConfig->framelength != 512 && hAacConfig->framelength != 480) { - return AACENC_INVALID_CONFIG; - } + hAacConfig->audioObjectType = config->userAOT; + hAacConfig->channelMode = + GetCoreChannelMode(config->userChannelMode, hAacConfig->audioObjectType); + hAacConfig->nChannels = + FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)->nChannels; + hAacConfig->bitrateMode = (AACENC_BITRATE_MODE)config->userBitrateMode; + hAacConfig->bandWidth = config->userBandwidth; + hAacConfig->useRequant = config->userAfterburner; + + hAacConfig->anc_Rate = config->userAncDataRate; + hAacConfig->syntaxFlags = 0; + hAacConfig->epConfig = -1; + + if (hAacConfig->audioObjectType != AOT_ER_AAC_ELD && + config->userDownscaleFactor > 1) { + return AACENC_INVALID_CONFIG; /* downscaling only allowed for AOT_ER_AAC_ELD + */ + } + if (config->userDownscaleFactor > 1 && config->userSbrEnabled == 1) { + return AACENC_INVALID_CONFIG; /* downscaling only allowed for AOT_ER_AAC_ELD + w/o SBR */ + } + if (config->userDownscaleFactor > 1 && config->userChannelMode == 128) { + return AACENC_INVALID_CONFIG; /* disallow downscaling for AAC-ELDv2 */ + } + + if (config->userTpType == TT_MP4_LATM_MCP1 || + config->userTpType == TT_MP4_LATM_MCP0 || + config->userTpType == TT_MP4_LOAS) { + hAacConfig->audioMuxVersion = config->userTpAmxv; + } else { + hAacConfig->audioMuxVersion = -1; + } + + /* Adapt internal AOT when necessary. */ + switch (config->userAOT) { + case AOT_MP2_AAC_LC: + case AOT_MP2_SBR: + hAacConfig->usePns = 0; + case AOT_AAC_LC: + case AOT_SBR: + case AOT_PS: + config->userTpType = + (config->userTpType != TT_UNKNOWN) ? config->userTpType : TT_MP4_ADTS; + hAacConfig->framelength = (config->userFramelength != (UINT)-1) + ? config->userFramelength + : 1024; + if (hAacConfig->framelength != 1024 && hAacConfig->framelength != 960) { + return AACENC_INVALID_CONFIG; + } + break; + case AOT_ER_AAC_LD: + hAacConfig->epConfig = 0; + hAacConfig->syntaxFlags |= AC_ER | AC_LD; + hAacConfig->syntaxFlags |= + ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0); + hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0); + hAacConfig->syntaxFlags |= ((config->userErTools & 0x4) ? AC_ER_RVLC : 0); + config->userTpType = + (config->userTpType != TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS; + hAacConfig->framelength = + (config->userFramelength != (UINT)-1) ? config->userFramelength : 512; + if (hAacConfig->framelength != 512 && hAacConfig->framelength != 480) { + return AACENC_INVALID_CONFIG; + } + break; + case AOT_ER_AAC_ELD: + hAacConfig->epConfig = 0; + hAacConfig->syntaxFlags |= AC_ER | AC_ELD; + hAacConfig->syntaxFlags |= + ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0); + hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0); + hAacConfig->syntaxFlags |= ((config->userErTools & 0x4) ? AC_ER_RVLC : 0); + hAacConfig->syntaxFlags |= + ((config->userSbrEnabled == 1) ? AC_SBR_PRESENT : 0); + hAacConfig->syntaxFlags |= + ((config->userChannelMode == MODE_212) ? AC_LD_MPS : 0); + config->userTpType = + (config->userTpType != TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS; + hAacConfig->framelength = + (config->userFramelength != (UINT)-1) ? config->userFramelength : 512; + + hAacConfig->downscaleFactor = config->userDownscaleFactor; + + switch (config->userDownscaleFactor) { + case 1: break; - default: + case 2: + case 4: + hAacConfig->syntaxFlags |= AC_ELD_DOWNSCALE; break; - } - - switch ( hAacConfig->audioObjectType ) { - case AOT_ER_AAC_LD: - case AOT_ER_AAC_ELD: - if (config->userBitrateMode==0) { - /* bitreservoir = (maxBitRes-minBitRes)/(maxBitRate-minBitrate)*(bitRate-minBitrate)+minBitRes; */ - if ( isLowDelay(hAacConfig->audioObjectType) ) { - INT bitreservoir; - INT brPerChannel = hAacConfig->bitRate/hAacConfig->nChannels; - brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel)); - FIXP_DBL slope = fDivNorm((brPerChannel-BITRATE_MIN_LD), BITRATE_MAX_LD-BITRATE_MIN_LD); /* calc slope for interpolation */ - bitreservoir = fMultI(slope, (INT)(BITRES_MAX_LD-BITRES_MIN_LD)) + BITRES_MIN_LD; /* interpolate */ - hAacConfig->bitreservoir = bitreservoir & ~7; /* align to bytes */ - } - } - if (hAacConfig->bitrateMode!=0) { + default: return AACENC_INVALID_CONFIG; - } - break; - default: - break; - } + } - hAacConfig->bitRate = config->userBitrate; + if (hAacConfig->framelength != 512 && hAacConfig->framelength != 480 && + hAacConfig->framelength != 256 && hAacConfig->framelength != 240 && + hAacConfig->framelength != 128 && hAacConfig->framelength != 120) { + return AACENC_INVALID_CONFIG; + } + break; + default: + break; + } - /* get bitrate in VBR configuration */ - if ( (hAacConfig->bitrateMode>=1) && (hAacConfig->bitrateMode<=5) ) { - /* In VBR mode; SBR-modul depends on bitrate, core encoder on bitrateMode. */ - hAacConfig->bitRate = FDKaacEnc_GetVBRBitrate(hAacConfig->bitrateMode, hAacConfig->channelMode); + /* Initialize SBR parameters */ + if ((config->userSbrRatio == 0) && (isSbrActive(hAacConfig))) { + /* Automatic SBR ratio configuration + * - downsampled SBR for ELD + * - otherwise always dualrate SBR + */ + if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) { + hAacConfig->sbrRatio = ((hAacConfig->syntaxFlags & AC_LD_MPS) && + (hAacConfig->sampleRate >= 27713)) + ? 2 + : 1; + } else { + hAacConfig->sbrRatio = 2; } + } else { + /* SBR ratio has been set by the user, so use it. */ + hAacConfig->sbrRatio = isSbrActive(hAacConfig) ? config->userSbrRatio : 0; + } + /* Set default bitrate */ + hAacConfig->bitRate = config->userBitrate; + switch (hAacConfig->bitrateMode) { + case AACENC_BR_MODE_CBR: + /* Set default bitrate if no external bitrate declared. */ + if (config->userBitrate == (UINT)-1) { + hAacConfig->bitRate = + FDKaacEnc_GetCBRBitrate(hAacConfig, config->userSbrRatio); + } + hAacConfig->averageBits = -1; + break; + case AACENC_BR_MODE_VBR_1: + case AACENC_BR_MODE_VBR_2: + case AACENC_BR_MODE_VBR_3: + case AACENC_BR_MODE_VBR_4: + case AACENC_BR_MODE_VBR_5: + /* Get bitrate in VBR configuration */ + /* In VBR mode; SBR-modul depends on bitrate, core encoder on bitrateMode. + */ + hAacConfig->bitRate = FDKaacEnc_GetVBRBitrate(hAacConfig->bitrateMode, + hAacConfig->channelMode); + break; + default: + return AACENC_INVALID_CONFIG; + } - /* Set default bitrate if no external bitrate declared. */ - if ( (hAacConfig->bitrateMode==0) && (config->userBitrate==(UINT)-1) ) { - INT bitrate = FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)->nChannelsEff * hAacConfig->sampleRate; - - if ( isPsActive(hAacConfig->audioObjectType) ) { - hAacConfig->bitRate = (bitrate>>1); /* 0.5 bit per sample */ - } - else if ( isSbrActive(hAacConfig) ) - { - if ( (config->userSbrRatio==2) || ((config->userSbrRatio==0)&&(hAacConfig->audioObjectType!=AOT_ER_AAC_ELD)) ) { - hAacConfig->bitRate = (bitrate + (bitrate>>2))>>1; /* 0.625 bits per sample */ - } - if ( (config->userSbrRatio==1) || ((config->userSbrRatio==0)&&(hAacConfig->audioObjectType==AOT_ER_AAC_ELD)) ) { - hAacConfig->bitRate = (bitrate + (bitrate>>3)); /* 1.125 bits per sample */ - } - } else - { - hAacConfig->bitRate = bitrate + (bitrate>>1); /* 1.5 bits per sample */ - } - } - - if ((hAacConfig->bitrateMode >= 0) && (hAacConfig->bitrateMode <= 5)) { + /* set bitreservoir size */ + switch (hAacConfig->bitrateMode) { + case AACENC_BR_MODE_VBR_1: + case AACENC_BR_MODE_VBR_2: + case AACENC_BR_MODE_VBR_3: + case AACENC_BR_MODE_VBR_4: + case AACENC_BR_MODE_VBR_5: + case AACENC_BR_MODE_CBR: if ((INT)config->userPeakBitrate != -1) { - hAacConfig->maxBitsPerFrame = (FDKaacEnc_CalcBitsPerFrame(fMax(hAacConfig->bitRate, (INT)config->userPeakBitrate), hAacConfig->framelength, hAacConfig->sampleRate) + 7)&~7; - } - else { + hAacConfig->maxBitsPerFrame = + (FDKaacEnc_CalcBitsPerFrame( + fMax(hAacConfig->bitRate, (INT)config->userPeakBitrate), + hAacConfig->framelength, hAacConfig->sampleRate) + + 7) & + ~7; + } else { hAacConfig->maxBitsPerFrame = -1; } - if (hAacConfig->audioMuxVersion==2) { - hAacConfig->minBitsPerFrame = fMin(32*8, FDKaacEnc_CalcBitsPerFrame(hAacConfig->bitRate, hAacConfig->framelength, hAacConfig->sampleRate))&~7; - } - } - - /* Initialize SBR parameters */ - if ( (hAacConfig->audioObjectType==AOT_ER_AAC_ELD) - && (config->userSbrEnabled == (UCHAR)-1) && (config->userSbrRatio==0) ) - { - UINT eldSbr = 0; - UINT eldSbrRatio = 0; - - if ( AACENC_OK!=(err=eldSbrConfigurator( - hAacConfig->sampleRate, - hAacConfig->channelMode, - hAacConfig->bitRate, - &eldSbr, - &eldSbrRatio)) ) - { - return err; + if (hAacConfig->audioMuxVersion == 2) { + hAacConfig->minBitsPerFrame = + fMin(32 * 8, FDKaacEnc_CalcBitsPerFrame(hAacConfig->bitRate, + hAacConfig->framelength, + hAacConfig->sampleRate)) & + ~7; } + break; + default: + return AACENC_INVALID_CONFIG; + } - hAacConfig->syntaxFlags |= ((eldSbr) ? AC_SBR_PRESENT : 0); - hAacConfig->sbrRatio = eldSbrRatio; - } - else - if ( (config->userSbrRatio==0) && (isSbrActive(hAacConfig)) ) { - /* Automatic SBR ratio configuration - * - downsampled SBR for ELD - * - otherwise always dualrate SBR - */ - hAacConfig->sbrRatio = (hAacConfig->audioObjectType==AOT_ER_AAC_ELD) ? 1 : 2; - } - else { - /* SBR ratio has been set by the user, so use it. */ - hAacConfig->sbrRatio = isSbrActive(hAacConfig) ? config->userSbrRatio : 0; + /* Max bits per frame limitation depending on transport format. */ + if ((config->userTpNsubFrames > 1)) { + int maxFrameLength = 8 * hAacEncoder->outBufferInBytes; + switch (config->userTpType) { + case TT_MP4_LOAS: + maxFrameLength = + fMin(maxFrameLength, 8 * (1 << 13)) / config->userTpNsubFrames; + break; + case TT_MP4_ADTS: + maxFrameLength = fMin(maxFrameLength, 8 * ((1 << 13) - 1)) / + config->userTpNsubFrames; + break; + default: + maxFrameLength = -1; } - - { - UCHAR tpSignaling=getSbrSignalingMode(hAacConfig->audioObjectType, config->userTpType, config->userTpSignaling, hAacConfig->sbrRatio); - - if ( (hAacConfig->audioObjectType==AOT_AAC_LC || hAacConfig->audioObjectType==AOT_SBR || hAacConfig->audioObjectType==AOT_PS) && - (config->userTpType==TT_MP4_LATM_MCP1 || config->userTpType==TT_MP4_LATM_MCP0 || config->userTpType==TT_MP4_LOAS) && - (tpSignaling==1) && (config->userTpAmxv==0) ) { - /* For backward compatible explicit signaling, AMV1 has to be active */ - return AACENC_INVALID_CONFIG; + if (maxFrameLength != -1) { + if (hAacConfig->maxBitsPerFrame > maxFrameLength) { + return AACENC_INVALID_CONFIG; + } else if (hAacConfig->maxBitsPerFrame == -1) { + hAacConfig->maxBitsPerFrame = maxFrameLength; } + } + } - if ( (hAacConfig->audioObjectType==AOT_AAC_LC || hAacConfig->audioObjectType==AOT_SBR || hAacConfig->audioObjectType==AOT_PS) && - (tpSignaling==0) && (hAacConfig->sbrRatio==1)) { - /* Downsampled SBR has to be signaled explicitely (for transmission of SBR sampling fequency) */ - return AACENC_INVALID_CONFIG; - } + if ((hAacConfig->audioObjectType == AOT_ER_AAC_ELD) && + !(hAacConfig->syntaxFlags & AC_ELD_DOWNSCALE) && + (config->userSbrEnabled == (UCHAR)-1) && (config->userSbrRatio == 0) && + ((hAacConfig->syntaxFlags & AC_LD_MPS) == 0)) { + const ELD_SBR_CONFIGURATOR *pConfig = NULL; + + if (NULL != + (pConfig = eldSbrConfigurator( + FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode) + ->nChannels, + hAacConfig->sampleRate, hAacConfig->bitRate))) { + hAacConfig->syntaxFlags |= (pConfig->sbrMode == 0) ? 0 : AC_SBR_PRESENT; + hAacConfig->syntaxFlags |= (pConfig->chMode == MODE_212) ? AC_LD_MPS : 0; + hAacConfig->channelMode = + GetCoreChannelMode(pConfig->chMode, hAacConfig->audioObjectType); + hAacConfig->nChannels = + FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode) + ->nChannels; + hAacConfig->sbrRatio = + (pConfig->sbrMode == 0) ? 0 : (pConfig->sbrMode == 1) ? 1 : 2; } + } + { + UCHAR tpSignaling = + getSbrSignalingMode(hAacConfig->audioObjectType, config->userTpType, + config->userTpSignaling, hAacConfig->sbrRatio); + + if ((hAacConfig->audioObjectType == AOT_AAC_LC || + hAacConfig->audioObjectType == AOT_SBR || + hAacConfig->audioObjectType == AOT_PS) && + (config->userTpType == TT_MP4_LATM_MCP1 || + config->userTpType == TT_MP4_LATM_MCP0 || + config->userTpType == TT_MP4_LOAS) && + (tpSignaling == 1) && (config->userTpAmxv == 0)) { + /* For backward compatible explicit signaling, AMV1 has to be active */ + return AACENC_INVALID_CONFIG; + } + + if ((hAacConfig->audioObjectType == AOT_AAC_LC || + hAacConfig->audioObjectType == AOT_SBR || + hAacConfig->audioObjectType == AOT_PS) && + (tpSignaling == 0) && (hAacConfig->sbrRatio == 1)) { + /* Downsampled SBR has to be signaled explicitely (for transmission of SBR + * sampling fequency) */ + return AACENC_INVALID_CONFIG; + } + } + switch (hAacConfig->bitrateMode) { + case AACENC_BR_MODE_CBR: + case AACENC_BR_MODE_VBR_1: + case AACENC_BR_MODE_VBR_2: + case AACENC_BR_MODE_VBR_3: + case AACENC_BR_MODE_VBR_4: + case AACENC_BR_MODE_VBR_5: + /* We need the frame length to call aacEncoder_LimitBitrate() */ + if (0 >= (hAacConfig->bitRate = aacEncoder_LimitBitrate( + NULL, hAacConfig->sampleRate, hAacConfig->framelength, + hAacConfig->nChannels, hAacConfig->channelMode, + hAacConfig->bitRate, hAacConfig->nSubFrames, + isSbrActive(hAacConfig), hAacConfig->sbrRatio, + hAacConfig->syntaxFlags, hAacConfig->audioObjectType))) { + return AACENC_INVALID_CONFIG; + } + break; + default: + break; + } - /* We need the frame length to call aacEncoder_LimitBitrate() */ - hAacConfig->bitRate = aacEncoder_LimitBitrate( - NULL, - hAacConfig->sampleRate, - hAacConfig->framelength, - hAacConfig->nChannels, - hAacConfig->channelMode, - hAacConfig->bitRate, - hAacConfig->nSubFrames, - isSbrActive(hAacConfig), - hAacConfig->sbrRatio, - hAacConfig->audioObjectType - ); - - /* Configure PNS */ - if ( ((hAacConfig->bitrateMode>=1) && (hAacConfig->bitrateMode<=5)) /* VBR without PNS. */ - || (hAacConfig->useTns == 0) ) /* TNS required. */ - { - hAacConfig->usePns = 0; - } + /* Configure PNS */ + if (AACENC_BR_MODE_IS_VBR(hAacConfig->bitrateMode) /* VBR without PNS. */ + || (hAacConfig->useTns == 0)) /* TNS required. */ + { + hAacConfig->usePns = 0; + } - if (hAacConfig->epConfig >= 0) { - hAacConfig->syntaxFlags |= AC_ER; - if (((INT)hAacConfig->channelMode < 1) || ((INT)hAacConfig->channelMode > 7)) { - return AACENC_INVALID_CONFIG; /* Cannel config 0 not supported. */ - } + if (hAacConfig->epConfig >= 0) { + hAacConfig->syntaxFlags |= AC_ER; + if (((INT)hAacConfig->channelMode < 1) || + ((INT)hAacConfig->channelMode > 14)) { + return AACENC_INVALID_CONFIG; /* Channel config 0 not supported. */ } + } - if ( FDKaacEnc_DetermineEncoderMode(&hAacConfig->channelMode, hAacConfig->nChannels) != AAC_ENC_OK) { - return AACENC_INVALID_CONFIG; /* nChannels doesn't match chMode, this is just a check-up */ + if ((hAacConfig->syntaxFlags & AC_LD_MPS) == 0) { + if (FDKaacEnc_DetermineEncoderMode(&hAacConfig->channelMode, + hAacConfig->nChannels) != AAC_ENC_OK) { + return AACENC_INVALID_CONFIG; /* nChannels doesn't match chMode, this is + just a check-up */ } + } - if ( (hAacConfig->nChannels > hAacEncoder->nMaxAacChannels) - || ( (FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)->nChannelsEff > hAacEncoder->nMaxSbrChannels) && - isSbrActive(hAacConfig) ) - ) - { - return AACENC_INVALID_CONFIG; /* not enough channels allocated */ - } + if ((hAacConfig->nChannels > hAacEncoder->nMaxAacChannels) || + ((FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode) + ->nChannelsEff > hAacEncoder->nMaxSbrChannels) && + isSbrActive(hAacConfig))) { + return AACENC_INVALID_CONFIG; /* not enough channels allocated */ + } - /* Meta data restriction. */ - switch (hAacConfig->audioObjectType) - { - /* Allow metadata support */ - case AOT_AAC_LC: - case AOT_SBR: - case AOT_PS: - hAacEncoder->metaDataAllowed = 1; - if (((INT)hAacConfig->channelMode < 1) || ((INT)hAacConfig->channelMode > 7)) { - config->userMetaDataMode = 0; - } - break; - /* Prohibit metadata support */ - default: - hAacEncoder->metaDataAllowed = 0; - } + /* Meta data restriction. */ + switch (hAacConfig->audioObjectType) { + /* Allow metadata support */ + case AOT_AAC_LC: + case AOT_SBR: + case AOT_PS: + case AOT_MP2_AAC_LC: + case AOT_MP2_SBR: + hAacEncoder->metaDataAllowed = 1; + if (!((((INT)hAacConfig->channelMode >= 1) && + ((INT)hAacConfig->channelMode <= 14)) || + (MODE_7_1_REAR_SURROUND == hAacConfig->channelMode) || + (MODE_7_1_FRONT_CENTER == hAacConfig->channelMode))) { + config->userMetaDataMode = 0; + } + break; + /* Prohibit metadata support */ + default: + hAacEncoder->metaDataAllowed = 0; + } - return err; + return err; } -static -INT aacenc_SbrCallback( - void * self, - HANDLE_FDK_BITSTREAM hBs, - const INT sampleRateIn, - const INT sampleRateOut, - const INT samplesPerFrame, - const AUDIO_OBJECT_TYPE coreCodec, - const MP4_ELEMENT_ID elementID, - const INT elementIndex - ) -{ +static INT aacenc_SbrCallback(void *self, HANDLE_FDK_BITSTREAM hBs, + const INT sampleRateIn, const INT sampleRateOut, + const INT samplesPerFrame, + const AUDIO_OBJECT_TYPE coreCodec, + const MP4_ELEMENT_ID elementID, + const INT elementIndex, const UCHAR harmonicSbr, + const UCHAR stereoConfigIndex, + const UCHAR configMode, UCHAR *configChanged, + const INT downscaleFactor) { HANDLE_AACENCODER hAacEncoder = (HANDLE_AACENCODER)self; sbrEncoder_GetHeader(hAacEncoder->hEnvEnc, hBs, elementIndex, 0); @@ -1006,725 +1213,835 @@ INT aacenc_SbrCallback( return 0; } -static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, - ULONG InitFlags, - USER_PARAM *config) -{ - AACENC_ERROR err = AACENC_OK; +INT aacenc_SscCallback(void *self, HANDLE_FDK_BITSTREAM hBs, + const AUDIO_OBJECT_TYPE coreCodec, + const INT samplingRate, const INT stereoConfigIndex, + const INT coreSbrFrameLengthIndex, const INT configBytes, + const UCHAR configMode, UCHAR *configChanged) { + HANDLE_AACENCODER hAacEncoder = (HANDLE_AACENCODER)self; - INT aacBufferOffset = 0; - HANDLE_SBR_ENCODER *hSbrEncoder = &hAacEncoder->hEnvEnc; - HANDLE_AACENC_CONFIG hAacConfig = &hAacEncoder->aacConfig; + return (FDK_MpegsEnc_WriteSpatialSpecificConfig(hAacEncoder->hMpsEnc, hBs)); +} - hAacEncoder->nZerosAppended = 0; /* count appended zeros */ +static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, ULONG InitFlags, + USER_PARAM *config) { + AACENC_ERROR err = AACENC_OK; - INT frameLength = hAacConfig->framelength; + INT aacBufferOffset = 0; + HANDLE_SBR_ENCODER *hSbrEncoder = &hAacEncoder->hEnvEnc; + HANDLE_AACENC_CONFIG hAacConfig = &hAacEncoder->aacConfig; - if ( (InitFlags & AACENC_INIT_CONFIG) ) - { - CHANNEL_MODE prevChMode = hAacConfig->channelMode; + hAacEncoder->nZerosAppended = 0; /* count appended zeros */ - /* Verify settings and update: config -> heAacEncoder */ - if ( (err=FDKaacEnc_AdjustEncSettings(hAacEncoder, config)) != AACENC_OK ) { - return err; - } - frameLength = hAacConfig->framelength; /* adapt temporal framelength */ + INT frameLength = hAacConfig->framelength; - /* Seamless channel reconfiguration in sbr not fully implemented */ - if ( (prevChMode!=hAacConfig->channelMode) && isSbrActive(hAacConfig) ) { - InitFlags |= AACENC_INIT_STATES; - } - } + if ((InitFlags & AACENC_INIT_CONFIG)) { + CHANNEL_MODE prevChMode = hAacConfig->channelMode; - /* Clear input buffer */ - if ( InitFlags == AACENC_INIT_ALL ) { - FDKmemclear(hAacEncoder->inputBuffer, sizeof(INT_PCM)*hAacEncoder->nMaxAacChannels*INPUTBUFFER_SIZE); + /* Verify settings and update: config -> heAacEncoder */ + if ((err = FDKaacEnc_AdjustEncSettings(hAacEncoder, config)) != AACENC_OK) { + return err; } + frameLength = hAacConfig->framelength; /* adapt temporal framelength */ - if ( (InitFlags & AACENC_INIT_CONFIG) ) - { - aacBufferOffset = 0; - if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) { - hAacEncoder->nDelay = DELAY_AACELD(hAacConfig->framelength); - } else - { - hAacEncoder->nDelay = DELAY_AAC(hAacConfig->framelength); /* AAC encoder delay */ - } - hAacConfig->ancDataBitRate = 0; + /* Seamless channel reconfiguration in sbr not fully implemented */ + if ((prevChMode != hAacConfig->channelMode) && isSbrActive(hAacConfig)) { + InitFlags |= AACENC_INIT_STATES; } + } - if ( isSbrActive(hAacConfig) && - ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES)) ) - { - INT sbrError; - SBR_ELEMENT_INFO sbrElInfo[(8)]; - CHANNEL_MAPPING channelMapping; - - if ( FDKaacEnc_InitChannelMapping(hAacConfig->channelMode, - hAacConfig->channelOrder, - &channelMapping) != AAC_ENC_OK ) - { - return AACENC_INIT_ERROR; - } + /* Clear input buffer */ + if (InitFlags == AACENC_INIT_ALL) { + FDKmemclear(hAacEncoder->inputBuffer, + sizeof(INT_PCM) * hAacEncoder->inputBufferSize); + } - /* Check return value and if the SBR encoder can handle enough elements */ - if (channelMapping.nElements > (8)) { - return AACENC_INIT_ERROR; - } + if ((InitFlags & AACENC_INIT_CONFIG)) { + aacBufferOffset = 0; + switch (hAacConfig->audioObjectType) { + case AOT_ER_AAC_LD: + hAacEncoder->nDelay = DELAY_AACLD(hAacConfig->framelength); + break; + case AOT_ER_AAC_ELD: + hAacEncoder->nDelay = DELAY_AACELD(hAacConfig->framelength); + break; + default: + hAacEncoder->nDelay = + DELAY_AAC(hAacConfig->framelength); /* AAC encoder delay */ + } - aacEncDistributeSbrBits(&channelMapping, sbrElInfo, hAacConfig->bitRate); - - UINT initFlag = 0; - initFlag += (InitFlags & AACENC_INIT_STATES) ? 1 : 0; - - /* Let the SBR encoder take a look at the configuration and change if required. */ - sbrError = sbrEncoder_Init( - *hSbrEncoder, - sbrElInfo, - channelMapping.nElements, - hAacEncoder->inputBuffer, - &hAacConfig->bandWidth, - &aacBufferOffset, - &hAacConfig->nChannels, - &hAacConfig->sampleRate, - &hAacConfig->sbrRatio, - &frameLength, - hAacConfig->audioObjectType, - &hAacEncoder->nDelay, - (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) ? 1 : TRANS_FAC, - (config->userTpHeaderPeriod!=0xFF) ? config->userTpHeaderPeriod : DEFAULT_HEADER_PERIOD_REPETITION_RATE, - initFlag - ); - - /* Suppress AOT reconfiguration and check error status. */ - if (sbrError) { - return AACENC_INIT_SBR_ERROR; - } + hAacConfig->ancDataBitRate = 0; + } - if (hAacConfig->nChannels == 1) { - hAacConfig->channelMode = MODE_1; - } + if ((NULL != hAacEncoder->hEnvEnc) && isSbrActive(hAacConfig) && + ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES))) { + INT sbrError; + UINT initFlag = 0; + SBR_ELEMENT_INFO sbrElInfo[(8)]; + CHANNEL_MAPPING channelMapping; + CHANNEL_MODE channelMode = isPsActive(hAacConfig->audioObjectType) + ? config->userChannelMode + : hAacConfig->channelMode; + INT numChannels = isPsActive(hAacConfig->audioObjectType) + ? config->nChannels + : hAacConfig->nChannels; - /* Never use PNS if SBR is active */ - if ( hAacConfig->usePns ) { - hAacConfig->usePns = 0; - } + if (FDKaacEnc_InitChannelMapping(channelMode, hAacConfig->channelOrder, + &channelMapping) != AAC_ENC_OK) { + return AACENC_INIT_ERROR; + } - /* estimated bitrate consumed by SBR or PS */ - hAacConfig->ancDataBitRate = sbrEncoder_GetEstimateBitrate(*hSbrEncoder) ; + /* Check return value and if the SBR encoder can handle enough elements */ + if (channelMapping.nElements > (8)) { + return AACENC_INIT_ERROR; + } - } /* sbr initialization */ + aacEncDistributeSbrBits(&channelMapping, sbrElInfo, hAacConfig->bitRate); + initFlag += (InitFlags & AACENC_INIT_STATES) ? 1 : 0; - /* - * Initialize Transport - Module. - */ - if ( (InitFlags & AACENC_INIT_TRANSPORT) ) - { - UINT flags = 0; - - FDKaacEnc_MapConfig( - &hAacEncoder->coderConfig, - config, - getSbrSignalingMode(hAacConfig->audioObjectType, config->userTpType, config->userTpSignaling, hAacConfig->sbrRatio), - hAacConfig); - - /* create flags for transport encoder */ - if (config->userTpAmxv != 0) { - flags |= TP_FLAG_LATM_AMV; - } - /* Clear output buffer */ - FDKmemclear(hAacEncoder->outBuffer, hAacEncoder->outBufferInBytes*sizeof(UCHAR)); + /* Let the SBR encoder take a look at the configuration and change if + * required. */ + sbrError = sbrEncoder_Init( + *hSbrEncoder, sbrElInfo, channelMapping.nElements, + hAacEncoder->inputBuffer, hAacEncoder->inputBufferSizePerChannel, + &hAacConfig->bandWidth, &aacBufferOffset, &numChannels, + hAacConfig->syntaxFlags, &hAacConfig->sampleRate, &hAacConfig->sbrRatio, + &frameLength, hAacConfig->audioObjectType, &hAacEncoder->nDelay, + (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) ? 1 : TRANS_FAC, + (config->userTpHeaderPeriod != 0xFF) + ? config->userTpHeaderPeriod + : DEFAULT_HEADER_PERIOD_REPETITION_RATE, + initFlag); - /* Initialize Bitstream encoder */ - if ( transportEnc_Init(hAacEncoder->hTpEnc, hAacEncoder->outBuffer, hAacEncoder->outBufferInBytes, config->userTpType, &hAacEncoder->coderConfig, flags) != 0) { - return AACENC_INIT_TP_ERROR; - } + /* Suppress AOT reconfiguration and check error status. */ + if ((sbrError) || (numChannels != hAacConfig->nChannels)) { + return AACENC_INIT_SBR_ERROR; + } - } /* transport initialization */ + if (numChannels == 1) { + hAacConfig->channelMode = MODE_1; + } - /* - * Initialize AAC - Core. - */ - if ( (InitFlags & AACENC_INIT_CONFIG) || - (InitFlags & AACENC_INIT_STATES) ) - { - AAC_ENCODER_ERROR err; - err = FDKaacEnc_Initialize(hAacEncoder->hAacEnc, - hAacConfig, - hAacEncoder->hTpEnc, - (InitFlags & AACENC_INIT_STATES) ? 1 : 0); - - if (err != AAC_ENC_OK) { - return AACENC_INIT_AAC_ERROR; - } + /* Never use PNS if SBR is active */ + if (hAacConfig->usePns) { + hAacConfig->usePns = 0; + } - } /* aac initialization */ + /* estimated bitrate consumed by SBR or PS */ + hAacConfig->ancDataBitRate = sbrEncoder_GetEstimateBitrate(*hSbrEncoder); - /* - * Initialize Meta Data - Encoder. - */ - if ( hAacEncoder->hMetadataEnc && (hAacEncoder->metaDataAllowed!=0) && - ((InitFlags & AACENC_INIT_CONFIG) ||(InitFlags & AACENC_INIT_STATES)) ) - { - INT inputDataDelay = DELAY_AAC(hAacConfig->framelength); + } /* sbr initialization */ - if ( isSbrActive(hAacConfig) && hSbrEncoder!=NULL) { - inputDataDelay = hAacConfig->sbrRatio*inputDataDelay + sbrEncoder_GetInputDataDelay(*hSbrEncoder); - } + if ((hAacEncoder->hMpsEnc != NULL) && (hAacConfig->syntaxFlags & AC_LD_MPS)) { + int coreCoderDelay = DELAY_AACELD(hAacConfig->framelength); - if ( FDK_MetadataEnc_Init(hAacEncoder->hMetadataEnc, - ((InitFlags&AACENC_INIT_STATES) ? 1 : 0), - config->userMetaDataMode, - inputDataDelay, - frameLength, - config->userSamplerate, - config->nChannels, - config->userChannelMode, - hAacConfig->channelOrder) != 0) - { - return AACENC_INIT_META_ERROR; - } + if (isSbrActive(hAacConfig)) { + coreCoderDelay = hAacConfig->sbrRatio * coreCoderDelay + + sbrEncoder_GetInputDataDelay(*hSbrEncoder); + } - hAacEncoder->nDelay += FDK_MetadataEnc_GetDelay(hAacEncoder->hMetadataEnc); + if (MPS_ENCODER_OK != + FDK_MpegsEnc_Init(hAacEncoder->hMpsEnc, hAacConfig->audioObjectType, + config->userSamplerate, hAacConfig->bitRate, + isSbrActive(hAacConfig) ? hAacConfig->sbrRatio : 0, + frameLength, /* for dual rate sbr this value is + already multiplied by 2 */ + hAacEncoder->inputBufferSizePerChannel, + coreCoderDelay)) { + return AACENC_INIT_MPS_ERROR; } + } + hAacEncoder->nDelay = + fMax(FDK_MpegsEnc_GetDelay(hAacEncoder->hMpsEnc), hAacEncoder->nDelay); - /* - * Update pointer to working buffer. - */ - if ( (InitFlags & AACENC_INIT_CONFIG) ) - { - hAacEncoder->inputBufferOffset = aacBufferOffset; + /* + * Initialize Transport - Module. + */ + if ((InitFlags & AACENC_INIT_TRANSPORT)) { + UINT flags = 0; - hAacEncoder->nSamplesToRead = frameLength * config->nChannels; + FDKaacEnc_MapConfig( + &hAacEncoder->coderConfig, config, + getSbrSignalingMode(hAacConfig->audioObjectType, config->userTpType, + config->userTpSignaling, hAacConfig->sbrRatio), + hAacConfig); - /* Make nDelay comparison compatible with config->nSamplesRead */ - hAacEncoder->nDelay *= config->nChannels; + /* create flags for transport encoder */ + if (config->userTpAmxv != 0) { + flags |= TP_FLAG_LATM_AMV; + } + /* Clear output buffer */ + FDKmemclear(hAacEncoder->outBuffer, + hAacEncoder->outBufferInBytes * sizeof(UCHAR)); - } /* parameter changed */ + /* Initialize Bitstream encoder */ + if (transportEnc_Init(hAacEncoder->hTpEnc, hAacEncoder->outBuffer, + hAacEncoder->outBufferInBytes, config->userTpType, + &hAacEncoder->coderConfig, flags) != 0) { + return AACENC_INIT_TP_ERROR; + } - return AACENC_OK; -} + } /* transport initialization */ + /* + * Initialize AAC - Core. + */ + if ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES)) { + if (FDKaacEnc_Initialize( + hAacEncoder->hAacEnc, hAacConfig, hAacEncoder->hTpEnc, + (InitFlags & AACENC_INIT_STATES) ? 1 : 0) != AAC_ENC_OK) { + return AACENC_INIT_AAC_ERROR; + } -AACENC_ERROR aacEncOpen( - HANDLE_AACENCODER *phAacEncoder, - const UINT encModules, - const UINT maxChannels - ) -{ - AACENC_ERROR err = AACENC_OK; - HANDLE_AACENCODER hAacEncoder = NULL; + } /* aac initialization */ - if (phAacEncoder == NULL) { - err = AACENC_INVALID_HANDLE; - goto bail; - } + /* + * Initialize Meta Data - Encoder. + */ + if (hAacEncoder->hMetadataEnc && (hAacEncoder->metaDataAllowed != 0) && + ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES))) { + INT inputDataDelay = DELAY_AAC(hAacConfig->framelength); - /* allocate memory */ - hAacEncoder = Get_AacEncoder(); + if (isSbrActive(hAacConfig) && hSbrEncoder != NULL) { + inputDataDelay = hAacConfig->sbrRatio * inputDataDelay + + sbrEncoder_GetInputDataDelay(*hSbrEncoder); + } - if (hAacEncoder == NULL) { - err = AACENC_MEMORY_ERROR; - goto bail; + if (FDK_MetadataEnc_Init(hAacEncoder->hMetadataEnc, + ((InitFlags & AACENC_INIT_STATES) ? 1 : 0), + config->userMetaDataMode, inputDataDelay, + frameLength, config->userSamplerate, + config->nChannels, config->userChannelMode, + hAacConfig->channelOrder) != 0) { + return AACENC_INIT_META_ERROR; } - FDKmemclear(hAacEncoder, sizeof(AACENCODER)); + hAacEncoder->nDelay += FDK_MetadataEnc_GetDelay(hAacEncoder->hMetadataEnc); + } - /* Specify encoder modules to be allocated. */ - if (encModules==0) { - hAacEncoder->encoder_modis = ENC_MODE_FLAG_AAC; - hAacEncoder->encoder_modis |= ENC_MODE_FLAG_SBR; - hAacEncoder->encoder_modis |= ENC_MODE_FLAG_PS; - hAacEncoder->encoder_modis |= ENC_MODE_FLAG_META; - } - else { - /* consider SAC and PS module */ - hAacEncoder->encoder_modis = encModules; - } + /* Get custom delay, i.e. the codec delay w/o the decoder's SBR- or MPS delay + */ + if ((hAacEncoder->hMpsEnc != NULL) && (hAacConfig->syntaxFlags & AC_LD_MPS)) { + hAacEncoder->nDelayCore = + hAacEncoder->nDelay - + fMax(0, FDK_MpegsEnc_GetDecDelay(hAacEncoder->hMpsEnc)); + } else if (isSbrActive(hAacConfig) && hSbrEncoder != NULL) { + hAacEncoder->nDelayCore = + hAacEncoder->nDelay - + fMax(0, sbrEncoder_GetSbrDecDelay(hAacEncoder->hEnvEnc)); + } else { + hAacEncoder->nDelayCore = hAacEncoder->nDelay; + } - /* Determine max channel configuration. */ - if (maxChannels==0) { - hAacEncoder->nMaxAacChannels = (8); - hAacEncoder->nMaxSbrChannels = (8); - } - else { - hAacEncoder->nMaxAacChannels = (maxChannels&0x00FF); - if ( (hAacEncoder->encoder_modis&ENC_MODE_FLAG_SBR) ) { - hAacEncoder->nMaxSbrChannels = (maxChannels&0xFF00) ? (maxChannels>>8) : hAacEncoder->nMaxAacChannels; - } + /* + * Update pointer to working buffer. + */ + if ((InitFlags & AACENC_INIT_CONFIG)) { + hAacEncoder->inputBufferOffset = aacBufferOffset; - if ( (hAacEncoder->nMaxAacChannels>(8)) || (hAacEncoder->nMaxSbrChannels>(8)) ) { - err = AACENC_INVALID_CONFIG; - goto bail; - } - } /* maxChannels==0 */ + hAacEncoder->nSamplesToRead = frameLength * config->nChannels; - /* Max number of elements could be tuned any more. */ - hAacEncoder->nMaxAacElements = fixMin((8), hAacEncoder->nMaxAacChannels); - hAacEncoder->nMaxSbrElements = fixMin((8), hAacEncoder->nMaxSbrChannels); - hAacEncoder->nMaxSubFrames = (1); + } /* parameter changed */ + return AACENC_OK; +} - /* In case of memory overlay, allocate memory out of libraries */ +AACENC_ERROR aacEncOpen(HANDLE_AACENCODER *phAacEncoder, const UINT encModules, + const UINT maxChannels) { + AACENC_ERROR err = AACENC_OK; + HANDLE_AACENCODER hAacEncoder = NULL; - hAacEncoder->inputBuffer = (INT_PCM*)FDKcalloc(hAacEncoder->nMaxAacChannels*INPUTBUFFER_SIZE, sizeof(INT_PCM)); + if (phAacEncoder == NULL) { + err = AACENC_INVALID_HANDLE; + goto bail; + } - /* Open SBR Encoder */ - if (hAacEncoder->encoder_modis&ENC_MODE_FLAG_SBR) { - if ( sbrEncoder_Open(&hAacEncoder->hEnvEnc, - hAacEncoder->nMaxSbrElements, - hAacEncoder->nMaxSbrChannels, - (hAacEncoder->encoder_modis&ENC_MODE_FLAG_PS) ? 1 : 0 ) ) - { - err = AACENC_MEMORY_ERROR; - goto bail; - } - } /* (encoder_modis&ENC_MODE_FLAG_SBR) */ + /* allocate memory */ + hAacEncoder = Get_AacEncoder(); + + if (hAacEncoder == NULL) { + err = AACENC_MEMORY_ERROR; + goto bail; + } + FDKmemclear(hAacEncoder, sizeof(AACENCODER)); - /* Open Aac Encoder */ - if ( FDKaacEnc_Open(&hAacEncoder->hAacEnc, - hAacEncoder->nMaxAacElements, - hAacEncoder->nMaxAacChannels, - (1)) != AAC_ENC_OK ) - { - err = AACENC_MEMORY_ERROR; - goto bail; - } + /* Specify encoder modules to be allocated. */ + if (encModules == 0) { + C_ALLOC_SCRATCH_START(_pLibInfo, LIB_INFO, FDK_MODULE_LAST) + LIB_INFO(*pLibInfo) + [FDK_MODULE_LAST] = (LIB_INFO(*)[FDK_MODULE_LAST])_pLibInfo; + FDKinitLibInfo(*pLibInfo); + aacEncGetLibInfo(*pLibInfo); - { /* Get bitstream outputbuffer size */ - UINT ld_M; - for (ld_M=1; (UINT)(1<nMaxSubFrames*hAacEncoder->nMaxAacChannels*6144)>>3; ld_M++) ; - hAacEncoder->outBufferInBytes = (1<encoder_modis = ENC_MODE_FLAG_AAC; + if (FDKlibInfo_getCapabilities(*pLibInfo, FDK_SBRENC) & CAPF_SBR_HQ) { + hAacEncoder->encoder_modis |= ENC_MODE_FLAG_SBR; } - hAacEncoder->outBuffer = GetRam_bsOutbuffer(); - if (OUTPUTBUFFER_SIZE < hAacEncoder->outBufferInBytes ) { - err = AACENC_MEMORY_ERROR; - goto bail; + if (FDKlibInfo_getCapabilities(*pLibInfo, FDK_SBRENC) & CAPF_SBR_PS_MPEG) { + hAacEncoder->encoder_modis |= ENC_MODE_FLAG_PS; } - - /* Open Meta Data Encoder */ - if (hAacEncoder->encoder_modis&ENC_MODE_FLAG_META) { - if ( FDK_MetadataEnc_Open(&hAacEncoder->hMetadataEnc) ) - { - err = AACENC_MEMORY_ERROR; - goto bail; - } - } /* (encoder_modis&ENC_MODE_FLAG_META) */ - - /* Open Transport Encoder */ - if ( transportEnc_Open(&hAacEncoder->hTpEnc) != 0 ) - { - err = AACENC_MEMORY_ERROR; - goto bail; + if (FDKlibInfo_getCapabilities(*pLibInfo, FDK_AACENC) & CAPF_AAC_DRC) { + hAacEncoder->encoder_modis |= ENC_MODE_FLAG_META; } - else { - C_ALLOC_SCRATCH_START(pLibInfo, LIB_INFO, FDK_MODULE_LAST); - - FDKinitLibInfo( pLibInfo); - transportEnc_GetLibInfo( pLibInfo ); + hAacEncoder->encoder_modis |= ENC_MODE_FLAG_SAC; - /* Get capabilty flag for transport encoder. */ - hAacEncoder->CAPF_tpEnc = FDKlibInfo_getCapabilities( pLibInfo, FDK_TPENC); + C_ALLOC_SCRATCH_END(_pLibInfo, LIB_INFO, FDK_MODULE_LAST) + } else { + hAacEncoder->encoder_modis = encModules; + } - C_ALLOC_SCRATCH_END(pLibInfo, LIB_INFO, FDK_MODULE_LAST); + /* Determine max channel configuration. */ + if (maxChannels == 0) { + hAacEncoder->nMaxAacChannels = (8); + hAacEncoder->nMaxSbrChannels = (8); + } else { + hAacEncoder->nMaxAacChannels = (maxChannels & 0x00FF); + if ((hAacEncoder->encoder_modis & ENC_MODE_FLAG_SBR)) { + hAacEncoder->nMaxSbrChannels = (maxChannels & 0xFF00) + ? (maxChannels >> 8) + : hAacEncoder->nMaxAacChannels; } - if ( transportEnc_RegisterSbrCallback(hAacEncoder->hTpEnc, aacenc_SbrCallback, hAacEncoder) != 0 ) { - err = AACENC_INIT_TP_ERROR; + + if ((hAacEncoder->nMaxAacChannels > (8)) || + (hAacEncoder->nMaxSbrChannels > (8))) { + err = AACENC_INVALID_CONFIG; goto bail; } + } /* maxChannels==0 */ - /* Initialize encoder instance with default parameters. */ - aacEncDefaultConfig(&hAacEncoder->aacConfig, &hAacEncoder->extParam); + /* Max number of elements could be tuned any more. */ + hAacEncoder->nMaxAacElements = fixMin(((8)), hAacEncoder->nMaxAacChannels); + hAacEncoder->nMaxSbrElements = fixMin((8), hAacEncoder->nMaxSbrChannels); - /* Initialize headerPeriod in coderConfig for aacEncoder_GetParam(). */ - hAacEncoder->coderConfig.headerPeriod = hAacEncoder->extParam.userTpHeaderPeriod; + /* In case of memory overlay, allocate memory out of libraries */ - /* All encoder modules have to be initialized */ - hAacEncoder->InitFlags = AACENC_INIT_ALL; + if (hAacEncoder->encoder_modis & (ENC_MODE_FLAG_SBR | ENC_MODE_FLAG_PS)) + hAacEncoder->inputBufferSizePerChannel = INPUTBUFFER_SIZE; + else + hAacEncoder->inputBufferSizePerChannel = (1024); - /* Return encoder instance */ - *phAacEncoder = hAacEncoder; + hAacEncoder->inputBufferSize = + hAacEncoder->nMaxAacChannels * hAacEncoder->inputBufferSizePerChannel; - return err; + if (NULL == (hAacEncoder->inputBuffer = (INT_PCM *)FDKcalloc( + hAacEncoder->inputBufferSize, sizeof(INT_PCM)))) { + err = AACENC_MEMORY_ERROR; + goto bail; + } -bail: - aacEncClose(&hAacEncoder); + /* Open SBR Encoder */ + if (hAacEncoder->encoder_modis & ENC_MODE_FLAG_SBR) { + if (sbrEncoder_Open( + &hAacEncoder->hEnvEnc, hAacEncoder->nMaxSbrElements, + hAacEncoder->nMaxSbrChannels, + (hAacEncoder->encoder_modis & ENC_MODE_FLAG_PS) ? 1 : 0)) { + err = AACENC_MEMORY_ERROR; + goto bail; + } - return err; -} + if (NULL == (hAacEncoder->pSbrPayload = (SBRENC_EXT_PAYLOAD *)FDKcalloc( + 1, sizeof(SBRENC_EXT_PAYLOAD)))) { + err = AACENC_MEMORY_ERROR; + goto bail; + } + } /* (encoder_modis&ENC_MODE_FLAG_SBR) */ + /* Open Aac Encoder */ + if (FDKaacEnc_Open(&hAacEncoder->hAacEnc, hAacEncoder->nMaxAacElements, + hAacEncoder->nMaxAacChannels, (1)) != AAC_ENC_OK) { + err = AACENC_MEMORY_ERROR; + goto bail; + } + /* Bitstream output buffer */ + hAacEncoder->outBufferInBytes = + 1 << (DFRACT_BITS - CntLeadingZeros(fixMax( + 1, ((1) * hAacEncoder->nMaxAacChannels * 6144) >> + 3))); /* buffer has to be 2^n */ + if (NULL == (hAacEncoder->outBuffer = (UCHAR *)FDKcalloc( + hAacEncoder->outBufferInBytes, sizeof(UCHAR)))) { + err = AACENC_MEMORY_ERROR; + goto bail; + } -AACENC_ERROR aacEncClose(HANDLE_AACENCODER *phAacEncoder) -{ - AACENC_ERROR err = AACENC_OK; + /* Open Meta Data Encoder */ + if (hAacEncoder->encoder_modis & ENC_MODE_FLAG_META) { + if (FDK_MetadataEnc_Open(&hAacEncoder->hMetadataEnc, + (UINT)hAacEncoder->nMaxAacChannels)) { + err = AACENC_MEMORY_ERROR; + goto bail; + } + } /* (encoder_modis&ENC_MODE_FLAG_META) */ - if (phAacEncoder == NULL) { - err = AACENC_INVALID_HANDLE; - goto bail; + /* Open MPEG Surround Encoder */ + if (hAacEncoder->encoder_modis & ENC_MODE_FLAG_SAC) { + if (MPS_ENCODER_OK != FDK_MpegsEnc_Open(&hAacEncoder->hMpsEnc)) { + err = AACENC_MEMORY_ERROR; + goto bail; } + } /* (hAacEncoder->encoder_modis&ENC_MODE_FLAG_SAC) */ - if (*phAacEncoder != NULL) { - HANDLE_AACENCODER hAacEncoder = *phAacEncoder; + /* Open Transport Encoder */ + if (transportEnc_Open(&hAacEncoder->hTpEnc) != 0) { + err = AACENC_MEMORY_ERROR; + goto bail; + } else { + C_ALLOC_SCRATCH_START(_pLibInfo, LIB_INFO, FDK_MODULE_LAST) + LIB_INFO(*pLibInfo) + [FDK_MODULE_LAST] = (LIB_INFO(*)[FDK_MODULE_LAST])_pLibInfo; - if (hAacEncoder->inputBuffer!=NULL) { - FDKfree(hAacEncoder->inputBuffer); - hAacEncoder->inputBuffer = NULL; - } + FDKinitLibInfo(*pLibInfo); + transportEnc_GetLibInfo(*pLibInfo); - if (hAacEncoder->outBuffer) { - FreeRam_bsOutbuffer(&hAacEncoder->outBuffer); - } + /* Get capabilty flag for transport encoder. */ + hAacEncoder->CAPF_tpEnc = FDKlibInfo_getCapabilities(*pLibInfo, FDK_TPENC); - if (hAacEncoder->hEnvEnc) { - sbrEncoder_Close (&hAacEncoder->hEnvEnc); - } - if (hAacEncoder->hAacEnc) { - FDKaacEnc_Close (&hAacEncoder->hAacEnc); - } + C_ALLOC_SCRATCH_END(_pLibInfo, LIB_INFO, FDK_MODULE_LAST) + } + if (transportEnc_RegisterSbrCallback(hAacEncoder->hTpEnc, aacenc_SbrCallback, + hAacEncoder) != 0) { + err = AACENC_INIT_TP_ERROR; + goto bail; + } + if (transportEnc_RegisterSscCallback(hAacEncoder->hTpEnc, aacenc_SscCallback, + hAacEncoder) != 0) { + err = AACENC_INIT_TP_ERROR; + goto bail; + } - transportEnc_Close(&hAacEncoder->hTpEnc); + /* Initialize encoder instance with default parameters. */ + aacEncDefaultConfig(&hAacEncoder->aacConfig, &hAacEncoder->extParam); - if (hAacEncoder->hMetadataEnc) { - FDK_MetadataEnc_Close (&hAacEncoder->hMetadataEnc); - } + /* Initialize headerPeriod in coderConfig for aacEncoder_GetParam(). */ + hAacEncoder->coderConfig.headerPeriod = + hAacEncoder->extParam.userTpHeaderPeriod; - Free_AacEncoder(phAacEncoder); - } + /* All encoder modules have to be initialized */ + hAacEncoder->InitFlags = AACENC_INIT_ALL; + + /* Return encoder instance */ + *phAacEncoder = hAacEncoder; + + return err; bail: - return err; -} + aacEncClose(&hAacEncoder); -AACENC_ERROR aacEncEncode( - const HANDLE_AACENCODER hAacEncoder, - const AACENC_BufDesc *inBufDesc, - const AACENC_BufDesc *outBufDesc, - const AACENC_InArgs *inargs, - AACENC_OutArgs *outargs - ) -{ - AACENC_ERROR err = AACENC_OK; - INT i, nBsBytes = 0; - INT outBytes[(1)]; - int nExtensions = 0; - int ancDataExtIdx = -1; - - /* deal with valid encoder handle */ - if (hAacEncoder==NULL) { - err = AACENC_INVALID_HANDLE; - goto bail; - } + return err; +} +AACENC_ERROR aacEncClose(HANDLE_AACENCODER *phAacEncoder) { + AACENC_ERROR err = AACENC_OK; - /* - * Adjust user settings and trigger reinitialization. - */ - if (hAacEncoder->InitFlags!=0) { + if (phAacEncoder == NULL) { + err = AACENC_INVALID_HANDLE; + goto bail; + } - err = aacEncInit(hAacEncoder, - hAacEncoder->InitFlags, - &hAacEncoder->extParam); + if (*phAacEncoder != NULL) { + HANDLE_AACENCODER hAacEncoder = *phAacEncoder; - if (err!=AACENC_OK) { - /* keep init flags alive! */ - goto bail; - } - hAacEncoder->InitFlags = AACENC_INIT_NONE; + if (hAacEncoder->inputBuffer != NULL) { + FDKfree(hAacEncoder->inputBuffer); + hAacEncoder->inputBuffer = NULL; } - - if (outargs!=NULL) { - FDKmemclear(outargs, sizeof(AACENC_OutArgs)); + if (hAacEncoder->outBuffer != NULL) { + FDKfree(hAacEncoder->outBuffer); + hAacEncoder->outBuffer = NULL; } - if (outBufDesc!=NULL) { - for (i=0; inumBufs; i++) { - if (outBufDesc->bufs[i]!=NULL) { - FDKmemclear(outBufDesc->bufs[i], outBufDesc->bufSizes[i]); - } - } + if (hAacEncoder->hEnvEnc) { + sbrEncoder_Close(&hAacEncoder->hEnvEnc); + } + if (hAacEncoder->pSbrPayload != NULL) { + FDKfree(hAacEncoder->pSbrPayload); + hAacEncoder->pSbrPayload = NULL; + } + if (hAacEncoder->hAacEnc) { + FDKaacEnc_Close(&hAacEncoder->hAacEnc); } - /* - * If only encoder handle given, independent (re)initialization can be triggered. - */ - if ( (hAacEncoder!=NULL) & (inBufDesc==NULL) && (outBufDesc==NULL) && (inargs==NULL) && (outargs==NULL) ) { - goto bail; + transportEnc_Close(&hAacEncoder->hTpEnc); + + if (hAacEncoder->hMetadataEnc) { + FDK_MetadataEnc_Close(&hAacEncoder->hMetadataEnc); + } + if (hAacEncoder->hMpsEnc) { + FDK_MpegsEnc_Close(&hAacEncoder->hMpsEnc); } - /* reset buffer wich signals number of valid bytes in output bitstream buffer */ - FDKmemclear(outBytes, hAacEncoder->aacConfig.nSubFrames*sizeof(INT)); + Free_AacEncoder(phAacEncoder); + } - /* - * Manage incoming audio samples. - */ - if ( (inargs->numInSamples > 0) && (getBufDescIdx(inBufDesc,IN_AUDIO_DATA) != -1) ) - { - /* Fetch data until nSamplesToRead reached */ - INT idx = getBufDescIdx(inBufDesc,IN_AUDIO_DATA); - INT newSamples = fixMax(0,fixMin(inargs->numInSamples, hAacEncoder->nSamplesToRead-hAacEncoder->nSamplesRead)); - INT_PCM *pIn = hAacEncoder->inputBuffer+hAacEncoder->inputBufferOffset+hAacEncoder->nSamplesRead; - - /* Copy new input samples to internal buffer */ - if (inBufDesc->bufElSizes[idx]==(INT)sizeof(INT_PCM)) { - FDKmemcpy(pIn, (INT_PCM*)inBufDesc->bufs[idx], newSamples*sizeof(INT_PCM)); /* Fast copy. */ - } - else if (inBufDesc->bufElSizes[idx]>(INT)sizeof(INT_PCM)) { - for (i=0; ibufs[idx])[i]>>16); /* Convert 32 to 16 bit. */ - } - } - else { - for (i=0; ibufs[idx])[i]))<<16; /* Convert 16 to 32 bit. */ - } - } - hAacEncoder->nSamplesRead += newSamples; +bail: + return err; +} - /* Number of fetched input buffer samples. */ - outargs->numInSamples = newSamples; - } +AACENC_ERROR aacEncEncode(const HANDLE_AACENCODER hAacEncoder, + const AACENC_BufDesc *inBufDesc, + const AACENC_BufDesc *outBufDesc, + const AACENC_InArgs *inargs, + AACENC_OutArgs *outargs) { + AACENC_ERROR err = AACENC_OK; + INT i, nBsBytes = 0; + INT outBytes[(1)]; + int nExtensions = 0; + int ancDataExtIdx = -1; + + /* deal with valid encoder handle */ + if (hAacEncoder == NULL) { + err = AACENC_INVALID_HANDLE; + goto bail; + } - /* input buffer completely filled ? */ - if (hAacEncoder->nSamplesRead < hAacEncoder->nSamplesToRead) - { - /* - eof reached and flushing enabled, or - - return to main and wait for further incoming audio samples */ - if (inargs->numInSamples==-1) - { - if ( (hAacEncoder->nZerosAppended < hAacEncoder->nDelay) - ) - { - int nZeros = hAacEncoder->nSamplesToRead - hAacEncoder->nSamplesRead; - - FDK_ASSERT(nZeros >= 0); - - /* clear out until end-of-buffer */ - if (nZeros) { - FDKmemclear(hAacEncoder->inputBuffer+hAacEncoder->inputBufferOffset+hAacEncoder->nSamplesRead, sizeof(INT_PCM)*nZeros ); - hAacEncoder->nZerosAppended += nZeros; - hAacEncoder->nSamplesRead = hAacEncoder->nSamplesToRead; - } - } - else { /* flushing completed */ - err = AACENC_ENCODE_EOF; /* eof reached */ - goto bail; - } - } - else { /* inargs->numInSamples!= -1 */ - goto bail; /* not enough samples in input buffer and no flushing enabled */ - } - } + /* + * Adjust user settings and trigger reinitialization. + */ + if (hAacEncoder->InitFlags != 0) { + err = + aacEncInit(hAacEncoder, hAacEncoder->InitFlags, &hAacEncoder->extParam); - /* init payload */ - FDKmemclear(hAacEncoder->extPayload, sizeof(AACENC_EXT_PAYLOAD) * MAX_TOTAL_EXT_PAYLOADS); - for (i = 0; i < MAX_TOTAL_EXT_PAYLOADS; i++) { - hAacEncoder->extPayload[i].associatedChElement = -1; + if (err != AACENC_OK) { + /* keep init flags alive! */ + goto bail; } - FDKmemclear(hAacEncoder->extPayloadData, sizeof(hAacEncoder->extPayloadData)); - FDKmemclear(hAacEncoder->extPayloadSize, sizeof(hAacEncoder->extPayloadSize)); + hAacEncoder->InitFlags = AACENC_INIT_NONE; + } + if (outargs != NULL) { + FDKmemclear(outargs, sizeof(AACENC_OutArgs)); + } - /* - * Calculate Meta Data info. - */ - if ( (hAacEncoder->hMetadataEnc!=NULL) && (hAacEncoder->metaDataAllowed!=0) ) { + if (outBufDesc != NULL) { + for (i = 0; i < outBufDesc->numBufs; i++) { + if (outBufDesc->bufs[i] != NULL) { + FDKmemclear(outBufDesc->bufs[i], outBufDesc->bufSizes[i]); + } + } + } - const AACENC_MetaData *pMetaData = NULL; - AACENC_EXT_PAYLOAD *pMetaDataExtPayload = NULL; - UINT nMetaDataExtensions = 0; - INT matrix_mixdown_idx = 0; + /* + * If only encoder handle given, independent (re)initialization can be + * triggered. + */ + if ((inBufDesc == NULL) && (outBufDesc == NULL) && (inargs == NULL) && + (outargs == NULL)) { + goto bail; + } - /* New meta data info available ? */ - if ( getBufDescIdx(inBufDesc,IN_METADATA_SETUP) != -1 ) { - pMetaData = (AACENC_MetaData*)inBufDesc->bufs[getBufDescIdx(inBufDesc,IN_METADATA_SETUP)]; - } + /* check if buffer descriptors are filled out properly. */ + if ((AACENC_OK != validateBufDesc(inBufDesc)) || + (AACENC_OK != validateBufDesc(outBufDesc)) || (inargs == NULL) || + (outargs == NULL)) { + err = AACENC_UNSUPPORTED_PARAMETER; + goto bail; + } - FDK_MetadataEnc_Process(hAacEncoder->hMetadataEnc, - hAacEncoder->inputBuffer+hAacEncoder->inputBufferOffset, - hAacEncoder->nSamplesRead, - pMetaData, - &pMetaDataExtPayload, - &nMetaDataExtensions, - &matrix_mixdown_idx - ); - - for (i=0; i<(INT)nMetaDataExtensions; i++) { /* Get meta data extension payload. */ - hAacEncoder->extPayload[nExtensions++] = pMetaDataExtPayload[i]; - } + /* reset buffer wich signals number of valid bytes in output bitstream buffer + */ + FDKmemclear(outBytes, hAacEncoder->aacConfig.nSubFrames * sizeof(INT)); + + /* + * Manage incoming audio samples. + */ + if ((inBufDesc != NULL) && (inargs->numInSamples > 0) && + (getBufDescIdx(inBufDesc, IN_AUDIO_DATA) != -1)) { + /* Fetch data until nSamplesToRead reached */ + INT idx = getBufDescIdx(inBufDesc, IN_AUDIO_DATA); + INT newSamples = + fixMax(0, fixMin(inargs->numInSamples, hAacEncoder->nSamplesToRead - + hAacEncoder->nSamplesRead)); + INT_PCM *pIn = + hAacEncoder->inputBuffer + + (hAacEncoder->inputBufferOffset + hAacEncoder->nSamplesRead) / + hAacEncoder->aacConfig.nChannels; + + /* Copy new input samples to internal buffer */ + if (inBufDesc->bufElSizes[idx] == (INT)sizeof(INT_PCM)) { + FDK_deinterleave((INT_PCM *)inBufDesc->bufs[idx], pIn, + hAacEncoder->extParam.nChannels, + newSamples / hAacEncoder->extParam.nChannels, + hAacEncoder->inputBufferSizePerChannel); + } else if (inBufDesc->bufElSizes[idx] > (INT)sizeof(INT_PCM)) { + FDK_deinterleave((LONG *)inBufDesc->bufs[idx], pIn, + hAacEncoder->extParam.nChannels, + newSamples / hAacEncoder->extParam.nChannels, + hAacEncoder->inputBufferSizePerChannel); + } else { + FDK_deinterleave((SHORT *)inBufDesc->bufs[idx], pIn, + hAacEncoder->extParam.nChannels, + newSamples / hAacEncoder->extParam.nChannels, + hAacEncoder->inputBufferSizePerChannel); + } + hAacEncoder->nSamplesRead += newSamples; + + /* Number of fetched input buffer samples. */ + outargs->numInSamples = newSamples; + } - if ( (matrix_mixdown_idx!=-1) - && ((hAacEncoder->extParam.userChannelMode==MODE_1_2_2)||(hAacEncoder->extParam.userChannelMode==MODE_1_2_2_1)) ) - { - /* Set matrix mixdown coefficient. */ - UINT pceValue = (UINT)( (0<<3) | ((matrix_mixdown_idx&0x3)<<1) | 1 ); - if (hAacEncoder->extParam.userPceAdditions != pceValue) { - hAacEncoder->extParam.userPceAdditions = pceValue; - hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + /* input buffer completely filled ? */ + if (hAacEncoder->nSamplesRead < hAacEncoder->nSamplesToRead) { + /* - eof reached and flushing enabled, or + - return to main and wait for further incoming audio samples */ + if (inargs->numInSamples == -1) { + if ((hAacEncoder->nZerosAppended < hAacEncoder->nDelay)) { + int nZeros = (hAacEncoder->nSamplesToRead - hAacEncoder->nSamplesRead) / + hAacEncoder->extParam.nChannels; + + FDK_ASSERT(nZeros >= 0); + + /* clear out until end-of-buffer */ + if (nZeros) { + for (i = 0; i < (int)hAacEncoder->extParam.nChannels; i++) { + FDKmemclear(hAacEncoder->inputBuffer + + i * hAacEncoder->inputBufferSizePerChannel + + (hAacEncoder->inputBufferOffset + + hAacEncoder->nSamplesRead) / + hAacEncoder->extParam.nChannels, + sizeof(INT_PCM) * nZeros); } + hAacEncoder->nZerosAppended += nZeros; + hAacEncoder->nSamplesRead = hAacEncoder->nSamplesToRead; } + } else { /* flushing completed */ + err = AACENC_ENCODE_EOF; /* eof reached */ + goto bail; + } + } else { /* inargs->numInSamples!= -1 */ + goto bail; /* not enough samples in input buffer and no flushing enabled + */ } + } + /* init payload */ + FDKmemclear(hAacEncoder->extPayload, + sizeof(AACENC_EXT_PAYLOAD) * MAX_TOTAL_EXT_PAYLOADS); + for (i = 0; i < MAX_TOTAL_EXT_PAYLOADS; i++) { + hAacEncoder->extPayload[i].associatedChElement = -1; + } + if (hAacEncoder->pSbrPayload != NULL) { + FDKmemclear(hAacEncoder->pSbrPayload, sizeof(*hAacEncoder->pSbrPayload)); + } - if ( isSbrActive(&hAacEncoder->aacConfig) ) { - - INT nPayload = 0; - - /* - * Encode SBR data. - */ - if (sbrEncoder_EncodeFrame(hAacEncoder->hEnvEnc, - hAacEncoder->inputBuffer, - hAacEncoder->extParam.nChannels, - hAacEncoder->extPayloadSize[nPayload], - hAacEncoder->extPayloadData[nPayload] -#if defined(EVAL_PACKAGE_SILENCE) || defined(EVAL_PACKAGE_SBR_SILENCE) - ,hAacEncoder->hAacEnc->clearOutput -#endif - )) - { - err = AACENC_ENCODE_ERROR; - goto bail; - } - else { - /* Add SBR extension payload */ - for (i = 0; i < (8); i++) { - if (hAacEncoder->extPayloadSize[nPayload][i] > 0) { - hAacEncoder->extPayload[nExtensions].pData = hAacEncoder->extPayloadData[nPayload][i]; - { - hAacEncoder->extPayload[nExtensions].dataSize = hAacEncoder->extPayloadSize[nPayload][i]; - hAacEncoder->extPayload[nExtensions].associatedChElement = i; - } - hAacEncoder->extPayload[nExtensions].dataType = EXT_SBR_DATA; /* Once SBR Encoder supports SBR CRC set EXT_SBR_DATA_CRC */ - nExtensions++; /* or EXT_SBR_DATA according to configuration. */ - FDK_ASSERT(nExtensions<=MAX_TOTAL_EXT_PAYLOADS); - } - } - nPayload++; - } - } /* sbrEnabled */ - - if ( (inargs->numAncBytes > 0) && ( getBufDescIdx(inBufDesc,IN_ANCILLRY_DATA)!=-1 ) ) { - INT idx = getBufDescIdx(inBufDesc,IN_ANCILLRY_DATA); - hAacEncoder->extPayload[nExtensions].dataSize = inargs->numAncBytes * 8; - hAacEncoder->extPayload[nExtensions].pData = (UCHAR*)inBufDesc->bufs[idx]; - hAacEncoder->extPayload[nExtensions].dataType = EXT_DATA_ELEMENT; - hAacEncoder->extPayload[nExtensions].associatedChElement = -1; - ancDataExtIdx = nExtensions; /* store index */ - nExtensions++; + /* + * Calculate Meta Data info. + */ + if ((hAacEncoder->hMetadataEnc != NULL) && + (hAacEncoder->metaDataAllowed != 0)) { + const AACENC_MetaData *pMetaData = NULL; + AACENC_EXT_PAYLOAD *pMetaDataExtPayload = NULL; + UINT nMetaDataExtensions = 0; + INT matrix_mixdown_idx = 0; + + /* New meta data info available ? */ + if (getBufDescIdx(inBufDesc, IN_METADATA_SETUP) != -1) { + pMetaData = + (AACENC_MetaData *) + inBufDesc->bufs[getBufDescIdx(inBufDesc, IN_METADATA_SETUP)]; + } + + FDK_MetadataEnc_Process( + hAacEncoder->hMetadataEnc, + hAacEncoder->inputBuffer + hAacEncoder->inputBufferOffset / + hAacEncoder->coderConfig.noChannels, + hAacEncoder->inputBufferSizePerChannel, hAacEncoder->nSamplesRead, + pMetaData, &pMetaDataExtPayload, &nMetaDataExtensions, + &matrix_mixdown_idx); + + for (i = 0; i < (INT)nMetaDataExtensions; + i++) { /* Get meta data extension payload. */ + hAacEncoder->extPayload[nExtensions++] = pMetaDataExtPayload[i]; + } + + if ((matrix_mixdown_idx != -1) && + ((hAacEncoder->extParam.userChannelMode == MODE_1_2_2) || + (hAacEncoder->extParam.userChannelMode == MODE_1_2_2_1))) { + /* Set matrix mixdown coefficient. */ + UINT pceValue = (UINT)((0 << 3) | ((matrix_mixdown_idx & 0x3) << 1) | 1); + if (hAacEncoder->extParam.userPceAdditions != pceValue) { + hAacEncoder->extParam.userPceAdditions = pceValue; + hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + } } + } - /* - * Encode AAC - Core. - */ - if ( FDKaacEnc_EncodeFrame( hAacEncoder->hAacEnc, - hAacEncoder->hTpEnc, - hAacEncoder->inputBuffer, - outBytes, - hAacEncoder->extPayload - ) != AAC_ENC_OK ) - { - err = AACENC_ENCODE_ERROR; - goto bail; + /* + * Encode MPS data. + */ + if ((hAacEncoder->hMpsEnc != NULL) && + (hAacEncoder->aacConfig.syntaxFlags & AC_LD_MPS)) { + AACENC_EXT_PAYLOAD mpsExtensionPayload; + FDKmemclear(&mpsExtensionPayload, sizeof(AACENC_EXT_PAYLOAD)); + + if (MPS_ENCODER_OK != + FDK_MpegsEnc_Process( + hAacEncoder->hMpsEnc, + hAacEncoder->inputBuffer + hAacEncoder->inputBufferOffset / + hAacEncoder->coderConfig.noChannels, + hAacEncoder->nSamplesRead, &mpsExtensionPayload)) { + err = AACENC_ENCODE_ERROR; + goto bail; } - if (ancDataExtIdx >= 0) { - outargs->numAncBytes = inargs->numAncBytes - (hAacEncoder->extPayload[ancDataExtIdx].dataSize>>3); + if ((mpsExtensionPayload.pData != NULL) && + ((mpsExtensionPayload.dataSize != 0))) { + hAacEncoder->extPayload[nExtensions++] = mpsExtensionPayload; } + } - /* samples exhausted */ - hAacEncoder->nSamplesRead -= hAacEncoder->nSamplesToRead; + if ((NULL != hAacEncoder->hEnvEnc) && (NULL != hAacEncoder->pSbrPayload) && + isSbrActive(&hAacEncoder->aacConfig)) { + INT nPayload = 0; /* - * Delay balancing buffer handling + * Encode SBR data. */ - if (isSbrActive(&hAacEncoder->aacConfig)) { - sbrEncoder_UpdateBuffers(hAacEncoder->hEnvEnc, hAacEncoder->inputBuffer); - } + if (sbrEncoder_EncodeFrame(hAacEncoder->hEnvEnc, hAacEncoder->inputBuffer, + hAacEncoder->inputBufferSizePerChannel, + hAacEncoder->pSbrPayload->dataSize[nPayload], + hAacEncoder->pSbrPayload->data[nPayload])) { + err = AACENC_ENCODE_ERROR; + goto bail; + } else { + /* Add SBR extension payload */ + for (i = 0; i < (8); i++) { + if (hAacEncoder->pSbrPayload->dataSize[nPayload][i] > 0) { + hAacEncoder->extPayload[nExtensions].pData = + hAacEncoder->pSbrPayload->data[nPayload][i]; + { + hAacEncoder->extPayload[nExtensions].dataSize = + hAacEncoder->pSbrPayload->dataSize[nPayload][i]; + hAacEncoder->extPayload[nExtensions].associatedChElement = i; + } + hAacEncoder->extPayload[nExtensions].dataType = + EXT_SBR_DATA; /* Once SBR Encoder supports SBR CRC set + EXT_SBR_DATA_CRC */ + nExtensions++; /* or EXT_SBR_DATA according to configuration. */ + FDK_ASSERT(nExtensions <= MAX_TOTAL_EXT_PAYLOADS); + } + } + nPayload++; + } + } /* sbrEnabled */ + + if ((inargs->numAncBytes > 0) && + (getBufDescIdx(inBufDesc, IN_ANCILLRY_DATA) != -1)) { + INT idx = getBufDescIdx(inBufDesc, IN_ANCILLRY_DATA); + hAacEncoder->extPayload[nExtensions].dataSize = inargs->numAncBytes * 8; + hAacEncoder->extPayload[nExtensions].pData = (UCHAR *)inBufDesc->bufs[idx]; + hAacEncoder->extPayload[nExtensions].dataType = EXT_DATA_ELEMENT; + hAacEncoder->extPayload[nExtensions].associatedChElement = -1; + ancDataExtIdx = nExtensions; /* store index */ + nExtensions++; + } - /* - * Make bitstream public - */ - if (outBufDesc->numBufs>=1) { + /* + * Encode AAC - Core. + */ + if (FDKaacEnc_EncodeFrame(hAacEncoder->hAacEnc, hAacEncoder->hTpEnc, + hAacEncoder->inputBuffer, + hAacEncoder->inputBufferSizePerChannel, outBytes, + hAacEncoder->extPayload) != AAC_ENC_OK) { + err = AACENC_ENCODE_ERROR; + goto bail; + } - INT bsIdx = getBufDescIdx(outBufDesc,OUT_BITSTREAM_DATA); - INT auIdx = getBufDescIdx(outBufDesc,OUT_AU_SIZES); + if (ancDataExtIdx >= 0) { + outargs->numAncBytes = + inargs->numAncBytes - + (hAacEncoder->extPayload[ancDataExtIdx].dataSize >> 3); + } - for (i=0,nBsBytes=0; iaacConfig.nSubFrames; i++) { - nBsBytes += outBytes[i]; + /* samples exhausted */ + hAacEncoder->nSamplesRead -= hAacEncoder->nSamplesToRead; - if (auIdx!=-1) { - ((INT*)outBufDesc->bufs[auIdx])[i] = outBytes[i]; - } - } + /* + * Delay balancing buffer handling + */ + if (isSbrActive(&hAacEncoder->aacConfig)) { + sbrEncoder_UpdateBuffers(hAacEncoder->hEnvEnc, hAacEncoder->inputBuffer, + hAacEncoder->inputBufferSizePerChannel); + } - if ( (bsIdx!=-1) && (outBufDesc->bufSizes[bsIdx]>=nBsBytes) ) { - FDKmemcpy(outBufDesc->bufs[bsIdx], hAacEncoder->outBuffer, sizeof(UCHAR)*nBsBytes); - outargs->numOutBytes = nBsBytes; - } - else { - /* output buffer too small, can't write valid bitstream */ - err = AACENC_ENCODE_ERROR; - goto bail; - } + /* + * Make bitstream public + */ + if ((outBufDesc != NULL) && (outBufDesc->numBufs >= 1)) { + INT bsIdx = getBufDescIdx(outBufDesc, OUT_BITSTREAM_DATA); + INT auIdx = getBufDescIdx(outBufDesc, OUT_AU_SIZES); + + for (i = 0, nBsBytes = 0; i < hAacEncoder->aacConfig.nSubFrames; i++) { + nBsBytes += outBytes[i]; + + if (auIdx != -1) { + ((INT *)outBufDesc->bufs[auIdx])[i] = outBytes[i]; + } } -bail: - if (err == AACENC_ENCODE_ERROR) { - /* All encoder modules have to be initialized */ - hAacEncoder->InitFlags = AACENC_INIT_ALL; + if ((bsIdx != -1) && (outBufDesc->bufSizes[bsIdx] >= nBsBytes)) { + FDKmemcpy(outBufDesc->bufs[bsIdx], hAacEncoder->outBuffer, + sizeof(UCHAR) * nBsBytes); + outargs->numOutBytes = nBsBytes; + outargs->bitResState = + FDKaacEnc_GetBitReservoirState(hAacEncoder->hAacEnc); + } else { + /* output buffer too small, can't write valid bitstream */ + err = AACENC_ENCODE_ERROR; + goto bail; } + } - return err; +bail: + if (err == AACENC_ENCODE_ERROR) { + /* All encoder modules have to be initialized */ + hAacEncoder->InitFlags = AACENC_INIT_ALL; + } + + return err; } -static -AAC_ENCODER_ERROR aacEncGetConf(HANDLE_AACENCODER hAacEncoder, - UINT *size, - UCHAR *confBuffer) -{ - FDK_BITSTREAM tmpConf; - UINT confType; - UCHAR buf[64]; - int err; +static AAC_ENCODER_ERROR aacEncGetConf(HANDLE_AACENCODER hAacEncoder, + UINT *size, UCHAR *confBuffer) { + FDK_BITSTREAM tmpConf; + UINT confType; + UCHAR buf[64]; + int err; - /* Init bit buffer */ - FDKinitBitStream(&tmpConf, buf, 64, 0, BS_WRITER); + /* Init bit buffer */ + FDKinitBitStream(&tmpConf, buf, 64, 0, BS_WRITER); - /* write conf in tmp buffer */ - err = transportEnc_GetConf(hAacEncoder->hTpEnc, &hAacEncoder->coderConfig, &tmpConf, &confType); + /* write conf in tmp buffer */ + err = transportEnc_GetConf(hAacEncoder->hTpEnc, &hAacEncoder->coderConfig, + &tmpConf, &confType); - /* copy data to outbuffer: length in bytes */ - FDKbyteAlign(&tmpConf, 0); + /* copy data to outbuffer: length in bytes */ + FDKbyteAlign(&tmpConf, 0); - /* Check buffer size */ - if (FDKgetValidBits(&tmpConf) > ((*size)<<3)) - return AAC_ENC_UNKNOWN; + /* Check buffer size */ + if (FDKgetValidBits(&tmpConf) > ((*size) << 3)) return AAC_ENC_UNKNOWN; - FDKfetchBuffer(&tmpConf, confBuffer, size); + FDKfetchBuffer(&tmpConf, confBuffer, size); - if (err != 0) - return AAC_ENC_UNKNOWN; - else - return AAC_ENC_OK; + if (err != 0) + return AAC_ENC_UNKNOWN; + else + return AAC_ENC_OK; } - -AACENC_ERROR aacEncGetLibInfo(LIB_INFO *info) -{ +AACENC_ERROR aacEncGetLibInfo(LIB_INFO *info) { int i = 0; if (info == NULL) { return AACENC_INVALID_HANDLE; } - FDK_toolsGetLibInfo( info ); - transportEnc_GetLibInfo( info ); - - sbrEncoder_GetLibInfo( info ); + FDK_toolsGetLibInfo(info); + transportEnc_GetLibInfo(info); + sbrEncoder_GetLibInfo(info); + FDK_MpegsEnc_GetLibInfo(info); /* search for next free tab */ for (i = 0; i < FDK_MODULE_LAST; i++) { @@ -1735,405 +2052,451 @@ AACENC_ERROR aacEncGetLibInfo(LIB_INFO *info) } info[i].module_id = FDK_AACENC; - info[i].build_date = (char*)AACENCODER_LIB_BUILD_DATE; - info[i].build_time = (char*)AACENCODER_LIB_BUILD_TIME; - info[i].title = (char*)AACENCODER_LIB_TITLE; - info[i].version = LIB_VERSION(AACENCODER_LIB_VL0, AACENCODER_LIB_VL1, AACENCODER_LIB_VL2);; + info[i].build_date = AACENCODER_LIB_BUILD_DATE; + info[i].build_time = AACENCODER_LIB_BUILD_TIME; + info[i].title = AACENCODER_LIB_TITLE; + info[i].version = + LIB_VERSION(AACENCODER_LIB_VL0, AACENCODER_LIB_VL1, AACENCODER_LIB_VL2); + ; LIB_VERSION_STRING(&info[i]); /* Capability flags */ - info[i].flags = 0 - | CAPF_AAC_1024 | CAPF_AAC_LC - | CAPF_AAC_512 - | CAPF_AAC_480 - | CAPF_AAC_DRC - ; + info[i].flags = 0 | CAPF_AAC_1024 | CAPF_AAC_LC | CAPF_AAC_512 | + CAPF_AAC_480 | CAPF_AAC_DRC | CAPF_AAC_ELD_DOWNSCALE; /* End of flags */ return AACENC_OK; } -AACENC_ERROR aacEncoder_SetParam( - const HANDLE_AACENCODER hAacEncoder, - const AACENC_PARAM param, - const UINT value - ) -{ - AACENC_ERROR err = AACENC_OK; - USER_PARAM *settings = &hAacEncoder->extParam; +AACENC_ERROR aacEncoder_SetParam(const HANDLE_AACENCODER hAacEncoder, + const AACENC_PARAM param, const UINT value) { + AACENC_ERROR err = AACENC_OK; + USER_PARAM *settings = &hAacEncoder->extParam; - /* check encoder handle */ - if (hAacEncoder == NULL) { - err = AACENC_INVALID_HANDLE; - goto bail; - } + /* check encoder handle */ + if (hAacEncoder == NULL) { + err = AACENC_INVALID_HANDLE; + goto bail; + } - /* apply param value */ - switch (param) - { + /* apply param value */ + switch (param) { case AACENC_AOT: - if (settings->userAOT != (AUDIO_OBJECT_TYPE)value) { - /* check if AOT matches the allocated modules */ - switch ( value ) { - case AOT_PS: - if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_PS))) { - err = AACENC_INVALID_CONFIG; - goto bail; - } - case AOT_SBR: - if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_SBR))) { - err = AACENC_INVALID_CONFIG; - goto bail; - } - case AOT_AAC_LC: - case AOT_ER_AAC_LD: - case AOT_ER_AAC_ELD: - if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_AAC))) { - err = AACENC_INVALID_CONFIG; - goto bail; - } - break; - default: - err = AACENC_INVALID_CONFIG; - goto bail; - }/* switch value */ - settings->userAOT = (AUDIO_OBJECT_TYPE)value; - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; - } - break; + if (settings->userAOT != (AUDIO_OBJECT_TYPE)value) { + /* check if AOT matches the allocated modules */ + switch (value) { + case AOT_PS: + if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_PS))) { + err = AACENC_INVALID_CONFIG; + goto bail; + } + case AOT_SBR: + case AOT_MP2_SBR: + if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_SBR))) { + err = AACENC_INVALID_CONFIG; + goto bail; + } + case AOT_AAC_LC: + case AOT_MP2_AAC_LC: + case AOT_ER_AAC_LD: + case AOT_ER_AAC_ELD: + if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_AAC))) { + err = AACENC_INVALID_CONFIG; + goto bail; + } + break; + default: + err = AACENC_INVALID_CONFIG; + goto bail; + } /* switch value */ + settings->userAOT = (AUDIO_OBJECT_TYPE)value; + hAacEncoder->InitFlags |= + AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; + } + break; case AACENC_BITRATE: - if (settings->userBitrate != value) { - settings->userBitrate = value; - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; - } - break; + if (settings->userBitrate != value) { + settings->userBitrate = value; + hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; + } + break; case AACENC_BITRATEMODE: - if (settings->userBitrateMode != value) { - switch ( value ) { - case 0: - case 1: case 2: case 3: case 4: case 5: - case 8: - settings->userBitrateMode = value; - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; - break; - default: - err = AACENC_INVALID_CONFIG; - break; - } /* switch value */ - } - break; + if (settings->userBitrateMode != value) { + switch (value) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + settings->userBitrateMode = value; + hAacEncoder->InitFlags |= + AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; + break; + default: + err = AACENC_INVALID_CONFIG; + break; + } /* switch value */ + } + break; case AACENC_SAMPLERATE: - if (settings->userSamplerate != value) { - if ( !( (value==8000) || (value==11025) || (value==12000) || (value==16000) || (value==22050) || (value==24000) || - (value==32000) || (value==44100) || (value==48000) || (value==64000) || (value==88200) || (value==96000) ) ) - { - err = AACENC_INVALID_CONFIG; - break; - } - settings->userSamplerate = value; - hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */ - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; + if (settings->userSamplerate != value) { + if (!((value == 8000) || (value == 11025) || (value == 12000) || + (value == 16000) || (value == 22050) || (value == 24000) || + (value == 32000) || (value == 44100) || (value == 48000) || + (value == 64000) || (value == 88200) || (value == 96000))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + settings->userSamplerate = value; + hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */ + hAacEncoder->InitFlags |= + AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; + } + break; case AACENC_CHANNELMODE: - if (settings->userChannelMode != (CHANNEL_MODE)value) { - const CHANNEL_MODE_CONFIG_TAB* pConfig = FDKaacEnc_GetChannelModeConfiguration((CHANNEL_MODE)value); - if (pConfig==NULL) { - err = AACENC_INVALID_CONFIG; - break; - } - if ( (pConfig->nElements > hAacEncoder->nMaxAacElements) - || (pConfig->nChannelsEff > hAacEncoder->nMaxAacChannels) - || !(((value>=1) && (value<=7))||((value>=33) && (value<=34))) - ) - { - err = AACENC_INVALID_CONFIG; - break; - } + if (settings->userChannelMode != (CHANNEL_MODE)value) { + if (((CHANNEL_MODE)value == MODE_212) && + (NULL != hAacEncoder->hMpsEnc)) { + settings->userChannelMode = (CHANNEL_MODE)value; + settings->nChannels = 2; + } else { + const CHANNEL_MODE_CONFIG_TAB *pConfig = + FDKaacEnc_GetChannelModeConfiguration((CHANNEL_MODE)value); + if (pConfig == NULL) { + err = AACENC_INVALID_CONFIG; + break; + } + if ((pConfig->nElements > hAacEncoder->nMaxAacElements) || + (pConfig->nChannelsEff > hAacEncoder->nMaxAacChannels)) { + err = AACENC_INVALID_CONFIG; + break; + } - settings->userChannelMode = (CHANNEL_MODE)value; - settings->nChannels = pConfig->nChannels; - hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */ - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; + settings->userChannelMode = (CHANNEL_MODE)value; + settings->nChannels = pConfig->nChannels; } - break; - case AACENC_BANDWIDTH: - if (settings->userBandwidth != value) { - settings->userBandwidth = value; - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG; + hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */ + hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; + if (!((value >= 1) && (value <= 6))) { + hAacEncoder->InitFlags |= AACENC_INIT_STATES; } - break; + } + break; + case AACENC_BANDWIDTH: + if (settings->userBandwidth != value) { + settings->userBandwidth = value; + hAacEncoder->InitFlags |= AACENC_INIT_CONFIG; + } + break; case AACENC_CHANNELORDER: - if (hAacEncoder->aacConfig.channelOrder != (CHANNEL_ORDER)value) { - if (! ((value==0) || (value==1)) ) { - err = AACENC_INVALID_CONFIG; - break; - } - hAacEncoder->aacConfig.channelOrder = (CHANNEL_ORDER)value; - hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */ - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; + if (hAacEncoder->aacConfig.channelOrder != (CHANNEL_ORDER)value) { + if (!((value == 0) || (value == 1))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + hAacEncoder->aacConfig.channelOrder = (CHANNEL_ORDER)value; + hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */ + hAacEncoder->InitFlags |= + AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; + } + break; case AACENC_AFTERBURNER: - if (settings->userAfterburner != value) { - if (! ((value==0) || (value==1)) ) { - err = AACENC_INVALID_CONFIG; - break; - } - settings->userAfterburner = value; - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG; + if (settings->userAfterburner != value) { + if (!((value == 0) || (value == 1))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + settings->userAfterburner = value; + hAacEncoder->InitFlags |= AACENC_INIT_CONFIG; + } + break; case AACENC_GRANULE_LENGTH: - if (settings->userFramelength != value) { - switch (value) { - case 1024: - case 512: - case 480: - settings->userFramelength = value; - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; - break; - default: - err = AACENC_INVALID_CONFIG; - break; - } + if (settings->userFramelength != value) { + switch (value) { + case 1024: + case 512: + case 480: + case 256: + case 240: + case 128: + case 120: + if ((value << 1) == 480 || (value << 1) == 512) { + settings->userDownscaleFactor = 2; + } else if ((value << 2) == 480 || (value << 2) == 512) { + settings->userDownscaleFactor = 4; + } + settings->userFramelength = value; + hAacEncoder->InitFlags |= + AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; + break; + default: + err = AACENC_INVALID_CONFIG; + break; } - break; + } + break; case AACENC_SBR_RATIO: - if (settings->userSbrRatio != value) { - if (! ((value==0) || (value==1) || (value==2)) ) { - err = AACENC_INVALID_CONFIG; - break; - } - settings->userSbrRatio = value; - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; + if (settings->userSbrRatio != value) { + if (!((value == 0) || (value == 1) || (value == 2))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + settings->userSbrRatio = value; + hAacEncoder->InitFlags |= + AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; + } + break; case AACENC_SBR_MODE: - if (settings->userSbrEnabled != value) { - settings->userSbrEnabled = value; - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; - } - break; + if ((settings->userSbrEnabled != value) && + (NULL != hAacEncoder->hEnvEnc)) { + settings->userSbrEnabled = value; + hAacEncoder->InitFlags |= + AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; + } + break; case AACENC_TRANSMUX: - if (settings->userTpType != (TRANSPORT_TYPE)value) { - - TRANSPORT_TYPE type = (TRANSPORT_TYPE)value; - UINT flags = hAacEncoder->CAPF_tpEnc; - - if ( !( ((type==TT_MP4_ADIF) && (flags&CAPF_ADIF)) - || ((type==TT_MP4_ADTS) && (flags&CAPF_ADTS)) - || ((type==TT_MP4_LATM_MCP0) && ((flags&CAPF_LATM) && (flags&CAPF_RAWPACKETS))) - || ((type==TT_MP4_LATM_MCP1) && ((flags&CAPF_LATM) && (flags&CAPF_RAWPACKETS))) - || ((type==TT_MP4_LOAS) && (flags&CAPF_LOAS)) - || ((type==TT_MP4_RAW) && (flags&CAPF_RAWPACKETS)) - ) ) - { - err = AACENC_INVALID_CONFIG; - break; - } - settings->userTpType = (TRANSPORT_TYPE)value; - hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + if (settings->userTpType != (TRANSPORT_TYPE)value) { + TRANSPORT_TYPE type = (TRANSPORT_TYPE)value; + UINT flags = hAacEncoder->CAPF_tpEnc; + + if (!(((type == TT_MP4_ADIF) && (flags & CAPF_ADIF)) || + ((type == TT_MP4_ADTS) && (flags & CAPF_ADTS)) || + ((type == TT_MP4_LATM_MCP0) && + ((flags & CAPF_LATM) && (flags & CAPF_RAWPACKETS))) || + ((type == TT_MP4_LATM_MCP1) && + ((flags & CAPF_LATM) && (flags & CAPF_RAWPACKETS))) || + ((type == TT_MP4_LOAS) && (flags & CAPF_LOAS)) || + ((type == TT_MP4_RAW) && (flags & CAPF_RAWPACKETS)))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + settings->userTpType = (TRANSPORT_TYPE)value; + hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + } + break; case AACENC_SIGNALING_MODE: - if (settings->userTpSignaling != value) { - if ( !((value==0) || (value==1) || (value==2)) ) { - err = AACENC_INVALID_CONFIG; - break; - } - settings->userTpSignaling = value; - hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + if (settings->userTpSignaling != value) { + if (!((value == 0) || (value == 1) || (value == 2))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + settings->userTpSignaling = value; + hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + } + break; case AACENC_PROTECTION: - if (settings->userTpProtection != value) { - if ( !((value==0) || (value==1)) ) { - err = AACENC_INVALID_CONFIG; - break; - } - settings->userTpProtection = value; - hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + if (settings->userTpProtection != value) { + if (!((value == 0) || (value == 1))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + settings->userTpProtection = value; + hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + } + break; case AACENC_HEADER_PERIOD: - if (settings->userTpHeaderPeriod != value) { - settings->userTpHeaderPeriod = value; - hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + if (settings->userTpHeaderPeriod != value) { + if (!(((INT)value >= 0) && (value <= 255))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + settings->userTpHeaderPeriod = value; + hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + } + break; case AACENC_AUDIOMUXVER: - if (settings->userTpAmxv != value) { - if ( !((value==0) || (value==1) || (value==2)) ) { - err = AACENC_INVALID_CONFIG; - break; - } - settings->userTpAmxv = value; - hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + if (settings->userTpAmxv != value) { + if (!((value == 0) || (value == 1) || (value == 2))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + settings->userTpAmxv = value; + hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + } + break; case AACENC_TPSUBFRAMES: - if (settings->userTpNsubFrames != value) { - if (! ( (value>=1) && (value<=4) ) ) { - err = AACENC_INVALID_CONFIG; - break; - } - settings->userTpNsubFrames = value; - hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + if (settings->userTpNsubFrames != value) { + if (!((value >= 1) && (value <= 4))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + settings->userTpNsubFrames = value; + hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + } + break; case AACENC_ANCILLARY_BITRATE: - if (settings->userAncDataRate != value) { - settings->userAncDataRate = value; - } - break; + if (settings->userAncDataRate != value) { + settings->userAncDataRate = value; + } + break; case AACENC_CONTROL_STATE: - if (hAacEncoder->InitFlags != value) { - if (value&AACENC_RESET_INBUFFER) { - hAacEncoder->nSamplesRead = 0; - } - hAacEncoder->InitFlags = value; + if (hAacEncoder->InitFlags != value) { + if (value & AACENC_RESET_INBUFFER) { + hAacEncoder->nSamplesRead = 0; } - break; + hAacEncoder->InitFlags = value; + } + break; case AACENC_METADATA_MODE: - if ((UINT)settings->userMetaDataMode != value) { - if ( !(((INT)value>=0) && ((INT)value<=2)) ) { - err = AACENC_INVALID_CONFIG; - break; - } - settings->userMetaDataMode = value; - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG; + if ((UINT)settings->userMetaDataMode != value) { + if (!(((INT)value >= 0) && ((INT)value <= 3))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + settings->userMetaDataMode = value; + hAacEncoder->InitFlags |= AACENC_INIT_CONFIG; + } + break; case AACENC_PEAK_BITRATE: - if (settings->userPeakBitrate != value) { - settings->userPeakBitrate = value; - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; - } - break; + if (settings->userPeakBitrate != value) { + settings->userPeakBitrate = value; + hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; + } + break; default: err = AACENC_UNSUPPORTED_PARAMETER; break; - } /* switch(param) */ + } /* switch(param) */ bail: - return err; + return err; } -UINT aacEncoder_GetParam( - const HANDLE_AACENCODER hAacEncoder, - const AACENC_PARAM param - ) -{ - UINT value = 0; - USER_PARAM *settings = &hAacEncoder->extParam; +UINT aacEncoder_GetParam(const HANDLE_AACENCODER hAacEncoder, + const AACENC_PARAM param) { + UINT value = 0; + USER_PARAM *settings = &hAacEncoder->extParam; - /* check encoder handle */ - if (hAacEncoder == NULL) { - goto bail; - } + /* check encoder handle */ + if (hAacEncoder == NULL) { + goto bail; + } - /* apply param value */ - switch (param) - { + /* apply param value */ + switch (param) { case AACENC_AOT: - value = (UINT)hAacEncoder->aacConfig.audioObjectType; - break; + value = (UINT)hAacEncoder->aacConfig.audioObjectType; + break; case AACENC_BITRATE: - value = (UINT)((hAacEncoder->aacConfig.bitrateMode==AACENC_BR_MODE_CBR) ? hAacEncoder->aacConfig.bitRate : -1); - break; + switch (hAacEncoder->aacConfig.bitrateMode) { + case AACENC_BR_MODE_CBR: + value = (UINT)hAacEncoder->aacConfig.bitRate; + break; + default: + value = (UINT)-1; + } + break; case AACENC_BITRATEMODE: - value = (UINT)hAacEncoder->aacConfig.bitrateMode; - break; + value = (UINT)((hAacEncoder->aacConfig.bitrateMode != AACENC_BR_MODE_FF) + ? hAacEncoder->aacConfig.bitrateMode + : AACENC_BR_MODE_CBR); + break; case AACENC_SAMPLERATE: - value = (UINT)hAacEncoder->coderConfig.extSamplingRate; - break; + value = (UINT)hAacEncoder->coderConfig.extSamplingRate; + break; case AACENC_CHANNELMODE: + if ((MODE_1 == hAacEncoder->aacConfig.channelMode) && + (hAacEncoder->aacConfig.syntaxFlags & AC_LD_MPS)) { + value = MODE_212; + } else { value = (UINT)hAacEncoder->aacConfig.channelMode; - break; + } + break; case AACENC_BANDWIDTH: - value = (UINT)hAacEncoder->aacConfig.bandWidth; - break; + value = (UINT)hAacEncoder->aacConfig.bandWidth; + break; case AACENC_CHANNELORDER: - value = (UINT)hAacEncoder->aacConfig.channelOrder; - break; + value = (UINT)hAacEncoder->aacConfig.channelOrder; + break; case AACENC_AFTERBURNER: - value = (UINT)hAacEncoder->aacConfig.useRequant; - break; + value = (UINT)hAacEncoder->aacConfig.useRequant; + break; case AACENC_GRANULE_LENGTH: - value = (UINT)hAacEncoder->aacConfig.framelength; - break; + value = (UINT)hAacEncoder->aacConfig.framelength; + break; case AACENC_SBR_RATIO: - value = isSbrActive(&hAacEncoder->aacConfig) ? hAacEncoder->aacConfig.sbrRatio : 0; - break; + value = isSbrActive(&hAacEncoder->aacConfig) + ? hAacEncoder->aacConfig.sbrRatio + : 0; + break; case AACENC_SBR_MODE: - value = (UINT) (hAacEncoder->aacConfig.syntaxFlags & AC_SBR_PRESENT) ? 1 : 0; - break; + value = + (UINT)(hAacEncoder->aacConfig.syntaxFlags & AC_SBR_PRESENT) ? 1 : 0; + break; case AACENC_TRANSMUX: - value = (UINT)settings->userTpType; - break; + value = (UINT)settings->userTpType; + break; case AACENC_SIGNALING_MODE: - value = (UINT)getSbrSignalingMode(hAacEncoder->aacConfig.audioObjectType, settings->userTpType, settings->userTpSignaling, hAacEncoder->aacConfig.sbrRatio); - break; + value = (UINT)getSbrSignalingMode( + hAacEncoder->aacConfig.audioObjectType, settings->userTpType, + settings->userTpSignaling, hAacEncoder->aacConfig.sbrRatio); + break; case AACENC_PROTECTION: - value = (UINT)settings->userTpProtection; - break; + value = (UINT)settings->userTpProtection; + break; case AACENC_HEADER_PERIOD: - value = (UINT)hAacEncoder->coderConfig.headerPeriod; - break; + value = (UINT)hAacEncoder->coderConfig.headerPeriod; + break; case AACENC_AUDIOMUXVER: - value = (UINT)hAacEncoder->aacConfig.audioMuxVersion; - break; + value = (UINT)hAacEncoder->aacConfig.audioMuxVersion; + break; case AACENC_TPSUBFRAMES: - value = (UINT)settings->userTpNsubFrames; - break; + value = (UINT)settings->userTpNsubFrames; + break; case AACENC_ANCILLARY_BITRATE: - value = (UINT)hAacEncoder->aacConfig.anc_Rate; - break; + value = (UINT)hAacEncoder->aacConfig.anc_Rate; + break; case AACENC_CONTROL_STATE: - value = (UINT)hAacEncoder->InitFlags; - break; + value = (UINT)hAacEncoder->InitFlags; + break; case AACENC_METADATA_MODE: - value = (hAacEncoder->metaDataAllowed==0) ? 0 : (UINT)settings->userMetaDataMode; - break; + value = (hAacEncoder->metaDataAllowed == 0) + ? 0 + : (UINT)settings->userMetaDataMode; + break; case AACENC_PEAK_BITRATE: - value = (UINT)-1; /* peak bitrate parameter is meaningless */ - if ( ((INT)hAacEncoder->extParam.userPeakBitrate!=-1) ) { - value = (UINT)(fMax((INT)hAacEncoder->extParam.userPeakBitrate, hAacEncoder->aacConfig.bitRate)); /* peak bitrate parameter is in use */ - } - break; + value = (UINT)-1; /* peak bitrate parameter is meaningless */ + if (((INT)hAacEncoder->extParam.userPeakBitrate != -1)) { + value = + (UINT)(fMax((INT)hAacEncoder->extParam.userPeakBitrate, + hAacEncoder->aacConfig + .bitRate)); /* peak bitrate parameter is in use */ + } + break; + default: - //err = MPS_INVALID_PARAMETER; + // err = MPS_INVALID_PARAMETER; break; - } /* switch(param) */ + } /* switch(param) */ bail: - return value; + return value; } -AACENC_ERROR aacEncInfo( - const HANDLE_AACENCODER hAacEncoder, - AACENC_InfoStruct *pInfo - ) -{ - AACENC_ERROR err = AACENC_OK; - - FDKmemclear(pInfo, sizeof(AACENC_InfoStruct)); - pInfo->confSize = 64; /* pre-initialize */ - - pInfo->maxOutBufBytes = ((hAacEncoder->nMaxAacChannels*6144)+7)>>3; - pInfo->maxAncBytes = hAacEncoder->aacConfig.maxAncBytesPerAU; - pInfo->inBufFillLevel = hAacEncoder->nSamplesRead/hAacEncoder->extParam.nChannels; - pInfo->inputChannels = hAacEncoder->extParam.nChannels; - pInfo->frameLength = hAacEncoder->nSamplesToRead/hAacEncoder->extParam.nChannels; - pInfo->encoderDelay = hAacEncoder->nDelay/hAacEncoder->extParam.nChannels; - - /* Get encoder configuration */ - if ( aacEncGetConf(hAacEncoder, &pInfo->confSize, &pInfo->confBuf[0]) != AAC_ENC_OK) { - err = AACENC_INIT_ERROR; - goto bail; - } +AACENC_ERROR aacEncInfo(const HANDLE_AACENCODER hAacEncoder, + AACENC_InfoStruct *pInfo) { + AACENC_ERROR err = AACENC_OK; + + FDKmemclear(pInfo, sizeof(AACENC_InfoStruct)); + pInfo->confSize = 64; /* pre-initialize */ + + pInfo->maxOutBufBytes = ((hAacEncoder->nMaxAacChannels * 6144) + 7) >> 3; + pInfo->maxAncBytes = hAacEncoder->aacConfig.maxAncBytesPerAU; + pInfo->inBufFillLevel = + hAacEncoder->nSamplesRead / hAacEncoder->extParam.nChannels; + pInfo->inputChannels = hAacEncoder->extParam.nChannels; + pInfo->frameLength = + hAacEncoder->nSamplesToRead / hAacEncoder->extParam.nChannels; + pInfo->nDelay = hAacEncoder->nDelay; + pInfo->nDelayCore = hAacEncoder->nDelayCore; + + /* Get encoder configuration */ + if (aacEncGetConf(hAacEncoder, &pInfo->confSize, &pInfo->confBuf[0]) != + AAC_ENC_OK) { + err = AACENC_INIT_ERROR; + goto bail; + } bail: - return err; + return err; } - diff --git a/libAACenc/src/aacenc_pns.cpp b/libAACenc/src/aacenc_pns.cpp index b9640d9..f0571d6 100644 --- a/libAACenc/src/aacenc_pns.cpp +++ b/libAACenc/src/aacenc_pns.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,43 +90,37 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Lohwasser - Initial author: M. Lohwasser - contents/description: pns.c + Description: pns.c -******************************************************************************/ +*******************************************************************************/ #include "aacenc_pns.h" + #include "psy_data.h" #include "pnsparam.h" #include "noisedet.h" #include "bit_cnt.h" #include "interface.h" - /* minCorrelationEnergy = (1.0e-10f)^2 ~ 2^-67 = 2^-47 * 2^-20 */ -static const FIXP_DBL minCorrelationEnergy = FL2FXCONST_DBL(0.0); /* FL2FXCONST_DBL((float)FDKpow(2.0,-47)); */ +static const FIXP_DBL minCorrelationEnergy = + FL2FXCONST_DBL(0.0); /* FL2FXCONST_DBL((float)FDKpow(2.0,-47)); */ /* noiseCorrelationThresh = 0.6^2 */ static const FIXP_DBL noiseCorrelationThresh = FL2FXCONST_DBL(0.36); -static void FDKaacEnc_FDKaacEnc_noiseDetection( PNS_CONFIG *pnsConf, - PNS_DATA *pnsData, - const INT sfbActive, - const INT *sfbOffset, - INT tnsOrder, - INT tnsPredictionGain, - INT tnsActive, - FIXP_DBL *mdctSpectrum, - INT *sfbMaxScaleSpec, - FIXP_SGL *sfbtonality ); - -static void FDKaacEnc_CalcNoiseNrgs( const INT sfbActive, - INT *pnsFlag, - FIXP_DBL *sfbEnergyLdData, - INT *noiseNrg ); +static void FDKaacEnc_FDKaacEnc_noiseDetection( + PNS_CONFIG *pnsConf, PNS_DATA *pnsData, const INT sfbActive, + const INT *sfbOffset, INT tnsOrder, INT tnsPredictionGain, INT tnsActive, + FIXP_DBL *mdctSpectrum, INT *sfbMaxScaleSpec, FIXP_SGL *sfbtonality); + +static void FDKaacEnc_CalcNoiseNrgs(const INT sfbActive, INT *pnsFlag, + FIXP_DBL *sfbEnergyLdData, INT *noiseNrg); /***************************************************************************** @@ -129,28 +134,15 @@ static void FDKaacEnc_CalcNoiseNrgs( const INT sfbActive, *****************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_InitPnsConfiguration(PNS_CONFIG *pnsConf, - INT bitRate, - INT sampleRate, - INT usePns, - INT sfbCnt, - const INT *sfbOffset, - const INT numChan, - const INT isLC) -{ +AAC_ENCODER_ERROR FDKaacEnc_InitPnsConfiguration( + PNS_CONFIG *pnsConf, INT bitRate, INT sampleRate, INT usePns, INT sfbCnt, + const INT *sfbOffset, const INT numChan, const INT isLC) { AAC_ENCODER_ERROR ErrorStatus; /* init noise detection */ - ErrorStatus = FDKaacEnc_GetPnsParam(&pnsConf->np, - bitRate, - sampleRate, - sfbCnt, - sfbOffset, - &usePns, - numChan, - isLC); - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; + ErrorStatus = FDKaacEnc_GetPnsParam(&pnsConf->np, bitRate, sampleRate, sfbCnt, + sfbOffset, &usePns, numChan, isLC); + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; pnsConf->minCorrelationEnergy = minCorrelationEnergy; pnsConf->noiseCorrelationThresh = noiseCorrelationThresh; @@ -160,8 +152,6 @@ AAC_ENCODER_ERROR FDKaacEnc_InitPnsConfiguration(PNS_CONFIG *pnsConf, return AAC_ENC_OK; } - - /***************************************************************************** functionname: FDKaacEnc_PnsDetect @@ -180,73 +170,55 @@ AAC_ENCODER_ERROR FDKaacEnc_InitPnsConfiguration(PNS_CONFIG *pnsConf, output: pnsFlag in pns data structure *****************************************************************************/ -void FDKaacEnc_PnsDetect(PNS_CONFIG *pnsConf, - PNS_DATA *pnsData, - const INT lastWindowSequence, - const INT sfbActive, - const INT maxSfbPerGroup, - FIXP_DBL *sfbThresholdLdData, - const INT *sfbOffset, - FIXP_DBL *mdctSpectrum, - INT *sfbMaxScaleSpec, - FIXP_SGL *sfbtonality, - INT tnsOrder, - INT tnsPredictionGain, - INT tnsActive, - FIXP_DBL *sfbEnergyLdData, - INT *noiseNrg ) +void FDKaacEnc_PnsDetect(PNS_CONFIG *pnsConf, PNS_DATA *pnsData, + const INT lastWindowSequence, const INT sfbActive, + const INT maxSfbPerGroup, FIXP_DBL *sfbThresholdLdData, + const INT *sfbOffset, FIXP_DBL *mdctSpectrum, + INT *sfbMaxScaleSpec, FIXP_SGL *sfbtonality, + INT tnsOrder, INT tnsPredictionGain, INT tnsActive, + FIXP_DBL *sfbEnergyLdData, INT *noiseNrg) { int sfb; int startNoiseSfb; - if (pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMLEXITY) { - if ( (!pnsConf->usePns) || /* pns enabled? */ - (lastWindowSequence == SHORT_WINDOW) ) /* currently only long blocks */ - { - FDKmemclear(pnsData->pnsFlag, MAX_GROUPED_SFB*sizeof(INT)); /* clear all pnsFlags */ - for (sfb=0; sfbpnsFlag, sizeof(pnsData->pnsFlag)); + for (sfb = 0; sfb < MAX_GROUPED_SFB; sfb++) { + noiseNrg[sfb] = NO_NOISE_PNS; + } + + /* Disable PNS and skip detection in certain cases. */ + if (pnsConf->usePns == 0) { + return; + } else { + /* AAC - LC core encoder */ + if ((pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMPLEXITY) && + (lastWindowSequence == SHORT_WINDOW)) { return; } - } - else { - if(!pnsConf->usePns) + /* AAC - (E)LD core encoder */ + if (!(pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMPLEXITY) && + (pnsConf->np.detectionAlgorithmFlags & JUST_LONG_WINDOW) && + (lastWindowSequence != LONG_WINDOW)) { return; - - /* PNS only for long Windows */ - if (pnsConf->np.detectionAlgorithmFlags & JUST_LONG_WINDOW) { - if(lastWindowSequence != LONG_WINDOW) { - for (sfb = 0; sfb < sfbActive; sfb++) { - pnsData->pnsFlag[sfb] = 0; /* clear all pnsFlags */ - } - return; - } } } + /* call noise detection */ - FDKaacEnc_FDKaacEnc_noiseDetection( pnsConf, - pnsData, - sfbActive, - sfbOffset, - tnsOrder, - tnsPredictionGain, - tnsActive, - mdctSpectrum, - sfbMaxScaleSpec, - sfbtonality ); + FDKaacEnc_FDKaacEnc_noiseDetection( + pnsConf, pnsData, sfbActive, sfbOffset, tnsOrder, tnsPredictionGain, + tnsActive, mdctSpectrum, sfbMaxScaleSpec, sfbtonality); /* set startNoiseSfb (long) */ startNoiseSfb = pnsConf->np.startSfb; /* Set noise substitution status */ - for(sfb = 0; sfb < sfbActive; sfb++) { - + for (sfb = 0; sfb < sfbActive; sfb++) { /* No PNS below startNoiseSfb */ - if(sfb < startNoiseSfb){ + if (sfb < startNoiseSfb) { pnsData->pnsFlag[sfb] = 0; continue; } @@ -258,17 +230,17 @@ void FDKaacEnc_PnsDetect(PNS_CONFIG *pnsConf, signal in coder band is not masked */ - if((pnsData->noiseFuzzyMeasure[sfb] > FL2FXCONST_SGL(0.5)) && - ( (sfbThresholdLdData[sfb] + FL2FXCONST_DBL(0.5849625f/64.0f)) /* thr * 1.5 = thrLd +ld(1.5)/64 */ - < sfbEnergyLdData[sfb] ) ) - { + if ((pnsData->noiseFuzzyMeasure[sfb] > FL2FXCONST_SGL(0.5)) && + ((sfbThresholdLdData[sfb] + + FL2FXCONST_DBL(0.5849625f / + 64.0f)) /* thr * 1.5 = thrLd +ld(1.5)/64 */ + < sfbEnergyLdData[sfb])) { /* mark in psyout flag array that we will code this band with PNS */ pnsData->pnsFlag[sfb] = 1; /* PNS_ON */ - } - else{ + } else { pnsData->pnsFlag[sfb] = 0; /* PNS_OFF */ } @@ -276,50 +248,49 @@ void FDKaacEnc_PnsDetect(PNS_CONFIG *pnsConf, } /* avoid PNS holes */ - if((pnsData->noiseFuzzyMeasure[0]>FL2FXCONST_SGL(0.5f)) && (pnsData->pnsFlag[1])) { + if ((pnsData->noiseFuzzyMeasure[0] > FL2FXCONST_SGL(0.5f)) && + (pnsData->pnsFlag[1])) { pnsData->pnsFlag[0] = 1; } - for(sfb=1; sfbnoiseFuzzyMeasure[sfb]>pnsConf->np.gapFillThr) && - (pnsData->pnsFlag[sfb-1]) && (pnsData->pnsFlag[sfb+1])) { + for (sfb = 1; sfb < maxSfbPerGroup - 1; sfb++) { + if ((pnsData->noiseFuzzyMeasure[sfb] > pnsConf->np.gapFillThr) && + (pnsData->pnsFlag[sfb - 1]) && (pnsData->pnsFlag[sfb + 1])) { pnsData->pnsFlag[sfb] = 1; } } - if(maxSfbPerGroup>0) { + if (maxSfbPerGroup > 0) { /* avoid PNS hole */ - if((pnsData->noiseFuzzyMeasure[maxSfbPerGroup-1]>pnsConf->np.gapFillThr) && (pnsData->pnsFlag[maxSfbPerGroup-2])) { - pnsData->pnsFlag[maxSfbPerGroup-1] = 1; + if ((pnsData->noiseFuzzyMeasure[maxSfbPerGroup - 1] > + pnsConf->np.gapFillThr) && + (pnsData->pnsFlag[maxSfbPerGroup - 2])) { + pnsData->pnsFlag[maxSfbPerGroup - 1] = 1; } /* avoid single PNS band */ - if(pnsData->pnsFlag[maxSfbPerGroup-2]==0) { - pnsData->pnsFlag[maxSfbPerGroup-1] = 0; + if (pnsData->pnsFlag[maxSfbPerGroup - 2] == 0) { + pnsData->pnsFlag[maxSfbPerGroup - 1] = 0; } } /* avoid single PNS bands */ - if(pnsData->pnsFlag[1]==0) { + if (pnsData->pnsFlag[1] == 0) { pnsData->pnsFlag[0] = 0; } - for(sfb=1; sfbpnsFlag[sfb-1]==0)&&(pnsData->pnsFlag[sfb+1]==0)) { + for (sfb = 1; sfb < maxSfbPerGroup - 1; sfb++) { + if ((pnsData->pnsFlag[sfb - 1] == 0) && (pnsData->pnsFlag[sfb + 1] == 0)) { pnsData->pnsFlag[sfb] = 0; } } - /* calculate noiseNrg's */ - FDKaacEnc_CalcNoiseNrgs( sfbActive, - pnsData->pnsFlag, - sfbEnergyLdData, - noiseNrg ); + FDKaacEnc_CalcNoiseNrgs(sfbActive, pnsData->pnsFlag, sfbEnergyLdData, + noiseNrg); } - /***************************************************************************** functionname:FDKaacEnc_FDKaacEnc_noiseDetection @@ -335,49 +306,36 @@ void FDKaacEnc_PnsDetect(PNS_CONFIG *pnsConf, flags tonal / nontonal *****************************************************************************/ -static void FDKaacEnc_FDKaacEnc_noiseDetection( PNS_CONFIG *pnsConf, - PNS_DATA *pnsData, - const INT sfbActive, - const INT *sfbOffset, - int tnsOrder, - INT tnsPredictionGain, - INT tnsActive, - FIXP_DBL *mdctSpectrum, - INT *sfbMaxScaleSpec, - FIXP_SGL *sfbtonality ) -{ - INT condition = TRUE; - if ( !(pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMLEXITY) ) { - condition = (tnsOrder > 3); - } +static void FDKaacEnc_FDKaacEnc_noiseDetection( + PNS_CONFIG *pnsConf, PNS_DATA *pnsData, const INT sfbActive, + const INT *sfbOffset, int tnsOrder, INT tnsPredictionGain, INT tnsActive, + FIXP_DBL *mdctSpectrum, INT *sfbMaxScaleSpec, FIXP_SGL *sfbtonality) { + INT condition = TRUE; + if (!(pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMPLEXITY)) { + condition = (tnsOrder > 3); + } + /* + no PNS if heavy TNS activity + clear pnsData->noiseFuzzyMeasure + */ + if ((pnsConf->np.detectionAlgorithmFlags & USE_TNS_GAIN_THR) && + (tnsPredictionGain >= pnsConf->np.tnsGainThreshold) && condition && + !((pnsConf->np.detectionAlgorithmFlags & USE_TNS_PNS) && + (tnsPredictionGain >= pnsConf->np.tnsPNSGainThreshold) && + (tnsActive))) { + /* clear all noiseFuzzyMeasure */ + FDKmemclear(pnsData->noiseFuzzyMeasure, sfbActive * sizeof(FIXP_SGL)); + } else { /* - no PNS if heavy TNS activity - clear pnsData->noiseFuzzyMeasure + call noise detection, output in pnsData->noiseFuzzyMeasure, + use real mdct spectral data */ - if((pnsConf->np.detectionAlgorithmFlags & USE_TNS_GAIN_THR) && - (tnsPredictionGain >= pnsConf->np.tnsGainThreshold) && condition && - !((pnsConf->np.detectionAlgorithmFlags & USE_TNS_PNS) && (tnsPredictionGain >= pnsConf->np.tnsPNSGainThreshold) && (tnsActive)) ) - { - /* clear all noiseFuzzyMeasure */ - FDKmemclear(pnsData->noiseFuzzyMeasure, sfbActive*sizeof(FIXP_SGL)); - } - else - { - /* - call noise detection, output in pnsData->noiseFuzzyMeasure, - use real mdct spectral data - */ - FDKaacEnc_noiseDetect( mdctSpectrum, - sfbMaxScaleSpec, - sfbActive, - sfbOffset, - pnsData->noiseFuzzyMeasure, - &pnsConf->np, - sfbtonality); - } + FDKaacEnc_noiseDetect(mdctSpectrum, sfbMaxScaleSpec, sfbActive, sfbOffset, + pnsData->noiseFuzzyMeasure, &pnsConf->np, + sfbtonality); + } } - /***************************************************************************** functionname:FDKaacEnc_CalcNoiseNrgs @@ -391,23 +349,21 @@ static void FDKaacEnc_FDKaacEnc_noiseDetection( PNS_CONFIG *pnsConf, *****************************************************************************/ -static void FDKaacEnc_CalcNoiseNrgs( const INT sfbActive, - INT *RESTRICT pnsFlag, - FIXP_DBL *RESTRICT sfbEnergyLdData, - INT *RESTRICT noiseNrg ) -{ +static void FDKaacEnc_CalcNoiseNrgs(const INT sfbActive, INT *RESTRICT pnsFlag, + FIXP_DBL *RESTRICT sfbEnergyLdData, + INT *RESTRICT noiseNrg) { int sfb; - INT tmp = (-LOG_NORM_PCM)<<2; + INT tmp = (-LOG_NORM_PCM) << 2; - for(sfb = 0; sfb < sfbActive; sfb++) { - if(pnsFlag[sfb]) { - INT nrg = (-sfbEnergyLdData[sfb]+FL2FXCONST_DBL(0.5f/64.0f))>>(DFRACT_BITS-1-7); + for (sfb = 0; sfb < sfbActive; sfb++) { + if (pnsFlag[sfb]) { + INT nrg = (-sfbEnergyLdData[sfb] + FL2FXCONST_DBL(0.5f / 64.0f)) >> + (DFRACT_BITS - 1 - 7); noiseNrg[sfb] = tmp - nrg; } } } - /***************************************************************************** functionname:FDKaacEnc_CodePnsChannel @@ -422,20 +378,18 @@ static void FDKaacEnc_CalcNoiseNrgs( const INT sfbActive, *****************************************************************************/ -void FDKaacEnc_CodePnsChannel(const INT sfbActive, - PNS_CONFIG *pnsConf, - INT *RESTRICT pnsFlag, - FIXP_DBL *RESTRICT sfbEnergyLdData, - INT *RESTRICT noiseNrg, - FIXP_DBL *RESTRICT sfbThresholdLdData) -{ +void FDKaacEnc_CodePnsChannel(const INT sfbActive, PNS_CONFIG *pnsConf, + INT *RESTRICT pnsFlag, + FIXP_DBL *RESTRICT sfbEnergyLdData, + INT *RESTRICT noiseNrg, + FIXP_DBL *RESTRICT sfbThresholdLdData) { INT sfb; INT lastiNoiseEnergy = 0; INT firstPNSband = 1; /* TRUE for first PNS-coded band */ /* no PNS */ - if(!pnsConf->usePns) { - for(sfb = 0; sfb < sfbActive; sfb++) { + if (!pnsConf->usePns) { + for (sfb = 0; sfb < sfbActive; sfb++) { /* no PNS coding */ noiseNrg[sfb] = NO_NOISE_PNS; } @@ -443,34 +397,32 @@ void FDKaacEnc_CodePnsChannel(const INT sfbActive, } /* code PNS */ - for(sfb = 0; sfb < sfbActive; sfb++) { - if(pnsFlag[sfb]) { + for (sfb = 0; sfb < sfbActive; sfb++) { + if (pnsFlag[sfb]) { /* high sfbThreshold causes pe = 0 */ - if(noiseNrg[sfb] != NO_NOISE_PNS) - sfbThresholdLdData[sfb] = sfbEnergyLdData[sfb] + FL2FXCONST_DBL(1.0f/LD_DATA_SCALING); + if (noiseNrg[sfb] != NO_NOISE_PNS) + sfbThresholdLdData[sfb] = + sfbEnergyLdData[sfb] + FL2FXCONST_DBL(1.0f / LD_DATA_SCALING); /* set noiseNrg in valid region */ - if(!firstPNSband) { + if (!firstPNSband) { INT deltaiNoiseEnergy = noiseNrg[sfb] - lastiNoiseEnergy; - if(deltaiNoiseEnergy > CODE_BOOK_PNS_LAV) - noiseNrg[sfb] -= deltaiNoiseEnergy - CODE_BOOK_PNS_LAV; - else if(deltaiNoiseEnergy < -CODE_BOOK_PNS_LAV) - noiseNrg[sfb] -= deltaiNoiseEnergy + CODE_BOOK_PNS_LAV; - } - else { + if (deltaiNoiseEnergy > CODE_BOOK_PNS_LAV) + noiseNrg[sfb] -= deltaiNoiseEnergy - CODE_BOOK_PNS_LAV; + else if (deltaiNoiseEnergy < -CODE_BOOK_PNS_LAV) + noiseNrg[sfb] -= deltaiNoiseEnergy + CODE_BOOK_PNS_LAV; + } else { firstPNSband = 0; } lastiNoiseEnergy = noiseNrg[sfb]; - } - else { + } else { /* no PNS coding */ noiseNrg[sfb] = NO_NOISE_PNS; } } } - /***************************************************************************** functionname:FDKaacEnc_PreProcessPnsChannelPair @@ -486,37 +438,40 @@ void FDKaacEnc_CodePnsChannel(const INT sfbActive, *****************************************************************************/ -void FDKaacEnc_PreProcessPnsChannelPair(const INT sfbActive, - FIXP_DBL *RESTRICT sfbEnergyLeft, - FIXP_DBL *RESTRICT sfbEnergyRight, - FIXP_DBL *RESTRICT sfbEnergyLeftLD, - FIXP_DBL *RESTRICT sfbEnergyRightLD, - FIXP_DBL *RESTRICT sfbEnergyMid, - PNS_CONFIG *RESTRICT pnsConf, - PNS_DATA *pnsDataLeft, - PNS_DATA *pnsDataRight) -{ +void FDKaacEnc_PreProcessPnsChannelPair( + const INT sfbActive, FIXP_DBL *RESTRICT sfbEnergyLeft, + FIXP_DBL *RESTRICT sfbEnergyRight, FIXP_DBL *RESTRICT sfbEnergyLeftLD, + FIXP_DBL *RESTRICT sfbEnergyRightLD, FIXP_DBL *RESTRICT sfbEnergyMid, + PNS_CONFIG *RESTRICT pnsConf, PNS_DATA *pnsDataLeft, + PNS_DATA *pnsDataRight) { INT sfb; FIXP_DBL ccf; - if(!pnsConf->usePns) - return; + if (!pnsConf->usePns) return; - FIXP_DBL *RESTRICT pNoiseEnergyCorrelationL = pnsDataLeft->noiseEnergyCorrelation; - FIXP_DBL *RESTRICT pNoiseEnergyCorrelationR = pnsDataRight->noiseEnergyCorrelation; + FIXP_DBL *RESTRICT pNoiseEnergyCorrelationL = + pnsDataLeft->noiseEnergyCorrelation; + FIXP_DBL *RESTRICT pNoiseEnergyCorrelationR = + pnsDataRight->noiseEnergyCorrelation; - for(sfb=0;sfb< sfbActive;sfb++) { - FIXP_DBL quot = (sfbEnergyLeftLD[sfb]>>1) + (sfbEnergyRightLD[sfb]>>1); + for (sfb = 0; sfb < sfbActive; sfb++) { + FIXP_DBL quot = (sfbEnergyLeftLD[sfb] >> 1) + (sfbEnergyRightLD[sfb] >> 1); - if(quot < FL2FXCONST_DBL(-32.0f/(float)LD_DATA_SCALING)) + if (quot < FL2FXCONST_DBL(-32.0f / (float)LD_DATA_SCALING)) ccf = FL2FXCONST_DBL(0.0f); else { - FIXP_DBL accu = sfbEnergyMid[sfb]- (((sfbEnergyLeft[sfb]>>1)+(sfbEnergyRight[sfb]>>1))>>1); - INT sign = (accu < FL2FXCONST_DBL(0.0f)) ? 1 : 0 ; + FIXP_DBL accu = + sfbEnergyMid[sfb] - + (((sfbEnergyLeft[sfb] >> 1) + (sfbEnergyRight[sfb] >> 1)) >> 1); + INT sign = (accu < FL2FXCONST_DBL(0.0f)) ? 1 : 0; accu = fixp_abs(accu); - ccf = CalcLdData(accu) + FL2FXCONST_DBL((float)1.0f/(float)LD_DATA_SCALING) - quot; /* ld(accu*2) = ld(accu) + 1 */ - ccf = (ccf>=FL2FXCONST_DBL(0.0)) ? ((FIXP_DBL)MAXVAL_DBL) : (sign) ? -CalcInvLdData(ccf) : CalcInvLdData(ccf); + ccf = CalcLdData(accu) + + FL2FXCONST_DBL((float)1.0f / (float)LD_DATA_SCALING) - + quot; /* ld(accu*2) = ld(accu) + 1 */ + ccf = (ccf >= FL2FXCONST_DBL(0.0)) + ? ((FIXP_DBL)MAXVAL_DBL) + : (sign) ? -CalcInvLdData(ccf) : CalcInvLdData(ccf); } pNoiseEnergyCorrelationL[sfb] = ccf; @@ -524,8 +479,6 @@ void FDKaacEnc_PreProcessPnsChannelPair(const INT sfbActive, } } - - /***************************************************************************** functionname:FDKaacEnc_PostProcessPnsChannelPair @@ -542,33 +495,29 @@ void FDKaacEnc_PreProcessPnsChannelPair(const INT sfbActive, *****************************************************************************/ -void FDKaacEnc_PostProcessPnsChannelPair(const INT sfbActive, - PNS_CONFIG *pnsConf, - PNS_DATA *pnsDataLeft, - PNS_DATA *pnsDataRight, - INT *RESTRICT msMask, - INT *msDigest ) -{ +void FDKaacEnc_PostProcessPnsChannelPair(const INT sfbActive, + PNS_CONFIG *pnsConf, + PNS_DATA *pnsDataLeft, + PNS_DATA *pnsDataRight, + INT *RESTRICT msMask, INT *msDigest) { INT sfb; - if(!pnsConf->usePns) - return; + if (!pnsConf->usePns) return; - for(sfb=0;sfbpnsFlag[sfb]) && - (pnsDataRight->pnsFlag[sfb]) ) { + if (msMask[sfb]) { + if ((pnsDataLeft->pnsFlag[sfb]) && (pnsDataRight->pnsFlag[sfb])) { /* AAC only: Standard */ /* do this to avoid ms flags in layers that should not have it */ - if(pnsDataLeft->noiseEnergyCorrelation[sfb] <= pnsConf->noiseCorrelationThresh){ + if (pnsDataLeft->noiseEnergyCorrelation[sfb] <= + pnsConf->noiseCorrelationThresh) { msMask[sfb] = 0; *msDigest = MS_SOME; } - } - else { + } else { /* No PNS coding */ @@ -581,8 +530,9 @@ void FDKaacEnc_PostProcessPnsChannelPair(const INT sfbActive, Use MS flag to signal noise correlation if pns is active in both channels */ - if( (pnsDataLeft->pnsFlag[sfb]) && (pnsDataRight->pnsFlag[sfb]) ) { - if(pnsDataLeft->noiseEnergyCorrelation[sfb] > pnsConf->noiseCorrelationThresh) { + if ((pnsDataLeft->pnsFlag[sfb]) && (pnsDataRight->pnsFlag[sfb])) { + if (pnsDataLeft->noiseEnergyCorrelation[sfb] > + pnsConf->noiseCorrelationThresh) { msMask[sfb] = 1; *msDigest = MS_SOME; } diff --git a/libAACenc/src/aacenc_pns.h b/libAACenc/src/aacenc_pns.h index 3bda9de..4938fcf 100644 --- a/libAACenc/src/aacenc_pns.h +++ b/libAACenc/src/aacenc_pns.h @@ -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,35 +90,35 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M. Lohwasser - contents/description: pns.h + Author(s): M. Lohwasser -******************************************************************************/ + Description: pns.h -#ifndef __PNS_H -#define __PNS_H +*******************************************************************************/ -#include "common_fix.h" +#ifndef AACENC_PNS_H +#define AACENC_PNS_H +#include "common_fix.h" #include "pnsparam.h" #define NO_NOISE_PNS FDK_INT_MIN -typedef struct{ +typedef struct { NOISEPARAMS np; FIXP_DBL minCorrelationEnergy; FIXP_DBL noiseCorrelationThresh; - INT usePns; + INT usePns; } PNS_CONFIG; -typedef struct{ +typedef struct { FIXP_SGL noiseFuzzyMeasure[MAX_GROUPED_SFB]; FIXP_DBL noiseEnergyCorrelation[MAX_GROUPED_SFB]; - INT pnsFlag[MAX_GROUPED_SFB]; + INT pnsFlag[MAX_GROUPED_SFB]; } PNS_DATA; -#endif +#endif /* AACENC_PNS_H */ diff --git a/libAACenc/src/aacenc_tns.cpp b/libAACenc/src/aacenc_tns.cpp index 9a07e8f..4462600 100644 --- a/libAACenc/src/aacenc_tns.cpp +++ b/libAACenc/src/aacenc_tns.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): Alex Groeschel, Tobias Chalupka - Initial author: Alex Groeschel, Tobias Chalupka - contents/description: Temporal noise shaping + Description: Temporal noise shaping -******************************************************************************/ +*******************************************************************************/ #include "aacenc_tns.h" #include "psy_const.h" @@ -94,192 +106,213 @@ amm-info@iis.fraunhofer.de #include "tns_func.h" #include "aacEnc_rom.h" #include "aacenc_tns.h" +#include "FDK_lpc.h" #define FILTER_DIRECTION 0 /* 0 = up, 1 = down */ -static const FIXP_DBL acfWindowLong[12+3+1] = { - 0x7fffffff,0x7fb80000,0x7ee00000,0x7d780000,0x7b800000,0x78f80000,0x75e00000,0x72380000, - 0x6e000000,0x69380000,0x63e00000,0x5df80000,0x57800000,0x50780000,0x48e00000,0x40b80000 -}; +static const FIXP_DBL acfWindowLong[12 + 3 + 1] = { + 0x7fffffff, 0x7fb80000, 0x7ee00000, 0x7d780000, 0x7b800000, 0x78f80000, + 0x75e00000, 0x72380000, 0x6e000000, 0x69380000, 0x63e00000, 0x5df80000, + 0x57800000, 0x50780000, 0x48e00000, 0x40b80000}; -static const FIXP_DBL acfWindowShort[4+3+1] = { - 0x7fffffff,0x7e000000,0x78000000,0x6e000000,0x60000000,0x4e000000,0x38000000,0x1e000000 -}; +static const FIXP_DBL acfWindowShort[4 + 3 + 1] = { + 0x7fffffff, 0x7e000000, 0x78000000, 0x6e000000, + 0x60000000, 0x4e000000, 0x38000000, 0x1e000000}; -typedef struct{ - INT bitRateFrom[2]; /* noneSbr=0, useSbr=1 */ - INT bitRateTo[2]; /* noneSbr=0, useSbr=1 */ - TNS_PARAMETER_TABULATED paramTab[2]; /* mono=0, stereo=1 */ +typedef struct { + INT bitRateFrom[2]; /* noneSbr=0, useSbr=1 */ + INT bitRateTo[2]; /* noneSbr=0, useSbr=1 */ + TNS_PARAMETER_TABULATED paramTab[2]; /* mono=0, stereo=1 */ } TNS_INFO_TAB; -#define TNS_TIMERES_SCALE (1) -#define FL2_TIMERES_FIX(a) ( FL2FXCONST_DBL(a/(float)(1<= tnsInfoTab[i].bitRateFrom[sbrLd?1:0]) && - bitRate <= tnsInfoTab[i].bitRateTo[sbrLd?1:0]) - { - tnsConfigTab = &tnsInfoTab[i].paramTab[(channels==1)?0:1]; + for (i = 0; i < (int)(sizeof(tnsInfoTab) / sizeof(TNS_INFO_TAB)); i++) { + if ((bitRate >= tnsInfoTab[i].bitRateFrom[sbrLd ? 1 : 0]) && + bitRate <= tnsInfoTab[i].bitRateTo[sbrLd ? 1 : 0]) { + tnsConfigTab = &tnsInfoTab[i].paramTab[(channels == 1) ? 0 : 1]; } } return tnsConfigTab; } - -static INT getTnsMaxBands( - const INT sampleRate, - const INT granuleLength, - const INT isShortBlock - ) -{ +static INT getTnsMaxBands(const INT sampleRate, const INT granuleLength, + const INT isShortBlock) { int i; INT numBands = -1; const TNS_MAX_TAB_ENTRY *pMaxBandsTab = NULL; int maxBandsTabSize = 0; switch (granuleLength) { + case 960: case 1024: pMaxBandsTab = tnsMaxBandsTab1024; - maxBandsTabSize = sizeof(tnsMaxBandsTab1024)/sizeof(TNS_MAX_TAB_ENTRY); + maxBandsTabSize = sizeof(tnsMaxBandsTab1024) / sizeof(TNS_MAX_TAB_ENTRY); + break; + case 120: + pMaxBandsTab = tnsMaxBandsTab120; + maxBandsTabSize = sizeof(tnsMaxBandsTab120) / sizeof(TNS_MAX_TAB_ENTRY); + break; + case 128: + pMaxBandsTab = tnsMaxBandsTab128; + maxBandsTabSize = sizeof(tnsMaxBandsTab128) / sizeof(TNS_MAX_TAB_ENTRY); + break; + case 240: + pMaxBandsTab = tnsMaxBandsTab240; + maxBandsTabSize = sizeof(tnsMaxBandsTab240) / sizeof(TNS_MAX_TAB_ENTRY); + break; + case 256: + pMaxBandsTab = tnsMaxBandsTab256; + maxBandsTabSize = sizeof(tnsMaxBandsTab256) / sizeof(TNS_MAX_TAB_ENTRY); break; case 480: pMaxBandsTab = tnsMaxBandsTab480; - maxBandsTabSize = sizeof(tnsMaxBandsTab480)/sizeof(TNS_MAX_TAB_ENTRY); + maxBandsTabSize = sizeof(tnsMaxBandsTab480) / sizeof(TNS_MAX_TAB_ENTRY); break; case 512: pMaxBandsTab = tnsMaxBandsTab512; - maxBandsTabSize = sizeof(tnsMaxBandsTab512)/sizeof(TNS_MAX_TAB_ENTRY); + maxBandsTabSize = sizeof(tnsMaxBandsTab512) / sizeof(TNS_MAX_TAB_ENTRY); break; default: numBands = -1; } - if (pMaxBandsTab!=NULL) { - for (i=0; i= pMaxBandsTab[i].samplingRate) { break; } @@ -291,7 +324,7 @@ static INT getTnsMaxBands( /***************************************************************************/ /*! - \brief FDKaacEnc_FreqToBandWithRounding + \brief FDKaacEnc_FreqToBandWidthRounding Returns index of nearest band border @@ -303,38 +336,31 @@ static INT getTnsMaxBands( \return band border ****************************************************************************/ -INT FDKaacEnc_FreqToBandWithRounding( - const INT freq, - const INT fs, - const INT numOfBands, - const INT *bandStartOffset - ) -{ +INT FDKaacEnc_FreqToBandWidthRounding(const INT freq, const INT fs, + const INT numOfBands, + const INT *bandStartOffset) { INT lineNumber, band; /* assert(freq >= 0); */ - lineNumber = (freq*bandStartOffset[numOfBands]*4/fs+1)/2; + lineNumber = (freq * bandStartOffset[numOfBands] * 4 / fs + 1) / 2; /* freq > fs/2 */ - if (lineNumber >= bandStartOffset[numOfBands]) - return numOfBands; + if (lineNumber >= bandStartOffset[numOfBands]) return numOfBands; /* find band the line number lies in */ - for (band=0; bandlineNumber) break; + for (band = 0; band < numOfBands; band++) { + if (bandStartOffset[band + 1] > lineNumber) break; } /* round to nearest band border */ if (lineNumber - bandStartOffset[band] > - bandStartOffset[band+1] - lineNumber ) - { - band++; - } + bandStartOffset[band + 1] - lineNumber) { + band++; + } - return(band); + return (band); } - /***************************************************************************** functionname: FDKaacEnc_InitTnsConfiguration @@ -348,113 +374,132 @@ INT FDKaacEnc_FreqToBandWithRounding( output: *****************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitRate, - INT sampleRate, - INT channels, - INT blockType, - INT granuleLength, - INT isLowDelay, - INT ldSbrPresent, - TNS_CONFIG *tC, - PSY_CONFIGURATION *pC, - INT active, - INT useTnsPeak) -{ +AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration( + INT bitRate, INT sampleRate, INT channels, INT blockType, INT granuleLength, + INT isLowDelay, INT ldSbrPresent, TNS_CONFIG *tC, PSY_CONFIGURATION *pC, + INT active, INT useTnsPeak) { int i; - //float acfTimeRes = (blockType == SHORT_WINDOW) ? 0.125f : 0.046875f; + // float acfTimeRes = (blockType == SHORT_WINDOW) ? 0.125f : 0.046875f; - if (channels <= 0) - return (AAC_ENCODER_ERROR)1; + if (channels <= 0) return (AAC_ENCODER_ERROR)1; tC->isLowDelay = isLowDelay; - /* initialize TNS filter flag, order, and coefficient resolution (in bits per coeff) */ - tC->tnsActive = (active) ? TRUE : FALSE; - tC->maxOrder = (blockType == SHORT_WINDOW) ? 5 : 12; /* maximum: 7, 20 */ - if (bitRate < 16000) - tC->maxOrder -= 2; - tC->coefRes = (blockType == SHORT_WINDOW) ? 3 : 4; + /* initialize TNS filter flag, order, and coefficient resolution (in bits per + * coeff) */ + tC->tnsActive = (active) ? TRUE : FALSE; + tC->maxOrder = (blockType == SHORT_WINDOW) ? 5 : 12; /* maximum: 7, 20 */ + if (bitRate < 16000) tC->maxOrder -= 2; + tC->coefRes = (blockType == SHORT_WINDOW) ? 3 : 4; - /* LPC stop line: highest MDCT line to be coded, but do not go beyond TNS_MAX_BANDS! */ - tC->lpcStopBand = getTnsMaxBands(sampleRate, granuleLength, (blockType == SHORT_WINDOW) ? 1 : 0); + /* LPC stop line: highest MDCT line to be coded, but do not go beyond + * TNS_MAX_BANDS! */ + tC->lpcStopBand = getTnsMaxBands(sampleRate, granuleLength, + (blockType == SHORT_WINDOW) ? 1 : 0); if (tC->lpcStopBand < 0) { return (AAC_ENCODER_ERROR)1; } - tC->lpcStopBand = FDKmin(tC->lpcStopBand, pC->sfbActive); - tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand]; + tC->lpcStopBand = fMin(tC->lpcStopBand, pC->sfbActive); + tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand]; switch (granuleLength) { + case 960: case 1024: - /* TNS start line: skip lower MDCT lines to prevent artifacts due to filter mismatch */ - tC->lpcStartBand[LOFILT] = (blockType == SHORT_WINDOW) ? 0 : ((sampleRate < 18783) ? 4 : 8); - tC->lpcStartLine[LOFILT] = pC->sfbOffset[tC->lpcStartBand[LOFILT]]; + /* TNS start line: skip lower MDCT lines to prevent artifacts due to + * filter mismatch */ + if (blockType == SHORT_WINDOW) { + tC->lpcStartBand[LOFILT] = 0; + } else { + tC->lpcStartBand[LOFILT] = + (sampleRate < 9391) ? 2 : ((sampleRate < 18783) ? 4 : 8); + } + tC->lpcStartLine[LOFILT] = pC->sfbOffset[tC->lpcStartBand[LOFILT]]; i = tC->lpcStopBand; - while (pC->sfbOffset[i] > (tC->lpcStartLine[LOFILT] + (tC->lpcStopLine - tC->lpcStartLine[LOFILT]) / 4)) i--; - tC->lpcStartBand[HIFILT] = i; - tC->lpcStartLine[HIFILT] = pC->sfbOffset[i]; + while (pC->sfbOffset[i] > + (tC->lpcStartLine[LOFILT] + + (tC->lpcStopLine - tC->lpcStartLine[LOFILT]) / 4)) + i--; + tC->lpcStartBand[HIFILT] = i; + tC->lpcStartLine[HIFILT] = pC->sfbOffset[i]; tC->confTab.threshOn[HIFILT] = 1437; tC->confTab.threshOn[LOFILT] = 1500; tC->confTab.tnsLimitOrder[HIFILT] = tC->maxOrder; - tC->confTab.tnsLimitOrder[LOFILT] = tC->maxOrder - 7; + tC->confTab.tnsLimitOrder[LOFILT] = fMax(0, tC->maxOrder - 7); tC->confTab.tnsFilterDirection[HIFILT] = FILTER_DIRECTION; tC->confTab.tnsFilterDirection[LOFILT] = FILTER_DIRECTION; - tC->confTab.acfSplit[HIFILT] = -1; /* signal Merged4to2QuartersAutoCorrelation in FDKaacEnc_MergedAutoCorrelation*/ - tC->confTab.acfSplit[LOFILT] = -1; /* signal Merged4to2QuartersAutoCorrelation in FDKaacEnc_MergedAutoCorrelation */ + tC->confTab.acfSplit[HIFILT] = + -1; /* signal Merged4to2QuartersAutoCorrelation in + FDKaacEnc_MergedAutoCorrelation*/ + tC->confTab.acfSplit[LOFILT] = + -1; /* signal Merged4to2QuartersAutoCorrelation in + FDKaacEnc_MergedAutoCorrelation */ tC->confTab.filterEnabled[HIFILT] = 1; tC->confTab.filterEnabled[LOFILT] = 1; tC->confTab.seperateFiltersAllowed = 1; - /* compute autocorrelation window based on maximum filter order for given block type */ + /* compute autocorrelation window based on maximum filter order for given + * block type */ /* for (i = 0; i <= tC->maxOrder + 3; i++) { float acfWinTemp = acfTimeRes * i; acfWindow[i] = FL2FXCONST_DBL(1.0f - acfWinTemp * acfWinTemp); } */ if (blockType == SHORT_WINDOW) { - FDKmemcpy(tC->acfWindow[HIFILT], acfWindowShort, FDKmin(sizeof(acfWindowShort), sizeof(tC->acfWindow[HIFILT]))); - FDKmemcpy(tC->acfWindow[LOFILT], acfWindowShort, FDKmin(sizeof(acfWindowShort), sizeof(tC->acfWindow[HIFILT]))); - } - else { - FDKmemcpy(tC->acfWindow[HIFILT], acfWindowLong, FDKmin(sizeof(acfWindowLong), sizeof(tC->acfWindow[HIFILT]))); - FDKmemcpy(tC->acfWindow[LOFILT], acfWindowLong, FDKmin(sizeof(acfWindowLong), sizeof(tC->acfWindow[HIFILT]))); + FDKmemcpy(tC->acfWindow[HIFILT], acfWindowShort, + fMin((LONG)sizeof(acfWindowShort), + (LONG)sizeof(tC->acfWindow[HIFILT]))); + FDKmemcpy(tC->acfWindow[LOFILT], acfWindowShort, + fMin((LONG)sizeof(acfWindowShort), + (LONG)sizeof(tC->acfWindow[HIFILT]))); + } else { + FDKmemcpy(tC->acfWindow[HIFILT], acfWindowLong, + fMin((LONG)sizeof(acfWindowLong), + (LONG)sizeof(tC->acfWindow[HIFILT]))); + FDKmemcpy(tC->acfWindow[LOFILT], acfWindowLong, + fMin((LONG)sizeof(acfWindowLong), + (LONG)sizeof(tC->acfWindow[HIFILT]))); } break; case 480: - case 512: - { - const TNS_PARAMETER_TABULATED* pCfg = FDKaacEnc_GetTnsParam(bitRate, channels, ldSbrPresent); - - if ( pCfg != NULL ) { - - FDKmemcpy(&(tC->confTab), pCfg, sizeof(tC->confTab)); - - tC->lpcStartBand[HIFILT] = FDKaacEnc_FreqToBandWithRounding(pCfg->filterStartFreq[HIFILT], sampleRate, pC->sfbCnt, pC->sfbOffset); - tC->lpcStartLine[HIFILT] = pC->sfbOffset[tC->lpcStartBand[HIFILT]]; - tC->lpcStartBand[LOFILT] = FDKaacEnc_FreqToBandWithRounding(pCfg->filterStartFreq[LOFILT], sampleRate, pC->sfbCnt, pC->sfbOffset); - tC->lpcStartLine[LOFILT] = pC->sfbOffset[tC->lpcStartBand[LOFILT]]; - - FDKaacEnc_CalcGaussWindow(tC->acfWindow[HIFILT], tC->maxOrder+1, sampleRate, granuleLength, pCfg->tnsTimeResolution[HIFILT], TNS_TIMERES_SCALE); - FDKaacEnc_CalcGaussWindow(tC->acfWindow[LOFILT], tC->maxOrder+1, sampleRate, granuleLength, pCfg->tnsTimeResolution[LOFILT], TNS_TIMERES_SCALE); - } - else { - tC->tnsActive = FALSE; /* no configuration available, disable tns tool */ - } + case 512: { + const TNS_PARAMETER_TABULATED *pCfg = + FDKaacEnc_GetTnsParam(bitRate, channels, ldSbrPresent); + if (pCfg != NULL) { + FDKmemcpy(&(tC->confTab), pCfg, sizeof(tC->confTab)); + + tC->lpcStartBand[HIFILT] = FDKaacEnc_FreqToBandWidthRounding( + pCfg->filterStartFreq[HIFILT], sampleRate, pC->sfbCnt, + pC->sfbOffset); + tC->lpcStartLine[HIFILT] = pC->sfbOffset[tC->lpcStartBand[HIFILT]]; + tC->lpcStartBand[LOFILT] = FDKaacEnc_FreqToBandWidthRounding( + pCfg->filterStartFreq[LOFILT], sampleRate, pC->sfbCnt, + pC->sfbOffset); + tC->lpcStartLine[LOFILT] = pC->sfbOffset[tC->lpcStartBand[LOFILT]]; + + FDKaacEnc_CalcGaussWindow( + tC->acfWindow[HIFILT], tC->maxOrder + 1, sampleRate, granuleLength, + pCfg->tnsTimeResolution[HIFILT], TNS_TIMERES_SCALE); + FDKaacEnc_CalcGaussWindow( + tC->acfWindow[LOFILT], tC->maxOrder + 1, sampleRate, granuleLength, + pCfg->tnsTimeResolution[LOFILT], TNS_TIMERES_SCALE); + } else { + tC->tnsActive = + FALSE; /* no configuration available, disable tns tool */ } - break; + } break; default: tC->tnsActive = FALSE; /* no configuration available, disable tns tool */ } return AAC_ENC_OK; - } /***************************************************************************/ @@ -471,29 +516,25 @@ AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitRate, \return scale factor ****************************************************************************/ -static inline INT FDKaacEnc_ScaleUpSpectrum( - FIXP_DBL *dest, - const FIXP_DBL *src, - const INT startLine, - const INT stopLine - ) -{ - INT i, scale; - - FIXP_DBL maxVal = FL2FXCONST_DBL(0.f); - - /* Get highest value in given spectrum */ - for (i=startLine; i>scale); - } +static inline FIXP_DBL FDKaacEnc_CalcAutoCorrValue(const FIXP_DBL *spectrum, + const INT startLine, + const INT stopLine, + const INT lag, + const INT scale) { + int i; + FIXP_DBL result = FL2FXCONST_DBL(0.f); + + /* This versions allows to save memory accesses, when computing pow2 */ + /* It is of interest for ARM, XTENSA without parallel memory access */ + if (lag == 0) { + for (i = startLine; i < stopLine; i++) { + result += (fPow2(spectrum[i]) >> scale); } - else { - for (i=startLine; i<(stopLine-lag); i++) { - result += (fMult(spectrum[i], spectrum[i+lag])>>scale); - } + } else { + for (i = startLine; i < (stopLine - lag); i++) { + result += (fMult(spectrum[i], spectrum[i + lag]) >> scale); } + } - return result; + return result; } /***************************************************************************/ @@ -545,172 +584,173 @@ static inline FIXP_DBL FDKaacEnc_CalcAutoCorrValue( \param filter start line ****************************************************************************/ -static inline FIXP_DBL FDKaacEnc_AutoCorrNormFac( - const FIXP_DBL value, - const INT scale, - INT *sc - ) -{ - #define HLM_MIN_NRG 0.0000000037252902984619140625f /* 2^-28 */ - #define MAX_INV_NRGFAC (1.f/HLM_MIN_NRG) - - FIXP_DBL retValue; - FIXP_DBL A, B; - - if (scale>=0) { - A = value; - B = FL2FXCONST_DBL(HLM_MIN_NRG)>>fixMin(DFRACT_BITS-1,scale); - } - else { - A = value>>fixMin(DFRACT_BITS-1,(-scale)); - B = FL2FXCONST_DBL(HLM_MIN_NRG); - } +static inline FIXP_DBL FDKaacEnc_AutoCorrNormFac(const FIXP_DBL value, + const INT scale, INT *sc) { +#define HLM_MIN_NRG 0.0000000037252902984619140625f /* 2^-28 */ +#define MAX_INV_NRGFAC (1.f / HLM_MIN_NRG) - if (A > B) { - int shift = 0; - FIXP_DBL tmp = invSqrtNorm2(value,&shift); + FIXP_DBL retValue; + FIXP_DBL A, B; - retValue = fMult(tmp,tmp); - *sc += (2*shift); - } - else { - /* MAX_INV_NRGFAC*FDKpow(2,-28) = 1/2^-28 * 2^-28 = 1.0 */ - retValue = /*FL2FXCONST_DBL(MAX_INV_NRGFAC*FDKpow(2,-28))*/ (FIXP_DBL)MAXVAL_DBL; - *sc += scale+28; - } + if (scale >= 0) { + A = value; + B = FL2FXCONST_DBL(HLM_MIN_NRG) >> fixMin(DFRACT_BITS - 1, scale); + } else { + A = value >> fixMin(DFRACT_BITS - 1, (-scale)); + B = FL2FXCONST_DBL(HLM_MIN_NRG); + } + + if (A > B) { + int shift = 0; + FIXP_DBL tmp = invSqrtNorm2(value, &shift); - return retValue; + retValue = fMult(tmp, tmp); + *sc += (2 * shift); + } else { + /* MAX_INV_NRGFAC*FDKpow(2,-28) = 1/2^-28 * 2^-28 = 1.0 */ + retValue = + /*FL2FXCONST_DBL(MAX_INV_NRGFAC*FDKpow(2,-28))*/ (FIXP_DBL)MAXVAL_DBL; + *sc += scale + 28; + } + + return retValue; } static void FDKaacEnc_MergedAutoCorrelation( - const FIXP_DBL *spectrum, - const INT isLowDelay, - const FIXP_DBL acfWindow[MAX_NUM_OF_FILTERS][TNS_MAX_ORDER+3+1], - const INT lpcStartLine[MAX_NUM_OF_FILTERS], - const INT lpcStopLine, - const INT maxOrder, - const INT acfSplit[MAX_NUM_OF_FILTERS], - FIXP_DBL *_rxx1, - FIXP_DBL *_rxx2 - ) -{ - int i, idx0, idx1, idx2, idx3, idx4, lag; - FIXP_DBL rxx1_0, rxx2_0, rxx3_0, rxx4_0; - - /* buffer for temporal spectrum */ - C_ALLOC_SCRATCH_START(pSpectrum, FIXP_DBL, (1024)); - - /* pre-initialization output */ - FDKmemclear(&_rxx1[0], sizeof(FIXP_DBL)*(maxOrder+1)); - FDKmemclear(&_rxx2[0], sizeof(FIXP_DBL)*(maxOrder+1)); - - idx0 = idx1 = idx2 = idx3 = idx4 = 0; - - /* MDCT line indices separating the 1st, 2nd, 3rd, and 4th analysis quarters */ - if ( (acfSplit[LOFILT]==-1) || (acfSplit[HIFILT]==-1) ) { - /* autocorrelation function for 1st, 2nd, 3rd, and 4th quarter of the spectrum */ - idx0 = lpcStartLine[LOFILT]; - i = lpcStopLine - lpcStartLine[LOFILT]; - idx1 = idx0 + i / 4; - idx2 = idx0 + i / 2; - idx3 = idx0 + i * 3 / 4; - idx4 = lpcStopLine; - } - else { - FDK_ASSERT(acfSplit[LOFILT]==1); - FDK_ASSERT(acfSplit[HIFILT]==3); - i = (lpcStopLine - lpcStartLine[HIFILT]) / 3; - idx0 = lpcStartLine[LOFILT]; - idx1 = lpcStartLine[HIFILT]; - idx2 = idx1 + i; - idx3 = idx2 + i; - idx4 = lpcStopLine; - } + const FIXP_DBL *spectrum, const INT isLowDelay, + const FIXP_DBL acfWindow[MAX_NUM_OF_FILTERS][TNS_MAX_ORDER + 3 + 1], + const INT lpcStartLine[MAX_NUM_OF_FILTERS], const INT lpcStopLine, + const INT maxOrder, const INT acfSplit[MAX_NUM_OF_FILTERS], FIXP_DBL *_rxx1, + FIXP_DBL *_rxx2) { + int i, idx0, idx1, idx2, idx3, idx4, lag; + FIXP_DBL rxx1_0, rxx2_0, rxx3_0, rxx4_0; + + /* buffer for temporal spectrum */ + C_ALLOC_SCRATCH_START(pSpectrum, FIXP_DBL, (1024)) + + /* MDCT line indices separating the 1st, 2nd, 3rd, and 4th analysis quarters + */ + if ((acfSplit[LOFILT] == -1) || (acfSplit[HIFILT] == -1)) { + /* autocorrelation function for 1st, 2nd, 3rd, and 4th quarter of the + * spectrum */ + idx0 = lpcStartLine[LOFILT]; + i = lpcStopLine - lpcStartLine[LOFILT]; + idx1 = idx0 + i / 4; + idx2 = idx0 + i / 2; + idx3 = idx0 + i * 3 / 4; + idx4 = lpcStopLine; + } else { + FDK_ASSERT(acfSplit[LOFILT] == 1); + FDK_ASSERT(acfSplit[HIFILT] == 3); + i = (lpcStopLine - lpcStartLine[HIFILT]) / 3; + idx0 = lpcStartLine[LOFILT]; + idx1 = lpcStartLine[HIFILT]; + idx2 = idx1 + i; + idx3 = idx2 + i; + idx4 = lpcStopLine; + } - /* copy spectrum to temporal buffer and scale up as much as possible */ - INT sc1 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx0, idx1); - INT sc2 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx1, idx2); - INT sc3 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx2, idx3); - INT sc4 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx3, idx4); - - /* get scaling values for summation */ - INT nsc1, nsc2, nsc3, nsc4; - for (nsc1=1; (1<dataRaw.Short.subBlockInfo[subBlockNumber] - : &tnsData->dataRaw.Long.subBlockInfo; + FDKmemclear(rxx1, sizeof(rxx1)); + FDKmemclear(rxx2, sizeof(rxx2)); + + TNS_SUBBLOCK_INFO *tsbi = + (blockType == SHORT_WINDOW) + ? &tnsData->dataRaw.Short.subBlockInfo[subBlockNumber] + : &tnsData->dataRaw.Long.subBlockInfo; - tnsData->filtersMerged = FALSE; + tnsData->filtersMerged = FALSE; - tsbi->tnsActive[HIFILT] = FALSE; - tsbi->predictionGain[HIFILT] = 1000; - tsbi->tnsActive[LOFILT] = FALSE; - tsbi->predictionGain[LOFILT] = 1000; + tsbi->tnsActive[HIFILT] = FALSE; + tsbi->predictionGain[HIFILT] = 1000; + tsbi->tnsActive[LOFILT] = FALSE; + tsbi->predictionGain[LOFILT] = 1000; tnsInfo->numOfFilters[subBlockNumber] = 0; - tnsInfo->coefRes[subBlockNumber] = tC->coefRes; + tnsInfo->coefRes[subBlockNumber] = tC->coefRes; for (i = 0; i < tC->maxOrder; i++) { - tnsInfo->coef[subBlockNumber][HIFILT][i] = tnsInfo->coef[subBlockNumber][LOFILT][i] = 0; + tnsInfo->coef[subBlockNumber][HIFILT][i] = + tnsInfo->coef[subBlockNumber][LOFILT][i] = 0; } - tnsInfo->length[subBlockNumber][HIFILT] = tnsInfo->length[subBlockNumber][LOFILT] = 0; - tnsInfo->order [subBlockNumber][HIFILT] = tnsInfo->order [subBlockNumber][LOFILT] = 0; + tnsInfo->length[subBlockNumber][HIFILT] = + tnsInfo->length[subBlockNumber][LOFILT] = 0; + tnsInfo->order[subBlockNumber][HIFILT] = + tnsInfo->order[subBlockNumber][LOFILT] = 0; - if ( (tC->tnsActive) && (tC->maxOrder>0) ) - { + if ((tC->tnsActive) && (tC->maxOrder > 0)) { int sumSqrCoef; FDKaacEnc_MergedAutoCorrelation( - spectrum, - tC->isLowDelay, - tC->acfWindow, - tC->lpcStartLine, - tC->lpcStopLine, - tC->maxOrder, - tC->confTab.acfSplit, - rxx1, - rxx2); - - /* compute higher TNS filter in lattice (ParCor) form with LeRoux-Gueguen algorithm */ - tsbi->predictionGain[HIFILT] = FDKaacEnc_AutoToParcor(rxx2, parcor_tmp, tC->confTab.tnsLimitOrder[HIFILT]); - - /* non-linear quantization of TNS lattice coefficients with given resolution */ - FDKaacEnc_Parcor2Index( - parcor_tmp, - tnsInfo->coef[subBlockNumber][HIFILT], - tC->confTab.tnsLimitOrder[HIFILT], - tC->coefRes); - - /* reduce filter order by truncating trailing zeros, compute sum(abs(coefs)) */ + spectrum, tC->isLowDelay, tC->acfWindow, tC->lpcStartLine, + tC->lpcStopLine, tC->maxOrder, tC->confTab.acfSplit, rxx1, rxx2); + + /* compute higher TNS filter coefficients in lattice form (ParCor) with + * LeRoux-Gueguen/Schur algorithm */ + { + FIXP_DBL predictionGain_m; + INT predictionGain_e; + + CLpc_AutoToParcor(rxx2, 0, parcor_tmp, tC->confTab.tnsLimitOrder[HIFILT], + &predictionGain_m, &predictionGain_e); + tsbi->predictionGain[HIFILT] = + (INT)fMultNorm(predictionGain_m, predictionGain_e, 1000, 31, 31); + } + + /* non-linear quantization of TNS lattice coefficients with given resolution + */ + FDKaacEnc_Parcor2Index(parcor_tmp, tnsInfo->coef[subBlockNumber][HIFILT], + tC->confTab.tnsLimitOrder[HIFILT], tC->coefRes); + + /* reduce filter order by truncating trailing zeros, compute sum(abs(coefs)) + */ for (i = tC->confTab.tnsLimitOrder[HIFILT] - 1; i >= 0; i--) { if (tnsInfo->coef[subBlockNumber][HIFILT][i] != 0) { break; @@ -796,35 +837,49 @@ INT FDKaacEnc_TnsDetect( sumSqrCoef = 0; for (; i >= 0; i--) { - sumSqrCoef += tnsInfo->coef[subBlockNumber][HIFILT][i] * tnsInfo->coef[subBlockNumber][HIFILT][i]; + sumSqrCoef += tnsInfo->coef[subBlockNumber][HIFILT][i] * + tnsInfo->coef[subBlockNumber][HIFILT][i]; } - tnsInfo->direction[subBlockNumber][HIFILT] = tC->confTab.tnsFilterDirection[HIFILT]; + tnsInfo->direction[subBlockNumber][HIFILT] = + tC->confTab.tnsFilterDirection[HIFILT]; tnsInfo->length[subBlockNumber][HIFILT] = sfbCnt - tC->lpcStartBand[HIFILT]; - /* disable TNS if predictionGain is less than 3dB or sumSqrCoef is too small */ - if ((tsbi->predictionGain[HIFILT] > tC->confTab.threshOn[HIFILT]) || (sumSqrCoef > (tC->confTab.tnsLimitOrder[HIFILT]/2 + 2))) - { + /* disable TNS if predictionGain is less than 3dB or sumSqrCoef is too small + */ + if ((tsbi->predictionGain[HIFILT] > tC->confTab.threshOn[HIFILT]) || + (sumSqrCoef > (tC->confTab.tnsLimitOrder[HIFILT] / 2 + 2))) { tsbi->tnsActive[HIFILT] = TRUE; tnsInfo->numOfFilters[subBlockNumber]++; - /* compute second filter for lower quarter; only allowed for long windows! */ - if ( (blockType != SHORT_WINDOW) && - (tC->confTab.filterEnabled[LOFILT]) && (tC->confTab.seperateFiltersAllowed) ) - { + /* compute second filter for lower quarter; only allowed for long windows! + */ + if ((blockType != SHORT_WINDOW) && (tC->confTab.filterEnabled[LOFILT]) && + (tC->confTab.seperateFiltersAllowed)) { /* compute second filter for lower frequencies */ - /* compute TNS filter in lattice (ParCor) form with LeRoux-Gueguen algorithm */ - INT predGain = FDKaacEnc_AutoToParcor(rxx1, parcor_tmp, tC->confTab.tnsLimitOrder[LOFILT]); + /* compute TNS filter in lattice (ParCor) form with LeRoux-Gueguen + * algorithm */ + INT predGain; + { + FIXP_DBL predictionGain_m; + INT predictionGain_e; + + CLpc_AutoToParcor(rxx1, 0, parcor_tmp, + tC->confTab.tnsLimitOrder[LOFILT], + &predictionGain_m, &predictionGain_e); + predGain = + (INT)fMultNorm(predictionGain_m, predictionGain_e, 1000, 31, 31); + } - /* non-linear quantization of TNS lattice coefficients with given resolution */ - FDKaacEnc_Parcor2Index( - parcor_tmp, - tnsInfo->coef[subBlockNumber][LOFILT], - tC->confTab.tnsLimitOrder[LOFILT], - tC->coefRes); + /* non-linear quantization of TNS lattice coefficients with given + * resolution */ + FDKaacEnc_Parcor2Index(parcor_tmp, + tnsInfo->coef[subBlockNumber][LOFILT], + tC->confTab.tnsLimitOrder[LOFILT], tC->coefRes); - /* reduce filter order by truncating trailing zeros, compute sum(abs(coefs)) */ + /* reduce filter order by truncating trailing zeros, compute + * sum(abs(coefs)) */ for (i = tC->confTab.tnsLimitOrder[LOFILT] - 1; i >= 0; i--) { if (tnsInfo->coef[subBlockNumber][LOFILT][i] != 0) { break; @@ -834,29 +889,37 @@ INT FDKaacEnc_TnsDetect( sumSqrCoef = 0; for (; i >= 0; i--) { - sumSqrCoef += tnsInfo->coef[subBlockNumber][LOFILT][i] * tnsInfo->coef[subBlockNumber][LOFILT][i]; + sumSqrCoef += tnsInfo->coef[subBlockNumber][LOFILT][i] * + tnsInfo->coef[subBlockNumber][LOFILT][i]; } - tnsInfo->direction[subBlockNumber][LOFILT] = tC->confTab.tnsFilterDirection[LOFILT]; - tnsInfo->length[subBlockNumber][LOFILT] = tC->lpcStartBand[HIFILT] - tC->lpcStartBand[LOFILT]; - - /* filter lower quarter if gain is high enough, but not if it's too high */ - if ( ( (predGain > tC->confTab.threshOn[LOFILT]) && (predGain < (16000 * tC->confTab.tnsLimitOrder[LOFILT])) ) - || ( (sumSqrCoef > 9) && (sumSqrCoef < 22 * tC->confTab.tnsLimitOrder[LOFILT]) ) ) - { - /* compare lower to upper filter; if they are very similar, merge them */ + tnsInfo->direction[subBlockNumber][LOFILT] = + tC->confTab.tnsFilterDirection[LOFILT]; + tnsInfo->length[subBlockNumber][LOFILT] = + tC->lpcStartBand[HIFILT] - tC->lpcStartBand[LOFILT]; + + /* filter lower quarter if gain is high enough, but not if it's too high + */ + if (((predGain > tC->confTab.threshOn[LOFILT]) && + (predGain < (16000 * tC->confTab.tnsLimitOrder[LOFILT]))) || + ((sumSqrCoef > 9) && + (sumSqrCoef < 22 * tC->confTab.tnsLimitOrder[LOFILT]))) { + /* compare lower to upper filter; if they are very similar, merge them + */ tsbi->tnsActive[LOFILT] = TRUE; sumSqrCoef = 0; for (i = 0; i < tC->confTab.tnsLimitOrder[LOFILT]; i++) { - sumSqrCoef += FDKabs(tnsInfo->coef[subBlockNumber][HIFILT][i] - tnsInfo->coef[subBlockNumber][LOFILT][i]); + sumSqrCoef += fAbs(tnsInfo->coef[subBlockNumber][HIFILT][i] - + tnsInfo->coef[subBlockNumber][LOFILT][i]); } - if ( (sumSqrCoef < 2) && - (tnsInfo->direction[subBlockNumber][LOFILT] == tnsInfo->direction[subBlockNumber][HIFILT]) ) - { + if ((sumSqrCoef < 2) && + (tnsInfo->direction[subBlockNumber][LOFILT] == + tnsInfo->direction[subBlockNumber][HIFILT])) { tnsData->filtersMerged = TRUE; - tnsInfo->length[subBlockNumber][HIFILT] = sfbCnt - tC->lpcStartBand[LOFILT]; + tnsInfo->length[subBlockNumber][HIFILT] = + sfbCnt - tC->lpcStartBand[LOFILT]; for (; i < tnsInfo->order[subBlockNumber][HIFILT]; i++) { - if (FDKabs(tnsInfo->coef[subBlockNumber][HIFILT][i]) > 1) { + if (fAbs(tnsInfo->coef[subBlockNumber][HIFILT][i]) > 1) { break; } } @@ -868,22 +931,19 @@ INT FDKaacEnc_TnsDetect( if (i < tnsInfo->order[subBlockNumber][HIFILT]) { tnsInfo->order[subBlockNumber][HIFILT] = i + 1; } - } - else { + } else { tnsInfo->numOfFilters[subBlockNumber]++; } } /* filter lower part */ - tsbi->predictionGain[LOFILT]=predGain; + tsbi->predictionGain[LOFILT] = predGain; } /* second filter allowed */ - } /* if predictionGain > 1437 ... */ - } /* maxOrder > 0 && tnsActive */ + } /* if predictionGain > 1437 ... */ + } /* maxOrder > 0 && tnsActive */ return 0; - } - /***************************************************************************/ /*! \brief FDKaacLdEnc_TnsSync @@ -898,79 +958,77 @@ INT FDKaacEnc_TnsDetect( \return void ****************************************************************************/ -void FDKaacEnc_TnsSync( - TNS_DATA *tnsDataDest, - const TNS_DATA *tnsDataSrc, - TNS_INFO *tnsInfoDest, - TNS_INFO *tnsInfoSrc, - const INT blockTypeDest, - const INT blockTypeSrc, - const TNS_CONFIG *tC - ) -{ +void FDKaacEnc_TnsSync(TNS_DATA *tnsDataDest, const TNS_DATA *tnsDataSrc, + TNS_INFO *tnsInfoDest, TNS_INFO *tnsInfoSrc, + const INT blockTypeDest, const INT blockTypeSrc, + const TNS_CONFIG *tC) { int i, w, absDiff, nWindows; TNS_SUBBLOCK_INFO *sbInfoDest; const TNS_SUBBLOCK_INFO *sbInfoSrc; - /* if one channel contains short blocks and the other not, do not synchronize */ - if ( (blockTypeSrc == SHORT_WINDOW && blockTypeDest != SHORT_WINDOW) || - (blockTypeDest == SHORT_WINDOW && blockTypeSrc != SHORT_WINDOW) ) - { + /* if one channel contains short blocks and the other not, do not synchronize + */ + if ((blockTypeSrc == SHORT_WINDOW && blockTypeDest != SHORT_WINDOW) || + (blockTypeDest == SHORT_WINDOW && blockTypeSrc != SHORT_WINDOW)) { return; } if (blockTypeDest != SHORT_WINDOW) { sbInfoDest = &tnsDataDest->dataRaw.Long.subBlockInfo; - sbInfoSrc = &tnsDataSrc->dataRaw.Long.subBlockInfo; - nWindows = 1; + sbInfoSrc = &tnsDataSrc->dataRaw.Long.subBlockInfo; + nWindows = 1; } else { sbInfoDest = &tnsDataDest->dataRaw.Short.subBlockInfo[0]; - sbInfoSrc = &tnsDataSrc->dataRaw.Short.subBlockInfo[0]; - nWindows = 8; + sbInfoSrc = &tnsDataSrc->dataRaw.Short.subBlockInfo[0]; + nWindows = 8; } - for (w=0; wtnsActive[HIFILT] || pSbInfoSrcW->tnsActive[HIFILT]) { - for (i = 0; i < tC->maxOrder; i++) { - absDiff = FDKabs(tnsInfoDest->coef[w][HIFILT][i] - tnsInfoSrc->coef[w][HIFILT][i]); - absDiffSum += absDiff; - /* if coefficients diverge too much between channels, do not synchronize */ - if ((absDiff > 1) || (absDiffSum > 2)) { - doSync = 0; - break; - } - } - - if (doSync) { - /* if no significant difference was detected, synchronize coefficient sets */ - if (pSbInfoSrcW->tnsActive[HIFILT]) { - /* no dest filter, or more dest than source filters: use one dest filter */ - if ((!pSbInfoDestW->tnsActive[HIFILT]) || - ((pSbInfoDestW->tnsActive[HIFILT]) && (tnsInfoDest->numOfFilters[w] > tnsInfoSrc->numOfFilters[w]))) - { - pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 1; - } - tnsDataDest->filtersMerged = tnsDataSrc->filtersMerged; - tnsInfoDest->order [w][HIFILT] = tnsInfoSrc->order [w][HIFILT]; - tnsInfoDest->length [w][HIFILT] = tnsInfoSrc->length [w][HIFILT]; - tnsInfoDest->direction [w][HIFILT] = tnsInfoSrc->direction [w][HIFILT]; - tnsInfoDest->coefCompress[w][HIFILT] = tnsInfoSrc->coefCompress[w][HIFILT]; - - for (i = 0; i < tC->maxOrder; i++) { - tnsInfoDest->coef[w][HIFILT][i] = tnsInfoSrc->coef[w][HIFILT][i]; - } - } - else - pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 0; - } + for (w = 0; w < nWindows; w++) { + const TNS_SUBBLOCK_INFO *pSbInfoSrcW = sbInfoSrc + w; + TNS_SUBBLOCK_INFO *pSbInfoDestW = sbInfoDest + w; + INT doSync = 1, absDiffSum = 0; + + /* if TNS is active in at least one channel, check if ParCor coefficients of + * higher filter are similar */ + if (pSbInfoDestW->tnsActive[HIFILT] || pSbInfoSrcW->tnsActive[HIFILT]) { + for (i = 0; i < tC->maxOrder; i++) { + absDiff = fAbs(tnsInfoDest->coef[w][HIFILT][i] - + tnsInfoSrc->coef[w][HIFILT][i]); + absDiffSum += absDiff; + /* if coefficients diverge too much between channels, do not synchronize + */ + if ((absDiff > 1) || (absDiffSum > 2)) { + doSync = 0; + break; } + } + if (doSync) { + /* if no significant difference was detected, synchronize coefficient + * sets */ + if (pSbInfoSrcW->tnsActive[HIFILT]) { + /* no dest filter, or more dest than source filters: use one dest + * filter */ + if ((!pSbInfoDestW->tnsActive[HIFILT]) || + ((pSbInfoDestW->tnsActive[HIFILT]) && + (tnsInfoDest->numOfFilters[w] > tnsInfoSrc->numOfFilters[w]))) { + pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 1; + } + tnsDataDest->filtersMerged = tnsDataSrc->filtersMerged; + tnsInfoDest->order[w][HIFILT] = tnsInfoSrc->order[w][HIFILT]; + tnsInfoDest->length[w][HIFILT] = tnsInfoSrc->length[w][HIFILT]; + tnsInfoDest->direction[w][HIFILT] = tnsInfoSrc->direction[w][HIFILT]; + tnsInfoDest->coefCompress[w][HIFILT] = + tnsInfoSrc->coefCompress[w][HIFILT]; + + for (i = 0; i < tC->maxOrder; i++) { + tnsInfoDest->coef[w][HIFILT][i] = tnsInfoSrc->coef[w][HIFILT][i]; + } + } else + pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 0; + } } + } } /***************************************************************************/ @@ -990,218 +1048,130 @@ void FDKaacEnc_TnsSync( \return ERROR STATUS ****************************************************************************/ -INT FDKaacEnc_TnsEncode( - TNS_INFO* tnsInfo, - TNS_DATA* tnsData, - const INT numOfSfb, - const TNS_CONFIG *tC, - const INT lowPassLine, - FIXP_DBL* spectrum, - const INT subBlockNumber, - const INT blockType - ) -{ - INT i, startLine, stopLine; - - if ( ( (blockType == SHORT_WINDOW) && (!tnsData->dataRaw.Short.subBlockInfo[subBlockNumber].tnsActive[HIFILT]) ) - || ( (blockType != SHORT_WINDOW) && (!tnsData->dataRaw.Long.subBlockInfo.tnsActive[HIFILT]) ) ) - { - return 1; - } +INT FDKaacEnc_TnsEncode(TNS_INFO *tnsInfo, TNS_DATA *tnsData, + const INT numOfSfb, const TNS_CONFIG *tC, + const INT lowPassLine, FIXP_DBL *spectrum, + const INT subBlockNumber, const INT blockType) { + INT i, startLine, stopLine; + + if (((blockType == SHORT_WINDOW) && + (!tnsData->dataRaw.Short.subBlockInfo[subBlockNumber] + .tnsActive[HIFILT])) || + ((blockType != SHORT_WINDOW) && + (!tnsData->dataRaw.Long.subBlockInfo.tnsActive[HIFILT]))) { + return 1; + } - startLine = (tnsData->filtersMerged) ? tC->lpcStartLine[LOFILT] : tC->lpcStartLine[HIFILT]; - stopLine = tC->lpcStopLine; - - for (i=0; inumOfFilters[subBlockNumber]; i++) { - - INT lpcGainFactor; - FIXP_DBL LpcCoeff[TNS_MAX_ORDER]; - FIXP_DBL workBuffer[TNS_MAX_ORDER]; - FIXP_DBL parcor_tmp[TNS_MAX_ORDER]; - - FDKaacEnc_Index2Parcor( - tnsInfo->coef[subBlockNumber][i], - parcor_tmp, - tnsInfo->order[subBlockNumber][i], - tC->coefRes); - - lpcGainFactor = FDKaacEnc_ParcorToLpc( - parcor_tmp, - LpcCoeff, - tnsInfo->order[subBlockNumber][i], - workBuffer); - - FDKaacEnc_AnalysisFilter( - &spectrum[startLine], - stopLine - startLine, - LpcCoeff, - tnsInfo->order[subBlockNumber][i], - lpcGainFactor); - - /* update for second filter */ - startLine = tC->lpcStartLine[LOFILT]; - stopLine = tC->lpcStartLine[HIFILT]; - } + startLine = (tnsData->filtersMerged) ? tC->lpcStartLine[LOFILT] + : tC->lpcStartLine[HIFILT]; + stopLine = tC->lpcStopLine; + + for (i = 0; i < tnsInfo->numOfFilters[subBlockNumber]; i++) { + INT lpcGainFactor; + FIXP_LPC LpcCoeff[TNS_MAX_ORDER]; + FIXP_DBL workBuffer[TNS_MAX_ORDER]; + FIXP_LPC parcor_tmp[TNS_MAX_ORDER]; + + FDKaacEnc_Index2Parcor(tnsInfo->coef[subBlockNumber][i], parcor_tmp, + tnsInfo->order[subBlockNumber][i], tC->coefRes); + + lpcGainFactor = CLpc_ParcorToLpc( + parcor_tmp, LpcCoeff, tnsInfo->order[subBlockNumber][i], workBuffer); - return(0); + FDKmemclear(workBuffer, TNS_MAX_ORDER * sizeof(FIXP_DBL)); + CLpc_Analysis(&spectrum[startLine], stopLine - startLine, LpcCoeff, + lpcGainFactor, tnsInfo->order[subBlockNumber][i], workBuffer, + NULL); + /* update for second filter */ + startLine = tC->lpcStartLine[LOFILT]; + stopLine = tC->lpcStartLine[HIFILT]; + } + + return (0); } -static void FDKaacEnc_CalcGaussWindow( - FIXP_DBL *win, - const int winSize, - const INT samplingRate, - const INT transformResolution, - const FIXP_DBL timeResolution, - const INT timeResolution_e - ) -{ - #define PI_E (2) - #define PI_M FL2FXCONST_DBL(3.1416f/(float)(1<> (DFRACT_BITS-1)); - tmp = (FIXP_DBL)((LONG)workBuffer[0]^sign); - - if(input[0]=0; j--) { - FIXP_DBL accu1 = fMult(tmp, input[j]); - FIXP_DBL accu2 = fMult(tmp, workBuffer[j]); - workBuffer[j] += accu1; - input[j] += accu2; - } - - workBuffer++; - } - - tmp = fMult((FIXP_DBL)((LONG)TNS_PREDGAIN_SCALE<<21), fDivNorm(fAbs(autoCorr_0), fAbs(input[0]), &scale)); - if ( fMultDiv2(autoCorr_0, input[0]) FDKaacEnc_tnsCoeff3Borders[i]) - index=i; + for (i = 0; i < 8; i++) { + if (parcor > FDKaacEnc_tnsCoeff3Borders[i]) index = i; } - return(index-4); + return (index - 4); } -static INT FDKaacEnc_Search4(FIXP_DBL parcor) -{ - INT i, index=0; +static INT FDKaacEnc_Search4(FIXP_LPC parcor) { + INT i, index = 0; - for(i=0;i<16;i++){ - if(parcor > FDKaacEnc_tnsCoeff4Borders[i]) - index=i; + for (i = 0; i < 16; i++) { + if (parcor > FDKaacEnc_tnsCoeff4Borders[i]) index = i; } - return(index-8); + return (index - 8); } - /***************************************************************************** functionname: FDKaacEnc_Parcor2Index *****************************************************************************/ -static void FDKaacEnc_Parcor2Index( - const FIXP_DBL *parcor, - INT *RESTRICT index, - const INT order, - const INT bitsPerCoeff - ) -{ +static void FDKaacEnc_Parcor2Index(const FIXP_LPC *parcor, INT *RESTRICT index, + const INT order, const INT bitsPerCoeff) { INT i; - for(i=0; i, - ptr. to work buffer (required size: order) - output: LPC coefficients - -*****************************************************************************/ -static INT FDKaacEnc_ParcorToLpc( - const FIXP_DBL *reflCoeff, - FIXP_DBL *RESTRICT LpcCoeff, - const INT numOfCoeff, - FIXP_DBL *RESTRICT workBuffer - ) -{ - INT i, j; - INT shiftval, par2LpcShiftVal = 6; /* 6 should be enough, bec. max(numOfCoeff) = 20 */ - FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f); - - LpcCoeff[0] = reflCoeff[0] >> par2LpcShiftVal; - for(i=1; i> par2LpcShiftVal; - } - - /* normalize LpcCoeff and calc shiftfactor */ - for(i=0; i=par2LpcShiftVal) ? par2LpcShiftVal : shiftval; - - for(i=0; i0) { - - INT idx = 0; - - /* keep filter coefficients twice and save memory copy operation in - modulo state buffer */ -#if defined(ARCH_PREFER_MULT_32x16) - FIXP_SGL coeff[2*TNS_MAX_ORDER]; - const FIXP_SGL *pCoeff; - for(i=0;i=0); - signal[j] = (tmp< 12 */ - /* for Short: length TRANS_FAC*TNS_MAX_ORDER (only 5 for short LC) is required -> 8*5=40 */ - /* Currently TRANS_FAC*TNS_MAX_ORDER = 8*12 = 96 (for LC) is used (per channel)! Memory could be saved here! */ + /* for Long: length TNS_MAX_ORDER (12 for LC) is required -> 12 */ + /* for Short: length TRANS_FAC*TNS_MAX_ORDER (only 5 for short LC) is required + * -> 8*5=40 */ + /* Currently TRANS_FAC*TNS_MAX_ORDER = 8*12 = 96 (for LC) is used (per + * channel)! Memory could be saved here! */ INT coef[TRANS_FAC][MAX_NUM_OF_FILTERS][TNS_MAX_ORDER]; -}TNS_INFO; +} TNS_INFO; -INT FDKaacEnc_FreqToBandWithRounding( - const INT freq, - const INT fs, - const INT numOfBands, - const INT *bandStartOffset - ); +INT FDKaacEnc_FreqToBandWidthRounding(const INT freq, const INT fs, + const INT numOfBands, + const INT *bandStartOffset); -#endif /* _TNS_H */ +#endif /* AACENC_TNS_H */ diff --git a/libAACenc/src/adj_thr.cpp b/libAACenc/src/adj_thr.cpp index 09584f4..6e19680 100644 --- a/libAACenc/src/adj_thr.cpp +++ b/libAACenc/src/adj_thr.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,889 +90,1015 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M. Werner - contents/description: Threshold compensation + Author(s): M. Werner -******************************************************************************/ + Description: Threshold compensation -#include "common_fix.h" +*******************************************************************************/ -#include "adj_thr_data.h" #include "adj_thr.h" -#include "qc_data.h" #include "sf_estim.h" #include "aacEnc_ram.h" +#define NUM_NRG_LEVS (8) +#define INV_INT_TAB_SIZE (8) +static const FIXP_DBL invInt[INV_INT_TAB_SIZE] = { + 0x7fffffff, 0x7fffffff, 0x40000000, 0x2aaaaaaa, + 0x20000000, 0x19999999, 0x15555555, 0x12492492}; - - -#define INV_INT_TAB_SIZE (8) -static const FIXP_DBL invInt[INV_INT_TAB_SIZE] = -{ - 0x7fffffff, 0x7fffffff, 0x40000000, 0x2aaaaaaa, 0x20000000, 0x19999999, 0x15555555, 0x12492492 -}; - - -#define INV_SQRT4_TAB_SIZE (8) -static const FIXP_DBL invSqrt4[INV_SQRT4_TAB_SIZE] = -{ - 0x7fffffff, 0x7fffffff, 0x6ba27e65, 0x61424bb5, 0x5a827999, 0x55994845, 0x51c8e33c, 0x4eb160d1 -}; - +#define INV_SQRT4_TAB_SIZE (8) +static const FIXP_DBL invSqrt4[INV_SQRT4_TAB_SIZE] = { + 0x7fffffff, 0x7fffffff, 0x6ba27e65, 0x61424bb5, + 0x5a827999, 0x55994845, 0x51c8e33c, 0x4eb160d1}; /*static const INT invRedExp = 4;*/ -static const FIXP_DBL SnrLdMin1 = (FIXP_DBL)0xfcad0ddf; /*FL2FXCONST_DBL(FDKlog(0.316)/FDKlog(2.0)/LD_DATA_SCALING);*/ -static const FIXP_DBL SnrLdMin2 = (FIXP_DBL)0x0351e1a2; /*FL2FXCONST_DBL(FDKlog(3.16) /FDKlog(2.0)/LD_DATA_SCALING);*/ -static const FIXP_DBL SnrLdFac = (FIXP_DBL)0xff5b2c3e; /*FL2FXCONST_DBL(FDKlog(0.8) /FDKlog(2.0)/LD_DATA_SCALING);*/ - -static const FIXP_DBL SnrLdMin3 = (FIXP_DBL)0xfe000000; /*FL2FXCONST_DBL(FDKlog(0.5) /FDKlog(2.0)/LD_DATA_SCALING);*/ -static const FIXP_DBL SnrLdMin4 = (FIXP_DBL)0x02000000; /*FL2FXCONST_DBL(FDKlog(2.0) /FDKlog(2.0)/LD_DATA_SCALING);*/ -static const FIXP_DBL SnrLdMin5 = (FIXP_DBL)0xfc000000; /*FL2FXCONST_DBL(FDKlog(0.25) /FDKlog(2.0)/LD_DATA_SCALING);*/ - +static const FIXP_DBL SnrLdMin1 = + (FIXP_DBL)0xfcad0ddf; /*FL2FXCONST_DBL(FDKlog(0.316)/FDKlog(2.0)/LD_DATA_SCALING);*/ +static const FIXP_DBL SnrLdMin2 = + (FIXP_DBL)0x0351e1a2; /*FL2FXCONST_DBL(FDKlog(3.16) + /FDKlog(2.0)/LD_DATA_SCALING);*/ +static const FIXP_DBL SnrLdFac = + (FIXP_DBL)0xff5b2c3e; /*FL2FXCONST_DBL(FDKlog(0.8) + /FDKlog(2.0)/LD_DATA_SCALING);*/ + +static const FIXP_DBL SnrLdMin3 = + (FIXP_DBL)0xfe000000; /*FL2FXCONST_DBL(FDKlog(0.5) + /FDKlog(2.0)/LD_DATA_SCALING);*/ +static const FIXP_DBL SnrLdMin4 = + (FIXP_DBL)0x02000000; /*FL2FXCONST_DBL(FDKlog(2.0) + /FDKlog(2.0)/LD_DATA_SCALING);*/ +static const FIXP_DBL SnrLdMin5 = + (FIXP_DBL)0xfc000000; /*FL2FXCONST_DBL(FDKlog(0.25) + /FDKlog(2.0)/LD_DATA_SCALING);*/ /* The bits2Pe factors are choosen for the case that some times the crash recovery strategy will be activated once. */ +#define AFTERBURNER_STATI 2 +#define MAX_ALLOWED_EL_CHANNELS 2 typedef struct { - INT bitrate; - ULONG bits2PeFactor_mono; - ULONG bits2PeFactor_mono_slope; - ULONG bits2PeFactor_stereo; - ULONG bits2PeFactor_stereo_slope; - ULONG bits2PeFactor_mono_scfOpt; - ULONG bits2PeFactor_mono_scfOpt_slope; - ULONG bits2PeFactor_stereo_scfOpt; - ULONG bits2PeFactor_stereo_scfOpt_slope; - + INT bitrate; + FIXP_DBL bits2PeFactor[AFTERBURNER_STATI][MAX_ALLOWED_EL_CHANNELS]; } BIT_PE_SFAC; typedef struct { - const INT sampleRate; - const BIT_PE_SFAC * pPeTab; - const INT nEntries; + INT sampleRate; + const BIT_PE_SFAC *pPeTab; + INT nEntries; } BITS2PE_CFG_TAB; +#define FL2B2PE(value) FL2FXCONST_DBL((value) / (1 << 2)) + static const BIT_PE_SFAC S_Bits2PeTab16000[] = { - { 10000, 0x228F5C29, 0x02FEF55D, 0x1D70A3D7, 0x09BC9D6D, 0x228F5C29, 0x02FEF55D, 0x1C28F5C3, 0x0CBB92CA}, - { 24000, 0x23D70A3D, 0x029F16B1, 0x2199999A, 0x07DD4413, 0x23D70A3D, 0x029F16B1, 0x2199999A, 0x07DD4413}, - { 32000, 0x247AE148, 0x11B1D92B, 0x23851EB8, 0x01F75105, 0x247AE148, 0x110A137F, 0x23851EB8, 0x01F75105}, - { 48000, 0x2D1EB852, 0x6833C600, 0x247AE148, 0x014F8B59, 0x2CCCCCCD, 0x68DB8BAC, 0x247AE148, 0x01F75105}, - { 64000, 0x25c28f40, 0x00000000, 0x251EB852, 0x01480000, 0x25c28f40, 0x00000000, 0x2570A3D7, 0x01480000}, - { 96000, 0x25c28f40, 0x00000000, 0x26000000, 0x01000000, 0x25c28f40, 0x00000000, 0x26000000, 0x01000000}, - {128000, 0x25c28f40, 0x00000000, 0x270a3d80, 0x01000000, 0x25c28f40, 0x00000000, 0x270a3d80, 0x01000000}, - {148000, 0x25c28f40, 0x00000000, 0x28000000, 0x00000000, 0x25c28f40, 0x00000000, 0x28000000, 0x00000000} -}; + /* bitrate| afterburner off | afterburner on | | nCh=1 + | nCh=2 | nCh=1 | nCh=2 */ + {10000, + {{FL2B2PE(1.60f), FL2B2PE(0.00f)}, {FL2B2PE(1.40f), FL2B2PE(0.00f)}}}, + {24000, + {{FL2B2PE(1.80f), FL2B2PE(1.40f)}, {FL2B2PE(1.60f), FL2B2PE(1.20f)}}}, + {32000, + {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}}, + {48000, + {{FL2B2PE(1.60f), FL2B2PE(1.80f)}, {FL2B2PE(1.60f), FL2B2PE(1.60f)}}}, + {64000, + {{FL2B2PE(1.20f), FL2B2PE(1.60f)}, {FL2B2PE(1.20f), FL2B2PE(1.60f)}}}, + {96000, + {{FL2B2PE(1.40f), FL2B2PE(1.80f)}, {FL2B2PE(1.40f), FL2B2PE(1.60f)}}}, + {128000, + {{FL2B2PE(1.40f), FL2B2PE(1.80f)}, {FL2B2PE(1.40f), FL2B2PE(1.80f)}}}, + {148000, + {{FL2B2PE(1.40f), FL2B2PE(1.80f)}, {FL2B2PE(1.40f), FL2B2PE(1.40f)}}}}; static const BIT_PE_SFAC S_Bits2PeTab22050[] = { - { 16000, 0x1a8f5c29, 0x1797cc3a, 0x128f5c29, 0x18e75793, 0x175c28f6, 0x221426fe, 0x00000000, 0x5a708ede}, - { 24000, 0x2051eb85, 0x092ccf6c, 0x18a3d70a, 0x13a92a30, 0x1fae147b, 0xbcbe61d, 0x16147ae1, 0x18e75793}, - { 32000, 0x228f5c29, 0x029f16b1, 0x1d70a3d7, 0x088509c0, 0x228f5c29, 0x29f16b1, 0x1c28f5c3, 0x0b242071}, - { 48000, 0x23d70a3d, 0x014f8b59, 0x2199999a, 0x03eea20a, 0x23d70a3d, 0x14f8b59, 0x2199999a, 0x03eea20a}, - { 64000, 0x247ae148, 0x08d8ec96, 0x23851eb8, 0x00fba882, 0x247ae148, 0x88509c0, 0x23851eb8, 0x00fba882}, - { 96000, 0x2d1eb852, 0x3419e300, 0x247ae148, 0x00a7c5ac, 0x2ccccccd, 0x346dc5d6, 0x247ae148, 0x00fba882}, - {128000, 0x25c28f40, 0x00000000, 0x251eb852, 0x029f16b1, 0x60000000, 0x25c28f40, 0x2570a3d7, 0x009f16b1}, - {148000, 0x25c28f40, 0x00000000, 0x26b851ec, 0x00000000, 0x60000000, 0x25c28f40, 0x270a3d71, 0x00000000} -}; + /* bitrate| afterburner off | afterburner on | | nCh=1 + | nCh=2 | nCh=1 | nCh=2 */ + {16000, + {{FL2B2PE(1.60f), FL2B2PE(1.40f)}, {FL2B2PE(1.20f), FL2B2PE(0.80f)}}}, + {24000, + {{FL2B2PE(1.60f), FL2B2PE(1.40f)}, {FL2B2PE(1.40f), FL2B2PE(1.00f)}}}, + {32000, + {{FL2B2PE(1.40f), FL2B2PE(1.40f)}, {FL2B2PE(1.40f), FL2B2PE(1.20f)}}}, + {48000, + {{FL2B2PE(1.20f), FL2B2PE(1.60f)}, {FL2B2PE(1.20f), FL2B2PE(1.40f)}}}, + {64000, + {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}}, + {96000, + {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.60f)}}}, + {128000, + {{FL2B2PE(1.80f), FL2B2PE(1.80f)}, {FL2B2PE(1.60f), FL2B2PE(1.60f)}}}, + {148000, + {{FL2B2PE(1.40f), FL2B2PE(1.80f)}, {FL2B2PE(1.40f), FL2B2PE(1.60f)}}}}; static const BIT_PE_SFAC S_Bits2PeTab24000[] = { - { 16000, 0x19eb851f, 0x13a92a30, 0x1147ae14, 0x164840e1, 0x1999999a, 0x12599ed8, 0x00000000, 0x46c764ae}, - { 24000, 0x1eb851ec, 0x0d1b7176, 0x16b851ec, 0x18e75793, 0x1e147ae1, 0x0fba8827, 0x1147ae14, 0x2c9081c3}, - { 32000, 0x21eb851f, 0x049667b6, 0x1ccccccd, 0x07357e67, 0x21eb851f, 0x03eea20a, 0x1c28f5c3, 0x07357e67}, - { 48000, 0x2428f5c3, 0x014f8b59, 0x2051eb85, 0x053e2d62, 0x23d70a3d, 0x01f75105, 0x1fae147b, 0x07357e67}, - { 64000, 0x24cccccd, 0x05e5f30e, 0x22e147ae, 0x01a36e2f, 0x24cccccd, 0x05e5f30e, 0x23333333, 0x014f8b59}, - { 96000, 0x2a8f5c29, 0x24b33db0, 0x247ae148, 0x00fba882, 0x2a8f5c29, 0x26fe718b, 0x247ae148, 0x00fba882}, - {128000, 0x4e666666, 0x1cd5f99c, 0x2570a3d7, 0x010c6f7a, 0x50a3d70a, 0x192a7371, 0x2570a3d7, 0x010c6f7a}, - {148000, 0x25c28f40, 0x00000000, 0x26147ae1, 0x00000000, 0x25c28f40, 0x00000000, 0x26147ae1, 0x00000000} -}; + /* bitrate| afterburner off | afterburner on | | nCh=1 + | nCh=2 | nCh=1 | nCh=2 */ + {16000, + {{FL2B2PE(1.40f), FL2B2PE(1.40f)}, {FL2B2PE(1.20f), FL2B2PE(0.80f)}}}, + {24000, + {{FL2B2PE(1.60f), FL2B2PE(1.20f)}, {FL2B2PE(1.40f), FL2B2PE(1.00f)}}}, + {32000, + {{FL2B2PE(1.40f), FL2B2PE(1.20f)}, {FL2B2PE(1.40f), FL2B2PE(0.80f)}}}, + {48000, + {{FL2B2PE(1.40f), FL2B2PE(1.60f)}, {FL2B2PE(1.40f), FL2B2PE(1.40f)}}}, + {64000, + {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}}, + {96000, + {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.60f)}}}, + {128000, + {{FL2B2PE(1.40f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.80f)}}}, + {148000, + {{FL2B2PE(1.40f), FL2B2PE(1.60f)}, {FL2B2PE(1.40f), FL2B2PE(1.80f)}}}}; static const BIT_PE_SFAC S_Bits2PeTab32000[] = { - { 16000, 0x247ae140, 0xFFFFAC1E, 0x270a3d80, 0xFFFE9B7C, 0x14ccccc0, 0x000110A1, 0x15c28f60, 0xFFFEEF5F}, - { 24000, 0x23333340, 0x0fba8827, 0x21999980, 0x1b866e44, 0x18f5c280, 0x0fba8827, 0x119999a0, 0x4d551d69}, - { 32000, 0x1d70a3d7, 0x07357e67, 0x17ae147b, 0x09d49518, 0x1b851eb8, 0x0a7c5ac4, 0x12e147ae, 0x110a137f}, - { 48000, 0x20f5c28f, 0x049667b6, 0x1c7ae148, 0x053e2d62, 0x20a3d70a, 0x053e2d62, 0x1b333333, 0x05e5f30e}, - { 64000, 0x23333333, 0x029f16b1, 0x1f0a3d71, 0x02f2f987, 0x23333333, 0x029f16b1, 0x1e147ae1, 0x03eea20a}, - { 96000, 0x25c28f5c, 0x2c3c9eed, 0x21eb851f, 0x01f75105, 0x25c28f5c, 0x0a7c5ac4, 0x21eb851f, 0x01a36e2f}, - {128000, 0x50f5c28f, 0x18a43bb4, 0x23d70a3d, 0x010c6f7a, 0x30000000, 0x168b5cc0, 0x23851eb8, 0x0192a737}, - {148000, 0x25c28f40, 0x00000000, 0x247ae148, 0x00dfb23b, 0x3dc28f5c, 0x300f4aaf, 0x247ae148, 0x01bf6476}, - {160000, 0x25c28f40, 0xb15b5740, 0x24cccccd, 0x053e2d62, 0x4f5c28f6, 0xbefd0072, 0x251eb852, 0x04fb1184}, - {200000, 0x25c28f40, 0x00000000, 0x2b333333, 0x0836be91, 0x25c28f40, 0x00000000, 0x2b333333, 0x0890390f}, - {320000, 0x25c28f40, 0x00000000, 0x4947ae14, 0x00000000, 0x25c28f40, 0x00000000, 0x4a8f5c29, 0x00000000} -}; + /* bitrate| afterburner off | afterburner on | | nCh=1 + | nCh=2 | nCh=1 | nCh=2 */ + {16000, + {{FL2B2PE(1.20f), FL2B2PE(1.40f)}, {FL2B2PE(0.80f), FL2B2PE(0.80f)}}}, + {24000, + {{FL2B2PE(1.40f), FL2B2PE(1.20f)}, {FL2B2PE(1.00f), FL2B2PE(0.60f)}}}, + {32000, + {{FL2B2PE(1.20f), FL2B2PE(1.20f)}, {FL2B2PE(1.00f), FL2B2PE(0.80f)}}}, + {48000, + {{FL2B2PE(1.40f), FL2B2PE(1.40f)}, {FL2B2PE(1.20f), FL2B2PE(1.20f)}}}, + {64000, + {{FL2B2PE(1.60f), FL2B2PE(1.40f)}, {FL2B2PE(1.60f), FL2B2PE(1.20f)}}}, + {96000, + {{FL2B2PE(1.60f), FL2B2PE(1.40f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}}, + {128000, + {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.60f)}}}, + {148000, + {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.60f)}}}, + {160000, + {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.60f)}}}, + {200000, + {{FL2B2PE(1.40f), FL2B2PE(1.60f)}, {FL2B2PE(1.40f), FL2B2PE(1.60f)}}}, + {320000, + {{FL2B2PE(3.20f), FL2B2PE(1.80f)}, {FL2B2PE(3.20f), FL2B2PE(1.80f)}}}}; static const BIT_PE_SFAC S_Bits2PeTab44100[] = { - { 16000, 0x10a3d70a, 0x1797cc3a, 0x00000000, 0x00000000, 0x00000000, 0x59210386, 0x00000000, 0x00000000}, - { 24000, 0x16666666, 0x1797cc3a, 0x00000000, 0x639d5e4a, 0x15c28f5c, 0x12599ed8, 0x00000000, 0x5bc01a37}, - { 32000, 0x1c28f5c3, 0x049667b6, 0x1851eb85, 0x049667b6, 0x1a3d70a4, 0x088509c0, 0x16666666, 0x053e2d62}, - { 48000, 0x1e666666, 0x05e5f30e, 0x1a8f5c29, 0x049667b6, 0x1e666666, 0x05e5f30e, 0x18f5c28f, 0x05e5f30e}, - { 64000, 0x2147ae14, 0x0346dc5d, 0x1ccccccd, 0x02f2f987, 0x2147ae14, 0x02f2f987, 0x1bd70a3d, 0x039abf34}, - { 96000, 0x247ae148, 0x068db8bb, 0x1fae147b, 0x029f16b1, 0x2428f5c3, 0x0639d5e5, 0x1f5c28f6, 0x029f16b1}, - {128000, 0x2ae147ae, 0x1b435265, 0x223d70a4, 0x0192a737, 0x2a3d70a4, 0x1040bfe4, 0x21eb851f, 0x0192a737}, - {148000, 0x3b851eb8, 0x2832069c, 0x23333333, 0x00dfb23b, 0x3428f5c3, 0x2054c288, 0x22e147ae, 0x00dfb23b}, - {160000, 0x4a3d70a4, 0xc32ebe5a, 0x23851eb8, 0x01d5c316, 0x40000000, 0xcb923a2b, 0x23333333, 0x01d5c316}, - {200000, 0x25c28f40, 0x00000000, 0x25c28f5c, 0x0713f078, 0x25c28f40, 0x00000000, 0x2570a3d7, 0x072a4f17}, - {320000, 0x25c28f40, 0x00000000, 0x3fae147b, 0x00000000, 0x25c28f40, 0x00000000, 0x3fae147b, 0x00000000} -}; + /* bitrate| afterburner off | afterburner on | | nCh=1 + | nCh=2 | nCh=1 | nCh=2 */ + {16000, + {{FL2B2PE(1.20f), FL2B2PE(1.60f)}, {FL2B2PE(0.80f), FL2B2PE(1.00f)}}}, + {24000, + {{FL2B2PE(1.00f), FL2B2PE(1.20f)}, {FL2B2PE(1.00f), FL2B2PE(0.80f)}}}, + {32000, + {{FL2B2PE(1.20f), FL2B2PE(1.20f)}, {FL2B2PE(0.80f), FL2B2PE(0.60f)}}}, + {48000, + {{FL2B2PE(1.20f), FL2B2PE(1.20f)}, {FL2B2PE(1.20f), FL2B2PE(0.80f)}}}, + {64000, + {{FL2B2PE(1.40f), FL2B2PE(1.20f)}, {FL2B2PE(1.20f), FL2B2PE(1.00f)}}}, + {96000, + {{FL2B2PE(1.60f), FL2B2PE(1.20f)}, {FL2B2PE(1.60f), FL2B2PE(1.20f)}}}, + {128000, + {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}}, + {148000, + {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.60f)}}}, + {160000, + {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.60f)}}}, + {200000, + {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.60f)}}}, + {320000, + {{FL2B2PE(3.20f), FL2B2PE(1.60f)}, {FL2B2PE(3.20f), FL2B2PE(1.60f)}}}}; static const BIT_PE_SFAC S_Bits2PeTab48000[] = { - { 16000, 0x0f5c28f6, 0x31ceaf25, 0x00000000, 0x00000000, 0x00000000, 0x74a771c9, 0x00000000, 0x00000000}, - { 24000, 0x1b851eb8, 0x029f16b1, 0x00000000, 0x663c74fb, 0x1c7ae148, 0xe47991bd, 0x00000000, 0x49667b5f}, - { 32000, 0x1c28f5c3, 0x029f16b1, 0x18f5c28f, 0x07357e67, 0x15c28f5c, 0x0f12c27a, 0x11eb851f, 0x13016484}, - { 48000, 0x1d70a3d7, 0x053e2d62, 0x1c7ae148, 0xfe08aefc, 0x1d1eb852, 0x068db8bb, 0x1b333333, 0xfeb074a8}, - { 64000, 0x20000000, 0x03eea20a, 0x1b851eb8, 0x0346dc5d, 0x2051eb85, 0x0346dc5d, 0x1a8f5c29, 0x039abf34}, - { 96000, 0x23d70a3d, 0x053e2d62, 0x1eb851ec, 0x029f16b1, 0x23851eb8, 0x04ea4a8c, 0x1e147ae1, 0x02f2f987}, - {128000, 0x28f5c28f, 0x14727dcc, 0x2147ae14, 0x0218def4, 0x2851eb85, 0x0e27e0f0, 0x20f5c28f, 0x0218def4}, - {148000, 0x3570a3d7, 0x1cd5f99c, 0x228f5c29, 0x01bf6476, 0x30f5c28f, 0x18777e75, 0x223d70a4, 0x01bf6476}, - {160000, 0x40000000, 0xcb923a2b, 0x23333333, 0x0192a737, 0x39eb851f, 0xd08d4bae, 0x22e147ae, 0x0192a737}, - {200000, 0x25c28f40, 0x00000000, 0x251eb852, 0x06775a1b, 0x25c28f40, 0x00000000, 0x24cccccd, 0x06a4175a}, - {320000, 0x25c28f40, 0x00000000, 0x3ccccccd, 0x00000000, 0x25c28f40, 0x00000000, 0x3d1eb852, 0x00000000} -}; + /* bitrate| afterburner off | afterburner on | | nCh=1 + | nCh=2 | nCh=1 | nCh=2 */ + {16000, + {{FL2B2PE(1.40f), FL2B2PE(0.00f)}, {FL2B2PE(0.80f), FL2B2PE(0.00f)}}}, + {24000, + {{FL2B2PE(1.40f), FL2B2PE(1.20f)}, {FL2B2PE(1.00f), FL2B2PE(0.80f)}}}, + {32000, + {{FL2B2PE(1.00f), FL2B2PE(1.20f)}, {FL2B2PE(0.60f), FL2B2PE(0.80f)}}}, + {48000, + {{FL2B2PE(1.20f), FL2B2PE(1.00f)}, {FL2B2PE(0.80f), FL2B2PE(0.80f)}}}, + {64000, + {{FL2B2PE(1.20f), FL2B2PE(1.20f)}, {FL2B2PE(1.20f), FL2B2PE(1.00f)}}}, + {96000, + {{FL2B2PE(1.60f), FL2B2PE(1.40f)}, {FL2B2PE(1.60f), FL2B2PE(1.20f)}}}, + {128000, + {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}}, + {148000, + {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}}, + {160000, + {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}}, + {200000, + {{FL2B2PE(1.20f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}}, + {320000, + {{FL2B2PE(3.20f), FL2B2PE(1.60f)}, {FL2B2PE(3.20f), FL2B2PE(1.60f)}}}}; static const BITS2PE_CFG_TAB bits2PeConfigTab[] = { - { 16000, S_Bits2PeTab16000, sizeof(S_Bits2PeTab16000)/sizeof(BIT_PE_SFAC) }, - { 22050, S_Bits2PeTab22050, sizeof(S_Bits2PeTab22050)/sizeof(BIT_PE_SFAC) }, - { 24000, S_Bits2PeTab24000, sizeof(S_Bits2PeTab24000)/sizeof(BIT_PE_SFAC) }, - { 32000, S_Bits2PeTab32000, sizeof(S_Bits2PeTab32000)/sizeof(BIT_PE_SFAC) }, - { 44100, S_Bits2PeTab44100, sizeof(S_Bits2PeTab44100)/sizeof(BIT_PE_SFAC) }, - { 48000, S_Bits2PeTab48000, sizeof(S_Bits2PeTab48000)/sizeof(BIT_PE_SFAC) } -}; - - + {16000, S_Bits2PeTab16000, sizeof(S_Bits2PeTab16000) / sizeof(BIT_PE_SFAC)}, + {22050, S_Bits2PeTab22050, sizeof(S_Bits2PeTab22050) / sizeof(BIT_PE_SFAC)}, + {24000, S_Bits2PeTab24000, sizeof(S_Bits2PeTab24000) / sizeof(BIT_PE_SFAC)}, + {32000, S_Bits2PeTab32000, sizeof(S_Bits2PeTab32000) / sizeof(BIT_PE_SFAC)}, + {44100, S_Bits2PeTab44100, sizeof(S_Bits2PeTab44100) / sizeof(BIT_PE_SFAC)}, + {48000, S_Bits2PeTab48000, + sizeof(S_Bits2PeTab48000) / sizeof(BIT_PE_SFAC)}}; /* values for avoid hole flag */ -enum _avoid_hole_state { - NO_AH =0, - AH_INACTIVE =1, - AH_ACTIVE =2 -}; - +enum _avoid_hole_state { NO_AH = 0, AH_INACTIVE = 1, AH_ACTIVE = 2 }; /* Q format definitions */ -#define Q_BITFAC (24) /* Q scaling used in FDKaacEnc_bitresCalcBitFac() calculation */ -#define Q_AVGBITS (17) /* scale bit values */ - +#define Q_BITFAC \ + (24) /* Q scaling used in FDKaacEnc_bitresCalcBitFac() calculation */ +#define Q_AVGBITS (17) /* scale bit values */ /***************************************************************************** functionname: FDKaacEnc_InitBits2PeFactor description: retrieve bits2PeFactor from table *****************************************************************************/ static void FDKaacEnc_InitBits2PeFactor( - FIXP_DBL *bits2PeFactor_m, - INT *bits2PeFactor_e, - const INT bitRate, - const INT nChannels, - const INT sampleRate, - const INT advancedBitsToPe, - const INT dZoneQuantEnable, - const INT invQuant - ) -{ - /* default bits2pe factor */ - FIXP_DBL bit2PE_m = FL2FXCONST_DBL(1.18f/(1<<(1))); - INT bit2PE_e = 1; - - /* make use of advanced bits to pe factor table */ - if (advancedBitsToPe) { - + FIXP_DBL *bits2PeFactor_m, INT *bits2PeFactor_e, const INT bitRate, + const INT nChannels, const INT sampleRate, const INT advancedBitsToPe, + const INT dZoneQuantEnable, const INT invQuant) { + /**** 1) Set default bits2pe factor ****/ + FIXP_DBL bit2PE_m = FL2FXCONST_DBL(1.18f / (1 << (1))); + INT bit2PE_e = 1; + + /**** 2) For AAC-(E)LD, make use of advanced bits to pe factor table ****/ + if (advancedBitsToPe && nChannels <= (2)) { int i; const BIT_PE_SFAC *peTab = NULL; INT size = 0; - - /* Get correct table entry */ - for (i=0; i<(INT)(sizeof(bits2PeConfigTab)/sizeof(BITS2PE_CFG_TAB)); i++) { + /*** 2.1) Get correct table entry ***/ + for (i = 0; i < (INT)(sizeof(bits2PeConfigTab) / sizeof(BITS2PE_CFG_TAB)); + i++) { if (sampleRate >= bits2PeConfigTab[i].sampleRate) { peTab = bits2PeConfigTab[i].pPeTab; - size = bits2PeConfigTab[i].nEntries; + size = bits2PeConfigTab[i].nEntries; } } - if ( (peTab!=NULL) && (size!=0) ) { - - INT startB = -1; - LONG startPF = 0; - LONG peSlope = 0; - - /* stereo or mono mode and invQuant used or not */ - for (i=0; ibitRate) || ((i==size-2)) )) - { - if (nChannels==1) - { - startPF = (!invQuant) ? peTab[i].bits2PeFactor_mono : peTab[i].bits2PeFactor_mono_scfOpt; - peSlope = (!invQuant) ? peTab[i].bits2PeFactor_mono_slope : peTab[i].bits2PeFactor_mono_scfOpt_slope; - /*endPF = (!invQuant) ? peTab[i+1].bits2PeFactor_mono : peTab[i+1].bits2PeFactor_mono_scfOpt; - endB=peTab[i+1].bitrate;*/ - startB=peTab[i].bitrate; - break; - } - else - { - startPF = (!invQuant) ? peTab[i].bits2PeFactor_stereo : peTab[i].bits2PeFactor_stereo_scfOpt; - peSlope = (!invQuant) ? peTab[i].bits2PeFactor_stereo_slope : peTab[i].bits2PeFactor_stereo_scfOpt_slope; - /*endPF = (!invQuant) ? peTab[i+1].bits2PeFactor_stereo : peTab[i+1].bits2PeFactor_stereo_scfOpt; - endB=peTab[i+1].bitrate;*/ - startB=peTab[i].bitrate; + if ((peTab != NULL) && (size != 0)) { + INT startB = -1; /* bitrate entry in table that is the next-lower to + actual bitrate */ + INT stopB = -1; /* bitrate entry in table that is the next-higher to + actual bitrate */ + FIXP_DBL startPF = + FL2FXCONST_DBL(0.0f); /* bits2PE factor entry in table that is the + next-lower to actual bits2PE factor */ + FIXP_DBL stopPF = FL2FXCONST_DBL(0.0f); /* bits2PE factor entry in table + that is the next-higher to + actual bits2PE factor */ + FIXP_DBL slope = FL2FXCONST_DBL( + 0.0f); /* the slope from the start bits2Pe entry to the next one */ + const int qualityIdx = (invQuant == 0) ? 0 : 1; + + if (bitRate >= peTab[size - 1].bitrate) { + /* Chosen bitrate is higher than the highest bitrate in table. + The slope for extrapolating the bits2PE factor must be zero. + Values are set accordingly. */ + startB = peTab[size - 1].bitrate; + stopB = + bitRate + + 1; /* Can be an arbitrary value greater than startB and bitrate. */ + startPF = peTab[size - 1].bits2PeFactor[qualityIdx][nChannels - 1]; + stopPF = peTab[size - 1].bits2PeFactor[qualityIdx][nChannels - 1]; + } else { + for (i = 0; i < size - 1; i++) { + if ((peTab[i].bitrate <= bitRate) && + (peTab[i + 1].bitrate > bitRate)) { + startB = peTab[i].bitrate; + stopB = peTab[i + 1].bitrate; + startPF = peTab[i].bits2PeFactor[qualityIdx][nChannels - 1]; + stopPF = peTab[i + 1].bits2PeFactor[qualityIdx][nChannels - 1]; break; } } - } /* for i */ + } - /* if a configuration is available */ - if (startB!=-1) { - /* linear interpolate to actual PEfactor */ - FIXP_DBL peFac = fMult((FIXP_DBL)(bitRate-startB)<<14, (FIXP_DBL)peSlope) << 2; - FIXP_DBL bit2PE = peFac + (FIXP_DBL)startPF; /* startPF_float = startPF << 2 */ + /*** 2.2) Configuration available? ***/ + if (startB != -1) { + /** 2.2.1) linear interpolate to actual PEfactor **/ + FIXP_DBL bit2PE = 0; - /* sanity check if bits2pe value is high enough */ - if ( bit2PE >= (FL2FXCONST_DBL(0.35f) >> 2) ) { + const FIXP_DBL maxBit2PE = FL2FXCONST_DBL(3.f / 4.f); + + /* bit2PE = ((stopPF-startPF)/(stopB-startB))*(bitRate-startB)+startPF; + */ + slope = fDivNorm(bitRate - startB, stopB - startB); + bit2PE = fMult(slope, stopPF - startPF) + startPF; + + bit2PE = fMin(maxBit2PE, bit2PE); + + /** 2.2.2) sanity check if bits2pe value is high enough **/ + if (bit2PE >= (FL2FXCONST_DBL(0.35f) >> 2)) { bit2PE_m = bit2PE; bit2PE_e = 2; /* table is fixed scaled */ } } /* br */ - } /* sr */ - } /* advancedBitsToPe */ + } /* sr */ + } /* advancedBitsToPe */ - - if (dZoneQuantEnable) - { - if(bit2PE_m >= (FL2FXCONST_DBL(0.6f))>>bit2PE_e) - { + if (dZoneQuantEnable) { + if (bit2PE_m >= (FL2FXCONST_DBL(0.6f)) >> bit2PE_e) { /* Additional headroom for addition */ bit2PE_m >>= 1; - bit2PE_e += 1; + bit2PE_e += 1; } - /* the quantTendencyCompensator compensates a lower bit consumption due to increasing the tendency to quantize low spectral values to the lower quantizer border for bitrates below a certain bitrate threshold --> see also function calcSfbDistLD in quantize.c */ - if ((bitRate/nChannels > 32000) && (bitRate/nChannels <= 40000)) { - bit2PE_m += (FL2FXCONST_DBL(0.4f))>>bit2PE_e; - } - else if (bitRate/nChannels > 20000) { - bit2PE_m += (FL2FXCONST_DBL(0.3f))>>bit2PE_e; - } - else if (bitRate/nChannels >= 16000) { - bit2PE_m += (FL2FXCONST_DBL(0.3f))>>bit2PE_e; - } - else { - bit2PE_m += (FL2FXCONST_DBL(0.0f))>>bit2PE_e; + /* the quantTendencyCompensator compensates a lower bit consumption due to + * increasing the tendency to quantize low spectral values to the lower + * quantizer border for bitrates below a certain bitrate threshold --> see + * also function calcSfbDistLD in quantize.c */ + if ((bitRate / nChannels > 32000) && (bitRate / nChannels <= 40000)) { + bit2PE_m += (FL2FXCONST_DBL(0.4f)) >> bit2PE_e; + } else if (bitRate / nChannels > 20000) { + bit2PE_m += (FL2FXCONST_DBL(0.3f)) >> bit2PE_e; + } else if (bitRate / nChannels >= 16000) { + bit2PE_m += (FL2FXCONST_DBL(0.3f)) >> bit2PE_e; + } else { + bit2PE_m += (FL2FXCONST_DBL(0.0f)) >> bit2PE_e; } } - /***** 3.) Return bits2pe factor *****/ *bits2PeFactor_m = bit2PE_m; *bits2PeFactor_e = bit2PE_e; } - /***************************************************************************** functionname: FDKaacEnc_bits2pe2 description: convert from bits to pe *****************************************************************************/ -static INT FDKaacEnc_bits2pe2( - const INT bits, - const FIXP_DBL factor_m, - const INT factor_e - ) -{ - return (INT)(fMult(factor_m, (FIXP_DBL)(bits<> (Q_AVGBITS-factor_e)); +FDK_INLINE INT FDKaacEnc_bits2pe2(const INT bits, const FIXP_DBL factor_m, + const INT factor_e) { + return (INT)(fMult(factor_m, (FIXP_DBL)(bits << Q_AVGBITS)) >> + (Q_AVGBITS - factor_e)); } /***************************************************************************** functionname: FDKaacEnc_calcThreshExp description: loudness calculation (threshold to the power of redExp) *****************************************************************************/ -static void FDKaacEnc_calcThreshExp(FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB], - QC_OUT_CHANNEL* qcOutChannel[(2)], - PSY_OUT_CHANNEL* psyOutChannel[(2)], - const INT nChannels) -{ - INT ch, sfb, sfbGrp; - FIXP_DBL thrExpLdData; - - for (ch=0; chsfbCnt;sfbGrp+= psyOutChannel[ch]->sfbPerGroup) { - for (sfb=0; sfbmaxSfbPerGroup; sfb++) { - thrExpLdData = psyOutChannel[ch]->sfbThresholdLdData[sfbGrp+sfb]>>2 ; - thrExp[ch][sfbGrp+sfb] = CalcInvLdData(thrExpLdData); - } - } - } +static void FDKaacEnc_calcThreshExp( + FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB], + const QC_OUT_CHANNEL *const qcOutChannel[(2)], + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], const INT nChannels) { + INT ch, sfb, sfbGrp; + FIXP_DBL thrExpLdData; + + for (ch = 0; ch < nChannels; ch++) { + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) { + thrExpLdData = psyOutChannel[ch]->sfbThresholdLdData[sfbGrp + sfb] >> 2; + thrExp[ch][sfbGrp + sfb] = CalcInvLdData(thrExpLdData); + } + } + } } - /***************************************************************************** functionname: FDKaacEnc_adaptMinSnr - description: reduce minSnr requirements for bands with relative low energies + description: reduce minSnr requirements for bands with relative low +energies *****************************************************************************/ -static void FDKaacEnc_adaptMinSnr(QC_OUT_CHANNEL *qcOutChannel[(2)], - PSY_OUT_CHANNEL *psyOutChannel[(2)], - MINSNR_ADAPT_PARAM *msaParam, - const INT nChannels) -{ +static void FDKaacEnc_adaptMinSnr( + QC_OUT_CHANNEL *const qcOutChannel[(2)], + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], + const MINSNR_ADAPT_PARAM *const msaParam, const INT nChannels) { INT ch, sfb, sfbGrp, nSfb; FIXP_DBL avgEnLD64, dbRatio, minSnrRed; - FIXP_DBL minSnrLimitLD64 = FL2FXCONST_DBL(-0.00503012648262f); /* ld64(0.8f) */ + FIXP_DBL minSnrLimitLD64 = + FL2FXCONST_DBL(-0.00503012648262f); /* ld64(0.8f) */ FIXP_DBL nSfbLD64; FIXP_DBL accu; - for (ch=0; chmaxRed; + FIXP_DBL msaParam_startRatio = msaParam->startRatio; + FIXP_DBL msaParam_redRatioFac = + fMult(msaParam->redRatioFac, FL2FXCONST_DBL(0.3010299956f)); + FIXP_DBL msaParam_redOffs = msaParam->redOffs; + + for (ch = 0; ch < nChannels; ch++) { /* calc average energy per scalefactor band */ nSfb = 0; accu = FL2FXCONST_DBL(0.0f); - for (sfbGrp=0; sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+=psyOutChannel[ch]->sfbPerGroup) { - for (sfb=0; sfbmaxSfbPerGroup; sfb++) { - accu += psyOutChannel[ch]->sfbEnergy[sfbGrp+sfb]>>6; - nSfb++; - } + DWORD_ALIGNED(psyOutChannel[ch]->sfbEnergy); + + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) { + int maxSfbPerGroup = psyOutChannel[ch]->maxSfbPerGroup; + nSfb += maxSfbPerGroup; + for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { + accu += psyOutChannel[ch]->sfbEnergy[sfbGrp + sfb] >> 6; + } } if ((accu == FL2FXCONST_DBL(0.0f)) || (nSfb == 0)) { avgEnLD64 = FL2FXCONST_DBL(-1.0f); - } - else { - nSfbLD64 = CalcLdInt(nSfb); + } else { + nSfbLD64 = CalcLdInt(nSfb); avgEnLD64 = CalcLdData(accu); - avgEnLD64 = avgEnLD64 + FL2FXCONST_DBL(0.09375f) - nSfbLD64; /* 0.09375f: compensate shift with 6 */ + avgEnLD64 = avgEnLD64 + FL2FXCONST_DBL(0.09375f) - + nSfbLD64; /* 0.09375f: compensate shift with 6 */ } /* reduce minSnr requirement by minSnr^minSnrRed dependent on avgEn/sfbEn */ - for (sfbGrp=0; sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+=psyOutChannel[ch]->sfbPerGroup) { - for (sfb=0; sfbmaxSfbPerGroup; sfb++) { - if ( (msaParam->startRatio + qcOutChannel[ch]->sfbEnergyLdData[sfbGrp+sfb]) < avgEnLD64 ) { - dbRatio = fMult((avgEnLD64 - qcOutChannel[ch]->sfbEnergyLdData[sfbGrp+sfb]),FL2FXCONST_DBL(0.3010299956f)); /* scaled by (1.0f/(10.0f*64.0f)) */ - minSnrRed = msaParam->redOffs + fMult(msaParam->redRatioFac,dbRatio); /* scaled by 1.0f/64.0f*/ - minSnrRed = fixMax(minSnrRed, msaParam->maxRed); /* scaled by 1.0f/64.0f*/ - qcOutChannel[ch]->sfbMinSnrLdData[sfbGrp+sfb] = (fMult(qcOutChannel[ch]->sfbMinSnrLdData[sfbGrp+sfb],minSnrRed)) << 6; - qcOutChannel[ch]->sfbMinSnrLdData[sfbGrp+sfb] = fixMin(minSnrLimitLD64, qcOutChannel[ch]->sfbMinSnrLdData[sfbGrp+sfb]); - } + int maxSfbPerGroup = psyOutChannel[ch]->maxSfbPerGroup; + int sfbCnt = psyOutChannel[ch]->sfbCnt; + int sfbPerGroup = psyOutChannel[ch]->sfbPerGroup; + + for (sfbGrp = 0; sfbGrp < sfbCnt; sfbGrp += sfbPerGroup) { + FIXP_DBL *RESTRICT psfbEnergyLdData = + &qcOutChannel[ch]->sfbEnergyLdData[sfbGrp]; + FIXP_DBL *RESTRICT psfbMinSnrLdData = + &qcOutChannel[ch]->sfbMinSnrLdData[sfbGrp]; + for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { + FIXP_DBL sfbEnergyLdData = *psfbEnergyLdData++; + FIXP_DBL sfbMinSnrLdData = *psfbMinSnrLdData; + dbRatio = avgEnLD64 - sfbEnergyLdData; + int update = (msaParam_startRatio < dbRatio) ? 1 : 0; + minSnrRed = msaParam_redOffs + fMult(msaParam_redRatioFac, + dbRatio); /* scaled by 1.0f/64.0f*/ + minSnrRed = + fixMax(minSnrRed, msaParam_maxRed); /* scaled by 1.0f/64.0f*/ + minSnrRed = (fMult(sfbMinSnrLdData, minSnrRed)) << 6; + minSnrRed = fixMin(minSnrLimitLD64, minSnrRed); + *psfbMinSnrLdData++ = update ? minSnrRed : sfbMinSnrLdData; } } } } - /***************************************************************************** functionname: FDKaacEnc_initAvoidHoleFlag description: determine bands where avoid hole is not necessary resp. possible *****************************************************************************/ -static void FDKaacEnc_initAvoidHoleFlag(QC_OUT_CHANNEL *qcOutChannel[(2)], - PSY_OUT_CHANNEL *psyOutChannel[(2)], - UCHAR ahFlag[(2)][MAX_GROUPED_SFB], - struct TOOLSINFO *toolsInfo, - const INT nChannels, - const PE_DATA *peData, - AH_PARAM *ahParam) -{ - INT ch, sfb, sfbGrp; - FIXP_DBL sfbEn, sfbEnm1; - FIXP_DBL sfbEnLdData; - FIXP_DBL avgEnLdData; - - /* decrease spread energy by 3dB for long blocks, resp. 2dB for shorts - (avoid more holes in long blocks) */ - for (ch=0; chlastWindowSequence != SHORT_WINDOW) { - for (sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt;sfbGrp+= psyOutChannel[ch]->sfbPerGroup) - for (sfb=0; sfbmaxSfbPerGroup; sfb++) - qcOutChan->sfbSpreadEnergy[sfbGrp+sfb] >>= 1 ; - } - else { - for (sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt;sfbGrp+= psyOutChannel[ch]->sfbPerGroup) - for (sfb=0; sfbmaxSfbPerGroup; sfb++) - qcOutChan->sfbSpreadEnergy[sfbGrp+sfb] = - fMult(FL2FXCONST_DBL(0.63f), - qcOutChan->sfbSpreadEnergy[sfbGrp+sfb]) ; - } - } - - /* increase minSnr for local peaks, decrease it for valleys */ - if (ahParam->modifyMinSnr) { - for(ch=0; chsfbCnt;sfbGrp+= psyOutChannel[ch]->sfbPerGroup){ - for (sfb=0; sfbmaxSfbPerGroup; sfb++) { - FIXP_DBL sfbEnp1, avgEn; - if (sfb > 0) - sfbEnm1 = qcOutChan->sfbEnergy[sfbGrp+sfb-1]; - else - sfbEnm1 = qcOutChan->sfbEnergy[sfbGrp+sfb]; - - if (sfb < psyOutChannel[ch]->maxSfbPerGroup-1) - sfbEnp1 = qcOutChan->sfbEnergy[sfbGrp+sfb+1]; - else - sfbEnp1 = qcOutChan->sfbEnergy[sfbGrp+sfb]; - - avgEn = (sfbEnm1>>1) + (sfbEnp1>>1); - avgEnLdData = CalcLdData(avgEn); - sfbEn = qcOutChan->sfbEnergy[sfbGrp+sfb]; - sfbEnLdData = qcOutChan->sfbEnergyLdData[sfbGrp+sfb]; - /* peak ? */ - if (sfbEn > avgEn) { - FIXP_DBL tmpMinSnrLdData; - if (psyOutChannel[ch]->lastWindowSequence==LONG_WINDOW) - tmpMinSnrLdData = fixMax( SnrLdFac + (FIXP_DBL)(avgEnLdData - sfbEnLdData), (FIXP_DBL)SnrLdMin1 ) ; - else - tmpMinSnrLdData = fixMax( SnrLdFac + (FIXP_DBL)(avgEnLdData - sfbEnLdData), (FIXP_DBL)SnrLdMin3 ) ; - - qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] = - fixMin(qcOutChan->sfbMinSnrLdData[sfbGrp+sfb], tmpMinSnrLdData); - } - /* valley ? */ - if ( ((sfbEnLdData+(FIXP_DBL)SnrLdMin4) < (FIXP_DBL)avgEnLdData) && (sfbEn > FL2FXCONST_DBL(0.0)) ) { - FIXP_DBL tmpMinSnrLdData = avgEnLdData - sfbEnLdData -(FIXP_DBL)SnrLdMin4 + qcOutChan->sfbMinSnrLdData[sfbGrp+sfb]; - tmpMinSnrLdData = fixMin((FIXP_DBL)SnrLdFac, tmpMinSnrLdData); - qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] = fixMin(tmpMinSnrLdData, - (FIXP_DBL)(qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] + SnrLdMin2 )); - } - } - } - } - } - - /* stereo: adapt the minimum requirements sfbMinSnr of mid and - side channels to avoid spending unnoticable bits */ - if (nChannels == 2) { - QC_OUT_CHANNEL* qcOutChanM = qcOutChannel[0]; - QC_OUT_CHANNEL* qcOutChanS = qcOutChannel[1]; - PSY_OUT_CHANNEL* psyOutChanM = psyOutChannel[0]; - for(sfbGrp = 0;sfbGrp < psyOutChanM->sfbCnt;sfbGrp+= psyOutChanM->sfbPerGroup){ - for (sfb=0; sfbmaxSfbPerGroup; sfb++) { - if (toolsInfo->msMask[sfbGrp+sfb]) { - FIXP_DBL maxSfbEnLd = fixMax(qcOutChanM->sfbEnergyLdData[sfbGrp+sfb],qcOutChanS->sfbEnergyLdData[sfbGrp+sfb]); - FIXP_DBL maxThrLd, sfbMinSnrTmpLd; - - if ( ((SnrLdMin5>>1) + (maxSfbEnLd>>1) + (qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb]>>1)) <= FL2FXCONST_DBL(-0.5f)) - maxThrLd = FL2FXCONST_DBL(-1.0f) ; - else - maxThrLd = SnrLdMin5 + maxSfbEnLd + qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb]; - - if (qcOutChanM->sfbEnergy[sfbGrp+sfb] > FL2FXCONST_DBL(0.0f)) - sfbMinSnrTmpLd = maxThrLd - qcOutChanM->sfbEnergyLdData[sfbGrp+sfb]; - else - sfbMinSnrTmpLd = FL2FXCONST_DBL(0.0f); - - qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb] = fixMax(qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb],sfbMinSnrTmpLd); - - if (qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb] <= FL2FXCONST_DBL(0.0f)) - qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb] = fixMin(qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb], (FIXP_DBL)SnrLdFac); - - if (qcOutChanS->sfbEnergy[sfbGrp+sfb] > FL2FXCONST_DBL(0.0f)) - sfbMinSnrTmpLd = maxThrLd - qcOutChanS->sfbEnergyLdData[sfbGrp+sfb]; - else - sfbMinSnrTmpLd = FL2FXCONST_DBL(0.0f); - - qcOutChanS->sfbMinSnrLdData[sfbGrp+sfb] = fixMax(qcOutChanS->sfbMinSnrLdData[sfbGrp+sfb],sfbMinSnrTmpLd); - - if (qcOutChanS->sfbMinSnrLdData[sfbGrp+sfb] <= FL2FXCONST_DBL(0.0f)) - qcOutChanS->sfbMinSnrLdData[sfbGrp+sfb] = fixMin(qcOutChanS->sfbMinSnrLdData[sfbGrp+sfb],(FIXP_DBL)SnrLdFac); - - if (qcOutChanM->sfbEnergy[sfbGrp+sfb]>qcOutChanM->sfbSpreadEnergy[sfbGrp+sfb]) - qcOutChanS->sfbSpreadEnergy[sfbGrp+sfb] = - fMult(qcOutChanS->sfbEnergy[sfbGrp+sfb], FL2FXCONST_DBL(0.9f)); - - if (qcOutChanS->sfbEnergy[sfbGrp+sfb]>qcOutChanS->sfbSpreadEnergy[sfbGrp+sfb]) - qcOutChanM->sfbSpreadEnergy[sfbGrp+sfb] = - fMult(qcOutChanM->sfbEnergy[sfbGrp+sfb], FL2FXCONST_DBL(0.9f)); - } - } - } - } - - /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */ - for(ch=0; chsfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){ - for (sfb=0; sfbmaxSfbPerGroup; sfb++) { - if ((qcOutChan->sfbSpreadEnergy[sfbGrp+sfb] > qcOutChan->sfbEnergy[sfbGrp+sfb]) - || (qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] > FL2FXCONST_DBL(0.0f))) { - ahFlag[ch][sfbGrp+sfb] = NO_AH; +static void FDKaacEnc_initAvoidHoleFlag( + QC_OUT_CHANNEL *const qcOutChannel[(2)], + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], + UCHAR ahFlag[(2)][MAX_GROUPED_SFB], const struct TOOLSINFO *const toolsInfo, + const INT nChannels, const AH_PARAM *const ahParam) { + INT ch, sfb, sfbGrp; + FIXP_DBL sfbEn, sfbEnm1; + FIXP_DBL sfbEnLdData; + FIXP_DBL avgEnLdData; + + /* decrease spread energy by 3dB for long blocks, resp. 2dB for shorts + (avoid more holes in long blocks) */ + for (ch = 0; ch < nChannels; ch++) { + QC_OUT_CHANNEL *const qcOutChan = qcOutChannel[ch]; + + if (psyOutChannel[ch]->lastWindowSequence != SHORT_WINDOW) { + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) + for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) + qcOutChan->sfbSpreadEnergy[sfbGrp + sfb] >>= 1; + } else { + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) + for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) + qcOutChan->sfbSpreadEnergy[sfbGrp + sfb] = fMult( + FL2FXCONST_DBL(0.63f), qcOutChan->sfbSpreadEnergy[sfbGrp + sfb]); + } + } + + /* increase minSnr for local peaks, decrease it for valleys */ + if (ahParam->modifyMinSnr) { + for (ch = 0; ch < nChannels; ch++) { + QC_OUT_CHANNEL *const qcOutChan = qcOutChannel[ch]; + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) { + FIXP_DBL sfbEnp1, avgEn; + if (sfb > 0) + sfbEnm1 = qcOutChan->sfbEnergy[sfbGrp + sfb - 1]; + else + sfbEnm1 = qcOutChan->sfbEnergy[sfbGrp + sfb]; + + if (sfb < psyOutChannel[ch]->maxSfbPerGroup - 1) + sfbEnp1 = qcOutChan->sfbEnergy[sfbGrp + sfb + 1]; + else + sfbEnp1 = qcOutChan->sfbEnergy[sfbGrp + sfb]; + + avgEn = (sfbEnm1 >> 1) + (sfbEnp1 >> 1); + avgEnLdData = CalcLdData(avgEn); + sfbEn = qcOutChan->sfbEnergy[sfbGrp + sfb]; + sfbEnLdData = qcOutChan->sfbEnergyLdData[sfbGrp + sfb]; + /* peak ? */ + if (sfbEn > avgEn) { + FIXP_DBL tmpMinSnrLdData; + if (psyOutChannel[ch]->lastWindowSequence == LONG_WINDOW) + tmpMinSnrLdData = + fixMax(SnrLdFac + (FIXP_DBL)(avgEnLdData - sfbEnLdData), + (FIXP_DBL)SnrLdMin1); + else + tmpMinSnrLdData = + fixMax(SnrLdFac + (FIXP_DBL)(avgEnLdData - sfbEnLdData), + (FIXP_DBL)SnrLdMin3); + + qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] = fixMin( + qcOutChan->sfbMinSnrLdData[sfbGrp + sfb], tmpMinSnrLdData); } - else { - ahFlag[ch][sfbGrp+sfb] = AH_INACTIVE; + /* valley ? */ + if (((sfbEnLdData + (FIXP_DBL)SnrLdMin4) < (FIXP_DBL)avgEnLdData) && + (sfbEn > FL2FXCONST_DBL(0.0))) { + FIXP_DBL tmpMinSnrLdData = avgEnLdData - sfbEnLdData - + (FIXP_DBL)SnrLdMin4 + + qcOutChan->sfbMinSnrLdData[sfbGrp + sfb]; + tmpMinSnrLdData = fixMin((FIXP_DBL)SnrLdFac, tmpMinSnrLdData); + qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] = + fixMin(tmpMinSnrLdData, + (FIXP_DBL)(qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] + + SnrLdMin2)); } } } - } -} + } + } + + /* stereo: adapt the minimum requirements sfbMinSnr of mid and + side channels to avoid spending unnoticable bits */ + if (nChannels == 2) { + QC_OUT_CHANNEL *qcOutChanM = qcOutChannel[0]; + QC_OUT_CHANNEL *qcOutChanS = qcOutChannel[1]; + const PSY_OUT_CHANNEL *const psyOutChanM = psyOutChannel[0]; + for (sfbGrp = 0; sfbGrp < psyOutChanM->sfbCnt; + sfbGrp += psyOutChanM->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChanM->maxSfbPerGroup; sfb++) { + if (toolsInfo->msMask[sfbGrp + sfb]) { + FIXP_DBL maxSfbEnLd = + fixMax(qcOutChanM->sfbEnergyLdData[sfbGrp + sfb], + qcOutChanS->sfbEnergyLdData[sfbGrp + sfb]); + FIXP_DBL maxThrLd, sfbMinSnrTmpLd; + + if (((SnrLdMin5 >> 1) + (maxSfbEnLd >> 1) + + (qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb] >> 1)) <= + FL2FXCONST_DBL(-0.5f)) + maxThrLd = FL2FXCONST_DBL(-1.0f); + else + maxThrLd = SnrLdMin5 + maxSfbEnLd + + qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb]; + + if (qcOutChanM->sfbEnergy[sfbGrp + sfb] > FL2FXCONST_DBL(0.0f)) + sfbMinSnrTmpLd = + maxThrLd - qcOutChanM->sfbEnergyLdData[sfbGrp + sfb]; + else + sfbMinSnrTmpLd = FL2FXCONST_DBL(0.0f); + qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb] = + fixMax(qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb], sfbMinSnrTmpLd); + if (qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb] <= FL2FXCONST_DBL(0.0f)) + qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb] = fixMin( + qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb], (FIXP_DBL)SnrLdFac); + + if (qcOutChanS->sfbEnergy[sfbGrp + sfb] > FL2FXCONST_DBL(0.0f)) + sfbMinSnrTmpLd = + maxThrLd - qcOutChanS->sfbEnergyLdData[sfbGrp + sfb]; + else + sfbMinSnrTmpLd = FL2FXCONST_DBL(0.0f); + + qcOutChanS->sfbMinSnrLdData[sfbGrp + sfb] = + fixMax(qcOutChanS->sfbMinSnrLdData[sfbGrp + sfb], sfbMinSnrTmpLd); + + if (qcOutChanS->sfbMinSnrLdData[sfbGrp + sfb] <= FL2FXCONST_DBL(0.0f)) + qcOutChanS->sfbMinSnrLdData[sfbGrp + sfb] = fixMin( + qcOutChanS->sfbMinSnrLdData[sfbGrp + sfb], (FIXP_DBL)SnrLdFac); + + if (qcOutChanM->sfbEnergy[sfbGrp + sfb] > + qcOutChanM->sfbSpreadEnergy[sfbGrp + sfb]) + qcOutChanS->sfbSpreadEnergy[sfbGrp + sfb] = fMult( + qcOutChanS->sfbEnergy[sfbGrp + sfb], FL2FXCONST_DBL(0.9f)); + + if (qcOutChanS->sfbEnergy[sfbGrp + sfb] > + qcOutChanS->sfbSpreadEnergy[sfbGrp + sfb]) + qcOutChanM->sfbSpreadEnergy[sfbGrp + sfb] = fMult( + qcOutChanM->sfbEnergy[sfbGrp + sfb], FL2FXCONST_DBL(0.9f)); + + } /* if (toolsInfo->msMask[sfbGrp+sfb]) */ + } /* sfb */ + } /* sfbGrp */ + } /* nChannels==2 */ + + /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */ + for (ch = 0; ch < nChannels; ch++) { + QC_OUT_CHANNEL *qcOutChan = qcOutChannel[ch]; + const PSY_OUT_CHANNEL *const psyOutChan = psyOutChannel[ch]; + for (sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt; + sfbGrp += psyOutChan->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChan->maxSfbPerGroup; sfb++) { + if ((qcOutChan->sfbSpreadEnergy[sfbGrp + sfb] > + qcOutChan->sfbEnergy[sfbGrp + sfb]) || + (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] > FL2FXCONST_DBL(0.0f))) { + ahFlag[ch][sfbGrp + sfb] = NO_AH; + } else { + ahFlag[ch][sfbGrp + sfb] = AH_INACTIVE; + } + } + } + } +} /** - * \brief Calculate constants that do not change during successive pe calculations. + * \brief Calculate constants that do not change during successive pe + * calculations. * - * \param peData Pointer to structure containing PE data of current element. - * \param psyOutChannel Pointer to PSY_OUT_CHANNEL struct holding nChannels elements. - * \param qcOutChannel Pointer to QC_OUT_CHANNEL struct holding nChannels elements. + * \param peData Pointer to structure containing PE data of + * current element. + * \param psyOutChannel Pointer to PSY_OUT_CHANNEL struct holding + * nChannels elements. + * \param qcOutChannel Pointer to QC_OUT_CHANNEL struct holding + * nChannels elements. * \param nChannels Number of channels in element. - * \param peOffset Fixed PE offset defined while FDKaacEnc_AdjThrInit() depending on bitrate. + * \param peOffset Fixed PE offset defined while + * FDKaacEnc_AdjThrInit() depending on bitrate. * * \return void */ -static -void FDKaacEnc_preparePe(PE_DATA *peData, - PSY_OUT_CHANNEL* psyOutChannel[(2)], - QC_OUT_CHANNEL* qcOutChannel[(2)], - const INT nChannels, - const INT peOffset) -{ - INT ch; - - for(ch=0; chpeChannelData[ch], - psyOutChan->sfbEnergyLdData, - psyOutChan->sfbThresholdLdData, - qcOutChannel[ch]->sfbFormFactorLdData, - psyOutChan->sfbOffsets, - psyOutChan->sfbCnt, - psyOutChan->sfbPerGroup, - psyOutChan->maxSfbPerGroup); - } - peData->offset = peOffset; +static void FDKaacEnc_preparePe(PE_DATA *const peData, + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], + const QC_OUT_CHANNEL *const qcOutChannel[(2)], + const INT nChannels, const INT peOffset) { + INT ch; + + for (ch = 0; ch < nChannels; ch++) { + const PSY_OUT_CHANNEL *const psyOutChan = psyOutChannel[ch]; + FDKaacEnc_prepareSfbPe( + &peData->peChannelData[ch], psyOutChan->sfbEnergyLdData, + psyOutChan->sfbThresholdLdData, qcOutChannel[ch]->sfbFormFactorLdData, + psyOutChan->sfbOffsets, psyOutChan->sfbCnt, psyOutChan->sfbPerGroup, + psyOutChan->maxSfbPerGroup); + } + peData->offset = peOffset; } /** * \brief Calculate weighting factor for threshold adjustment. * - * Calculate weighting factor to be applied at energies and thresholds in ld64 format. + * Calculate weighting factor to be applied at energies and thresholds in ld64 + * format. * * \param peData, Pointer to PE data in current element. - * \param psyOutChannel Pointer to PSY_OUT_CHANNEL struct holding nChannels elements. - * \param qcOutChannel Pointer to QC_OUT_CHANNEL struct holding nChannels elements. + * \param psyOutChannel Pointer to PSY_OUT_CHANNEL struct holding + * nChannels elements. + * \param qcOutChannel Pointer to QC_OUT_CHANNEL struct holding + * nChannels elements. * \param toolsInfo Pointer to tools info struct of current element. - * \param adjThrStateElement Pointer to ATS_ELEMENT holding enFacPatch states. + * \param adjThrStateElement Pointer to ATS_ELEMENT holding enFacPatch + * states. * \param nChannels Number of channels in element. * \param usePatchTool Apply the weighting tool 0 (no) else (yes). * * \return void */ -static -void FDKaacEnc_calcWeighting(PE_DATA *peData, - PSY_OUT_CHANNEL* psyOutChannel[(2)], - QC_OUT_CHANNEL* qcOutChannel[(2)], - struct TOOLSINFO *toolsInfo, - ATS_ELEMENT* adjThrStateElement, - const INT nChannels, - const INT usePatchTool) -{ - int ch, noShortWindowInFrame = TRUE; - INT exePatchM = 0; - - for (ch=0; chlastWindowSequence == SHORT_WINDOW) { - noShortWindowInFrame = FALSE; - } - FDKmemclear(qcOutChannel[ch]->sfbEnFacLd, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); - } - - if (usePatchTool==0) { - return; /* tool is disabled */ +static void FDKaacEnc_calcWeighting( + const PE_DATA *const peData, + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], + QC_OUT_CHANNEL *const qcOutChannel[(2)], + const struct TOOLSINFO *const toolsInfo, + ATS_ELEMENT *const adjThrStateElement, const INT nChannels, + const INT usePatchTool) { + int ch, noShortWindowInFrame = TRUE; + INT exePatchM = 0; + + for (ch = 0; ch < nChannels; ch++) { + if (psyOutChannel[ch]->lastWindowSequence == SHORT_WINDOW) { + noShortWindowInFrame = FALSE; } + FDKmemclear(qcOutChannel[ch]->sfbEnFacLd, + MAX_GROUPED_SFB * sizeof(FIXP_DBL)); + } - for (ch=0; chsfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) { + FIXP_DBL nrgFac12 = CalcInvLdData( + psyOutChan->sfbEnergyLdData[sfbGrp + sfb] >> 1); /* nrg^(1/2) */ + FIXP_DBL nrgFac14 = CalcInvLdData( + psyOutChan->sfbEnergyLdData[sfbGrp + sfb] >> 2); /* nrg^(1/4) */ + + /* maximal number of bands is 64, results scaling factor 6 */ + nLinesSum += peData->peChannelData[ch] + .sfbNLines[sfbGrp + sfb]; /* relevant lines */ + nrgTotal += + (psyOutChan->sfbEnergy[sfbGrp + sfb] >> 6); /* sum up nrg */ + nrgSum12 += (nrgFac12 >> 6); /* sum up nrg^(2/4) */ + nrgSum14 += (nrgFac14 >> 6); /* sum up nrg^(1/4) */ + nrgSum34 += (fMult(nrgFac14, nrgFac12) >> 6); /* sum up nrg^(3/4) */ + } + } - /* calculate flatness of audible spectrum, i.e. spectrum above masking threshold. */ - for (sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+=psyOutChannel[ch]->sfbPerGroup) { - for (sfb=0; sfbmaxSfbPerGroup; sfb++) { - FIXP_DBL nrgFac12 = CalcInvLdData(psyOutChan->sfbEnergyLdData[sfbGrp+sfb]>>1); /* nrg^(1/2) */ - FIXP_DBL nrgFac14 = CalcInvLdData(psyOutChan->sfbEnergyLdData[sfbGrp+sfb]>>2); /* nrg^(1/4) */ + nrgTotal = CalcLdData(nrgTotal); /* get ld64 of total nrg */ + + nrgFacLd_14 = + CalcLdData(nrgSum14) - nrgTotal; /* ld64(nrgSum14/nrgTotal) */ + nrgFacLd_12 = + CalcLdData(nrgSum12) - nrgTotal; /* ld64(nrgSum12/nrgTotal) */ + nrgFacLd_34 = + CalcLdData(nrgSum34) - nrgTotal; /* ld64(nrgSum34/nrgTotal) */ + + /* Note: nLinesSum cannot be larger than the number of total lines, thats + * taken care of in line_pe.cpp FDKaacEnc_prepareSfbPe() */ + adjThrStateElement->chaosMeasureEnFac[ch] = + fMax(FL2FXCONST_DBL(0.1875f), + fDivNorm(nLinesSum, psyOutChan->sfbOffsets[psyOutChan->sfbCnt])); + + usePatch = (adjThrStateElement->chaosMeasureEnFac[ch] > + FL2FXCONST_DBL(0.78125f)); + exePatch = ((usePatch) && (adjThrStateElement->lastEnFacPatch[ch])); + + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) { + INT sfbExePatch; + /* for MS coupled SFBs, also execute patch in side channel if done in + * mid channel */ + if ((ch == 1) && (toolsInfo->msMask[sfbGrp + sfb])) { + sfbExePatch = exePatchM; + } else { + sfbExePatch = exePatch; + } - /* maximal number of bands is 64, results scaling factor 6 */ - nLinesSum += peData->peChannelData[ch].sfbNLines[sfbGrp+sfb]; /* relevant lines */ - nrgTotal += ( psyOutChan->sfbEnergy[sfbGrp+sfb] >> 6 ); /* sum up nrg */ - nrgSum12 += ( nrgFac12 >> 6 ); /* sum up nrg^(2/4) */ - nrgSum14 += ( nrgFac14 >> 6 ); /* sum up nrg^(1/4) */ - nrgSum34 += ( fMult(nrgFac14, nrgFac12) >> 6 ); /* sum up nrg^(3/4) */ - } + if ((sfbExePatch) && + (psyOutChan->sfbEnergy[sfbGrp + sfb] > FL2FXCONST_DBL(0.f))) { + /* execute patch based on spectral flatness calculated above */ + if (adjThrStateElement->chaosMeasureEnFac[ch] > + FL2FXCONST_DBL(0.8125f)) { + qcOutChannel[ch]->sfbEnFacLd[sfbGrp + sfb] = + ((nrgFacLd_14 + + (psyOutChan->sfbEnergyLdData[sfbGrp + sfb] + + (psyOutChan->sfbEnergyLdData[sfbGrp + sfb] >> 1))) >> + 1); /* sfbEnergy^(3/4) */ + } else if (adjThrStateElement->chaosMeasureEnFac[ch] > + FL2FXCONST_DBL(0.796875f)) { + qcOutChannel[ch]->sfbEnFacLd[sfbGrp + sfb] = + ((nrgFacLd_12 + psyOutChan->sfbEnergyLdData[sfbGrp + sfb]) >> + 1); /* sfbEnergy^(2/4) */ + } else { + qcOutChannel[ch]->sfbEnFacLd[sfbGrp + sfb] = + ((nrgFacLd_34 + + (psyOutChan->sfbEnergyLdData[sfbGrp + sfb] >> 1)) >> + 1); /* sfbEnergy^(1/4) */ } - - nrgTotal = CalcLdData(nrgTotal); /* get ld64 of total nrg */ - - nrgFacLd_14 = CalcLdData(nrgSum14) - nrgTotal; /* ld64(nrgSum14/nrgTotal) */ - nrgFacLd_12 = CalcLdData(nrgSum12) - nrgTotal; /* ld64(nrgSum12/nrgTotal) */ - nrgFacLd_34 = CalcLdData(nrgSum34) - nrgTotal; /* ld64(nrgSum34/nrgTotal) */ - - adjThrStateElement->chaosMeasureEnFac[ch] = FDKmax( FL2FXCONST_DBL(0.1875f), fDivNorm(nLinesSum,psyOutChan->sfbOffsets[psyOutChan->sfbCnt]) ); - - usePatch = (adjThrStateElement->chaosMeasureEnFac[ch] > FL2FXCONST_DBL(0.78125f)); - exePatch = ((usePatch) && (adjThrStateElement->lastEnFacPatch[ch])); - - for (sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+=psyOutChannel[ch]->sfbPerGroup) { - for (sfb=0; sfbmaxSfbPerGroup; sfb++) { - - INT sfbExePatch; - - /* for MS coupled SFBs, also execute patch in side channel if done in mid channel */ - if ((ch == 1) && (toolsInfo->msMask[sfbGrp+sfb])) { - sfbExePatch = exePatchM; - } - else { - sfbExePatch = exePatch; - } - - if ( (sfbExePatch) && (psyOutChan->sfbEnergy[sfbGrp+sfb]>FL2FXCONST_DBL(0.f)) ) - { - /* execute patch based on spectral flatness calculated above */ - if (adjThrStateElement->chaosMeasureEnFac[ch] > FL2FXCONST_DBL(0.8125f)) { - qcOutChannel[ch]->sfbEnFacLd[sfbGrp+sfb] = ( (nrgFacLd_14 + (psyOutChan->sfbEnergyLdData[sfbGrp+sfb]+(psyOutChan->sfbEnergyLdData[sfbGrp+sfb]>>1)))>>1 ); /* sfbEnergy^(3/4) */ - } - else if (adjThrStateElement->chaosMeasureEnFac[ch] > FL2FXCONST_DBL(0.796875f)) { - qcOutChannel[ch]->sfbEnFacLd[sfbGrp+sfb] = ( (nrgFacLd_12 + psyOutChan->sfbEnergyLdData[sfbGrp+sfb])>>1 ); /* sfbEnergy^(2/4) */ - } - else { - qcOutChannel[ch]->sfbEnFacLd[sfbGrp+sfb] = ( (nrgFacLd_34 + (psyOutChan->sfbEnergyLdData[sfbGrp+sfb]>>1))>>1 ); /* sfbEnergy^(1/4) */ - } - qcOutChannel[ch]->sfbEnFacLd[sfbGrp+sfb] = fixMin(qcOutChannel[ch]->sfbEnFacLd[sfbGrp+sfb],(FIXP_DBL)0); - - } - } - } /* sfb loop */ - - adjThrStateElement->lastEnFacPatch[ch] = usePatch; - exePatchM = exePatch; - } - else { - /* !noShortWindowInFrame */ - adjThrStateElement->chaosMeasureEnFac[ch] = FL2FXCONST_DBL(0.75f); - adjThrStateElement->lastEnFacPatch[ch] = TRUE; /* allow use of sfbEnFac patch in upcoming frame */ + qcOutChannel[ch]->sfbEnFacLd[sfbGrp + sfb] = + fixMin(qcOutChannel[ch]->sfbEnFacLd[sfbGrp + sfb], (FIXP_DBL)0); + } } + } /* sfb loop */ - } /* ch loop */ + adjThrStateElement->lastEnFacPatch[ch] = usePatch; + exePatchM = exePatch; + } else { + /* !noShortWindowInFrame */ + adjThrStateElement->chaosMeasureEnFac[ch] = FL2FXCONST_DBL(0.75f); + adjThrStateElement->lastEnFacPatch[ch] = + TRUE; /* allow use of sfbEnFac patch in upcoming frame */ + } + } /* ch loop */ } - - - /***************************************************************************** functionname: FDKaacEnc_calcPe description: calculate pe for both channels *****************************************************************************/ -static -void FDKaacEnc_calcPe(PSY_OUT_CHANNEL* psyOutChannel[(2)], - QC_OUT_CHANNEL* qcOutChannel[(2)], - PE_DATA *peData, - const INT nChannels) -{ - INT ch; - - peData->pe = peData->offset; - peData->constPart = 0; - peData->nActiveLines = 0; - for(ch=0; chpeChannelData[ch]; - FDKaacEnc_calcSfbPe(&peData->peChannelData[ch], - qcOutChannel[ch]->sfbWeightedEnergyLdData, - qcOutChannel[ch]->sfbThresholdLdData, - psyOutChannel[ch]->sfbCnt, - psyOutChannel[ch]->sfbPerGroup, - psyOutChannel[ch]->maxSfbPerGroup, - psyOutChannel[ch]->isBook, - psyOutChannel[ch]->isScale); - - peData->pe += peChanData->pe; - peData->constPart += peChanData->constPart; - peData->nActiveLines += peChanData->nActiveLines; - } +static void FDKaacEnc_calcPe(const PSY_OUT_CHANNEL *const psyOutChannel[(2)], + const QC_OUT_CHANNEL *const qcOutChannel[(2)], + PE_DATA *const peData, const INT nChannels) { + INT ch; + + peData->pe = peData->offset; + peData->constPart = 0; + peData->nActiveLines = 0; + for (ch = 0; ch < nChannels; ch++) { + PE_CHANNEL_DATA *peChanData = &peData->peChannelData[ch]; + + FDKaacEnc_calcSfbPe( + peChanData, qcOutChannel[ch]->sfbWeightedEnergyLdData, + qcOutChannel[ch]->sfbThresholdLdData, psyOutChannel[ch]->sfbCnt, + psyOutChannel[ch]->sfbPerGroup, psyOutChannel[ch]->maxSfbPerGroup, + psyOutChannel[ch]->isBook, psyOutChannel[ch]->isScale); + + peData->pe += peChanData->pe; + peData->constPart += peChanData->constPart; + peData->nActiveLines += peChanData->nActiveLines; + } } -void FDKaacEnc_peCalculation(PE_DATA *peData, - PSY_OUT_CHANNEL* psyOutChannel[(2)], - QC_OUT_CHANNEL* qcOutChannel[(2)], - struct TOOLSINFO *toolsInfo, - ATS_ELEMENT* adjThrStateElement, - const INT nChannels) -{ +void FDKaacEnc_peCalculation(PE_DATA *const peData, + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], + QC_OUT_CHANNEL *const qcOutChannel[(2)], + const struct TOOLSINFO *const toolsInfo, + ATS_ELEMENT *const adjThrStateElement, + const INT nChannels) { /* constants that will not change during successive pe calculations */ - FDKaacEnc_preparePe(peData, psyOutChannel, qcOutChannel, nChannels, adjThrStateElement->peOffset); + FDKaacEnc_preparePe(peData, psyOutChannel, qcOutChannel, nChannels, + adjThrStateElement->peOffset); /* calculate weighting factor for threshold adjustment */ - FDKaacEnc_calcWeighting(peData, psyOutChannel, qcOutChannel, toolsInfo, adjThrStateElement, nChannels, 1); -{ + FDKaacEnc_calcWeighting(peData, psyOutChannel, qcOutChannel, toolsInfo, + adjThrStateElement, nChannels, 1); + { /* no weighting of threholds and energies for mlout */ /* weight energies and thresholds */ int ch; - for (ch=0; chsfbCnt; sfbGrp+=psyOutChannel[ch]->sfbPerGroup) { - for (sfb=0; sfbmaxSfbPerGroup; sfb++) { - pQcOutCh->sfbWeightedEnergyLdData[sfb+sfbGrp] = pQcOutCh->sfbEnergyLdData[sfb+sfbGrp] - pQcOutCh->sfbEnFacLd[sfb+sfbGrp]; - pQcOutCh->sfbThresholdLdData[sfb+sfbGrp] -= pQcOutCh->sfbEnFacLd[sfb+sfbGrp]; - } + for (ch = 0; ch < nChannels; ch++) { + int sfb, sfbGrp; + QC_OUT_CHANNEL *pQcOutCh = qcOutChannel[ch]; + + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) { + pQcOutCh->sfbWeightedEnergyLdData[sfb + sfbGrp] = + pQcOutCh->sfbEnergyLdData[sfb + sfbGrp] - + pQcOutCh->sfbEnFacLd[sfb + sfbGrp]; + pQcOutCh->sfbThresholdLdData[sfb + sfbGrp] -= + pQcOutCh->sfbEnFacLd[sfb + sfbGrp]; } + } } -} + } /* pe without reduction */ FDKaacEnc_calcPe(psyOutChannel, qcOutChannel, peData, nChannels); } - - /***************************************************************************** functionname: FDKaacEnc_FDKaacEnc_calcPeNoAH description: sum the pe data only for bands where avoid hole is inactive *****************************************************************************/ -static void FDKaacEnc_FDKaacEnc_calcPeNoAH(INT *pe, - INT *constPart, - INT *nActiveLines, - PE_DATA *peData, - UCHAR ahFlag[(2)][MAX_GROUPED_SFB], - PSY_OUT_CHANNEL* psyOutChannel[(2)], - const INT nChannels) -{ - INT ch, sfb,sfbGrp; - - INT pe_tmp = peData->offset; - INT constPart_tmp = 0; - INT nActiveLines_tmp = 0; - for(ch=0; chpeChannelData[ch]; - for(sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt;sfbGrp+= psyOutChannel[ch]->sfbPerGroup){ - for (sfb=0; sfbmaxSfbPerGroup; sfb++) { - if(ahFlag[ch][sfbGrp+sfb] < AH_ACTIVE) { - pe_tmp += peChanData->sfbPe[sfbGrp+sfb]; - constPart_tmp += peChanData->sfbConstPart[sfbGrp+sfb]; - nActiveLines_tmp += peChanData->sfbNActiveLines[sfbGrp+sfb]; - } - } +#define CONSTPART_HEADROOM 4 +static void FDKaacEnc_FDKaacEnc_calcPeNoAH( + INT *const pe, INT *const constPart, INT *const nActiveLines, + const PE_DATA *const peData, const UCHAR ahFlag[(2)][MAX_GROUPED_SFB], + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], const INT nChannels) { + INT ch, sfb, sfbGrp; + + INT pe_tmp = peData->offset; + INT constPart_tmp = 0; + INT nActiveLines_tmp = 0; + for (ch = 0; ch < nChannels; ch++) { + const PE_CHANNEL_DATA *const peChanData = &peData->peChannelData[ch]; + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) { + if (ahFlag[ch][sfbGrp + sfb] < AH_ACTIVE) { + pe_tmp += peChanData->sfbPe[sfbGrp + sfb]; + constPart_tmp += + peChanData->sfbConstPart[sfbGrp + sfb] >> CONSTPART_HEADROOM; + nActiveLines_tmp += peChanData->sfbNActiveLines[sfbGrp + sfb]; } + } } - /* correct scaled pe and constPart values */ - *pe = pe_tmp >> PE_CONSTPART_SHIFT; - *constPart = constPart_tmp >> PE_CONSTPART_SHIFT; + } + /* correct scaled pe and constPart values */ + *pe = pe_tmp >> PE_CONSTPART_SHIFT; + *constPart = constPart_tmp >> (PE_CONSTPART_SHIFT - CONSTPART_HEADROOM); - *nActiveLines = nActiveLines_tmp; + *nActiveLines = nActiveLines_tmp; } - /***************************************************************************** functionname: FDKaacEnc_reduceThresholdsCBR description: apply reduction formula *****************************************************************************/ -static const FIXP_DBL limitThrReducedLdData = (FIXP_DBL)0x00008000; /*FL2FXCONST_DBL(FDKpow(2.0,-LD_DATA_SCALING/4.0));*/ - -static void FDKaacEnc_reduceThresholdsCBR(QC_OUT_CHANNEL* qcOutChannel[(2)], - PSY_OUT_CHANNEL* psyOutChannel[(2)], - UCHAR ahFlag[(2)][MAX_GROUPED_SFB], - FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB], - const INT nChannels, - const FIXP_DBL redVal, - const SCHAR redValScaling) -{ - INT ch, sfb, sfbGrp; - FIXP_DBL sfbEnLdData, sfbThrLdData, sfbThrReducedLdData; - FIXP_DBL sfbThrExp; - - for(ch=0; chsfbCnt; sfbGrp+= psyOutChannel[ch]->sfbPerGroup){ - for (sfb=0; sfbmaxSfbPerGroup; sfb++) { - sfbEnLdData = qcOutChan->sfbWeightedEnergyLdData[sfbGrp+sfb]; - sfbThrLdData = qcOutChan->sfbThresholdLdData[sfbGrp+sfb]; - sfbThrExp = thrExp[ch][sfbGrp+sfb]; - if ((sfbEnLdData > sfbThrLdData) && (ahFlag[ch][sfbGrp+sfb] != AH_ACTIVE)) { - - /* threshold reduction formula: - float tmp = thrExp[ch][sfb]+redVal; - tmp *= tmp; - sfbThrReduced = tmp*tmp; - */ - int minScale = fixMin(CountLeadingBits(sfbThrExp), CountLeadingBits(redVal) - (DFRACT_BITS-1-redValScaling) )-1; - - /* 4*log( sfbThrExp + redVal ) */ - sfbThrReducedLdData = CalcLdData(fAbs(scaleValue(sfbThrExp, minScale) + scaleValue(redVal,(DFRACT_BITS-1-redValScaling)+minScale))) - - (FIXP_DBL)(minScale<<(DFRACT_BITS-1-LD_DATA_SHIFT)); - sfbThrReducedLdData <<= 2; - - /* avoid holes */ - if ( ((sfbThrReducedLdData - sfbEnLdData) > qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] ) - && (ahFlag[ch][sfbGrp+sfb] != NO_AH) ) - { - if (qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] > (FL2FXCONST_DBL(-1.0f) - sfbEnLdData) ){ - sfbThrReducedLdData = fixMax((qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] + sfbEnLdData), sfbThrLdData); - } - else sfbThrReducedLdData = sfbThrLdData; - ahFlag[ch][sfbGrp+sfb] = AH_ACTIVE; - } +static const FIXP_DBL limitThrReducedLdData = + (FIXP_DBL)0x00008000; /*FL2FXCONST_DBL(FDKpow(2.0,-LD_DATA_SCALING/4.0));*/ + +static void FDKaacEnc_reduceThresholdsCBR( + QC_OUT_CHANNEL *const qcOutChannel[(2)], + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], + UCHAR ahFlag[(2)][MAX_GROUPED_SFB], + const FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB], const INT nChannels, + const FIXP_DBL redVal_m, const SCHAR redVal_e) { + INT ch, sfb, sfbGrp; + FIXP_DBL sfbEnLdData, sfbThrLdData, sfbThrReducedLdData; + FIXP_DBL sfbThrExp; + + for (ch = 0; ch < nChannels; ch++) { + QC_OUT_CHANNEL *qcOutChan = qcOutChannel[ch]; + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) { + sfbEnLdData = qcOutChan->sfbWeightedEnergyLdData[sfbGrp + sfb]; + sfbThrLdData = qcOutChan->sfbThresholdLdData[sfbGrp + sfb]; + sfbThrExp = thrExp[ch][sfbGrp + sfb]; + if ((sfbEnLdData > sfbThrLdData) && + (ahFlag[ch][sfbGrp + sfb] != AH_ACTIVE)) { + /* threshold reduction formula: + float tmp = thrExp[ch][sfb]+redVal; + tmp *= tmp; + sfbThrReduced = tmp*tmp; + */ + int minScale = fixMin(CountLeadingBits(sfbThrExp), + CountLeadingBits(redVal_m) - redVal_e) - + 1; + + /* 4*log( sfbThrExp + redVal ) */ + sfbThrReducedLdData = + CalcLdData(fAbs(scaleValue(sfbThrExp, minScale) + + scaleValue(redVal_m, redVal_e + minScale))) - + (FIXP_DBL)(minScale << (DFRACT_BITS - 1 - LD_DATA_SHIFT)); + sfbThrReducedLdData <<= 2; - /* minimum of 29 dB Ratio for Thresholds */ - if ((sfbEnLdData+(FIXP_DBL)MAXVAL_DBL) > FL2FXCONST_DBL(9.6336206/LD_DATA_SCALING)){ - sfbThrReducedLdData = fixMax(sfbThrReducedLdData, (sfbEnLdData - FL2FXCONST_DBL(9.6336206/LD_DATA_SCALING))); - } + /* avoid holes */ + if ((sfbThrReducedLdData > + (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] + sfbEnLdData)) && + (ahFlag[ch][sfbGrp + sfb] != NO_AH)) { + if (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] > + (FL2FXCONST_DBL(-1.0f) - sfbEnLdData)) { + sfbThrReducedLdData = fixMax( + (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] + sfbEnLdData), + sfbThrLdData); + } else + sfbThrReducedLdData = sfbThrLdData; + ahFlag[ch][sfbGrp + sfb] = AH_ACTIVE; + } - qcOutChan->sfbThresholdLdData[sfbGrp+sfb] = sfbThrReducedLdData; - } + /* minimum of 29 dB Ratio for Thresholds */ + if ((sfbEnLdData + (FIXP_DBL)MAXVAL_DBL) > + FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING)) { + sfbThrReducedLdData = fixMax( + sfbThrReducedLdData, + (sfbEnLdData - FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING))); + } + + qcOutChan->sfbThresholdLdData[sfbGrp + sfb] = sfbThrReducedLdData; } } - } + } + } } /* similar to prepareSfbPe1() */ -static FIXP_DBL FDKaacEnc_calcChaosMeasure(PSY_OUT_CHANNEL *psyOutChannel, - const FIXP_DBL *sfbFormFactorLdData) -{ - #define SCALE_FORM_FAC (4) /* (SCALE_FORM_FAC+FORM_FAC_SHIFT) >= ld(FRAME_LENGTH)*/ - #define SCALE_NRGS (8) - #define SCALE_NLINES (16) - #define SCALE_NRGS_SQRT4 (2) /* 0.25 * SCALE_NRGS */ - #define SCALE_NLINES_P34 (12) /* 0.75 * SCALE_NLINES */ - - INT sfbGrp, sfb; +static FIXP_DBL FDKaacEnc_calcChaosMeasure( + const PSY_OUT_CHANNEL *const psyOutChannel, + const FIXP_DBL *const sfbFormFactorLdData) { +#define SCALE_FORM_FAC \ + (4) /* (SCALE_FORM_FAC+FORM_FAC_SHIFT) >= ld(FRAME_LENGTH)*/ +#define SCALE_NRGS (8) +#define SCALE_NLINES (16) +#define SCALE_NRGS_SQRT4 (2) /* 0.25 * SCALE_NRGS */ +#define SCALE_NLINES_P34 (12) /* 0.75 * SCALE_NLINES */ + + INT sfbGrp, sfb; FIXP_DBL chaosMeasure; INT frameNLines = 0; FIXP_DBL frameFormFactor = FL2FXCONST_DBL(0.f); FIXP_DBL frameEnergy = FL2FXCONST_DBL(0.f); - for (sfbGrp=0; sfbGrpsfbCnt; sfbGrp+=psyOutChannel->sfbPerGroup) { - for (sfb=0; sfbmaxSfbPerGroup; sfb++){ - if (psyOutChannel->sfbEnergyLdData[sfbGrp+sfb] > psyOutChannel->sfbThresholdLdData[sfbGrp+sfb]) { - frameFormFactor += (CalcInvLdData(sfbFormFactorLdData[sfbGrp+sfb])>>SCALE_FORM_FAC); - frameNLines += (psyOutChannel->sfbOffsets[sfbGrp+sfb+1] - psyOutChannel->sfbOffsets[sfbGrp+sfb]); - frameEnergy += (psyOutChannel->sfbEnergy[sfbGrp+sfb]>>SCALE_NRGS); + for (sfbGrp = 0; sfbGrp < psyOutChannel->sfbCnt; + sfbGrp += psyOutChannel->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { + if (psyOutChannel->sfbEnergyLdData[sfbGrp + sfb] > + psyOutChannel->sfbThresholdLdData[sfbGrp + sfb]) { + frameFormFactor += (CalcInvLdData(sfbFormFactorLdData[sfbGrp + sfb]) >> + SCALE_FORM_FAC); + frameNLines += (psyOutChannel->sfbOffsets[sfbGrp + sfb + 1] - + psyOutChannel->sfbOffsets[sfbGrp + sfb]); + frameEnergy += (psyOutChannel->sfbEnergy[sfbGrp + sfb] >> SCALE_NRGS); } } } - if(frameNLines > 0){ - - /* frameNActiveLines = frameFormFactor*2^FORM_FAC_SHIFT * ((frameEnergy *2^SCALE_NRGS)/frameNLines)^-0.25 - chaosMeasure = frameNActiveLines / frameNLines */ - chaosMeasure = - CalcInvLdData( (((CalcLdData(frameFormFactor)>>1) - - (CalcLdData(frameEnergy)>>(2+1))) - - (fMultDiv2(FL2FXCONST_DBL(0.75f),CalcLdData((FIXP_DBL)frameNLines<<(DFRACT_BITS-1-SCALE_NLINES))) - - (((FIXP_DBL)(-((-SCALE_FORM_FAC+SCALE_NRGS_SQRT4-FORM_FAC_SHIFT+SCALE_NLINES_P34) << (DFRACT_BITS-1-LD_DATA_SHIFT))))>>1)) - )<<1 ); + if (frameNLines > 0) { + /* frameNActiveLines = frameFormFactor*2^FORM_FAC_SHIFT * ((frameEnergy + *2^SCALE_NRGS)/frameNLines)^-0.25 chaosMeasure = frameNActiveLines / + frameNLines */ + chaosMeasure = CalcInvLdData( + (((CalcLdData(frameFormFactor) >> 1) - + (CalcLdData(frameEnergy) >> (2 + 1))) - + (fMultDiv2(FL2FXCONST_DBL(0.75f), + CalcLdData((FIXP_DBL)frameNLines + << (DFRACT_BITS - 1 - SCALE_NLINES))) - + (((FIXP_DBL)(-((-SCALE_FORM_FAC + SCALE_NRGS_SQRT4 - FORM_FAC_SHIFT + + SCALE_NLINES_P34) + << (DFRACT_BITS - 1 - LD_DATA_SHIFT)))) >> + 1))) + << 1); } else { - /* assuming total chaos, if no sfb is above thresholds */ chaosMeasure = FL2FXCONST_DBL(1.f); } @@ -970,47 +1107,46 @@ static FIXP_DBL FDKaacEnc_calcChaosMeasure(PSY_OUT_CHANNEL *psyOutChannel, } /* apply reduction formula for VBR-mode */ -static void FDKaacEnc_reduceThresholdsVBR(QC_OUT_CHANNEL* qcOutChannel[(2)], - PSY_OUT_CHANNEL* psyOutChannel[(2)], - UCHAR ahFlag[(2)][MAX_GROUPED_SFB], - FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB], - const INT nChannels, - const FIXP_DBL vbrQualFactor, - FIXP_DBL* chaosMeasureOld) -{ +static void FDKaacEnc_reduceThresholdsVBR( + QC_OUT_CHANNEL *const qcOutChannel[(2)], + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], + UCHAR ahFlag[(2)][MAX_GROUPED_SFB], + const FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB], const INT nChannels, + const FIXP_DBL vbrQualFactor, FIXP_DBL *const chaosMeasureOld) { INT ch, sfbGrp, sfb; - FIXP_DBL chGroupEnergy[TRANS_FAC][2];/*energy for each group and channel*/ + FIXP_DBL chGroupEnergy[TRANS_FAC][2]; /*energy for each group and channel*/ FIXP_DBL chChaosMeasure[2]; FIXP_DBL frameEnergy = FL2FXCONST_DBL(1e-10f); FIXP_DBL chaosMeasure = FL2FXCONST_DBL(0.f); FIXP_DBL sfbEnLdData, sfbThrLdData, sfbThrExp; FIXP_DBL sfbThrReducedLdData; FIXP_DBL chaosMeasureAvg; - INT groupCnt; /* loop counter */ - FIXP_DBL redVal[TRANS_FAC]; /* reduction values; in short-block case one redVal for each group */ - QC_OUT_CHANNEL *qcOutChan = NULL; - PSY_OUT_CHANNEL *psyOutChan = NULL; + INT groupCnt; /* loop counter */ + FIXP_DBL redVal[TRANS_FAC]; /* reduction values; in short-block case one + redVal for each group */ + QC_OUT_CHANNEL *qcOutChan = NULL; + const PSY_OUT_CHANNEL *psyOutChan = NULL; -#define SCALE_GROUP_ENERGY (8) +#define SCALE_GROUP_ENERGY (8) -#define CONST_CHAOS_MEAS_AVG_FAC_0 (FL2FXCONST_DBL(0.25f)) -#define CONST_CHAOS_MEAS_AVG_FAC_1 (FL2FXCONST_DBL(1.f-0.25f)) +#define CONST_CHAOS_MEAS_AVG_FAC_0 (FL2FXCONST_DBL(0.25f)) +#define CONST_CHAOS_MEAS_AVG_FAC_1 (FL2FXCONST_DBL(1.f - 0.25f)) -#define MIN_LDTHRESH (FL2FXCONST_DBL(-0.515625f)) +#define MIN_LDTHRESH (FL2FXCONST_DBL(-0.515625f)) - - for(ch=0; chsfbCnt; sfbGrp+=psyOutChan->sfbPerGroup, groupCnt++) { + for (sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt; + sfbGrp += psyOutChan->sfbPerGroup, groupCnt++) { chGroupEnergy[groupCnt][ch] = FL2FXCONST_DBL(0.f); - for (sfb=0; sfbmaxSfbPerGroup; sfb++){ - chGroupEnergy[groupCnt][ch] += (psyOutChan->sfbEnergy[sfbGrp+sfb]>>SCALE_GROUP_ENERGY); + for (sfb = 0; sfb < psyOutChan->maxSfbPerGroup; sfb++) { + chGroupEnergy[groupCnt][ch] += + (psyOutChan->sfbEnergy[sfbGrp + sfb] >> SCALE_GROUP_ENERGY); } chEnergy += chGroupEnergy[groupCnt][ch]; } @@ -1018,110 +1154,133 @@ static void FDKaacEnc_reduceThresholdsVBR(QC_OUT_CHANNEL* qcOutChannel[(2)], /* chaosMeasure */ if (psyOutChannel[0]->lastWindowSequence == SHORT_WINDOW) { - chChaosMeasure[ch] = FL2FXCONST_DBL(0.5f); /* assume a constant chaos measure of 0.5f for short blocks */ + chChaosMeasure[ch] = FL2FXCONST_DBL( + 0.5f); /* assume a constant chaos measure of 0.5f for short blocks */ } else { - chChaosMeasure[ch] = FDKaacEnc_calcChaosMeasure(psyOutChannel[ch], qcOutChannel[ch]->sfbFormFactorLdData); + chChaosMeasure[ch] = FDKaacEnc_calcChaosMeasure( + psyOutChannel[ch], qcOutChannel[ch]->sfbFormFactorLdData); } chaosMeasure += fMult(chChaosMeasure[ch], chEnergy); } - if(frameEnergy > chaosMeasure) { + if (frameEnergy > chaosMeasure) { INT scale = CntLeadingZeros(frameEnergy) - 1; - FIXP_DBL num = chaosMeasure<>2) + fMult(FL2FXCONST_DBL(0.7f/(4.f*0.3f)), (chaosMeasure - FL2FXCONST_DBL(0.2f)))); - chaosMeasure = (fixMin((FIXP_DBL)(FL2FXCONST_DBL(1.0f)>>2), fixMax((FIXP_DBL)(FL2FXCONST_DBL(0.1f)>>2), chaosMeasure)))<<2; + chaosMeasure = ((FL2FXCONST_DBL(0.2f) >> 2) + + fMult(FL2FXCONST_DBL(0.7f / (4.f * 0.3f)), + (chaosMeasure - FL2FXCONST_DBL(0.2f)))); + chaosMeasure = + (fixMin((FIXP_DBL)(FL2FXCONST_DBL(1.0f) >> 2), + fixMax((FIXP_DBL)(FL2FXCONST_DBL(0.1f) >> 2), chaosMeasure))) + << 2; /* calculation of reduction value */ - if (psyOutChannel[0]->lastWindowSequence == SHORT_WINDOW){ /* short-blocks */ - FDK_ASSERT(TRANS_FAC==8); - #define WIN_TYPE_SCALE (3) - - INT sfbGrp, groupCnt=0; - for (sfbGrp=0; sfbGrpsfbCnt; sfbGrp+=psyOutChan->sfbPerGroup,groupCnt++) { + if (psyOutChannel[0]->lastWindowSequence == SHORT_WINDOW) { /* short-blocks */ + FDK_ASSERT(TRANS_FAC == 8); +#define WIN_TYPE_SCALE (3) + groupCnt = 0; + for (sfbGrp = 0; sfbGrp < psyOutChannel[0]->sfbCnt; + sfbGrp += psyOutChannel[0]->sfbPerGroup, groupCnt++) { FIXP_DBL groupEnergy = FL2FXCONST_DBL(0.f); - for(ch=0;chgroupLen[groupCnt]<=INV_INT_TAB_SIZE); - groupEnergy = fMult(groupEnergy,invInt[psyOutChannel[0]->groupLen[groupCnt]]); /* correction of group energy */ - groupEnergy = fixMin(groupEnergy, frameEnergy>>WIN_TYPE_SCALE); /* do not allow an higher redVal as calculated framewise */ - - groupEnergy>>=2; /* 2*WIN_TYPE_SCALE = 6 => 6+2 = 8 ==> 8/4 = int number */ - - redVal[groupCnt] = fMult(fMult(vbrQualFactor,chaosMeasure), - CalcInvLdData(CalcLdData(groupEnergy)>>2) ) - << (int)( ( 2 + (2*WIN_TYPE_SCALE) + SCALE_GROUP_ENERGY )>>2 ) ; - + FDK_ASSERT(psyOutChannel[0]->groupLen[groupCnt] <= INV_INT_TAB_SIZE); + groupEnergy = fMult( + groupEnergy, + invInt[psyOutChannel[0]->groupLen[groupCnt]]); /* correction of + group energy */ + groupEnergy = fixMin(groupEnergy, + frameEnergy >> WIN_TYPE_SCALE); /* do not allow an + higher redVal as + calculated + framewise */ + + groupEnergy >>= + 2; /* 2*WIN_TYPE_SCALE = 6 => 6+2 = 8 ==> 8/4 = int number */ + + redVal[groupCnt] = + fMult(fMult(vbrQualFactor, chaosMeasure), + CalcInvLdData(CalcLdData(groupEnergy) >> 2)) + << (int)((2 + (2 * WIN_TYPE_SCALE) + SCALE_GROUP_ENERGY) >> 2); } } else { /* long-block */ - redVal[0] = fMult( fMult(vbrQualFactor,chaosMeasure), - CalcInvLdData(CalcLdData(frameEnergy)>>2) ) - << (int)( SCALE_GROUP_ENERGY>>2 ) ; + redVal[0] = fMult(fMult(vbrQualFactor, chaosMeasure), + CalcInvLdData(CalcLdData(frameEnergy) >> 2)) + << (int)(SCALE_GROUP_ENERGY >> 2); } - for(ch=0; chsfbCnt; sfbGrp+=psyOutChan->sfbPerGroup) { - for (sfb=0; sfbmaxSfbPerGroup; sfb++){ - - sfbEnLdData = (qcOutChan->sfbWeightedEnergyLdData[sfbGrp+sfb]); - sfbThrLdData = (qcOutChan->sfbThresholdLdData[sfbGrp+sfb]); - sfbThrExp = thrExp[ch][sfbGrp+sfb]; + for (ch = 0; ch < nChannels; ch++) { + qcOutChan = qcOutChannel[ch]; + psyOutChan = psyOutChannel[ch]; - if ( (sfbThrLdData>=MIN_LDTHRESH) && (sfbEnLdData > sfbThrLdData) && (ahFlag[ch][sfbGrp+sfb] != AH_ACTIVE)) { + for (sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt; + sfbGrp += psyOutChan->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChan->maxSfbPerGroup; sfb++) { + sfbEnLdData = (qcOutChan->sfbWeightedEnergyLdData[sfbGrp + sfb]); + sfbThrLdData = (qcOutChan->sfbThresholdLdData[sfbGrp + sfb]); + sfbThrExp = thrExp[ch][sfbGrp + sfb]; + if ((sfbThrLdData >= MIN_LDTHRESH) && (sfbEnLdData > sfbThrLdData) && + (ahFlag[ch][sfbGrp + sfb] != AH_ACTIVE)) { /* Short-Window */ if (psyOutChannel[ch]->lastWindowSequence == SHORT_WINDOW) { - const int groupNumber = (int) sfb/psyOutChan->sfbPerGroup; - - FDK_ASSERT(INV_SQRT4_TAB_SIZE>psyOutChan->groupLen[groupNumber]); - - sfbThrExp = fMult(sfbThrExp, fMult( FL2FXCONST_DBL(2.82f/4.f), invSqrt4[psyOutChan->groupLen[groupNumber]]))<<2 ; - - if ( sfbThrExp <= (limitThrReducedLdData-redVal[groupNumber]) ) { - sfbThrReducedLdData = FL2FXCONST_DBL(-1.0f); - } - else { - if ((FIXP_DBL)redVal[groupNumber] >= FL2FXCONST_DBL(1.0f)-sfbThrExp) - sfbThrReducedLdData = FL2FXCONST_DBL(0.0f); - else { - /* threshold reduction formula */ - sfbThrReducedLdData = CalcLdData(sfbThrExp + redVal[groupNumber]); - sfbThrReducedLdData <<= 2; - } + const int groupNumber = (int)sfb / psyOutChan->sfbPerGroup; + + FDK_ASSERT(INV_SQRT4_TAB_SIZE > psyOutChan->groupLen[groupNumber]); + + sfbThrExp = + fMult(sfbThrExp, + fMult(FL2FXCONST_DBL(2.82f / 4.f), + invSqrt4[psyOutChan->groupLen[groupNumber]])) + << 2; + + if (sfbThrExp <= (limitThrReducedLdData - redVal[groupNumber])) { + sfbThrReducedLdData = FL2FXCONST_DBL(-1.0f); + } else { + if ((FIXP_DBL)redVal[groupNumber] >= + FL2FXCONST_DBL(1.0f) - sfbThrExp) + sfbThrReducedLdData = FL2FXCONST_DBL(0.0f); + else { + /* threshold reduction formula */ + sfbThrReducedLdData = + CalcLdData(sfbThrExp + redVal[groupNumber]); + sfbThrReducedLdData <<= 2; + } } - sfbThrReducedLdData += ( CalcLdInt(psyOutChan->groupLen[groupNumber]) - - ((FIXP_DBL)6<<(DFRACT_BITS-1-LD_DATA_SHIFT)) ); + sfbThrReducedLdData += + (CalcLdInt(psyOutChan->groupLen[groupNumber]) - + ((FIXP_DBL)6 << (DFRACT_BITS - 1 - LD_DATA_SHIFT))); } /* Long-Window */ else { - if ((FIXP_DBL)redVal[0] >= FL2FXCONST_DBL(1.0f)-sfbThrExp) { + if ((FIXP_DBL)redVal[0] >= FL2FXCONST_DBL(1.0f) - sfbThrExp) { sfbThrReducedLdData = FL2FXCONST_DBL(0.0f); - } - else { + } else { /* threshold reduction formula */ sfbThrReducedLdData = CalcLdData(sfbThrExp + redVal[0]); sfbThrReducedLdData <<= 2; @@ -1129,27 +1288,33 @@ static void FDKaacEnc_reduceThresholdsVBR(QC_OUT_CHANNEL* qcOutChannel[(2)], } /* avoid holes */ - if ( ((sfbThrReducedLdData - sfbEnLdData) > qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] ) - && (ahFlag[ch][sfbGrp+sfb] != NO_AH) ) - { - if (qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] > (FL2FXCONST_DBL(-1.0f) - sfbEnLdData) ){ - sfbThrReducedLdData = fixMax((qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] + sfbEnLdData), sfbThrLdData); - } - else sfbThrReducedLdData = sfbThrLdData; - ahFlag[ch][sfbGrp+sfb] = AH_ACTIVE; + if (((sfbThrReducedLdData - sfbEnLdData) > + qcOutChan->sfbMinSnrLdData[sfbGrp + sfb]) && + (ahFlag[ch][sfbGrp + sfb] != NO_AH)) { + if (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] > + (FL2FXCONST_DBL(-1.0f) - sfbEnLdData)) { + sfbThrReducedLdData = fixMax( + (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] + sfbEnLdData), + sfbThrLdData); + } else + sfbThrReducedLdData = sfbThrLdData; + ahFlag[ch][sfbGrp + sfb] = AH_ACTIVE; } - if (sfbThrReducedLdData FL2FXCONST_DBL(9.6336206/LD_DATA_SCALING)){ - sfbThrReducedLdData = fixMax(sfbThrReducedLdData, sfbEnLdData - FL2FXCONST_DBL(9.6336206/LD_DATA_SCALING)); + if ((sfbEnLdData + FL2FXCONST_DBL(1.0f)) > + FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING)) { + sfbThrReducedLdData = fixMax( + sfbThrReducedLdData, + sfbEnLdData - FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING)); } - sfbThrReducedLdData = fixMax(MIN_LDTHRESH,sfbThrReducedLdData); + sfbThrReducedLdData = fixMax(MIN_LDTHRESH, sfbThrReducedLdData); - qcOutChan->sfbThresholdLdData[sfbGrp+sfb] = sfbThrReducedLdData; + qcOutChan->sfbThresholdLdData[sfbGrp + sfb] = sfbThrReducedLdData; } } } @@ -1158,174 +1323,197 @@ static void FDKaacEnc_reduceThresholdsVBR(QC_OUT_CHANNEL* qcOutChannel[(2)], /***************************************************************************** functionname: FDKaacEnc_correctThresh -description: if pe difference deltaPe between desired pe and real pe is small enough, -the difference can be distributed among the scale factor bands. -New thresholds can be derived from this pe-difference +description: if pe difference deltaPe between desired pe and real pe is small +enough, the difference can be distributed among the scale factor bands. New +thresholds can be derived from this pe-difference *****************************************************************************/ -static void FDKaacEnc_correctThresh(CHANNEL_MAPPING* cm, - QC_OUT_ELEMENT* qcElement[(8)], - PSY_OUT_ELEMENT* psyOutElement[(8)], - UCHAR ahFlag[(8)][(2)][MAX_GROUPED_SFB], - FIXP_DBL thrExp[(8)][(2)][MAX_GROUPED_SFB], - const FIXP_DBL redVal[(8)], - const SCHAR redValScaling[(8)], - const INT deltaPe, - const INT processElements, - const INT elementOffset) -{ - INT ch, sfb, sfbGrp; - QC_OUT_CHANNEL *qcOutChan; - PSY_OUT_CHANNEL *psyOutChan; - PE_CHANNEL_DATA *peChanData; - FIXP_DBL thrFactorLdData; - FIXP_DBL sfbEnLdData, sfbThrLdData, sfbThrReducedLdData; - FIXP_DBL *sfbPeFactorsLdData[(8)][(2)]; - FIXP_DBL sfbNActiveLinesLdData[(8)][(2)][MAX_GROUPED_SFB]; - INT normFactorInt; - FIXP_DBL normFactorLdData; - - INT nElements = elementOffset+processElements; - INT elementId; - - /* scratch is empty; use temporal memory from quantSpec in QC_OUT_CHANNEL */ - for(elementId=elementOffset;elementIdelInfo[elementId].nChannelsInEl; ch++) { - SHORT* ptr = qcElement[elementId]->qcOutChannel[ch]->quantSpec; - sfbPeFactorsLdData[elementId][ch] = (FIXP_DBL*)ptr; - } - } - - /* for each sfb calc relative factors for pe changes */ - normFactorInt = 0; - - for(elementId=elementOffset;elementIdelInfo[elementId].elType != ID_DSE) { - - for(ch=0; chelInfo[elementId].nChannelsInEl; ch++) { - - qcOutChan = qcElement[elementId]->qcOutChannel[ch]; - psyOutChan = psyOutElement[elementId]->psyOutChannel[ch]; - peChanData = &qcElement[elementId]->peData.peChannelData[ch]; - - for(sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt; sfbGrp+= psyOutChan->sfbPerGroup){ - for (sfb=0; sfbmaxSfbPerGroup; sfb++) { - - if ( peChanData->sfbNActiveLines[sfbGrp+sfb] == 0 ) { - sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb] = FL2FXCONST_DBL(-1.0f); - } - else { - /* Both CalcLdInt and CalcLdData can be used! - * No offset has to be subtracted, because sfbNActiveLinesLdData - * is shorted while thrFactor calculation */ - sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb] = CalcLdInt(peChanData->sfbNActiveLines[sfbGrp+sfb]); - } - if ( ((ahFlag[elementId][ch][sfbGrp+sfb] < AH_ACTIVE) || (deltaPe > 0)) && - peChanData->sfbNActiveLines[sfbGrp+sfb] != 0 ) - { - if (thrExp[elementId][ch][sfbGrp+sfb] > -redVal[elementId]) { - - /* sfbPeFactors[ch][sfbGrp+sfb] = peChanData->sfbNActiveLines[sfbGrp+sfb] / - (thrExp[elementId][ch][sfbGrp+sfb] + redVal[elementId]); */ - - int minScale = fixMin(CountLeadingBits(thrExp[elementId][ch][sfbGrp+sfb]), CountLeadingBits(redVal[elementId]) - (DFRACT_BITS-1-redValScaling[elementId]) ) - 1; - - /* sumld = ld64( sfbThrExp + redVal ) */ - FIXP_DBL sumLd = CalcLdData(scaleValue(thrExp[elementId][ch][sfbGrp+sfb], minScale) + scaleValue(redVal[elementId], (DFRACT_BITS-1-redValScaling[elementId])+minScale)) - - (FIXP_DBL)(minScale<<(DFRACT_BITS-1-LD_DATA_SHIFT)); - - if (sumLd < FL2FXCONST_DBL(0.f)) { - sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb] = sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb] - sumLd; - } - else { - if ( sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb] > (FL2FXCONST_DBL(-1.f) + sumLd) ) { - sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb] = sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb] - sumLd; - } - else { - sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb] = sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb]; - } - } - - normFactorInt += (INT)CalcInvLdData(sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb]); - } - else sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb] = FL2FXCONST_DBL(1.0f); - } - else sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb] = FL2FXCONST_DBL(-1.0f); +static void FDKaacEnc_correctThresh( + const CHANNEL_MAPPING *const cm, QC_OUT_ELEMENT *const qcElement[((8))], + const PSY_OUT_ELEMENT *const psyOutElement[((8))], + UCHAR ahFlag[((8))][(2)][MAX_GROUPED_SFB], + const FIXP_DBL thrExp[((8))][(2)][MAX_GROUPED_SFB], const FIXP_DBL redVal_m, + const SCHAR redVal_e, const INT deltaPe, const INT processElements, + const INT elementOffset) { + INT ch, sfb, sfbGrp; + QC_OUT_CHANNEL *qcOutChan; + PSY_OUT_CHANNEL *psyOutChan; + PE_CHANNEL_DATA *peChanData; + FIXP_DBL thrFactorLdData; + FIXP_DBL sfbEnLdData, sfbThrLdData, sfbThrReducedLdData; + FIXP_DBL *sfbPeFactorsLdData[((8))][(2)]; + FIXP_DBL(*sfbNActiveLinesLdData)[(2)][MAX_GROUPED_SFB]; + + INT normFactorInt; + FIXP_DBL normFactorLdData; + + INT nElements = elementOffset + processElements; + INT elementId; + + /* scratch is empty; use temporal memory from quantSpec in QC_OUT_CHANNEL */ + for (elementId = elementOffset; elementId < nElements; elementId++) { + for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) { + /* The reinterpret_cast is used to suppress a compiler warning. We know + * that qcElement[elementId]->qcOutChannel[ch]->quantSpec is sufficiently + * aligned, so the cast is safe */ + sfbPeFactorsLdData[elementId][ch] = + reinterpret_cast(reinterpret_cast( + qcElement[elementId]->qcOutChannel[ch]->quantSpec)); + } + } + /* The reinterpret_cast is used to suppress a compiler warning. We know that + * qcElement[0]->dynMem_SfbNActiveLinesLdData is sufficiently aligned, so the + * cast is safe */ + sfbNActiveLinesLdData = reinterpret_cast( + reinterpret_cast(qcElement[0]->dynMem_SfbNActiveLinesLdData)); + + /* for each sfb calc relative factors for pe changes */ + normFactorInt = 0; + + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) { + psyOutChan = psyOutElement[elementId]->psyOutChannel[ch]; + peChanData = &qcElement[elementId]->peData.peChannelData[ch]; + + for (sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt; + sfbGrp += psyOutChan->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChan->maxSfbPerGroup; sfb++) { + if (peChanData->sfbNActiveLines[sfbGrp + sfb] == 0) { + sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] = + FL2FXCONST_DBL(-1.0f); + } else { + /* Both CalcLdInt and CalcLdData can be used! + * No offset has to be subtracted, because sfbNActiveLinesLdData + * is shorted while thrFactor calculation */ + sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] = + CalcLdInt(peChanData->sfbNActiveLines[sfbGrp + sfb]); } + if (((ahFlag[elementId][ch][sfbGrp + sfb] < AH_ACTIVE) || + (deltaPe > 0)) && + peChanData->sfbNActiveLines[sfbGrp + sfb] != 0) { + if (thrExp[elementId][ch][sfbGrp + sfb] > -redVal_m) { + /* sfbPeFactors[ch][sfbGrp+sfb] = + peChanData->sfbNActiveLines[sfbGrp+sfb] / + (thrExp[elementId][ch][sfbGrp+sfb] + + redVal[elementId]); */ + + int minScale = + fixMin( + CountLeadingBits(thrExp[elementId][ch][sfbGrp + sfb]), + CountLeadingBits(redVal_m) - redVal_e) - + 1; + + /* sumld = ld64( sfbThrExp + redVal ) */ + FIXP_DBL sumLd = + CalcLdData(scaleValue(thrExp[elementId][ch][sfbGrp + sfb], + minScale) + + scaleValue(redVal_m, redVal_e + minScale)) - + (FIXP_DBL)(minScale << (DFRACT_BITS - 1 - LD_DATA_SHIFT)); + + if (sumLd < FL2FXCONST_DBL(0.f)) { + sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] = + sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] - + sumLd; + } else { + if (sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] > + (FL2FXCONST_DBL(-1.f) + sumLd)) { + sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] = + sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] - + sumLd; + } else { + sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] = + sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb]; + } + } + + normFactorInt += (INT)CalcInvLdData( + sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb]); + } else + sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] = + FL2FXCONST_DBL(1.0f); + } else + sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] = + FL2FXCONST_DBL(-1.0f); } - } - } - } - - /* normFactorLdData = ld64(deltaPe/normFactorInt) */ - normFactorLdData = CalcLdData((FIXP_DBL)((deltaPe<0) ? (-deltaPe) : (deltaPe))) - CalcLdData((FIXP_DBL)normFactorInt); - - /* distribute the pe difference to the scalefactors - and calculate the according thresholds */ - for(elementId=elementOffset;elementIdelInfo[elementId].elType != ID_DSE) { - - for(ch=0; chelInfo[elementId].nChannelsInEl; ch++) { - qcOutChan = qcElement[elementId]->qcOutChannel[ch]; - psyOutChan = psyOutElement[elementId]->psyOutChannel[ch]; - peChanData = &qcElement[elementId]->peData.peChannelData[ch]; - - for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){ - for (sfb=0; sfbmaxSfbPerGroup; sfb++) { - - if (peChanData->sfbNActiveLines[sfbGrp+sfb] > 0) { - - /* pe difference for this sfb */ - if ( (sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb]==FL2FXCONST_DBL(-1.0f)) || - (deltaPe==0) ) - { - thrFactorLdData = FL2FXCONST_DBL(0.f); - } - else { - /* new threshold */ - FIXP_DBL tmp = CalcInvLdData(sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb] + normFactorLdData - sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb] - FL2FXCONST_DBL((float)LD_DATA_SHIFT/LD_DATA_SCALING)); - - /* limit thrFactor to 60dB */ - tmp = (deltaPe<0) ? tmp : (-tmp); - thrFactorLdData = FDKmin(tmp, FL2FXCONST_DBL(20.f/LD_DATA_SCALING)); - } - - /* new threshold */ - sfbThrLdData = qcOutChan->sfbThresholdLdData[sfbGrp+sfb]; - sfbEnLdData = qcOutChan->sfbWeightedEnergyLdData[sfbGrp+sfb]; - - if (thrFactorLdData < FL2FXCONST_DBL(0.f)) { - if( sfbThrLdData > (FL2FXCONST_DBL(-1.f)-thrFactorLdData) ) { - sfbThrReducedLdData = sfbThrLdData + thrFactorLdData; - } - else { - sfbThrReducedLdData = FL2FXCONST_DBL(-1.f); - } - } - else{ - sfbThrReducedLdData = sfbThrLdData + thrFactorLdData; - } - - /* avoid hole */ - if ( (sfbThrReducedLdData - sfbEnLdData > qcOutChan->sfbMinSnrLdData[sfbGrp+sfb]) && - (ahFlag[elementId][ch][sfbGrp+sfb] == AH_INACTIVE) ) - { - /* sfbThrReduced = max(psyOutChan[ch]->sfbMinSnr[i] * sfbEn, sfbThr); */ - if ( sfbEnLdData > (sfbThrLdData-qcOutChan->sfbMinSnrLdData[sfbGrp+sfb]) ) { - sfbThrReducedLdData = qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] + sfbEnLdData; - } - else { - sfbThrReducedLdData = sfbThrLdData; - } - ahFlag[elementId][ch][sfbGrp+sfb] = AH_ACTIVE; - } - - qcOutChan->sfbThresholdLdData[sfbGrp+sfb] = sfbThrReducedLdData; + } + } + } + } + + /* normFactorLdData = ld64(deltaPe/normFactorInt) */ + normFactorLdData = + CalcLdData((FIXP_DBL)((deltaPe < 0) ? (-deltaPe) : (deltaPe))) - + CalcLdData((FIXP_DBL)normFactorInt); + + /* distribute the pe difference to the scalefactors + and calculate the according thresholds */ + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) { + qcOutChan = qcElement[elementId]->qcOutChannel[ch]; + psyOutChan = psyOutElement[elementId]->psyOutChannel[ch]; + peChanData = &qcElement[elementId]->peData.peChannelData[ch]; + + for (sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt; + sfbGrp += psyOutChan->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChan->maxSfbPerGroup; sfb++) { + if (peChanData->sfbNActiveLines[sfbGrp + sfb] > 0) { + /* pe difference for this sfb */ + if ((sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] == + FL2FXCONST_DBL(-1.0f)) || + (deltaPe == 0)) { + thrFactorLdData = FL2FXCONST_DBL(0.f); + } else { + /* new threshold */ + FIXP_DBL tmp = CalcInvLdData( + sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] + + normFactorLdData - + sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] - + FL2FXCONST_DBL((float)LD_DATA_SHIFT / LD_DATA_SCALING)); + + /* limit thrFactor to 60dB */ + tmp = (deltaPe < 0) ? tmp : (-tmp); + thrFactorLdData = + fMin(tmp, FL2FXCONST_DBL(20.f / LD_DATA_SCALING)); } + + /* new threshold */ + sfbThrLdData = qcOutChan->sfbThresholdLdData[sfbGrp + sfb]; + sfbEnLdData = qcOutChan->sfbWeightedEnergyLdData[sfbGrp + sfb]; + + if (thrFactorLdData < FL2FXCONST_DBL(0.f)) { + if (sfbThrLdData > (FL2FXCONST_DBL(-1.f) - thrFactorLdData)) { + sfbThrReducedLdData = sfbThrLdData + thrFactorLdData; + } else { + sfbThrReducedLdData = FL2FXCONST_DBL(-1.f); + } + } else { + sfbThrReducedLdData = sfbThrLdData + thrFactorLdData; + } + + /* avoid hole */ + if ((sfbThrReducedLdData - sfbEnLdData > + qcOutChan->sfbMinSnrLdData[sfbGrp + sfb]) && + (ahFlag[elementId][ch][sfbGrp + sfb] == AH_INACTIVE)) { + /* sfbThrReduced = max(psyOutChan[ch]->sfbMinSnr[i] * sfbEn, + * sfbThr); */ + if (sfbEnLdData > + (sfbThrLdData - qcOutChan->sfbMinSnrLdData[sfbGrp + sfb])) { + sfbThrReducedLdData = + qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] + sfbEnLdData; + } else { + sfbThrReducedLdData = sfbThrLdData; + } + ahFlag[elementId][ch][sfbGrp + sfb] = AH_ACTIVE; + } + + qcOutChan->sfbThresholdLdData[sfbGrp + sfb] = sfbThrReducedLdData; } } - } - } - } + } + } + } + } } /***************************************************************************** @@ -1333,628 +1521,688 @@ static void FDKaacEnc_correctThresh(CHANNEL_MAPPING* cm, description: if the desired pe can not be reached, reduce pe by reducing minSnr *****************************************************************************/ -void FDKaacEnc_reduceMinSnr(CHANNEL_MAPPING* cm, - QC_OUT_ELEMENT* qcElement[(8)], - PSY_OUT_ELEMENT* psyOutElement[(8)], - UCHAR ahFlag[(8)][(2)][MAX_GROUPED_SFB], - const INT desiredPe, - INT* redPeGlobal, - const INT processElements, - const INT elementOffset) +static void FDKaacEnc_reduceMinSnr( + const CHANNEL_MAPPING *const cm, QC_OUT_ELEMENT *const qcElement[((8))], + const PSY_OUT_ELEMENT *const psyOutElement[((8))], + const UCHAR ahFlag[((8))][(2)][MAX_GROUPED_SFB], const INT desiredPe, + INT *const redPeGlobal, const INT processElements, const INT elementOffset) { - INT elementId; - INT nElements = elementOffset+processElements; - - INT newGlobalPe = *redPeGlobal; - - for(elementId=elementOffset;elementIdelInfo[elementId].elType != ID_DSE) { - INT ch; - INT maxSfbPerGroup[2]; - INT sfbCnt[2]; - INT sfbPerGroup[2]; - - for(ch=0; chelInfo[elementId].nChannelsInEl; ch++) { - maxSfbPerGroup[ch] = psyOutElement[elementId]->psyOutChannel[ch]->maxSfbPerGroup-1; - sfbCnt[ch] = psyOutElement[elementId]->psyOutChannel[ch]->sfbCnt; - sfbPerGroup[ch] = psyOutElement[elementId]->psyOutChannel[ch]->sfbPerGroup; - } + INT ch, elementId, globalMaxSfb = 0; + const INT nElements = elementOffset + processElements; + INT newGlobalPe = *redPeGlobal; - PE_DATA *peData = &qcElement[elementId]->peData; - - do - { - for(ch=0; chelInfo[elementId].nChannelsInEl; ch++) { - - INT sfb, sfbGrp; - QC_OUT_CHANNEL *qcOutChan = qcElement[elementId]->qcOutChannel[ch]; - INT noReduction = 1; - - if (maxSfbPerGroup[ch]>=0) { /* sfb in next channel */ - INT deltaPe = 0; - sfb = maxSfbPerGroup[ch]--; - noReduction = 0; - - for (sfbGrp = 0; sfbGrp < sfbCnt[ch]; sfbGrp += sfbPerGroup[ch]) { - - if (ahFlag[elementId][ch][sfbGrp+sfb] != NO_AH && - qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] < SnrLdFac) - { - /* increase threshold to new minSnr of 1dB */ - qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] = SnrLdFac; - - /* sfbThrReduced = max(psyOutChan[ch]->sfbMinSnr[i] * sfbEn, sfbThr); */ - if ( qcOutChan->sfbWeightedEnergyLdData[sfbGrp+sfb] >= qcOutChan->sfbThresholdLdData[sfbGrp+sfb] - qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] ) { - - qcOutChan->sfbThresholdLdData[sfbGrp+sfb] = qcOutChan->sfbWeightedEnergyLdData[sfbGrp+sfb] + qcOutChan->sfbMinSnrLdData[sfbGrp+sfb]; - - /* calc new pe */ - /* C2 + C3*ld(1/0.8) = 1.5 */ - deltaPe -= (peData->peChannelData[ch].sfbPe[sfbGrp+sfb]>>PE_CONSTPART_SHIFT); - - /* sfbPe = 1.5 * sfbNLines */ - peData->peChannelData[ch].sfbPe[sfbGrp+sfb] = (3*peData->peChannelData[ch].sfbNLines[sfbGrp+sfb]) << (PE_CONSTPART_SHIFT-1); - deltaPe += (peData->peChannelData[ch].sfbPe[sfbGrp+sfb]>>PE_CONSTPART_SHIFT); - } - } - - } /* sfbGrp loop */ + if (newGlobalPe <= desiredPe) { + goto bail; + } - peData->pe += deltaPe; - peData->peChannelData[ch].pe += deltaPe; - newGlobalPe += deltaPe; + /* global maximum of maxSfbPerGroup */ + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) { + globalMaxSfb = + fMax(globalMaxSfb, + psyOutElement[elementId]->psyOutChannel[ch]->maxSfbPerGroup); + } + } + } - /* stop if enough has been saved */ - if (peData->pe <= desiredPe) { - goto bail; + /* as long as globalPE is above desirePE reduce SNR to 1.0 dB, starting at + * highest SFB */ + while ((newGlobalPe > desiredPe) && (--globalMaxSfb >= 0)) { + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + PE_DATA *peData = &qcElement[elementId]->peData; + + for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) { + QC_OUT_CHANNEL *qcOutChan = qcElement[elementId]->qcOutChannel[ch]; + PSY_OUT_CHANNEL *psyOutChan = + psyOutElement[elementId]->psyOutChannel[ch]; + + /* try to reduce SNR of channel's uppermost SFB(s) */ + if (globalMaxSfb < psyOutChan->maxSfbPerGroup) { + INT sfb, deltaPe = 0; + + for (sfb = globalMaxSfb; sfb < psyOutChan->sfbCnt; + sfb += psyOutChan->sfbPerGroup) { + if (ahFlag[elementId][ch][sfb] != NO_AH && + qcOutChan->sfbMinSnrLdData[sfb] < SnrLdFac && + (qcOutChan->sfbWeightedEnergyLdData[sfb] > + qcOutChan->sfbThresholdLdData[sfb] - SnrLdFac)) { + /* increase threshold to new minSnr of 1dB */ + qcOutChan->sfbMinSnrLdData[sfb] = SnrLdFac; + qcOutChan->sfbThresholdLdData[sfb] = + qcOutChan->sfbWeightedEnergyLdData[sfb] + SnrLdFac; + + /* calc new pe */ + /* C2 + C3*ld(1/0.8) = 1.5 */ + deltaPe -= peData->peChannelData[ch].sfbPe[sfb]; + + /* sfbPe = 1.5 * sfbNLines */ + peData->peChannelData[ch].sfbPe[sfb] = + (3 * peData->peChannelData[ch].sfbNLines[sfb]) + << (PE_CONSTPART_SHIFT - 1); + deltaPe += peData->peChannelData[ch].sfbPe[sfb]; } - } /* sfb > 0 */ - - if ( (ch==(cm->elInfo[elementId].nChannelsInEl-1)) && noReduction ) { - goto bail; - } + } /* sfb loop */ - } /* ch loop */ + deltaPe >>= PE_CONSTPART_SHIFT; + peData->pe += deltaPe; + peData->peChannelData[ch].pe += deltaPe; + newGlobalPe += deltaPe; - } while ( peData->pe > desiredPe); + } /* if globalMaxSfb < maxSfbPerGroup */ - } /* != ID_DSE */ - } /* element loop */ + /* stop if enough has been saved */ + if (newGlobalPe <= desiredPe) { + goto bail; + } + } /* ch loop */ + } /* != ID_DSE */ + } /* elementId loop */ + } /* while ( newGlobalPe > desiredPe) && (--globalMaxSfb >= 0) ) */ bail: - /* update global PE */ - *redPeGlobal = newGlobalPe; + /* update global PE */ + *redPeGlobal = newGlobalPe; } - /***************************************************************************** functionname: FDKaacEnc_allowMoreHoles description: if the desired pe can not be reached, some more scalefactor bands have to be quantized to zero *****************************************************************************/ -static void FDKaacEnc_allowMoreHoles(CHANNEL_MAPPING* cm, - QC_OUT_ELEMENT* qcElement[(8)], - PSY_OUT_ELEMENT* psyOutElement[(8)], - ATS_ELEMENT* AdjThrStateElement[(8)], - UCHAR ahFlag[(8)][(2)][MAX_GROUPED_SFB], - const INT desiredPe, - const INT currentPe, - const int processElements, - const int elementOffset) -{ +static void FDKaacEnc_allowMoreHoles( + const CHANNEL_MAPPING *const cm, QC_OUT_ELEMENT *const qcElement[((8))], + const PSY_OUT_ELEMENT *const psyOutElement[((8))], + const ATS_ELEMENT *const AdjThrStateElement[((8))], + UCHAR ahFlag[((8))][(2)][MAX_GROUPED_SFB], const INT desiredPe, + const INT currentPe, const int processElements, const int elementOffset) { INT elementId; - INT nElements = elementOffset+processElements; + INT nElements = elementOffset + processElements; INT actPe = currentPe; if (actPe <= desiredPe) { return; /* nothing to do */ } - for (elementId = elementOffset;elementIdelInfo[elementId].elType != ID_DSE) { - INT ch, sfb, sfbGrp; PE_DATA *peData = &qcElement[elementId]->peData; const INT nChannels = cm->elInfo[elementId].nChannelsInEl; - QC_OUT_CHANNEL* qcOutChannel[(2)] = {NULL}; - PSY_OUT_CHANNEL* psyOutChannel[(2)] = {NULL}; - - for (ch=0; chqcOutChannel[ch]; psyOutChannel[ch] = psyOutElement[elementId]->psyOutChannel[ch]; - for(sfbGrp=0; sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+= psyOutChannel[ch]->sfbPerGroup) { - for (sfb=psyOutChannel[ch]->maxSfbPerGroup; sfbsfbPerGroup; sfb++) { - peData->peChannelData[ch].sfbPe[sfbGrp+sfb] = 0; + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) { + for (sfb = psyOutChannel[ch]->maxSfbPerGroup; + sfb < psyOutChannel[ch]->sfbPerGroup; sfb++) { + peData->peChannelData[ch].sfbPe[sfbGrp + sfb] = 0; } } } /* for MS allow hole in the channel with less energy */ - if ( nChannels==2 && psyOutChannel[0]->lastWindowSequence==psyOutChannel[1]->lastWindowSequence ) { - - for (sfb=0; sfbmaxSfbPerGroup; sfb++) { - for(sfbGrp=0; sfbGrp < psyOutChannel[0]->sfbCnt; sfbGrp+=psyOutChannel[0]->sfbPerGroup) { - if (psyOutElement[elementId]->toolsInfo.msMask[sfbGrp+sfb]) { - FIXP_DBL EnergyLd_L = qcOutChannel[0]->sfbWeightedEnergyLdData[sfbGrp+sfb]; - FIXP_DBL EnergyLd_R = qcOutChannel[1]->sfbWeightedEnergyLdData[sfbGrp+sfb]; + if (nChannels == 2 && psyOutChannel[0]->lastWindowSequence == + psyOutChannel[1]->lastWindowSequence) { + for (sfb = psyOutChannel[0]->maxSfbPerGroup - 1; sfb >= 0; sfb--) { + for (sfbGrp = 0; sfbGrp < psyOutChannel[0]->sfbCnt; + sfbGrp += psyOutChannel[0]->sfbPerGroup) { + if (psyOutElement[elementId]->toolsInfo.msMask[sfbGrp + sfb]) { + FIXP_DBL EnergyLd_L = + qcOutChannel[0]->sfbWeightedEnergyLdData[sfbGrp + sfb]; + FIXP_DBL EnergyLd_R = + qcOutChannel[1]->sfbWeightedEnergyLdData[sfbGrp + sfb]; /* allow hole in side channel ? */ - if ( (ahFlag[elementId][1][sfbGrp+sfb] != NO_AH) && - (((FL2FXCONST_DBL(-0.02065512648f)>>1) + (qcOutChannel[0]->sfbMinSnrLdData[sfbGrp+sfb]>>1)) - > ((EnergyLd_R>>1) - (EnergyLd_L>>1))) ) - { - ahFlag[elementId][1][sfbGrp+sfb] = NO_AH; - qcOutChannel[1]->sfbThresholdLdData[sfbGrp+sfb] = FL2FXCONST_DBL(0.015625f) + EnergyLd_R; - actPe -= peData->peChannelData[1].sfbPe[sfbGrp+sfb]>>PE_CONSTPART_SHIFT; + if ((ahFlag[elementId][1][sfbGrp + sfb] != NO_AH) && + (((FL2FXCONST_DBL(-0.02065512648f) >> 1) + + (qcOutChannel[0]->sfbMinSnrLdData[sfbGrp + sfb] >> 1)) > + ((EnergyLd_R >> 1) - (EnergyLd_L >> 1)))) { + ahFlag[elementId][1][sfbGrp + sfb] = NO_AH; + qcOutChannel[1]->sfbThresholdLdData[sfbGrp + sfb] = + FL2FXCONST_DBL(0.015625f) + EnergyLd_R; + actPe -= peData->peChannelData[1].sfbPe[sfbGrp + sfb] >> + PE_CONSTPART_SHIFT; } /* allow hole in mid channel ? */ - else if ( (ahFlag[elementId][0][sfbGrp+sfb] != NO_AH) && - (((FL2FXCONST_DBL(-0.02065512648f)>>1) + (qcOutChannel[1]->sfbMinSnrLdData[sfbGrp+sfb]>>1)) - > ((EnergyLd_L>>1) - (EnergyLd_R>>1))) ) - { - ahFlag[elementId][0][sfbGrp+sfb] = NO_AH; - qcOutChannel[0]->sfbThresholdLdData[sfbGrp+sfb] = FL2FXCONST_DBL(0.015625f) + EnergyLd_L; - actPe -= peData->peChannelData[0].sfbPe[sfbGrp+sfb]>>PE_CONSTPART_SHIFT; + else if ((ahFlag[elementId][0][sfbGrp + sfb] != NO_AH) && + (((FL2FXCONST_DBL(-0.02065512648f) >> 1) + + (qcOutChannel[1]->sfbMinSnrLdData[sfbGrp + sfb] >> + 1)) > ((EnergyLd_L >> 1) - (EnergyLd_R >> 1)))) { + ahFlag[elementId][0][sfbGrp + sfb] = NO_AH; + qcOutChannel[0]->sfbThresholdLdData[sfbGrp + sfb] = + FL2FXCONST_DBL(0.015625f) + EnergyLd_L; + actPe -= peData->peChannelData[0].sfbPe[sfbGrp + sfb] >> + PE_CONSTPART_SHIFT; } /* if (ahFlag) */ - } /* if MS */ - } /* sfbGrp */ + } /* if MS */ + } /* sfbGrp */ if (actPe <= desiredPe) { return; /* stop if enough has been saved */ } } /* sfb */ - } /* MS possible ? */ - - /* more holes necessary? subsequently erase bands - starting with low energies */ - INT startSfb[2]; - FIXP_DBL avgEnLD64,minEnLD64; - INT ahCnt; - FIXP_DBL ahCntLD64; - INT enIdx; - FIXP_DBL enLD64[4]; - FIXP_DBL avgEn; - - /* do not go below startSfb */ - for (ch=0; chlastWindowSequence != SHORT_WINDOW) - startSfb[ch] = AdjThrStateElement[elementId]->ahParam.startSfbL; - else - startSfb[ch] = AdjThrStateElement[elementId]->ahParam.startSfbS; - } - - /* calc avg and min energies of bands that avoid holes */ - avgEn = FL2FXCONST_DBL(0.0f); - minEnLD64 = FL2FXCONST_DBL(0.0f); - ahCnt = 0; + } /* MS possible ? */ - for (ch=0; chmaxSfbPerGroup; sfb++) { - if ((ahFlag[elementId][ch][sfbGrp+sfb]!=NO_AH) && - (qcOutChannel[ch]->sfbWeightedEnergyLdData[sfbGrp+sfb] > qcOutChannel[ch]->sfbThresholdLdData[sfbGrp+sfb])){ - minEnLD64 = fixMin(minEnLD64,qcOutChannel[ch]->sfbEnergyLdData[sfbGrp+sfb]); - avgEn += qcOutChannel[ch]->sfbEnergy[sfbGrp+sfb] >> 6; - ahCnt++; - } + if (actPe > desiredPe) { + /* more holes necessary? subsequently erase bands starting with low energies + */ + INT ch, sfb, sfbGrp; + INT minSfb, maxSfb; + INT enIdx, ahCnt, done; + INT startSfb[(8)]; + INT sfbCnt[(8)]; + INT sfbPerGroup[(8)]; + INT maxSfbPerGroup[(8)]; + FIXP_DBL avgEn; + FIXP_DBL minEnLD64; + FIXP_DBL avgEnLD64; + FIXP_DBL enLD64[NUM_NRG_LEVS]; + INT avgEn_e; + + /* get the scaling factor over all audio elements and channels */ + maxSfb = 0; + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) { + for (sfbGrp = 0; + sfbGrp < psyOutElement[elementId]->psyOutChannel[ch]->sfbCnt; + sfbGrp += + psyOutElement[elementId]->psyOutChannel[ch]->sfbPerGroup) { + maxSfb += + psyOutElement[elementId]->psyOutChannel[ch]->maxSfbPerGroup; } - - sfbGrp += psyOutChannel[ch]->sfbPerGroup; - sfb=0; - - } while (sfbGrp < psyOutChannel[ch]->sfbCnt); - } - - if ( (avgEn == FL2FXCONST_DBL(0.0f)) || (ahCnt == 0) ) { - avgEnLD64 = FL2FXCONST_DBL(0.0f); - } - else { - avgEnLD64 = CalcLdData(avgEn); - ahCntLD64 = CalcLdInt(ahCnt); - avgEnLD64 = avgEnLD64 + FL2FXCONST_DBL(0.09375f) - ahCntLD64; /* compensate shift with 6 */ + } } + } + avgEn_e = + (DFRACT_BITS - fixnormz_D((LONG)fMax(0, maxSfb - 1))); /* ilog2() */ + + ahCnt = 0; + maxSfb = 0; + minSfb = MAX_SFB; + avgEn = FL2FXCONST_DBL(0.0f); + minEnLD64 = FL2FXCONST_DBL(0.0f); + + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) { + const INT chIdx = cm->elInfo[elementId].ChannelIndex[ch]; + QC_OUT_CHANNEL *qcOutChannel = qcElement[elementId]->qcOutChannel[ch]; + PSY_OUT_CHANNEL *psyOutChannel = + psyOutElement[elementId]->psyOutChannel[ch]; + + maxSfbPerGroup[chIdx] = psyOutChannel->maxSfbPerGroup; + sfbCnt[chIdx] = psyOutChannel->sfbCnt; + sfbPerGroup[chIdx] = psyOutChannel->sfbPerGroup; + + maxSfb = fMax(maxSfb, psyOutChannel->maxSfbPerGroup); + + if (psyOutChannel->lastWindowSequence != SHORT_WINDOW) { + startSfb[chIdx] = AdjThrStateElement[elementId]->ahParam.startSfbL; + } else { + startSfb[chIdx] = AdjThrStateElement[elementId]->ahParam.startSfbS; + } - /* calc some energy borders between minEn and avgEn */ - /* for (enIdx=0; enIdx<4; enIdx++) */ - /* en[enIdx] = minEn * (float)FDKpow(avgEn/(minEn+FLT_MIN), (2*enIdx+1)/7.0f); */ - enLD64[0] = minEnLD64 + fMult((avgEnLD64-minEnLD64),FL2FXCONST_DBL(0.14285714285f)); - enLD64[1] = minEnLD64 + fMult((avgEnLD64-minEnLD64),FL2FXCONST_DBL(0.42857142857f)); - enLD64[2] = minEnLD64 + fMult((avgEnLD64-minEnLD64),FL2FXCONST_DBL(0.71428571428f)); - enLD64[3] = minEnLD64 + (avgEnLD64-minEnLD64); - - for (enIdx=0; enIdx<4; enIdx++) { - INT noReduction = 1; - - INT maxSfbPerGroup[2]; - INT sfbCnt[2]; - INT sfbPerGroup[2]; - - for(ch=0; chelInfo[elementId].nChannelsInEl; ch++) { - maxSfbPerGroup[ch] = psyOutElement[elementId]->psyOutChannel[ch]->maxSfbPerGroup-1; - sfbCnt[ch] = psyOutElement[elementId]->psyOutChannel[ch]->sfbCnt; - sfbPerGroup[ch] = psyOutElement[elementId]->psyOutChannel[ch]->sfbPerGroup; - } + minSfb = fMin(minSfb, startSfb[chIdx]); - do { + sfbGrp = 0; + sfb = startSfb[chIdx]; - noReduction = 1; + do { + for (; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { + if ((ahFlag[elementId][ch][sfbGrp + sfb] != NO_AH) && + (qcOutChannel->sfbWeightedEnergyLdData[sfbGrp + sfb] > + qcOutChannel->sfbThresholdLdData[sfbGrp + sfb])) { + minEnLD64 = fixMin(minEnLD64, + qcOutChannel->sfbEnergyLdData[sfbGrp + sfb]); + avgEn += qcOutChannel->sfbEnergy[sfbGrp + sfb] >> avgEn_e; + ahCnt++; + } + } - for(ch=0; chelInfo[elementId].nChannelsInEl; ch++) { + sfbGrp += psyOutChannel->sfbPerGroup; + sfb = startSfb[chIdx]; - INT sfb, sfbGrp; + } while (sfbGrp < psyOutChannel->sfbCnt); + } + } /* (cm->elInfo[elementId].elType != ID_DSE) */ + } /* (elementId = elementOffset;elementId=startSfb[ch]) { /* sfb in next channel */ - sfb = maxSfbPerGroup[ch]--; - noReduction = 0; + if ((avgEn == FL2FXCONST_DBL(0.0f)) || (ahCnt == 0)) { + avgEnLD64 = FL2FXCONST_DBL(0.0f); + } else { + avgEnLD64 = CalcLdData(avgEn) + + (FIXP_DBL)(avgEn_e << (DFRACT_BITS - 1 - LD_DATA_SHIFT)) - + CalcLdInt(ahCnt); + } - for (sfbGrp = 0; sfbGrp < sfbCnt[ch]; sfbGrp += sfbPerGroup[ch]) { + /* calc some energy borders between minEn and avgEn */ + + /* for (enIdx = 0; enIdx < NUM_NRG_LEVS; enIdx++) { + en[enIdx] = (2.0f*enIdx+1.0f)/(2.0f*NUM_NRG_LEVS-1.0f); + } */ + enLD64[0] = + minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.06666667f)); + enLD64[1] = + minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.20000000f)); + enLD64[2] = + minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.33333334f)); + enLD64[3] = + minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.46666667f)); + enLD64[4] = + minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.60000002f)); + enLD64[5] = + minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.73333335f)); + enLD64[6] = + minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.86666667f)); + enLD64[7] = minEnLD64 + (avgEnLD64 - minEnLD64); + + done = 0; + enIdx = 0; + sfb = maxSfb - 1; + + while (!done) { + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + PE_DATA *peData = &qcElement[elementId]->peData; + for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) { + const INT chIdx = cm->elInfo[elementId].ChannelIndex[ch]; + QC_OUT_CHANNEL *qcOutChannel = + qcElement[elementId]->qcOutChannel[ch]; + if (sfb >= startSfb[chIdx] && sfb < maxSfbPerGroup[chIdx]) { + for (sfbGrp = 0; sfbGrp < sfbCnt[chIdx]; + sfbGrp += sfbPerGroup[chIdx]) { /* sfb energy below border ? */ - if (ahFlag[elementId][ch][sfbGrp+sfb] != NO_AH && qcOutChannel[ch]->sfbEnergyLdData[sfbGrp+sfb] < enLD64[enIdx]) { + if (ahFlag[elementId][ch][sfbGrp + sfb] != NO_AH && + qcOutChannel->sfbEnergyLdData[sfbGrp + sfb] < + enLD64[enIdx]) { /* allow hole */ - ahFlag[elementId][ch][sfbGrp+sfb] = NO_AH; - qcOutChannel[ch]->sfbThresholdLdData[sfbGrp+sfb] = FL2FXCONST_DBL(0.015625f) + qcOutChannel[ch]->sfbWeightedEnergyLdData[sfbGrp+sfb]; - actPe -= peData->peChannelData[ch].sfbPe[sfbGrp+sfb]>>PE_CONSTPART_SHIFT; + ahFlag[elementId][ch][sfbGrp + sfb] = NO_AH; + qcOutChannel->sfbThresholdLdData[sfbGrp + sfb] = + FL2FXCONST_DBL(0.015625f) + + qcOutChannel->sfbWeightedEnergyLdData[sfbGrp + sfb]; + actPe -= peData->peChannelData[ch].sfbPe[sfbGrp + sfb] >> + PE_CONSTPART_SHIFT; } - } /* sfbGrp */ - - if (actPe <= desiredPe) { - return; /* stop if enough has been saved */ - } - } /* sfb > 0 */ - } /* ch loop */ - - } while( (noReduction == 0) && (actPe > desiredPe) ); - - if (actPe <= desiredPe) { - return; /* stop if enough has been saved */ + if (actPe <= desiredPe) { + return; /* stop if enough has been saved */ + } + } /* sfbGrp */ + } /* sfb */ + } /* nChannelsInEl */ + } /* ID_DSE */ + } /* elementID */ + + sfb--; + if (sfb < minSfb) { + /* restart with next energy border */ + sfb = maxSfb; + enIdx++; + if (enIdx >= NUM_NRG_LEVS) { + done = 1; } - - } /* enIdx loop */ - - } /* EOF DSE-suppression */ - } /* EOF for all elements... */ - + } + } /* done */ + } /* (actPe <= desiredPe) */ } /* reset avoid hole flags from AH_ACTIVE to AH_INACTIVE */ -static void FDKaacEnc_resetAHFlags( UCHAR ahFlag[(2)][MAX_GROUPED_SFB], - const int nChannels, - PSY_OUT_CHANNEL *psyOutChannel[(2)]) -{ +static void FDKaacEnc_resetAHFlags( + UCHAR ahFlag[(2)][MAX_GROUPED_SFB], const INT nChannels, + const PSY_OUT_CHANNEL *const psyOutChannel[(2)]) { int ch, sfb, sfbGrp; - for(ch=0; chsfbCnt; sfbGrp+=psyOutChannel[ch]->sfbPerGroup) { - for (sfb=0; sfbmaxSfbPerGroup; sfb++) { - if ( ahFlag[ch][sfbGrp+sfb] == AH_ACTIVE) { - ahFlag[ch][sfbGrp+sfb] = AH_INACTIVE; + for (ch = 0; ch < nChannels; ch++) { + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) { + if (ahFlag[ch][sfbGrp + sfb] == AH_ACTIVE) { + ahFlag[ch][sfbGrp + sfb] = AH_INACTIVE; } } } } } +static FIXP_DBL CalcRedValPower(FIXP_DBL num, FIXP_DBL denum, INT *scaling) { + FIXP_DBL value = FL2FXCONST_DBL(0.f); -static FIXP_DBL CalcRedValPower(FIXP_DBL num, - FIXP_DBL denum, - INT* scaling ) -{ - FIXP_DBL value = FL2FXCONST_DBL(0.f); - - if (num>=FL2FXCONST_DBL(0.f)) { - value = fDivNorm( num, denum, scaling); - } - else { - value = -fDivNorm( -num, denum, scaling); - } - value = f2Pow(value, *scaling, scaling); - *scaling = DFRACT_BITS-1-*scaling; + if (num >= FL2FXCONST_DBL(0.f)) { + value = fDivNorm(num, denum, scaling); + } else { + value = -fDivNorm(-num, denum, scaling); + } + value = f2Pow(value, *scaling, scaling); - return value; + return value; } - /***************************************************************************** functionname: FDKaacEnc_adaptThresholdsToPe -description: two guesses for the reduction value and one final correction of the thresholds +description: two guesses for the reduction value and one final correction of +the thresholds *****************************************************************************/ -static void FDKaacEnc_adaptThresholdsToPe(CHANNEL_MAPPING* cm, - ATS_ELEMENT* AdjThrStateElement[(8)], - QC_OUT_ELEMENT* qcElement[(8)], - PSY_OUT_ELEMENT* psyOutElement[(8)], - const INT desiredPe, - const INT maxIter2ndGuess, - const INT processElements, - const INT elementOffset) -{ - FIXP_DBL redValue[(8)]; - SCHAR redValScaling[(8)]; - UCHAR pAhFlag[(8)][(2)][MAX_GROUPED_SFB]; - FIXP_DBL pThrExp[(8)][(2)][MAX_GROUPED_SFB]; - int iter; - - INT constPartGlobal, noRedPeGlobal, nActiveLinesGlobal, redPeGlobal; - constPartGlobal = noRedPeGlobal = nActiveLinesGlobal = redPeGlobal = 0; - - int elementId; +static void FDKaacEnc_adaptThresholdsToPe( + const CHANNEL_MAPPING *const cm, + ATS_ELEMENT *const AdjThrStateElement[((8))], + QC_OUT_ELEMENT *const qcElement[((8))], + const PSY_OUT_ELEMENT *const psyOutElement[((8))], const INT desiredPe, + const INT maxIter2ndGuess, const INT processElements, + const INT elementOffset) { + FIXP_DBL reductionValue_m; + SCHAR reductionValue_e; + UCHAR(*pAhFlag)[(2)][MAX_GROUPED_SFB]; + FIXP_DBL(*pThrExp)[(2)][MAX_GROUPED_SFB]; + int iter; + + INT constPartGlobal, noRedPeGlobal, nActiveLinesGlobal, redPeGlobal; + constPartGlobal = noRedPeGlobal = nActiveLinesGlobal = redPeGlobal = 0; + + int elementId; + + int nElements = elementOffset + processElements; + if (nElements > cm->nElements) { + nElements = cm->nElements; + } - int nElements = elementOffset+processElements; - if(nElements > cm->nElements) { - nElements = cm->nElements; - } + /* The reinterpret_cast is used to suppress a compiler warning. We know that + * qcElement[0]->dynMem_Ah_Flag is sufficiently aligned, so the cast is safe + */ + pAhFlag = reinterpret_cast( + reinterpret_cast(qcElement[0]->dynMem_Ah_Flag)); + /* The reinterpret_cast is used to suppress a compiler warning. We know that + * qcElement[0]->dynMem_Thr_Exp is sufficiently aligned, so the cast is safe + */ + pThrExp = reinterpret_cast( + reinterpret_cast(qcElement[0]->dynMem_Thr_Exp)); - /* ------------------------------------------------------- */ - /* Part I: Initialize data structures and variables... */ - /* ------------------------------------------------------- */ - for (elementId = elementOffset;elementIdelInfo[elementId].elType != ID_DSE) { - - INT nChannels = cm->elInfo[elementId].nChannelsInEl; - PE_DATA *peData = &qcElement[elementId]->peData; - - /* thresholds to the power of redExp */ - FDKaacEnc_calcThreshExp(pThrExp[elementId], qcElement[elementId]->qcOutChannel, psyOutElement[elementId]->psyOutChannel, nChannels); - - /* lower the minSnr requirements for low energies compared to the average - energy in this frame */ - FDKaacEnc_adaptMinSnr(qcElement[elementId]->qcOutChannel, psyOutElement[elementId]->psyOutChannel, &AdjThrStateElement[elementId]->minSnrAdaptParam, nChannels); - - /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */ - FDKaacEnc_initAvoidHoleFlag(qcElement[elementId]->qcOutChannel, psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId], &psyOutElement[elementId]->toolsInfo, nChannels, peData, &AdjThrStateElement[elementId]->ahParam); + /* ------------------------------------------------------- */ + /* Part I: Initialize data structures and variables... */ + /* ------------------------------------------------------- */ + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + INT nChannels = cm->elInfo[elementId].nChannelsInEl; + PE_DATA *peData = &qcElement[elementId]->peData; - /* sum up */ - constPartGlobal += peData->constPart; - noRedPeGlobal += peData->pe; - nActiveLinesGlobal += fixMax((INT)peData->nActiveLines, 1); + /* thresholds to the power of redExp */ + FDKaacEnc_calcThreshExp( + pThrExp[elementId], qcElement[elementId]->qcOutChannel, + psyOutElement[elementId]->psyOutChannel, nChannels); + + /* lower the minSnr requirements for low energies compared to the average + energy in this frame */ + FDKaacEnc_adaptMinSnr(qcElement[elementId]->qcOutChannel, + psyOutElement[elementId]->psyOutChannel, + &AdjThrStateElement[elementId]->minSnrAdaptParam, + nChannels); + + /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */ + FDKaacEnc_initAvoidHoleFlag( + qcElement[elementId]->qcOutChannel, + psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId], + &psyOutElement[elementId]->toolsInfo, nChannels, + &AdjThrStateElement[elementId]->ahParam); + + /* sum up */ + constPartGlobal += peData->constPart; + noRedPeGlobal += peData->pe; + nActiveLinesGlobal += fixMax((INT)peData->nActiveLines, 1); - } /* EOF DSE-suppression */ - } /* EOF for all elements... */ + } /* EOF DSE-suppression */ + } /* EOF for all elements... */ + + /* + First guess of reduction value: + avgThrExp = (float)pow(2.0f, (constPartGlobal - noRedPeGlobal)/(4.0f * + nActiveLinesGlobal)); redVal = (float)pow(2.0f, (constPartGlobal - + desiredPe)/(4.0f * nActiveLinesGlobal)) - avgThrExp; redVal = max(0.f, + redVal); + */ + int redVal_e, avgThrExp_e, result_e; + FIXP_DBL redVal_m, avgThrExp_m; + + redVal_m = CalcRedValPower(constPartGlobal - desiredPe, + 4 * nActiveLinesGlobal, &redVal_e); + avgThrExp_m = CalcRedValPower(constPartGlobal - noRedPeGlobal, + 4 * nActiveLinesGlobal, &avgThrExp_e); + result_e = fMax(redVal_e, avgThrExp_e) + 1; + + reductionValue_m = fMax(FL2FXCONST_DBL(0.f), + scaleValue(redVal_m, redVal_e - result_e) - + scaleValue(avgThrExp_m, avgThrExp_e - result_e)); + reductionValue_e = result_e; + + /* ----------------------------------------------------------------------- */ + /* Part II: Calculate bit consumption of initial bit constraints setup */ + /* ----------------------------------------------------------------------- */ + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + INT nChannels = cm->elInfo[elementId].nChannelsInEl; + PE_DATA *peData = &qcElement[elementId]->peData; - /* ----------------------------------------------------------------------- */ - /* Part II: Calculate bit consumption of initial bit constraints setup */ - /* ----------------------------------------------------------------------- */ - for (elementId = elementOffset;elementIdelInfo[elementId].elType != ID_DSE) { - /* - redVal = ( 2 ^ ( (constPartGlobal-desiredPe) / (invRedExp*nActiveLinesGlobal) ) - - 2 ^ ( (constPartGlobal-noRedPeGlobal) / (invRedExp*nActiveLinesGlobal) ) ) - */ - - - INT nChannels = cm->elInfo[elementId].nChannelsInEl; - PE_DATA *peData = &qcElement[elementId]->peData; - - /* first guess of reduction value */ - int scale0=0, scale1=0; - FIXP_DBL tmp0 = CalcRedValPower( constPartGlobal-desiredPe, 4*nActiveLinesGlobal, &scale0 ); - FIXP_DBL tmp1 = CalcRedValPower( constPartGlobal-noRedPeGlobal, 4*nActiveLinesGlobal, &scale1 ); - - int scalMin = FDKmin(scale0, scale1)-1; - - redValue[elementId] = scaleValue(tmp0,(scalMin-scale0)) - scaleValue(tmp1,(scalMin-scale1)); - redValScaling[elementId] = scalMin; - - /* reduce thresholds */ - FDKaacEnc_reduceThresholdsCBR(qcElement[elementId]->qcOutChannel, psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId], pThrExp[elementId], nChannels, redValue[elementId], redValScaling[elementId]); - - /* pe after first guess */ - FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel, qcElement[elementId]->qcOutChannel, peData, nChannels); - - redPeGlobal += peData->pe; - } /* EOF DSE-suppression */ - } /* EOF for all elements... */ - - /* -------------------------------------------------- */ - /* Part III: Iterate until bit constraints are met */ - /* -------------------------------------------------- */ - iter = 0; - while ((fixp_abs(redPeGlobal - desiredPe) > fMultI(FL2FXCONST_DBL(0.05f),desiredPe)) && (iter < maxIter2ndGuess)) { + /* reduce thresholds */ + FDKaacEnc_reduceThresholdsCBR( + qcElement[elementId]->qcOutChannel, + psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId], + pThrExp[elementId], nChannels, reductionValue_m, reductionValue_e); - INT desiredPeNoAHGlobal; - INT redPeNoAHGlobal = 0; - INT constPartNoAHGlobal = 0; - INT nActiveLinesNoAHGlobal = 0; + /* pe after first guess */ + FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel, + qcElement[elementId]->qcOutChannel, peData, nChannels); - for (elementId = elementOffset;elementIdelInfo[elementId].elType != ID_DSE) { + redPeGlobal += peData->pe; + } /* EOF DSE-suppression */ + } /* EOF for all elements... */ + + /* -------------------------------------------------- */ + /* Part III: Iterate until bit constraints are met */ + /* -------------------------------------------------- */ + iter = 0; + while ((fixp_abs(redPeGlobal - desiredPe) > + fMultI(FL2FXCONST_DBL(0.05f), desiredPe)) && + (iter < maxIter2ndGuess)) { + INT desiredPeNoAHGlobal; + INT redPeNoAHGlobal = 0; + INT constPartNoAHGlobal = 0; + INT nActiveLinesNoAHGlobal = 0; + + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + INT redPeNoAH, constPartNoAH, nActiveLinesNoAH; + INT nChannels = cm->elInfo[elementId].nChannelsInEl; + PE_DATA *peData = &qcElement[elementId]->peData; + + /* pe for bands where avoid hole is inactive */ + FDKaacEnc_FDKaacEnc_calcPeNoAH( + &redPeNoAH, &constPartNoAH, &nActiveLinesNoAH, peData, + pAhFlag[elementId], psyOutElement[elementId]->psyOutChannel, + nChannels); + + redPeNoAHGlobal += redPeNoAH; + constPartNoAHGlobal += constPartNoAH; + nActiveLinesNoAHGlobal += nActiveLinesNoAH; + } /* EOF DSE-suppression */ + } /* EOF for all elements... */ + + /* Calculate new redVal ... */ + if (desiredPe < redPeGlobal) { + /* new desired pe without bands where avoid hole is active */ + desiredPeNoAHGlobal = desiredPe - (redPeGlobal - redPeNoAHGlobal); + + /* limit desiredPeNoAH to positive values, as the PE can not become + * negative */ + desiredPeNoAHGlobal = fMax(0, desiredPeNoAHGlobal); + + /* second guess (only if there are bands left where avoid hole is + * inactive)*/ + if (nActiveLinesNoAHGlobal > 0) { + /* + avgThrExp = (float)pow(2.0f, (constPartNoAHGlobal - redPeNoAHGlobal) / + (4.0f * nActiveLinesNoAHGlobal)); redVal += (float)pow(2.0f, + (constPartNoAHGlobal - desiredPeNoAHGlobal) / (4.0f * + nActiveLinesNoAHGlobal)) - avgThrExp; redVal = max(0.0f, redVal); + */ + + redVal_m = CalcRedValPower(constPartNoAHGlobal - desiredPeNoAHGlobal, + 4 * nActiveLinesNoAHGlobal, &redVal_e); + avgThrExp_m = CalcRedValPower(constPartNoAHGlobal - redPeNoAHGlobal, + 4 * nActiveLinesNoAHGlobal, &avgThrExp_e); + result_e = fMax(reductionValue_e, fMax(redVal_e, avgThrExp_e) + 1) + 1; + + reductionValue_m = + fMax(FL2FXCONST_DBL(0.f), + scaleValue(reductionValue_m, reductionValue_e - result_e) + + scaleValue(redVal_m, redVal_e - result_e) - + scaleValue(avgThrExp_m, avgThrExp_e - result_e)); + reductionValue_e = result_e; + + } /* nActiveLinesNoAHGlobal > 0 */ + } else { + /* redVal *= redPeGlobal/desiredPe; */ + int sc0, sc1; + reductionValue_m = fMultNorm( + reductionValue_m, + fDivNorm((FIXP_DBL)redPeGlobal, (FIXP_DBL)desiredPe, &sc0), &sc1); + reductionValue_e += sc0 + sc1; + + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + FDKaacEnc_resetAHFlags(pAhFlag[elementId], + cm->elInfo[elementId].nChannelsInEl, + psyOutElement[elementId]->psyOutChannel); + } /* EOF DSE-suppression */ + } /* EOF for all elements... */ + } - INT redPeNoAH, constPartNoAH, nActiveLinesNoAH; - INT nChannels = cm->elInfo[elementId].nChannelsInEl; - PE_DATA *peData = &qcElement[elementId]->peData; - - /* pe for bands where avoid hole is inactive */ - FDKaacEnc_FDKaacEnc_calcPeNoAH(&redPeNoAH, &constPartNoAH, &nActiveLinesNoAH, - peData, pAhFlag[elementId], psyOutElement[elementId]->psyOutChannel, nChannels); - - redPeNoAHGlobal += redPeNoAH; - constPartNoAHGlobal += constPartNoAH; - nActiveLinesNoAHGlobal += nActiveLinesNoAH; - } /* EOF DSE-suppression */ - } /* EOF for all elements... */ - - /* Calculate new redVal ... */ - if(desiredPe < redPeGlobal) { - - /* new desired pe without bands where avoid hole is active */ - desiredPeNoAHGlobal = desiredPe - (redPeGlobal - redPeNoAHGlobal); - - /* limit desiredPeNoAH to positive values, as the PE can not become negative */ - desiredPeNoAHGlobal = FDKmax(0,desiredPeNoAHGlobal); - - /* second guess (only if there are bands left where avoid hole is inactive)*/ - if (nActiveLinesNoAHGlobal > 0) { - for (elementId = elementOffset;elementIdelInfo[elementId].elType != ID_DSE) { - /* - redVal += ( 2 ^ ( (constPartNoAHGlobal-desiredPeNoAHGlobal) / (invRedExp*nActiveLinesNoAHGlobal) ) - - 2 ^ ( (constPartNoAHGlobal-redPeNoAHGlobal) / (invRedExp*nActiveLinesNoAHGlobal) ) ) - */ - int scale0 = 0; - int scale1 = 0; - - FIXP_DBL tmp0 = CalcRedValPower( constPartNoAHGlobal-desiredPeNoAHGlobal, 4*nActiveLinesNoAHGlobal, &scale0 ); - FIXP_DBL tmp1 = CalcRedValPower( constPartNoAHGlobal-redPeNoAHGlobal, 4*nActiveLinesNoAHGlobal, &scale1 ); - - int scalMin = FDKmin(scale0, scale1)-1; - - tmp0 = scaleValue(tmp0,(scalMin-scale0)) - scaleValue(tmp1,(scalMin-scale1)); - scale0 = scalMin; - - /* old reduction value */ - tmp1 = redValue[elementId]; - scale1 = redValScaling[elementId]; - - scalMin = fixMin(scale0,scale1)-1; - - /* sum up old and new reduction value */ - redValue[elementId] = scaleValue(tmp0,(scalMin-scale0)) + scaleValue(tmp1,(scalMin-scale1)); - redValScaling[elementId] = scalMin; - - } /* EOF DSE-suppression */ - } /* EOF for all elements... */ - } /* nActiveLinesNoAHGlobal > 0 */ - } - else { - /* desiredPe >= redPeGlobal */ - for (elementId = elementOffset;elementIdelInfo[elementId].elType != ID_DSE) { - - INT redVal_scale = 0; - FIXP_DBL tmp = fDivNorm((FIXP_DBL)redPeGlobal, (FIXP_DBL)desiredPe, &redVal_scale); - - /* redVal *= redPeGlobal/desiredPe; */ - redValue[elementId] = fMult(redValue[elementId], tmp); - redValScaling[elementId] -= redVal_scale; - - FDKaacEnc_resetAHFlags(pAhFlag[elementId], cm->elInfo[elementId].nChannelsInEl, psyOutElement[elementId]->psyOutChannel); - } /* EOF DSE-suppression */ - } /* EOF for all elements... */ - } - - redPeGlobal = 0; - /* Calculate new redVal's PE... */ - for (elementId = elementOffset;elementIdelInfo[elementId].elType != ID_DSE) { - - INT nChannels = cm->elInfo[elementId].nChannelsInEl; - PE_DATA *peData = &qcElement[elementId]->peData; - - /* reduce thresholds */ - FDKaacEnc_reduceThresholdsCBR(qcElement[elementId]->qcOutChannel, psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId], pThrExp[elementId], nChannels, redValue[elementId], redValScaling[elementId]); - - /* pe after second guess */ - FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel, qcElement[elementId]->qcOutChannel, peData, nChannels); - redPeGlobal += peData->pe; - - } /* EOF DSE-suppression */ - } /* EOF for all elements... */ - - iter++; - } /* EOF while */ - - - /* ------------------------------------------------------- */ - /* Part IV: if still required, further reduce constraints */ - /* ------------------------------------------------------- */ - /* 1.0* 1.15* 1.20* - * desiredPe desiredPe desiredPe - * | | | - * ...XXXXXXXXXXXXXXXXXXXXXXXXXXX| | - * | | |XXXXXXXXXXX... - * | |XXXXXXXXXXX| - * --- A --- | --- B --- | --- C --- - * - * (X): redPeGlobal - * (A): FDKaacEnc_correctThresh() - * (B): FDKaacEnc_allowMoreHoles() - * (C): FDKaacEnc_reduceMinSnr() + redPeGlobal = 0; + /* Calculate new redVal's PE... */ + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + INT nChannels = cm->elInfo[elementId].nChannelsInEl; + PE_DATA *peData = &qcElement[elementId]->peData; + + /* reduce thresholds */ + FDKaacEnc_reduceThresholdsCBR( + qcElement[elementId]->qcOutChannel, + psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId], + pThrExp[elementId], nChannels, reductionValue_m, reductionValue_e); + + /* pe after second guess */ + FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel, + qcElement[elementId]->qcOutChannel, peData, nChannels); + redPeGlobal += peData->pe; + + } /* EOF DSE-suppression */ + } /* EOF for all elements... */ + + iter++; + } /* EOF while */ + + /* ------------------------------------------------------- */ + /* Part IV: if still required, further reduce constraints */ + /* ------------------------------------------------------- */ + /* 1.0* 1.15* 1.20* + * desiredPe desiredPe desiredPe + * | | | + * ...XXXXXXXXXXXXXXXXXXXXXXXXXXX| | + * | | |XXXXXXXXXXX... + * | |XXXXXXXXXXX| + * --- A --- | --- B --- | --- C --- + * + * (X): redPeGlobal + * (A): FDKaacEnc_correctThresh() + * (B): FDKaacEnc_allowMoreHoles() + * (C): FDKaacEnc_reduceMinSnr() */ - /* correct thresholds to get closer to the desired pe */ - if ( redPeGlobal > desiredPe ) { - FDKaacEnc_correctThresh(cm, qcElement, psyOutElement, pAhFlag, pThrExp, redValue, redValScaling, - desiredPe - redPeGlobal, processElements, elementOffset); - - /* update PE */ - redPeGlobal = 0; - for(elementId=elementOffset;elementIdelInfo[elementId].elType != ID_DSE) { - - INT nChannels = cm->elInfo[elementId].nChannelsInEl; - PE_DATA *peData = &qcElement[elementId]->peData; - - /* pe after correctThresh */ - FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel, qcElement[elementId]->qcOutChannel, peData, nChannels); - redPeGlobal += peData->pe; - - } /* EOF DSE-suppression */ - } /* EOF for all elements... */ - } - - if ( redPeGlobal > desiredPe ) { - /* reduce pe by reducing minSnr requirements */ - FDKaacEnc_reduceMinSnr(cm, qcElement, psyOutElement, pAhFlag, - (fMultI(FL2FXCONST_DBL(0.15f),desiredPe) + desiredPe), - &redPeGlobal, processElements, elementOffset); - - /* reduce pe by allowing additional spectral holes */ - FDKaacEnc_allowMoreHoles(cm, qcElement, psyOutElement, AdjThrStateElement, pAhFlag, - desiredPe, redPeGlobal, processElements, elementOffset); - } + /* correct thresholds to get closer to the desired pe */ + if (redPeGlobal > desiredPe) { + FDKaacEnc_correctThresh(cm, qcElement, psyOutElement, pAhFlag, pThrExp, + reductionValue_m, reductionValue_e, + desiredPe - redPeGlobal, processElements, + elementOffset); + + /* update PE */ + redPeGlobal = 0; + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + INT nChannels = cm->elInfo[elementId].nChannelsInEl; + PE_DATA *peData = &qcElement[elementId]->peData; + + /* pe after correctThresh */ + FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel, + qcElement[elementId]->qcOutChannel, peData, nChannels); + redPeGlobal += peData->pe; + + } /* EOF DSE-suppression */ + } /* EOF for all elements... */ + } + if (redPeGlobal > desiredPe) { + /* reduce pe by reducing minSnr requirements */ + FDKaacEnc_reduceMinSnr( + cm, qcElement, psyOutElement, pAhFlag, + (fMultI(FL2FXCONST_DBL(0.15f), desiredPe) + desiredPe), &redPeGlobal, + processElements, elementOffset); + + /* reduce pe by allowing additional spectral holes */ + FDKaacEnc_allowMoreHoles(cm, qcElement, psyOutElement, AdjThrStateElement, + pAhFlag, desiredPe, redPeGlobal, processElements, + elementOffset); + } } /* similar to FDKaacEnc_adaptThresholdsToPe(), for VBR-mode */ -void FDKaacEnc_AdaptThresholdsVBR(QC_OUT_CHANNEL* qcOutChannel[(2)], - PSY_OUT_CHANNEL* psyOutChannel[(2)], - ATS_ELEMENT* AdjThrStateElement, - struct TOOLSINFO *toolsInfo, - PE_DATA *peData, - const INT nChannels) -{ - UCHAR (*pAhFlag)[MAX_GROUPED_SFB]; - FIXP_DBL (*pThrExp)[MAX_GROUPED_SFB]; - - /* allocate scratch memory */ - C_ALLOC_SCRATCH_START(_pAhFlag, UCHAR, (2)*MAX_GROUPED_SFB) - C_ALLOC_SCRATCH_START(_pThrExp, FIXP_DBL, (2)*MAX_GROUPED_SFB) - pAhFlag = (UCHAR(*)[MAX_GROUPED_SFB])_pAhFlag; - pThrExp = (FIXP_DBL(*)[MAX_GROUPED_SFB])_pThrExp; - - /* thresholds to the power of redExp */ - FDKaacEnc_calcThreshExp(pThrExp, qcOutChannel, psyOutChannel, nChannels); - - /* lower the minSnr requirements for low energies compared to the average - energy in this frame */ - FDKaacEnc_adaptMinSnr(qcOutChannel, psyOutChannel, &AdjThrStateElement->minSnrAdaptParam, nChannels); - - /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */ - FDKaacEnc_initAvoidHoleFlag(qcOutChannel, psyOutChannel, pAhFlag, toolsInfo, - nChannels, peData, &AdjThrStateElement->ahParam); - - /* reduce thresholds */ - FDKaacEnc_reduceThresholdsVBR(qcOutChannel, psyOutChannel, pAhFlag, pThrExp, nChannels, - AdjThrStateElement->vbrQualFactor, - &AdjThrStateElement->chaosMeasureOld); - - /* free scratch memory */ - C_ALLOC_SCRATCH_END(_pThrExp, FIXP_DBL, (2)*MAX_GROUPED_SFB) - C_ALLOC_SCRATCH_END(_pAhFlag, UCHAR, (2)*MAX_GROUPED_SFB) +static void FDKaacEnc_AdaptThresholdsVBR( + QC_OUT_CHANNEL *const qcOutChannel[(2)], + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], + ATS_ELEMENT *const AdjThrStateElement, + const struct TOOLSINFO *const toolsInfo, const INT nChannels) { + UCHAR(*pAhFlag)[MAX_GROUPED_SFB]; + FIXP_DBL(*pThrExp)[MAX_GROUPED_SFB]; + + /* allocate scratch memory */ + C_ALLOC_SCRATCH_START(_pAhFlag, UCHAR, (2) * MAX_GROUPED_SFB) + C_ALLOC_SCRATCH_START(_pThrExp, FIXP_DBL, (2) * MAX_GROUPED_SFB) + pAhFlag = (UCHAR(*)[MAX_GROUPED_SFB])_pAhFlag; + pThrExp = (FIXP_DBL(*)[MAX_GROUPED_SFB])_pThrExp; + + /* thresholds to the power of redExp */ + FDKaacEnc_calcThreshExp(pThrExp, qcOutChannel, psyOutChannel, nChannels); + + /* lower the minSnr requirements for low energies compared to the average + energy in this frame */ + FDKaacEnc_adaptMinSnr(qcOutChannel, psyOutChannel, + &AdjThrStateElement->minSnrAdaptParam, nChannels); + + /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */ + FDKaacEnc_initAvoidHoleFlag(qcOutChannel, psyOutChannel, pAhFlag, toolsInfo, + nChannels, &AdjThrStateElement->ahParam); + + /* reduce thresholds */ + FDKaacEnc_reduceThresholdsVBR(qcOutChannel, psyOutChannel, pAhFlag, pThrExp, + nChannels, AdjThrStateElement->vbrQualFactor, + &AdjThrStateElement->chaosMeasureOld); + + /* free scratch memory */ + C_ALLOC_SCRATCH_END(_pThrExp, FIXP_DBL, (2) * MAX_GROUPED_SFB) + C_ALLOC_SCRATCH_END(_pAhFlag, UCHAR, (2) * MAX_GROUPED_SFB) } - /***************************************************************************** functionname: FDKaacEnc_calcBitSave @@ -1978,20 +2226,19 @@ void FDKaacEnc_AdaptThresholdsVBR(QC_OUT_CHANNEL* qcOutChannel[(2)], clipHigh maxBitres */ static FIXP_DBL FDKaacEnc_calcBitSave(FIXP_DBL fillLevel, - const FIXP_DBL clipLow, - const FIXP_DBL clipHigh, - const FIXP_DBL minBitSave, - const FIXP_DBL maxBitSave, - const FIXP_DBL bitsave_slope) -{ - FIXP_DBL bitsave; + const FIXP_DBL clipLow, + const FIXP_DBL clipHigh, + const FIXP_DBL minBitSave, + const FIXP_DBL maxBitSave, + const FIXP_DBL bitsave_slope) { + FIXP_DBL bitsave; - fillLevel = fixMax(fillLevel, clipLow); - fillLevel = fixMin(fillLevel, clipHigh); + fillLevel = fixMax(fillLevel, clipLow); + fillLevel = fixMin(fillLevel, clipHigh); - bitsave = maxBitSave - fMult((fillLevel-clipLow), bitsave_slope); + bitsave = maxBitSave - fMult((fillLevel - clipLow), bitsave_slope); - return (bitsave); + return (bitsave); } /***************************************************************************** @@ -2017,23 +2264,21 @@ static FIXP_DBL FDKaacEnc_calcBitSave(FIXP_DBL fillLevel, clipLow */ static FIXP_DBL FDKaacEnc_calcBitSpend(FIXP_DBL fillLevel, - const FIXP_DBL clipLow, - const FIXP_DBL clipHigh, - const FIXP_DBL minBitSpend, - const FIXP_DBL maxBitSpend, - const FIXP_DBL bitspend_slope) -{ - FIXP_DBL bitspend; + const FIXP_DBL clipLow, + const FIXP_DBL clipHigh, + const FIXP_DBL minBitSpend, + const FIXP_DBL maxBitSpend, + const FIXP_DBL bitspend_slope) { + FIXP_DBL bitspend; - fillLevel = fixMax(fillLevel, clipLow); - fillLevel = fixMin(fillLevel, clipHigh); + fillLevel = fixMax(fillLevel, clipLow); + fillLevel = fixMin(fillLevel, clipHigh); - bitspend = minBitSpend + fMult(fillLevel-clipLow, bitspend_slope); + bitspend = minBitSpend + fMult(fillLevel - clipLow, bitspend_slope); - return (bitspend); + return (bitspend); } - /***************************************************************************** functionname: FDKaacEnc_adjustPeMinMax() @@ -2043,52 +2288,46 @@ static FIXP_DBL FDKaacEnc_calcBitSpend(FIXP_DBL fillLevel, output: adjusted peMin/peMax *****************************************************************************/ -static void FDKaacEnc_adjustPeMinMax(const INT currPe, - INT *peMin, - INT *peMax) -{ - FIXP_DBL minFacHi = FL2FXCONST_DBL(0.3f), maxFacHi = (FIXP_DBL)MAXVAL_DBL, minFacLo = FL2FXCONST_DBL(0.14f), maxFacLo = FL2FXCONST_DBL(0.07f); - INT diff; - - INT minDiff_fix = fMultI(FL2FXCONST_DBL(0.1666666667f), currPe); - - if (currPe > *peMax) - { - diff = (currPe-*peMax) ; - *peMin += fMultI(minFacHi,diff); - *peMax += fMultI(maxFacHi,diff); - } - else if (currPe < *peMin) - { - diff = (*peMin-currPe) ; - *peMin -= fMultI(minFacLo,diff); - *peMax -= fMultI(maxFacLo,diff); - } - else - { - *peMin += fMultI(minFacHi, (currPe - *peMin)); - *peMax -= fMultI(maxFacLo, (*peMax - currPe)); - } +static void FDKaacEnc_adjustPeMinMax(const INT currPe, INT *peMin, INT *peMax) { + FIXP_DBL minFacHi = FL2FXCONST_DBL(0.3f), maxFacHi = (FIXP_DBL)MAXVAL_DBL, + minFacLo = FL2FXCONST_DBL(0.14f), maxFacLo = FL2FXCONST_DBL(0.07f); + INT diff; + + INT minDiff_fix = fMultI(FL2FXCONST_DBL(0.1666666667f), currPe); + + if (currPe > *peMax) { + diff = (currPe - *peMax); + *peMin += fMultI(minFacHi, diff); + *peMax += fMultI(maxFacHi, diff); + } else if (currPe < *peMin) { + diff = (*peMin - currPe); + *peMin -= fMultI(minFacLo, diff); + *peMax -= fMultI(maxFacLo, diff); + } else { + *peMin += fMultI(minFacHi, (currPe - *peMin)); + *peMax -= fMultI(maxFacLo, (*peMax - currPe)); + } - if ((*peMax - *peMin) < minDiff_fix) - { - INT peMax_fix = *peMax, peMin_fix = *peMin; - FIXP_DBL partLo_fix, partHi_fix; + if ((*peMax - *peMin) < minDiff_fix) { + INT peMax_fix = *peMax, peMin_fix = *peMin; + FIXP_DBL partLo_fix, partHi_fix; - partLo_fix = (FIXP_DBL)fixMax(0, currPe - peMin_fix); - partHi_fix = (FIXP_DBL)fixMax(0, peMax_fix - currPe); + partLo_fix = (FIXP_DBL)fixMax(0, currPe - peMin_fix); + partHi_fix = (FIXP_DBL)fixMax(0, peMax_fix - currPe); - peMax_fix = (INT)(currPe + fMultI(fDivNorm(partHi_fix, (partLo_fix+partHi_fix)), minDiff_fix)); - peMin_fix = (INT)(currPe - fMultI(fDivNorm(partLo_fix, (partLo_fix+partHi_fix)), minDiff_fix)); - peMin_fix = fixMax(0, peMin_fix); + peMax_fix = + (INT)(currPe + fMultI(fDivNorm(partHi_fix, (partLo_fix + partHi_fix)), + minDiff_fix)); + peMin_fix = + (INT)(currPe - fMultI(fDivNorm(partLo_fix, (partLo_fix + partHi_fix)), + minDiff_fix)); + peMin_fix = fixMax(0, peMin_fix); - *peMax = peMax_fix; - *peMin = peMin_fix; - } + *peMax = peMax_fix; + *peMin = peMin_fix; + } } - - /***************************************************************************** functionname: BitresCalcBitFac @@ -2115,206 +2354,223 @@ static void FDKaacEnc_adjustPeMinMax(const INT currPe, pemin */ -static FIXP_DBL FDKaacEnc_bitresCalcBitFac(const INT bitresBits, - const INT maxBitresBits, - const INT pe, - const INT lastWindowSequence, - const INT avgBits, - const FIXP_DBL maxBitFac, - ADJ_THR_STATE *AdjThr, - ATS_ELEMENT *adjThrChan) -{ - BRES_PARAM *bresParam; - INT pex; +void FDKaacEnc_bitresCalcBitFac(const INT bitresBits, const INT maxBitresBits, + const INT pe, const INT lastWindowSequence, + const INT avgBits, const FIXP_DBL maxBitFac, + const ADJ_THR_STATE *const AdjThr, + ATS_ELEMENT *const adjThrChan, + FIXP_DBL *const pBitresFac, + INT *const pBitresFac_e) { + const BRES_PARAM *bresParam; + INT pex; + FIXP_DBL fillLevel; + INT fillLevel_e = 0; + + FIXP_DBL bitresFac; + INT bitresFac_e; + + FIXP_DBL bitSave, bitSpend; + FIXP_DBL bitsave_slope, bitspend_slope; + FIXP_DBL fillLevel_fix = MAXVAL_DBL; + + FIXP_DBL slope = MAXVAL_DBL; + + if (lastWindowSequence != SHORT_WINDOW) { + bresParam = &(AdjThr->bresParamLong); + bitsave_slope = FL2FXCONST_DBL(0.466666666); + bitspend_slope = FL2FXCONST_DBL(0.666666666); + } else { + bresParam = &(AdjThr->bresParamShort); + bitsave_slope = (FIXP_DBL)0x2E8BA2E9; + bitspend_slope = (FIXP_DBL)0x7fffffff; + } + + // fillLevel = (float)(bitresBits+avgBits) / (float)(maxBitresBits + avgBits); + if (bitresBits < maxBitresBits) { + fillLevel_fix = fDivNorm(bitresBits, maxBitresBits); + } - INT qmin, qbr, qbres, qmbr; - FIXP_DBL bitSave, bitSpend; + pex = fMax(pe, adjThrChan->peMin); + pex = fMin(pex, adjThrChan->peMax); - FIXP_DBL bitresFac_fix, tmp_cst, tmp_fix; - FIXP_DBL pe_pers, bits_ratio, maxBrVal; - FIXP_DBL bitsave_slope, bitspend_slope, maxBitFac_tmp; - FIXP_DBL fillLevel_fix = (FIXP_DBL)0x7fffffff; - FIXP_DBL UNITY = (FIXP_DBL)0x7fffffff; - FIXP_DBL POINT7 = (FIXP_DBL)0x5999999A; + bitSave = FDKaacEnc_calcBitSave( + fillLevel_fix, bresParam->clipSaveLow, bresParam->clipSaveHigh, + bresParam->minBitSave, bresParam->maxBitSave, bitsave_slope); - if (maxBitresBits > bitresBits) { - fillLevel_fix = fDivNorm(bitresBits, maxBitresBits); - } + bitSpend = FDKaacEnc_calcBitSpend( + fillLevel_fix, bresParam->clipSpendLow, bresParam->clipSpendHigh, + bresParam->minBitSpend, bresParam->maxBitSpend, bitspend_slope); - if (lastWindowSequence != SHORT_WINDOW) - { - bresParam = &(AdjThr->bresParamLong); - bitsave_slope = (FIXP_DBL)0x3BBBBBBC; - bitspend_slope = (FIXP_DBL)0x55555555; - } - else - { - bresParam = &(AdjThr->bresParamShort); - bitsave_slope = (FIXP_DBL)0x2E8BA2E9; - bitspend_slope = (FIXP_DBL)0x7fffffff; - } + slope = schur_div((pex - adjThrChan->peMin), + (adjThrChan->peMax - adjThrChan->peMin), 31); - pex = fixMax(pe, adjThrChan->peMin); - pex = fixMin(pex, adjThrChan->peMax); - - bitSave = FDKaacEnc_calcBitSave(fillLevel_fix, - bresParam->clipSaveLow, bresParam->clipSaveHigh, - bresParam->minBitSave, bresParam->maxBitSave, bitsave_slope); - - bitSpend = FDKaacEnc_calcBitSpend(fillLevel_fix, - bresParam->clipSpendLow, bresParam->clipSpendHigh, - bresParam->minBitSpend, bresParam->maxBitSpend, bitspend_slope); - - pe_pers = (pex > adjThrChan->peMin) ? fDivNorm(pex - adjThrChan->peMin, adjThrChan->peMax - adjThrChan->peMin) : 0; - tmp_fix = fMult(((FIXP_DBL)bitSpend + (FIXP_DBL)bitSave), pe_pers); - bitresFac_fix = (UNITY>>1) - ((FIXP_DBL)bitSave>>1) + (tmp_fix>>1); qbres = (DFRACT_BITS-2); - - /* (float)bitresBits/(float)avgBits */ - bits_ratio = fDivNorm(bitresBits, avgBits, &qbr); - qbr = DFRACT_BITS-1-qbr; - - /* Add 0.7 in q31 to bits_ratio in qbr */ - /* 0.7f + (float)bitresBits/(float)avgBits */ - qmin = fixMin(qbr, (DFRACT_BITS-1)); - bits_ratio = bits_ratio >> (qbr - qmin); - tmp_cst = POINT7 >> ((DFRACT_BITS-1) - qmin); - maxBrVal = (bits_ratio>>1) + (tmp_cst>>1); qmbr = qmin - 1; - - /* bitresFac_fix = fixMin(bitresFac_fix, 0.7 + bitresBits/avgBits); */ - bitresFac_fix = bitresFac_fix >> (qbres - qmbr); qbres = qmbr; - bitresFac_fix = fixMin(bitresFac_fix, maxBrVal); - - /* Compare with maxBitFac */ - qmin = fixMin(Q_BITFAC, qbres); - bitresFac_fix = bitresFac_fix >> (qbres - qmin); - maxBitFac_tmp = maxBitFac >> (Q_BITFAC - qmin); - if(maxBitFac_tmp < bitresFac_fix) - { - bitresFac_fix = maxBitFac; - } - else - { - if(qmin < Q_BITFAC) - { - bitresFac_fix = bitresFac_fix << (Q_BITFAC-qmin); - } - else - { - bitresFac_fix = bitresFac_fix >> (qmin-Q_BITFAC); - } - } + /* scale down by 1 bit because the result of the following addition can be + * bigger than 1 (though smaller than 2) */ + bitresFac = ((FIXP_DBL)(MAXVAL_DBL >> 1) - (bitSave >> 1)); + bitresFac_e = 1; /* exp=1 */ + bitresFac = fMultAddDiv2(bitresFac, slope, bitSpend + bitSave); /* exp=1 */ - FDKaacEnc_adjustPeMinMax(pe, &adjThrChan->peMin, &adjThrChan->peMax); + /*** limit bitresFac for small bitreservoir ***/ + fillLevel = fDivNorm(bitresBits, avgBits, &fillLevel_e); + if (fillLevel_e < 0) { + fillLevel = scaleValue(fillLevel, fillLevel_e); + fillLevel_e = 0; + } + /* shift down value by 1 because of summation, ... */ + fillLevel >>= 1; + fillLevel_e += 1; + /* ..., this summation: */ + fillLevel += scaleValue(FL2FXCONST_DBL(0.7f), -fillLevel_e); + /* set bitresfactor to same exponent as fillLevel */ + if (scaleValue(bitresFac, -fillLevel_e + 1) > fillLevel) { + bitresFac = fillLevel; + bitresFac_e = fillLevel_e; + } - return bitresFac_fix; -} + /* limit bitresFac for high bitrates */ + if (scaleValue(bitresFac, bitresFac_e - (DFRACT_BITS - 1 - 24)) > maxBitFac) { + bitresFac = maxBitFac; + bitresFac_e = (DFRACT_BITS - 1 - 24); + } + FDKaacEnc_adjustPeMinMax(pe, &adjThrChan->peMin, &adjThrChan->peMax); + + /* output values */ + *pBitresFac = bitresFac; + *pBitresFac_e = bitresFac_e; +} /***************************************************************************** functionname: FDKaacEnc_AdjThrNew description: allocate ADJ_THR_STATE *****************************************************************************/ -INT FDKaacEnc_AdjThrNew(ADJ_THR_STATE** phAdjThr, - INT nElements) -{ - INT err = 0; - INT i; - ADJ_THR_STATE* hAdjThr = GetRam_aacEnc_AdjustThreshold(); - if (hAdjThr==NULL) { - err = 1; - goto bail; - } +INT FDKaacEnc_AdjThrNew(ADJ_THR_STATE **phAdjThr, INT nElements) { + INT err = 0; + INT i; + ADJ_THR_STATE *hAdjThr = GetRam_aacEnc_AdjustThreshold(); + if (hAdjThr == NULL) { + err = 1; + goto bail; + } - for (i=0; iadjThrStateElem[i] = GetRam_aacEnc_AdjThrStateElement(i); - if (hAdjThr->adjThrStateElem[i]==NULL) { - err = 1; - goto bail; - } + for (i = 0; i < nElements; i++) { + hAdjThr->adjThrStateElem[i] = GetRam_aacEnc_AdjThrStateElement(i); + if (hAdjThr->adjThrStateElem[i] == NULL) { + err = 1; + goto bail; } + } bail: - *phAdjThr = hAdjThr; - return err; + *phAdjThr = hAdjThr; + return err; } - /***************************************************************************** functionname: FDKaacEnc_AdjThrInit description: initialize ADJ_THR_STATE *****************************************************************************/ void FDKaacEnc_AdjThrInit( - ADJ_THR_STATE *hAdjThr, - const INT meanPe, - ELEMENT_BITS *elBits[(8)], - INT invQuant, - INT nElements, - INT nChannelsEff, - INT sampleRate, - INT advancedBitsToPe, - FIXP_DBL vbrQualFactor, - const INT dZoneQuantEnable - ) -{ + ADJ_THR_STATE *const hAdjThr, const INT meanPe, const INT invQuant, + const CHANNEL_MAPPING *const channelMapping, const INT sampleRate, + const INT totalBitrate, const INT isLowDelay, + const AACENC_BITRES_MODE bitResMode, const INT dZoneQuantEnable, + const INT bitDistributionMode, const FIXP_DBL vbrQualFactor) { INT i; FIXP_DBL POINT8 = FL2FXCONST_DBL(0.8f); FIXP_DBL POINT6 = FL2FXCONST_DBL(0.6f); - /* Max number of iterations in second guess is 3 for lowdelay aot and for configurations with - multiple audio elements in general, otherwise iteration value is always 1. */ - hAdjThr->maxIter2ndGuess = (advancedBitsToPe!=0 || nElements>1) ? 3 : 1; + if (bitDistributionMode == 1) { + hAdjThr->bitDistributionMode = AACENC_BD_MODE_INTRA_ELEMENT; + } else { + hAdjThr->bitDistributionMode = AACENC_BD_MODE_INTER_ELEMENT; + } + + /* Max number of iterations in second guess is 3 for lowdelay aot and for + configurations with multiple audio elements in general, otherwise iteration + value is always 1. */ + hAdjThr->maxIter2ndGuess = + (isLowDelay != 0 || channelMapping->nElements > 1) ? 3 : 1; /* common for all elements: */ /* parameters for bitres control */ - hAdjThr->bresParamLong.clipSaveLow = (FIXP_DBL)0x1999999a; /* FL2FXCONST_DBL(0.2f); */ - hAdjThr->bresParamLong.clipSaveHigh = (FIXP_DBL)0x7999999a; /* FL2FXCONST_DBL(0.95f); */ - hAdjThr->bresParamLong.minBitSave = (FIXP_DBL)0xf999999a; /* FL2FXCONST_DBL(-0.05f); */ - hAdjThr->bresParamLong.maxBitSave = (FIXP_DBL)0x26666666; /* FL2FXCONST_DBL(0.3f); */ - hAdjThr->bresParamLong.clipSpendLow = (FIXP_DBL)0x1999999a; /* FL2FXCONST_DBL(0.2f); */ - hAdjThr->bresParamLong.clipSpendHigh = (FIXP_DBL)0x7999999a; /* FL2FXCONST_DBL(0.95f); */ - hAdjThr->bresParamLong.minBitSpend = (FIXP_DBL)0xf3333333; /* FL2FXCONST_DBL(-0.10f); */ - hAdjThr->bresParamLong.maxBitSpend = (FIXP_DBL)0x33333333; /* FL2FXCONST_DBL(0.4f); */ - - hAdjThr->bresParamShort.clipSaveLow = (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */ - hAdjThr->bresParamShort.clipSaveHigh = (FIXP_DBL)0x5fffffff; /* FL2FXCONST_DBL(0.75f); */ - hAdjThr->bresParamShort.minBitSave = (FIXP_DBL)0x00000000; /* FL2FXCONST_DBL(0.0f); */ - hAdjThr->bresParamShort.maxBitSave = (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */ - hAdjThr->bresParamShort.clipSpendLow = (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */ - hAdjThr->bresParamShort.clipSpendHigh = (FIXP_DBL)0x5fffffff; /* FL2FXCONST_DBL(0.75f); */ - hAdjThr->bresParamShort.minBitSpend = (FIXP_DBL)0xf9999998; /* FL2FXCONST_DBL(-0.05f); */ - hAdjThr->bresParamShort.maxBitSpend = (FIXP_DBL)0x40000000; /* FL2FXCONST_DBL(0.5f); */ + hAdjThr->bresParamLong.clipSaveLow = + (FIXP_DBL)0x1999999a; /* FL2FXCONST_DBL(0.2f); */ + hAdjThr->bresParamLong.clipSaveHigh = + (FIXP_DBL)0x7999999a; /* FL2FXCONST_DBL(0.95f); */ + hAdjThr->bresParamLong.minBitSave = + (FIXP_DBL)0xf999999a; /* FL2FXCONST_DBL(-0.05f); */ + hAdjThr->bresParamLong.maxBitSave = + (FIXP_DBL)0x26666666; /* FL2FXCONST_DBL(0.3f); */ + hAdjThr->bresParamLong.clipSpendLow = + (FIXP_DBL)0x1999999a; /* FL2FXCONST_DBL(0.2f); */ + hAdjThr->bresParamLong.clipSpendHigh = + (FIXP_DBL)0x7999999a; /* FL2FXCONST_DBL(0.95f); */ + hAdjThr->bresParamLong.minBitSpend = + (FIXP_DBL)0xf3333333; /* FL2FXCONST_DBL(-0.10f); */ + hAdjThr->bresParamLong.maxBitSpend = + (FIXP_DBL)0x33333333; /* FL2FXCONST_DBL(0.4f); */ + + hAdjThr->bresParamShort.clipSaveLow = + (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */ + hAdjThr->bresParamShort.clipSaveHigh = + (FIXP_DBL)0x5fffffff; /* FL2FXCONST_DBL(0.75f); */ + hAdjThr->bresParamShort.minBitSave = + (FIXP_DBL)0x00000000; /* FL2FXCONST_DBL(0.0f); */ + hAdjThr->bresParamShort.maxBitSave = + (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */ + hAdjThr->bresParamShort.clipSpendLow = + (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */ + hAdjThr->bresParamShort.clipSpendHigh = + (FIXP_DBL)0x5fffffff; /* FL2FXCONST_DBL(0.75f); */ + hAdjThr->bresParamShort.minBitSpend = + (FIXP_DBL)0xf9999998; /* FL2FXCONST_DBL(-0.05f); */ + hAdjThr->bresParamShort.maxBitSpend = + (FIXP_DBL)0x40000000; /* FL2FXCONST_DBL(0.5f); */ /* specific for each element: */ - for (i=0; iadjThrStateElem[i]; + for (i = 0; i < channelMapping->nElements; i++) { + const FIXP_DBL relativeBits = channelMapping->elInfo[i].relativeBits; + const INT nChannelsInElement = channelMapping->elInfo[i].nChannelsInEl; + const INT bitrateInElement = + (relativeBits != (FIXP_DBL)MAXVAL_DBL) + ? (INT)fMultNorm(relativeBits, (FIXP_DBL)totalBitrate) + : totalBitrate; + const INT chBitrate = bitrateInElement >> (nChannelsInElement == 1 ? 0 : 1); + + ATS_ELEMENT *atsElem = hAdjThr->adjThrStateElem[i]; MINSNR_ADAPT_PARAM *msaParam = &atsElem->minSnrAdaptParam; - INT chBitrate = elBits[i]->chBitrateEl; /* parameters for bitres control */ - atsElem->peMin = fMultI(POINT8, meanPe) >> 1; - atsElem->peMax = fMultI(POINT6, meanPe); + if (isLowDelay) { + atsElem->peMin = fMultI(POINT8, meanPe); + atsElem->peMax = fMultI(POINT6, meanPe) << 1; + } else { + atsElem->peMin = fMultI(POINT8, meanPe) >> 1; + atsElem->peMax = fMultI(POINT6, meanPe); + } /* for use in FDKaacEnc_reduceThresholdsVBR */ atsElem->chaosMeasureOld = FL2FXCONST_DBL(0.3f); /* additional pe offset to correct pe2bits for low bitrates */ + /* ---- no longer necessary, set by table ----- */ atsElem->peOffset = 0; /* vbr initialisation */ atsElem->vbrQualFactor = vbrQualFactor; - if (chBitrate < 32000) - { - atsElem->peOffset = fixMax(50, 100-fMultI((FIXP_DBL)0x666667, chBitrate)); + if (chBitrate < 32000) { + atsElem->peOffset = + fixMax(50, 100 - fMultI((FIXP_DBL)0x666667, chBitrate)); } /* avoid hole parameters */ - if (chBitrate > 20000) { + if (chBitrate >= 20000) { atsElem->ahParam.modifyMinSnr = TRUE; atsElem->ahParam.startSfbL = 15; atsElem->ahParam.startSfbS = 3; - } - else { + } else { atsElem->ahParam.modifyMinSnr = FALSE; atsElem->ahParam.startSfbL = 0; atsElem->ahParam.startSfbS = 0; @@ -2327,9 +2583,11 @@ void FDKaacEnc_AdjThrInit( /* maximum minSnr reduction to minSnr^maxRed is reached for avgEn/sfbEn >= maxRatio */ /* msaParam->maxRatio = 1000.0f; */ - /*msaParam->redRatioFac = ((float)1.0f - msaParam->maxRed) / ((float)10.0f*log10(msaParam->startRatio/msaParam->maxRatio)/log10(2.0f)*(float)0.3010299956f);*/ + /*msaParam->redRatioFac = ((float)1.0f - msaParam->maxRed) / + * ((float)10.0f*log10(msaParam->startRatio/msaParam->maxRatio)/log10(2.0f)*(float)0.3010299956f);*/ msaParam->redRatioFac = FL2FXCONST_DBL(-0.375f); /* -0.0375f * 10.0f */ - /*msaParam->redOffs = (float)1.0f - msaParam->redRatioFac * (float)10.0f * log10(msaParam->startRatio)/log10(2.0f) * (float)0.3010299956f;*/ + /*msaParam->redOffs = (float)1.0f - msaParam->redRatioFac * (float)10.0f * + * log10(msaParam->startRatio)/log10(2.0f) * (float)0.3010299956f;*/ msaParam->redOffs = FL2FXCONST_DBL(0.021484375); /* 1.375f/64.0f */ /* init pe correction */ @@ -2343,324 +2601,324 @@ void FDKaacEnc_AdjThrInit( /* init bits2PeFactor */ FDKaacEnc_InitBits2PeFactor( - &atsElem->bits2PeFactor_m, - &atsElem->bits2PeFactor_e, - chBitrate*nChannelsEff, /* overall bitrate */ - nChannelsEff, /* number of channels */ - sampleRate, - advancedBitsToPe, - dZoneQuantEnable, - invQuant - ); + &atsElem->bits2PeFactor_m, &atsElem->bits2PeFactor_e, bitrateInElement, + nChannelsInElement, sampleRate, isLowDelay, dZoneQuantEnable, invQuant); } /* for nElements */ - } - /***************************************************************************** functionname: FDKaacEnc_FDKaacEnc_calcPeCorrection description: calc desired pe *****************************************************************************/ static void FDKaacEnc_FDKaacEnc_calcPeCorrection( - FIXP_DBL *const correctionFac_m, - INT *const correctionFac_e, - const INT peAct, - const INT peLast, - const INT bitsLast, - const FIXP_DBL bits2PeFactor_m, - const INT bits2PeFactor_e - ) -{ - if ( (bitsLast > 0) && (peAct < 1.5f*peLast) && (peAct > 0.7f*peLast) && - (FDKaacEnc_bits2pe2(bitsLast, fMult(FL2FXCONST_DBL(1.2f/2.f), bits2PeFactor_m), bits2PeFactor_e+1) > peLast) && - (FDKaacEnc_bits2pe2(bitsLast, fMult(FL2FXCONST_DBL(0.65f), bits2PeFactor_m), bits2PeFactor_e ) < peLast) ) - { + FIXP_DBL *const correctionFac_m, INT *const correctionFac_e, + const INT peAct, const INT peLast, const INT bitsLast, + const FIXP_DBL bits2PeFactor_m, const INT bits2PeFactor_e) { + if ((bitsLast > 0) && (peAct < 1.5f * peLast) && (peAct > 0.7f * peLast) && + (FDKaacEnc_bits2pe2(bitsLast, + fMult(FL2FXCONST_DBL(1.2f / 2.f), bits2PeFactor_m), + bits2PeFactor_e + 1) > peLast) && + (FDKaacEnc_bits2pe2(bitsLast, + fMult(FL2FXCONST_DBL(0.65f), bits2PeFactor_m), + bits2PeFactor_e) < peLast)) { FIXP_DBL corrFac = *correctionFac_m; int scaling = 0; - FIXP_DBL denum = (FIXP_DBL)FDKaacEnc_bits2pe2(bitsLast, bits2PeFactor_m, bits2PeFactor_e); + FIXP_DBL denum = (FIXP_DBL)FDKaacEnc_bits2pe2(bitsLast, bits2PeFactor_m, + bits2PeFactor_e); FIXP_DBL newFac = fDivNorm((FIXP_DBL)peLast, denum, &scaling); /* dead zone, newFac and corrFac are scaled by 0.5 */ if ((FIXP_DBL)peLast <= denum) { /* ratio <= 1.f */ - newFac = fixMax(scaleValue(fixMin( fMult(FL2FXCONST_DBL(1.1f/2.f), newFac), scaleValue(FL2FXCONST_DBL( 1.f/2.f), -scaling)), scaling), FL2FXCONST_DBL(0.85f/2.f) ); - } - else { /* ratio < 1.f */ - newFac = fixMax( fixMin( scaleValue(fMult(FL2FXCONST_DBL(0.9f/2.f), newFac), scaling), FL2FXCONST_DBL(1.15f/2.f) ), FL2FXCONST_DBL( 1.f/2.f) ); + newFac = fixMax( + scaleValue(fixMin(fMult(FL2FXCONST_DBL(1.1f / 2.f), newFac), + scaleValue(FL2FXCONST_DBL(1.f / 2.f), -scaling)), + scaling), + FL2FXCONST_DBL(0.85f / 2.f)); + } else { /* ratio < 1.f */ + newFac = fixMax( + fixMin(scaleValue(fMult(FL2FXCONST_DBL(0.9f / 2.f), newFac), scaling), + FL2FXCONST_DBL(1.15f / 2.f)), + FL2FXCONST_DBL(1.f / 2.f)); } - if ( ((newFac > FL2FXCONST_DBL(1.f/2.f)) && (corrFac < FL2FXCONST_DBL(1.f/2.f))) - || ((newFac < FL2FXCONST_DBL(1.f/2.f)) && (corrFac > FL2FXCONST_DBL(1.f/2.f)))) - { - corrFac = FL2FXCONST_DBL(1.f/2.f); + if (((newFac > FL2FXCONST_DBL(1.f / 2.f)) && + (corrFac < FL2FXCONST_DBL(1.f / 2.f))) || + ((newFac < FL2FXCONST_DBL(1.f / 2.f)) && + (corrFac > FL2FXCONST_DBL(1.f / 2.f)))) { + corrFac = FL2FXCONST_DBL(1.f / 2.f); } /* faster adaptation towards 1.0, slower in the other direction */ - if ( (corrFac < FL2FXCONST_DBL(1.f/2.f) && newFac < corrFac) - || (corrFac > FL2FXCONST_DBL(1.f/2.f) && newFac > corrFac) ) - { - corrFac = fMult(FL2FXCONST_DBL(0.85f), corrFac) + fMult(FL2FXCONST_DBL(0.15f), newFac); - } - else { - corrFac = fMult(FL2FXCONST_DBL(0.7f), corrFac) + fMult(FL2FXCONST_DBL(0.3f), newFac); + if ((corrFac < FL2FXCONST_DBL(1.f / 2.f) && newFac < corrFac) || + (corrFac > FL2FXCONST_DBL(1.f / 2.f) && newFac > corrFac)) { + corrFac = fMult(FL2FXCONST_DBL(0.85f), corrFac) + + fMult(FL2FXCONST_DBL(0.15f), newFac); + } else { + corrFac = fMult(FL2FXCONST_DBL(0.7f), corrFac) + + fMult(FL2FXCONST_DBL(0.3f), newFac); } - corrFac = fixMax( fixMin( corrFac, FL2FXCONST_DBL(1.15f/2.f) ), FL2FXCONST_DBL(0.85/2.f) ); + corrFac = fixMax(fixMin(corrFac, FL2FXCONST_DBL(1.15f / 2.f)), + FL2FXCONST_DBL(0.85 / 2.f)); *correctionFac_m = corrFac; *correctionFac_e = 1; - } - else { - *correctionFac_m = FL2FXCONST_DBL(1.f/2.f); + } else { + *correctionFac_m = FL2FXCONST_DBL(1.f / 2.f); *correctionFac_e = 1; } } - static void FDKaacEnc_calcPeCorrectionLowBitRes( - FIXP_DBL *const correctionFac_m, - INT *const correctionFac_e, - const INT peLast, - const INT bitsLast, - const INT bitresLevel, - const INT nChannels, - const FIXP_DBL bits2PeFactor_m, - const INT bits2PeFactor_e - ) -{ + FIXP_DBL *const correctionFac_m, INT *const correctionFac_e, + const INT peLast, const INT bitsLast, const INT bitresLevel, + const INT nChannels, const FIXP_DBL bits2PeFactor_m, + const INT bits2PeFactor_e) { /* tuning params */ - const FIXP_DBL amp = FL2FXCONST_DBL(0.005); + const FIXP_DBL amp = FL2FXCONST_DBL(0.005); const FIXP_DBL maxDiff = FL2FXCONST_DBL(0.25f); if (bitsLast > 0) { - - /* Estimate deviation of granted and used dynamic bits in previous frame, in PE units */ - const int bitsBalLast = peLast - FDKaacEnc_bits2pe2( - bitsLast, - bits2PeFactor_m, - bits2PeFactor_e); + /* Estimate deviation of granted and used dynamic bits in previous frame, in + * PE units */ + const int bitsBalLast = + peLast - FDKaacEnc_bits2pe2(bitsLast, bits2PeFactor_m, bits2PeFactor_e); /* reserve n bits per channel */ - int headroom = (bitresLevel>=50*nChannels) ? 0 : (100*nChannels); + int headroom = (bitresLevel >= 50 * nChannels) ? 0 : (100 * nChannels); /* in PE units */ - headroom = FDKaacEnc_bits2pe2( - headroom, - bits2PeFactor_m, - bits2PeFactor_e); + headroom = FDKaacEnc_bits2pe2(headroom, bits2PeFactor_m, bits2PeFactor_e); /* * diff = amp * ((bitsBalLast - headroom) / (bitresLevel + headroom) * diff = max ( min ( diff, maxDiff, -maxDiff)) / 2 */ - FIXP_DBL denominator = (FIXP_DBL)FDKaacEnc_bits2pe2(bitresLevel, bits2PeFactor_m, bits2PeFactor_e) + (FIXP_DBL)headroom; + FIXP_DBL denominator = (FIXP_DBL)FDKaacEnc_bits2pe2( + bitresLevel, bits2PeFactor_m, bits2PeFactor_e) + + (FIXP_DBL)headroom; int scaling = 0; - FIXP_DBL diff = (bitsBalLast>=headroom) - ? fMult(amp, fDivNorm( (FIXP_DBL)(bitsBalLast - headroom), denominator, &scaling)) - : -fMult(amp, fDivNorm(-(FIXP_DBL)(bitsBalLast - headroom), denominator, &scaling)) ; + FIXP_DBL diff = + (bitsBalLast >= headroom) + ? fMult(amp, fDivNorm((FIXP_DBL)(bitsBalLast - headroom), + denominator, &scaling)) + : -fMult(amp, fDivNorm(-(FIXP_DBL)(bitsBalLast - headroom), + denominator, &scaling)); scaling -= 1; /* divide by 2 */ - diff = (scaling<=0) ? FDKmax( FDKmin (diff>>(-scaling), maxDiff>>1), -maxDiff>>1) - : FDKmax( FDKmin (diff, maxDiff>>(1+scaling)), -maxDiff>>(1+scaling)) << scaling; + diff = (scaling <= 0) + ? fMax(fMin(diff >> (-scaling), maxDiff >> 1), -maxDiff >> 1) + : fMax(fMin(diff, maxDiff >> (1 + scaling)), + -maxDiff >> (1 + scaling)) + << scaling; /* * corrFac += diff * corrFac = max ( min ( corrFac/2.f, 1.f/2.f, 0.75f/2.f ) ) */ - *correctionFac_m = FDKmax(FDKmin((*correctionFac_m)+diff, FL2FXCONST_DBL(1.0f/2.f)), FL2FXCONST_DBL(0.75f/2.f)) ; + *correctionFac_m = + fMax(fMin((*correctionFac_m) + diff, FL2FXCONST_DBL(1.0f / 2.f)), + FL2FXCONST_DBL(0.75f / 2.f)); *correctionFac_e = 1; - } - else { - *correctionFac_m = FL2FXCONST_DBL(0.75/2.f); + } else { + *correctionFac_m = FL2FXCONST_DBL(0.75 / 2.f); *correctionFac_e = 1; } } -void FDKaacEnc_DistributeBits(ADJ_THR_STATE *adjThrState, - ATS_ELEMENT *AdjThrStateElement, - PSY_OUT_CHANNEL *psyOutChannel[(2)], - PE_DATA *peData, - INT *grantedPe, - INT *grantedPeCorr, - const INT nChannels, - const INT commonWindow, - const INT grantedDynBits, - const INT bitresBits, - const INT maxBitresBits, - const FIXP_DBL maxBitFac, - const INT bitDistributionMode) -{ +void FDKaacEnc_DistributeBits( + ADJ_THR_STATE *adjThrState, ATS_ELEMENT *AdjThrStateElement, + PSY_OUT_CHANNEL *psyOutChannel[(2)], PE_DATA *peData, INT *grantedPe, + INT *grantedPeCorr, const INT nChannels, const INT commonWindow, + const INT grantedDynBits, const INT bitresBits, const INT maxBitresBits, + const FIXP_DBL maxBitFac, const AACENC_BITRES_MODE bitResMode) { FIXP_DBL bitFactor; + INT bitFactor_e; INT noRedPe = peData->pe; /* prefer short windows for calculation of bitFactor */ INT curWindowSequence = LONG_WINDOW; - if (nChannels==2) { + if (nChannels == 2) { if ((psyOutChannel[0]->lastWindowSequence == SHORT_WINDOW) || (psyOutChannel[1]->lastWindowSequence == SHORT_WINDOW)) { - curWindowSequence = SHORT_WINDOW; + curWindowSequence = SHORT_WINDOW; } - } - else { + } else { curWindowSequence = psyOutChannel[0]->lastWindowSequence; } if (grantedDynBits >= 1) { - if (bitDistributionMode!=0) { - *grantedPe = FDKaacEnc_bits2pe2(grantedDynBits, AdjThrStateElement->bits2PeFactor_m, AdjThrStateElement->bits2PeFactor_e); - } - else - { - /* factor dependend on current fill level and pe */ - bitFactor = FDKaacEnc_bitresCalcBitFac(bitresBits, maxBitresBits, noRedPe, - curWindowSequence, grantedDynBits, maxBitFac, - adjThrState, - AdjThrStateElement - ); - - /* desired pe for actual frame */ - /* Worst case max of grantedDynBits is = 1024 * 5.27 * 2 */ - *grantedPe = FDKaacEnc_bits2pe2(grantedDynBits, - fMult(bitFactor, AdjThrStateElement->bits2PeFactor_m), AdjThrStateElement->bits2PeFactor_e+(DFRACT_BITS-1-Q_BITFAC) - ); + if (bitResMode != AACENC_BR_MODE_FULL) { + /* small or disabled bitreservoir */ + *grantedPe = FDKaacEnc_bits2pe2(grantedDynBits, + AdjThrStateElement->bits2PeFactor_m, + AdjThrStateElement->bits2PeFactor_e); + } else { + /* factor dependend on current fill level and pe */ + FDKaacEnc_bitresCalcBitFac( + bitresBits, maxBitresBits, noRedPe, curWindowSequence, grantedDynBits, + maxBitFac, adjThrState, AdjThrStateElement, &bitFactor, &bitFactor_e); + + /* desired pe for actual frame */ + /* Worst case max of grantedDynBits is = 1024 * 5.27 * 2 */ + *grantedPe = FDKaacEnc_bits2pe2( + grantedDynBits, fMult(bitFactor, AdjThrStateElement->bits2PeFactor_m), + AdjThrStateElement->bits2PeFactor_e + bitFactor_e); } - } - else { + } else { *grantedPe = 0; /* prevent divsion by 0 */ } /* correction of pe value */ - switch (bitDistributionMode) { - case 2: - case 1: - FDKaacEnc_calcPeCorrectionLowBitRes( - &AdjThrStateElement->peCorrectionFactor_m, - &AdjThrStateElement->peCorrectionFactor_e, - AdjThrStateElement->peLast, - AdjThrStateElement->dynBitsLast, - bitresBits, - nChannels, - AdjThrStateElement->bits2PeFactor_m, - AdjThrStateElement->bits2PeFactor_e - ); - break; - case 0: - default: + switch (bitResMode) { + case AACENC_BR_MODE_DISABLED: + case AACENC_BR_MODE_REDUCED: + /* correction of pe value for low bitres */ + FDKaacEnc_calcPeCorrectionLowBitRes( + &AdjThrStateElement->peCorrectionFactor_m, + &AdjThrStateElement->peCorrectionFactor_e, AdjThrStateElement->peLast, + AdjThrStateElement->dynBitsLast, bitresBits, nChannels, + AdjThrStateElement->bits2PeFactor_m, + AdjThrStateElement->bits2PeFactor_e); + break; + case AACENC_BR_MODE_FULL: + default: + /* correction of pe value for high bitres */ FDKaacEnc_FDKaacEnc_calcPeCorrection( - &AdjThrStateElement->peCorrectionFactor_m, - &AdjThrStateElement->peCorrectionFactor_e, - fixMin(*grantedPe, noRedPe), - AdjThrStateElement->peLast, - AdjThrStateElement->dynBitsLast, - AdjThrStateElement->bits2PeFactor_m, - AdjThrStateElement->bits2PeFactor_e - ); - break; + &AdjThrStateElement->peCorrectionFactor_m, + &AdjThrStateElement->peCorrectionFactor_e, + fixMin(*grantedPe, noRedPe), AdjThrStateElement->peLast, + AdjThrStateElement->dynBitsLast, AdjThrStateElement->bits2PeFactor_m, + AdjThrStateElement->bits2PeFactor_e); + break; } - *grantedPeCorr = (INT)(fMult((FIXP_DBL)(*grantedPe<peCorrectionFactor_m) >> (Q_AVGBITS-AdjThrStateElement->peCorrectionFactor_e)); + *grantedPeCorr = + (INT)(fMult((FIXP_DBL)(*grantedPe << Q_AVGBITS), + AdjThrStateElement->peCorrectionFactor_m) >> + (Q_AVGBITS - AdjThrStateElement->peCorrectionFactor_e)); /* update last pe */ AdjThrStateElement->peLast = *grantedPe; AdjThrStateElement->dynBitsLast = -1; - } /***************************************************************************** functionname: FDKaacEnc_AdjustThresholds description: adjust thresholds *****************************************************************************/ -void FDKaacEnc_AdjustThresholds(ATS_ELEMENT* AdjThrStateElement[(8)], - QC_OUT_ELEMENT* qcElement[(8)], - QC_OUT* qcOut, - PSY_OUT_ELEMENT* psyOutElement[(8)], - INT CBRbitrateMode, - INT maxIter2ndGuess, - CHANNEL_MAPPING* cm) -{ - int i; - if (CBRbitrateMode) - { - /* In case, no bits must be shifted between different elements, */ - /* an element-wise execution of the pe-dependent threshold- */ - /* adaption becomes necessary... */ - for (i=0; inElements; i++) - { - ELEMENT_INFO elInfo = cm->elInfo[i]; - - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - /* qcElement[i]->grantedPe = 2000; */ /* Use this only for debugging */ - //if (totalGrantedPeCorr < totalNoRedPe) { - if (qcElement[i]->grantedPe < qcElement[i]->peData.pe) - { - /* calc threshold necessary for desired pe */ - FDKaacEnc_adaptThresholdsToPe(cm, - AdjThrStateElement, - qcElement, - psyOutElement, - qcElement[i]->grantedPeCorr, - maxIter2ndGuess, - 1, /* Process only 1 element */ - i); /* Process exactly THIS element */ - - } - - } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ - - } /* -end- element loop */ - } - else { - for (i=0; inElements; i++) - { - ELEMENT_INFO elInfo = cm->elInfo[i]; - - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - /* for VBR-mode */ - FDKaacEnc_AdaptThresholdsVBR(qcElement[i]->qcOutChannel, - psyOutElement[i]->psyOutChannel, - AdjThrStateElement[i], - &psyOutElement[i]->toolsInfo, - &qcElement[i]->peData, - cm->elInfo[i].nChannelsInEl); - } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ - - } /* -end- element loop */ - - } - for (i=0; inElements; i++) { - int ch,sfb,sfbGrp; - /* no weighting of threholds and energies for mlout */ - /* weight energies and thresholds */ - for (ch=0; chelInfo[i].nChannelsInEl; ch++) { - QC_OUT_CHANNEL* pQcOutCh = qcElement[i]->qcOutChannel[ch]; - for (sfbGrp = 0;sfbGrp < psyOutElement[i]->psyOutChannel[ch]->sfbCnt; sfbGrp+=psyOutElement[i]->psyOutChannel[ch]->sfbPerGroup) { - for (sfb=0; sfbpsyOutChannel[ch]->maxSfbPerGroup; sfb++) { - pQcOutCh->sfbThresholdLdData[sfb+sfbGrp] += pQcOutCh->sfbEnFacLd[sfb+sfbGrp]; - } +void FDKaacEnc_AdjustThresholds( + ADJ_THR_STATE *const hAdjThr, QC_OUT_ELEMENT *const qcElement[((8))], + QC_OUT *const qcOut, const PSY_OUT_ELEMENT *const psyOutElement[((8))], + const INT CBRbitrateMode, const CHANNEL_MAPPING *const cm) { + int i; + + if (CBRbitrateMode) { + /* In case, no bits must be shifted between different elements, */ + /* an element-wise execution of the pe-dependent threshold- */ + /* adaption becomes necessary... */ + if (hAdjThr->bitDistributionMode == AACENC_BD_MODE_INTRA_ELEMENT) { + for (i = 0; i < cm->nElements; i++) { + ELEMENT_INFO elInfo = cm->elInfo[i]; + + if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || + (elInfo.elType == ID_LFE)) { + /* qcElement[i]->grantedPe = 2000; */ /* Use this only for debugging + */ + // if (totalGrantedPeCorr < totalNoRedPe) { + if (qcElement[i]->grantedPeCorr < qcElement[i]->peData.pe) { + /* calc threshold necessary for desired pe */ + FDKaacEnc_adaptThresholdsToPe( + cm, hAdjThr->adjThrStateElem, qcElement, psyOutElement, + qcElement[i]->grantedPeCorr, hAdjThr->maxIter2ndGuess, + 1, /* Process only 1 element */ + i /* Process exactly THIS element */ + ); + } + } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ + } /* -end- element loop */ + } /* AACENC_BD_MODE_INTRA_ELEMENT */ + else if (hAdjThr->bitDistributionMode == AACENC_BD_MODE_INTER_ELEMENT) { + /* Use global Pe to obtain the thresholds? */ + if (qcOut->totalGrantedPeCorr < qcOut->totalNoRedPe) { + /* add equal loadness quantization noise to match the */ + /* desired pe calc threshold necessary for desired pe */ + /* Now carried out globally to cover all(!) channels. */ + FDKaacEnc_adaptThresholdsToPe(cm, hAdjThr->adjThrStateElem, qcElement, + psyOutElement, qcOut->totalGrantedPeCorr, + hAdjThr->maxIter2ndGuess, + cm->nElements, /* Process all elements */ + 0); /* Process exactly THIS element */ + } else { + /* In case global pe doesn't need to be reduced check each element to + hold estimated bitrate below maximum element bitrate. */ + for (i = 0; i < cm->nElements; i++) { + if ((cm->elInfo[i].elType == ID_SCE) || + (cm->elInfo[i].elType == ID_CPE) || + (cm->elInfo[i].elType == ID_LFE)) { + /* Element pe applies to dynamic bits of maximum element bitrate. */ + const int maxElementPe = FDKaacEnc_bits2pe2( + (cm->elInfo[i].nChannelsInEl * MIN_BUFSIZE_PER_EFF_CHAN) - + qcElement[i]->staticBitsUsed - qcElement[i]->extBitsUsed, + hAdjThr->adjThrStateElem[i]->bits2PeFactor_m, + hAdjThr->adjThrStateElem[i]->bits2PeFactor_e); + + if (maxElementPe < qcElement[i]->peData.pe) { + FDKaacEnc_adaptThresholdsToPe( + cm, hAdjThr->adjThrStateElem, qcElement, psyOutElement, + maxElementPe, hAdjThr->maxIter2ndGuess, 1, i); } + } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ + } /* -end- element loop */ + } /* (qcOut->totalGrantedPeCorr < qcOut->totalNoRedPe) */ + } /* AACENC_BD_MODE_INTER_ELEMENT */ + } else { + for (i = 0; i < cm->nElements; i++) { + ELEMENT_INFO elInfo = cm->elInfo[i]; + + if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || + (elInfo.elType == ID_LFE)) { + /* for VBR-mode */ + FDKaacEnc_AdaptThresholdsVBR( + qcElement[i]->qcOutChannel, psyOutElement[i]->psyOutChannel, + hAdjThr->adjThrStateElem[i], &psyOutElement[i]->toolsInfo, + cm->elInfo[i].nChannelsInEl); + } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ + + } /* -end- element loop */ + } + for (i = 0; i < cm->nElements; i++) { + int ch, sfb, sfbGrp; + /* no weighting of threholds and energies for mlout */ + /* weight energies and thresholds */ + for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) { + QC_OUT_CHANNEL *pQcOutCh = qcElement[i]->qcOutChannel[ch]; + for (sfbGrp = 0; sfbGrp < psyOutElement[i]->psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutElement[i]->psyOutChannel[ch]->sfbPerGroup) { + for (sfb = 0; sfb < psyOutElement[i]->psyOutChannel[ch]->maxSfbPerGroup; + sfb++) { + pQcOutCh->sfbThresholdLdData[sfb + sfbGrp] += + pQcOutCh->sfbEnFacLd[sfb + sfbGrp]; } + } } + } } -void FDKaacEnc_AdjThrClose(ADJ_THR_STATE** phAdjThr) -{ - INT i; - ADJ_THR_STATE* hAdjThr = *phAdjThr; +void FDKaacEnc_AdjThrClose(ADJ_THR_STATE **phAdjThr) { + INT i; + ADJ_THR_STATE *hAdjThr = *phAdjThr; - if (hAdjThr!=NULL) { - for (i=0; i<(8); i++) { - if (hAdjThr->adjThrStateElem[i]!=NULL) { - FreeRam_aacEnc_AdjThrStateElement(&hAdjThr->adjThrStateElem[i]); - } + if (hAdjThr != NULL) { + for (i = 0; i < ((8)); i++) { + if (hAdjThr->adjThrStateElem[i] != NULL) { + FreeRam_aacEnc_AdjThrStateElement(&hAdjThr->adjThrStateElem[i]); } - FreeRam_aacEnc_AdjustThreshold(phAdjThr); } + FreeRam_aacEnc_AdjustThreshold(phAdjThr); + } } - diff --git a/libAACenc/src/adj_thr.h b/libAACenc/src/adj_thr.h index be68c6e..1f5f998 100644 --- a/libAACenc/src/adj_thr.h +++ b/libAACenc/src/adj_thr.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,71 +90,77 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M. Werner - contents/description: Threshold compensation + Author(s): M. Werner -******************************************************************************/ + Description: Threshold compensation -#ifndef __ADJ_THR_H -#define __ADJ_THR_H +*******************************************************************************/ +#ifndef ADJ_THR_H +#define ADJ_THR_H +#include "common_fix.h" #include "adj_thr_data.h" #include "qc_data.h" #include "line_pe.h" #include "interface.h" - -void FDKaacEnc_peCalculation( - PE_DATA *peData, - PSY_OUT_CHANNEL* psyOutChannel[(2)], - QC_OUT_CHANNEL* qcOutChannel[(2)], - struct TOOLSINFO *toolsInfo, - ATS_ELEMENT* adjThrStateElement, - const INT nChannels - ); - -INT FDKaacEnc_AdjThrNew(ADJ_THR_STATE** phAdjThr, - INT nElements); - -void FDKaacEnc_AdjThrInit(ADJ_THR_STATE *hAdjThr, - const INT peMean, - ELEMENT_BITS* elBits[(8)], - INT invQuant, - INT nElements, - INT nChannelsEff, - INT sampleRate, - INT advancedBitsToPe, - FIXP_DBL vbrQualFactor, - const INT dZoneQuantEnable); - - -void FDKaacEnc_DistributeBits(ADJ_THR_STATE *adjThrState, - ATS_ELEMENT *AdjThrStateElement, - PSY_OUT_CHANNEL *psyOutChannel[(2)], - PE_DATA *peData, - INT *grantedPe, - INT *grantedPeCorr, - const INT nChannels, - const INT commonWindow, - const INT avgBits, - const INT bitresBits, - const INT maxBitresBits, - const FIXP_DBL maxBitFac, - const INT bitDistributionMode); - -void FDKaacEnc_AdjustThresholds(ATS_ELEMENT* AdjThrStateElement[(8)], - QC_OUT_ELEMENT* qcElement[(8)], - QC_OUT* qcOut, - PSY_OUT_ELEMENT* psyOutElement[(8)], - INT CBRbitrateMode, - INT maxIter2ndGuess, - CHANNEL_MAPPING* cm); - -void FDKaacEnc_AdjThrClose(ADJ_THR_STATE** hAdjThr); +/***************************************************************************** + functionname: FDKaacEnc_peCalculation + description: +*****************************************************************************/ +void FDKaacEnc_peCalculation(PE_DATA *const peData, + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], + QC_OUT_CHANNEL *const qcOutChannel[(2)], + const struct TOOLSINFO *const toolsInfo, + ATS_ELEMENT *const adjThrStateElement, + const INT nChannels); + +/***************************************************************************** +functionname: FDKaacEnc_AdjThrNew +description: allocate ADJ_THR_STATE +*****************************************************************************/ +INT FDKaacEnc_AdjThrNew(ADJ_THR_STATE **phAdjThr, INT nElements); + +/***************************************************************************** +functionname: FDKaacEnc_AdjThrInit +description: initialize ADJ_THR_STATE +*****************************************************************************/ +void FDKaacEnc_AdjThrInit( + ADJ_THR_STATE *const hAdjThr, const INT meanPe, const INT invQuant, + const CHANNEL_MAPPING *const channelMapping, const INT sampleRate, + const INT totalBitrate, const INT isLowDelay, + const AACENC_BITRES_MODE bitResMode, const INT dZoneQuantEnable, + const INT bitDistributionMode, const FIXP_DBL vbrQualFactor); + +/***************************************************************************** +functionname: FDKaacEnc_DistributeBits +description: +*****************************************************************************/ +void FDKaacEnc_DistributeBits( + ADJ_THR_STATE *adjThrState, ATS_ELEMENT *AdjThrStateElement, + PSY_OUT_CHANNEL *psyOutChannel[(2)], PE_DATA *peData, INT *grantedPe, + INT *grantedPeCorr, const INT nChannels, const INT commonWindow, + const INT avgBits, const INT bitresBits, const INT maxBitresBits, + const FIXP_DBL maxBitFac, const AACENC_BITRES_MODE bitResMode); + +/***************************************************************************** +functionname: FDKaacEnc_AdjustThresholds +description: adjust thresholds +*****************************************************************************/ +void FDKaacEnc_AdjustThresholds( + ADJ_THR_STATE *const hAdjThr, QC_OUT_ELEMENT *const qcElement[((8))], + QC_OUT *const qcOut, const PSY_OUT_ELEMENT *const psyOutElement[((8))], + const INT CBRbitrateMode, const CHANNEL_MAPPING *const cm); + +/***************************************************************************** +functionname: FDKaacEnc_AdjThrClose +description: +*****************************************************************************/ +void FDKaacEnc_AdjThrClose(ADJ_THR_STATE **hAdjThr); #endif diff --git a/libAACenc/src/adj_thr_data.h b/libAACenc/src/adj_thr_data.h index 7c3a191..4cd1299 100644 --- a/libAACenc/src/adj_thr_data.h +++ b/libAACenc/src/adj_thr_data.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,31 +90,42 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/************************* Fast MPEG AAC Audio Encoder ********************** +/**************************** AAC encoder library ****************************** - Initial author: M. Schug / A. Groeschel - contents/description: threshold calculations + Author(s): M. Schug / A. Groeschel -******************************************************************************/ + Description: threshold calculations -#ifndef __ADJ_THR_DATA_H -#define __ADJ_THR_DATA_H +*******************************************************************************/ +#ifndef ADJ_THR_DATA_H +#define ADJ_THR_DATA_H #include "psy_const.h" +typedef enum { + AACENC_BD_MODE_INTER_ELEMENT = 0, + AACENC_BD_MODE_INTRA_ELEMENT = 1 +} AACENC_BIT_DISTRIBUTION_MODE; + +typedef enum { + AACENC_BR_MODE_FULL = 0, + AACENC_BR_MODE_REDUCED = 1, + AACENC_BR_MODE_DISABLED = 2 +} AACENC_BITRES_MODE; + typedef struct { - FIXP_DBL clipSaveLow, clipSaveHigh; - FIXP_DBL minBitSave, maxBitSave; - FIXP_DBL clipSpendLow, clipSpendHigh; - FIXP_DBL minBitSpend, maxBitSpend; + FIXP_DBL clipSaveLow, clipSaveHigh; + FIXP_DBL minBitSave, maxBitSave; + FIXP_DBL clipSpendLow, clipSpendHigh; + FIXP_DBL minBitSpend, maxBitSpend; } BRES_PARAM; typedef struct { - INT modifyMinSnr; - INT startSfbL, startSfbS; + INT modifyMinSnr; + INT startSfbL, startSfbS; } AH_PARAM; typedef struct { @@ -118,19 +140,20 @@ typedef struct { /* parameters for bitreservoir control */ INT peMin, peMax; /* constant offset to pe */ - INT peOffset; + INT peOffset; /* constant PeFactor */ FIXP_DBL bits2PeFactor_m; - INT bits2PeFactor_e; + INT bits2PeFactor_e; /* avoid hole parameters */ AH_PARAM ahParam; - /* values for correction of pe */ - /* paramters for adaptation of minSnr */ + /* parameters for adaptation of minSnr */ MINSNR_ADAPT_PARAM minSnrAdaptParam; + + /* values for correction of pe */ INT peLast; INT dynBitsLast; FIXP_DBL peCorrectionFactor_m; - INT peCorrectionFactor_e; + INT peCorrectionFactor_e; /* vbr encoding */ FIXP_DBL vbrQualFactor; @@ -138,13 +161,14 @@ typedef struct { /* threshold weighting */ FIXP_DBL chaosMeasureEnFac[(2)]; - INT lastEnFacPatch[(2)]; + INT lastEnFacPatch[(2)]; } ATS_ELEMENT; typedef struct { BRES_PARAM bresParamLong, bresParamShort; - ATS_ELEMENT* adjThrStateElem[(8)]; + ATS_ELEMENT* adjThrStateElem[((8))]; + AACENC_BIT_DISTRIBUTION_MODE bitDistributionMode; INT maxIter2ndGuess; } ADJ_THR_STATE; diff --git a/libAACenc/src/band_nrg.cpp b/libAACenc/src/band_nrg.cpp index 861f7a8..fb22dbb 100644 --- a/libAACenc/src/band_nrg.cpp +++ b/libAACenc/src/band_nrg.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,17 +90,17 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M. Werner - contents/description: Band/Line energy calculations + Author(s): M. Werner -******************************************************************************/ + Description: Band/Line energy calculations -#include "band_nrg.h" +*******************************************************************************/ +#include "band_nrg.h" /***************************************************************************** functionname: FDKaacEnc_CalcSfbMaxScaleSpec @@ -97,23 +108,26 @@ amm-info@iis.fraunhofer.de input: output: *****************************************************************************/ -void -FDKaacEnc_CalcSfbMaxScaleSpec(const FIXP_DBL *RESTRICT mdctSpectrum, - const INT *RESTRICT bandOffset, - INT *RESTRICT sfbMaxScaleSpec, - const INT numBands) -{ - INT i,j; +void FDKaacEnc_CalcSfbMaxScaleSpec(const FIXP_DBL *RESTRICT mdctSpectrum, + const INT *RESTRICT bandOffset, + INT *RESTRICT sfbMaxScaleSpec, + const INT numBands) { + INT i, j; FIXP_DBL maxSpc, tmp; - for(i=0; i 0 */ + j = CntLeadingZeros(maxSpc) - 1; + sfbMaxScaleSpec[i] = fixMin((DFRACT_BITS - 2), j); + /* CountLeadingBits() is not necessary here since test value is always > 0 + */ } } @@ -124,43 +138,45 @@ FDKaacEnc_CalcSfbMaxScaleSpec(const FIXP_DBL *RESTRICT mdctSpectrum, output: *****************************************************************************/ FIXP_DBL -FDKaacEnc_CheckBandEnergyOptim(const FIXP_DBL *RESTRICT mdctSpectrum, - INT *RESTRICT sfbMaxScaleSpec, - const INT *RESTRICT bandOffset, - const INT numBands, - FIXP_DBL *RESTRICT bandEnergy, - FIXP_DBL *RESTRICT bandEnergyLdData, - INT minSpecShift) -{ +FDKaacEnc_CheckBandEnergyOptim(const FIXP_DBL *const RESTRICT mdctSpectrum, + const INT *const RESTRICT sfbMaxScaleSpec, + const INT *const RESTRICT bandOffset, + const INT numBands, + FIXP_DBL *RESTRICT bandEnergy, + FIXP_DBL *RESTRICT bandEnergyLdData, + const INT minSpecShift) { INT i, j, scale, nr = 0; FIXP_DBL maxNrgLd = FL2FXCONST_DBL(-1.0f); FIXP_DBL maxNrg = 0; FIXP_DBL spec; - for(i=0; i maxNrgLd) { - maxNrgLd = bandEnergyLdData[i]; - nr = i; + maxNrgLd = bandEnergyLdData[i]; + nr = i; } } /* return unscaled maxNrg*/ - scale = fixMax(0,sfbMaxScaleSpec[nr]-4); - scale = fixMax(2*(minSpecShift-scale),-(DFRACT_BITS-1)); + scale = fixMax(0, sfbMaxScaleSpec[nr] - 4); + scale = fixMax(2 * (minSpecShift - scale), -(DFRACT_BITS - 1)); maxNrg = scaleValue(bandEnergy[nr], scale); @@ -173,187 +189,173 @@ FDKaacEnc_CheckBandEnergyOptim(const FIXP_DBL *RESTRICT mdctSpectrum, input: output: *****************************************************************************/ -INT -FDKaacEnc_CalcBandEnergyOptimLong(const FIXP_DBL *RESTRICT mdctSpectrum, - INT *RESTRICT sfbMaxScaleSpec, - const INT *RESTRICT bandOffset, - const INT numBands, - FIXP_DBL *RESTRICT bandEnergy, - FIXP_DBL *RESTRICT bandEnergyLdData) -{ +INT FDKaacEnc_CalcBandEnergyOptimLong(const FIXP_DBL *RESTRICT mdctSpectrum, + INT *RESTRICT sfbMaxScaleSpec, + const INT *RESTRICT bandOffset, + const INT numBands, + FIXP_DBL *RESTRICT bandEnergy, + FIXP_DBL *RESTRICT bandEnergyLdData) { INT i, j, shiftBits = 0; FIXP_DBL maxNrgLd = FL2FXCONST_DBL(0.0f); FIXP_DBL spec; - for(i=0; i 7/2 = 4 (spc*spc) */ - FIXP_DBL tmp = FL2FXCONST_DBL(0.0); - /* don't use scaleValue() here, it increases workload quite sufficiently... */ - if (leadingBits>=0) { - for (j=bandOffset[i];j>shift; - tmp = fPow2AddDiv2(tmp, spec); - } - } - bandEnergy[i] = tmp<<1; + for (i = 0; i < numBands; i++) { + INT leadingBits = sfbMaxScaleSpec[i] - + 4; /* max sfbWidth = 96 ; 2^7=128 => 7/2 = 4 (spc*spc) */ + FIXP_DBL tmp = FL2FXCONST_DBL(0.0); + /* don't use scaleValue() here, it increases workload quite sufficiently... + */ + if (leadingBits >= 0) { + for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) { + spec = mdctSpectrum[j] << leadingBits; + tmp = fPow2AddDiv2(tmp, spec); + } + } else { + INT shift = -leadingBits; + for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) { + spec = mdctSpectrum[j] >> shift; + tmp = fPow2AddDiv2(tmp, spec); + } + } + bandEnergy[i] = tmp << 1; } /* calculate ld of bandNrg, subtract scaling */ LdDataVector(bandEnergy, bandEnergyLdData, numBands); - for(i=numBands; i--!=0; ) { - FIXP_DBL scaleDiff = (sfbMaxScaleSpec[i]-4)*FL2FXCONST_DBL(2.0/64); - - bandEnergyLdData[i] = (bandEnergyLdData[i] >= ((FL2FXCONST_DBL(-1.f)>>1) + (scaleDiff>>1))) - ? bandEnergyLdData[i]-scaleDiff : FL2FXCONST_DBL(-1.f); - /* find maxNrgLd */ - maxNrgLd = fixMax(maxNrgLd, bandEnergyLdData[i]); + for (i = numBands; i-- != 0;) { + FIXP_DBL scaleDiff = (sfbMaxScaleSpec[i] - 4) * FL2FXCONST_DBL(2.0 / 64); + + bandEnergyLdData[i] = (bandEnergyLdData[i] >= + ((FL2FXCONST_DBL(-1.f) >> 1) + (scaleDiff >> 1))) + ? bandEnergyLdData[i] - scaleDiff + : FL2FXCONST_DBL(-1.f); + /* find maxNrgLd */ + maxNrgLd = fixMax(maxNrgLd, bandEnergyLdData[i]); } - if (maxNrgLd<=(FIXP_DBL)0) - { - for(i=numBands; i--!=0; ) - { - INT scale = fixMin((sfbMaxScaleSpec[i]-4)<<1,(DFRACT_BITS-1)); - bandEnergy[i] = scaleValue(bandEnergy[i], -scale); - } - return 0; - } - else - { /* scale down NRGs */ - while (maxNrgLd>FL2FXCONST_DBL(0.0f)) - { - maxNrgLd -= FL2FXCONST_DBL(2.0/64); - shiftBits++; - } - for(i=numBands; i--!=0; ) - { - INT scale = fixMin( ((sfbMaxScaleSpec[i]-4)+shiftBits)<<1, (DFRACT_BITS-1)); - bandEnergyLdData[i] -= shiftBits*FL2FXCONST_DBL(2.0/64); - bandEnergy[i] = scaleValue(bandEnergy[i], -scale); - } - return shiftBits; + if (maxNrgLd <= (FIXP_DBL)0) { + for (i = numBands; i-- != 0;) { + INT scale = fixMin((sfbMaxScaleSpec[i] - 4) << 1, (DFRACT_BITS - 1)); + bandEnergy[i] = scaleValue(bandEnergy[i], -scale); + } + return 0; + } else { /* scale down NRGs */ + while (maxNrgLd > FL2FXCONST_DBL(0.0f)) { + maxNrgLd -= FL2FXCONST_DBL(2.0 / 64); + shiftBits++; + } + for (i = numBands; i-- != 0;) { + INT scale = fixMin(((sfbMaxScaleSpec[i] - 4) + shiftBits) << 1, + (DFRACT_BITS - 1)); + bandEnergyLdData[i] -= shiftBits * FL2FXCONST_DBL(2.0 / 64); + bandEnergy[i] = scaleValue(bandEnergy[i], -scale); + } + return shiftBits; } } - /***************************************************************************** functionname: FDKaacEnc_CalcBandEnergyOptimShort description: input: output: *****************************************************************************/ -void -FDKaacEnc_CalcBandEnergyOptimShort(const FIXP_DBL *RESTRICT mdctSpectrum, - INT *RESTRICT sfbMaxScaleSpec, - const INT *RESTRICT bandOffset, - const INT numBands, - FIXP_DBL *RESTRICT bandEnergy) -{ +void FDKaacEnc_CalcBandEnergyOptimShort(const FIXP_DBL *RESTRICT mdctSpectrum, + INT *RESTRICT sfbMaxScaleSpec, + const INT *RESTRICT bandOffset, + const INT numBands, + FIXP_DBL *RESTRICT bandEnergy) { INT i, j; - for(i=0; i 6/2 = 3 (spc*spc) */ + for (i = 0; i < numBands; i++) { + int leadingBits = sfbMaxScaleSpec[i] - + 3; /* max sfbWidth = 36 ; 2^6=64 => 6/2 = 3 (spc*spc) */ FIXP_DBL tmp = FL2FXCONST_DBL(0.0); - for (j=bandOffset[i];j 6/2 = 3 (spc*spc) */ - scale = fixMax(fixMin(scale,(DFRACT_BITS-1)),-(DFRACT_BITS-1)); - bandEnergy[i] = scaleValueSaturate(bandEnergy[i], -scale); + for (i = 0; i < numBands; i++) { + INT scale = (2 * (sfbMaxScaleSpec[i] - 3)) - + 1; /* max sfbWidth = 36 ; 2^6=64 => 6/2 = 3 (spc*spc) */ + scale = fixMax(fixMin(scale, (DFRACT_BITS - 1)), -(DFRACT_BITS - 1)); + bandEnergy[i] = scaleValueSaturate(bandEnergy[i], -scale); } } - /***************************************************************************** functionname: FDKaacEnc_CalcBandNrgMSOpt description: input: output: *****************************************************************************/ -void FDKaacEnc_CalcBandNrgMSOpt(const FIXP_DBL *RESTRICT mdctSpectrumLeft, - const FIXP_DBL *RESTRICT mdctSpectrumRight, - INT *RESTRICT sfbMaxScaleSpecLeft, - INT *RESTRICT sfbMaxScaleSpecRight, - const INT *RESTRICT bandOffset, - const INT numBands, - FIXP_DBL *RESTRICT bandEnergyMid, - FIXP_DBL *RESTRICT bandEnergySide, - INT calcLdData, - FIXP_DBL *RESTRICT bandEnergyMidLdData, - FIXP_DBL *RESTRICT bandEnergySideLdData) -{ +void FDKaacEnc_CalcBandNrgMSOpt( + const FIXP_DBL *RESTRICT mdctSpectrumLeft, + const FIXP_DBL *RESTRICT mdctSpectrumRight, + INT *RESTRICT sfbMaxScaleSpecLeft, INT *RESTRICT sfbMaxScaleSpecRight, + const INT *RESTRICT bandOffset, const INT numBands, + FIXP_DBL *RESTRICT bandEnergyMid, FIXP_DBL *RESTRICT bandEnergySide, + INT calcLdData, FIXP_DBL *RESTRICT bandEnergyMidLdData, + FIXP_DBL *RESTRICT bandEnergySideLdData) { INT i, j, minScale; FIXP_DBL NrgMid, NrgSide, specm, specs; - for (i=0; i 0) { - for (j=bandOffset[i];j>1; - FIXP_DBL specR = mdctSpectrumRight[j]>>1; - specm = specL + specR; - specs = specL - specR; - NrgMid = fPow2AddDiv2(NrgMid, specm); - NrgSide = fPow2AddDiv2(NrgSide, specs); + for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) { + FIXP_DBL specL = mdctSpectrumLeft[j] >> 1; + FIXP_DBL specR = mdctSpectrumRight[j] >> 1; + specm = specL + specR; + specs = specL - specR; + NrgMid = fPow2AddDiv2(NrgMid, specm); + NrgSide = fPow2AddDiv2(NrgSide, specs); } } - bandEnergyMid[i] = NrgMid<<1; - bandEnergySide[i] = NrgSide<<1; + bandEnergyMid[i] = fMin(NrgMid, (FIXP_DBL)MAXVAL_DBL >> 1) << 1; + bandEnergySide[i] = fMin(NrgSide, (FIXP_DBL)MAXVAL_DBL >> 1) << 1; } - if(calcLdData) { + if (calcLdData) { LdDataVector(bandEnergyMid, bandEnergyMidLdData, numBands); LdDataVector(bandEnergySide, bandEnergySideLdData, numBands); } - for (i=0; i>= scale; + scale = fixMin(scale, (DFRACT_BITS - 1)); + bandEnergyMid[i] >>= scale; bandEnergySide[i] >>= scale; } } diff --git a/libAACenc/src/band_nrg.h b/libAACenc/src/band_nrg.h index 540a8ef..4137565 100644 --- a/libAACenc/src/band_nrg.h +++ b/libAACenc/src/band_nrg.h @@ -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,71 +90,53 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** Author(s): M. Werner + Description: Band/Line energy calculation -******************************************************************************/ +*******************************************************************************/ -#ifndef _BAND_NRG_H -#define _BAND_NRG_H +#ifndef BAND_NRG_H +#define BAND_NRG_H #include "common_fix.h" - -void -FDKaacEnc_CalcSfbMaxScaleSpec( - const FIXP_DBL *mdctSpectrum, - const INT *bandOffset, - INT *sfbMaxScaleSpec, - const INT numBands - ); +void FDKaacEnc_CalcSfbMaxScaleSpec(const FIXP_DBL *mdctSpectrum, + const INT *bandOffset, INT *sfbMaxScaleSpec, + const INT numBands); FIXP_DBL -FDKaacEnc_CheckBandEnergyOptim( - const FIXP_DBL *mdctSpectrum, - INT *sfbMaxScaleSpec, - const INT *bandOffset, - const INT numBands, - FIXP_DBL *bandEnergy, - FIXP_DBL *bandEnergyLdData, - INT minSpecShift - ); - -INT -FDKaacEnc_CalcBandEnergyOptimLong( - const FIXP_DBL *mdctSpectrum, - INT *sfbMaxScaleSpec, - const INT *bandOffset, - const INT numBands, - FIXP_DBL *bandEnergy, - FIXP_DBL *bandEnergyLdData - ); - -void -FDKaacEnc_CalcBandEnergyOptimShort( - const FIXP_DBL *mdctSpectrum, - INT *sfbMaxScaleSpec, - const INT *bandOffset, - const INT numBands, - FIXP_DBL *bandEnergy - ); - +FDKaacEnc_CheckBandEnergyOptim(const FIXP_DBL *const RESTRICT mdctSpectrum, + const INT *const RESTRICT sfbMaxScaleSpec, + const INT *const RESTRICT bandOffset, + const INT numBands, + FIXP_DBL *RESTRICT bandEnergy, + FIXP_DBL *RESTRICT bandEnergyLdData, + const INT minSpecShift); + +INT FDKaacEnc_CalcBandEnergyOptimLong(const FIXP_DBL *mdctSpectrum, + INT *sfbMaxScaleSpec, + const INT *bandOffset, const INT numBands, + FIXP_DBL *bandEnergy, + FIXP_DBL *bandEnergyLdData); + +void FDKaacEnc_CalcBandEnergyOptimShort(const FIXP_DBL *mdctSpectrum, + INT *sfbMaxScaleSpec, + const INT *bandOffset, + const INT numBands, + FIXP_DBL *bandEnergy); void FDKaacEnc_CalcBandNrgMSOpt( - const FIXP_DBL *RESTRICT mdctSpectrumLeft, - const FIXP_DBL *RESTRICT mdctSpectrumRight, - INT *RESTRICT sfbMaxScaleSpecLeft, - INT *RESTRICT sfbMaxScaleSpecRight, - const INT *RESTRICT bandOffset, - const INT numBands, - FIXP_DBL *RESTRICT bandEnergyMid, - FIXP_DBL *RESTRICT bandEnergySide, - INT calcLdData, - FIXP_DBL *RESTRICT bandEnergyMidLdData, - FIXP_DBL *RESTRICT bandEnergySideLdData); + const FIXP_DBL *RESTRICT mdctSpectrumLeft, + const FIXP_DBL *RESTRICT mdctSpectrumRight, + INT *RESTRICT sfbMaxScaleSpecLeft, INT *RESTRICT sfbMaxScaleSpecRight, + const INT *RESTRICT bandOffset, const INT numBands, + FIXP_DBL *RESTRICT bandEnergyMid, FIXP_DBL *RESTRICT bandEnergySide, + INT calcLdData, FIXP_DBL *RESTRICT bandEnergyMidLdData, + FIXP_DBL *RESTRICT bandEnergySideLdData); #endif diff --git a/libAACenc/src/bandwidth.cpp b/libAACenc/src/bandwidth.cpp index 6937362..36cd64d 100644 --- a/libAACenc/src/bandwidth.cpp +++ b/libAACenc/src/bandwidth.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,20 +90,21 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/************************* Fast MPEG AAC Audio Encoder ********************** + Author(s): M. Schug / A. Groeschel - Initial author: M. Schug / A. Groeschel - contents/description: bandwidth expert + Description: bandwidth expert -******************************************************************************/ +*******************************************************************************/ #include "channel_map.h" #include "bandwidth.h" #include "aacEnc_ram.h" -typedef struct{ +typedef struct { INT chanBitRate; INT bandWidthMono; INT bandWidth2AndMoreChan; @@ -100,114 +112,71 @@ typedef struct{ } BANDWIDTH_TAB; static const BANDWIDTH_TAB bandWidthTable[] = { - {0, 3700, 5000}, - {12000, 5000, 6400}, - {20000, 6900, 9640}, - {28000, 9600, 13050}, - {40000, 12060, 14260}, - {56000, 13950, 15500}, - {72000, 14200, 16120}, - {96000, 17000, 17000}, - {576001,17000, 17000} -}; - + {0, 3700, 5000}, {12000, 5000, 6400}, {20000, 6900, 9640}, + {28000, 9600, 13050}, {40000, 12060, 14260}, {56000, 13950, 15500}, + {72000, 14200, 16120}, {96000, 17000, 17000}, {576001, 17000, 17000}}; static const BANDWIDTH_TAB bandWidthTable_LD_22050[] = { - { 8000, 2000, 2400}, - {12000, 2500, 2700}, - {16000, 3300, 3100}, - {24000, 6250, 7200}, - {32000, 9200, 10500}, - {40000, 16000, 16000}, - {48000, 16000, 16000}, - {360001, 16000, 16000} -}; + {8000, 2000, 2400}, {12000, 2500, 2700}, {16000, 3300, 3100}, + {24000, 6250, 7200}, {32000, 9200, 10500}, {40000, 16000, 16000}, + {48000, 16000, 16000}, {282241, 16000, 16000}}; static const BANDWIDTH_TAB bandWidthTable_LD_24000[] = { - { 8000, 2000, 2000}, - {12000, 2000, 2300}, - {16000, 2200, 2500}, - {24000, 5650, 7200}, - {32000, 11600, 12000}, - {40000, 12000, 16000}, - {48000, 16000, 16000}, - {64000, 16000, 16000}, - {360001, 16000, 16000} -}; + {8000, 2000, 2000}, {12000, 2000, 2300}, {16000, 2200, 2500}, + {24000, 5650, 7200}, {32000, 11600, 12000}, {40000, 12000, 16000}, + {48000, 16000, 16000}, {64000, 16000, 16000}, {307201, 16000, 16000}}; static const BANDWIDTH_TAB bandWidthTable_LD_32000[] = { - { 8000, 2000, 2000}, - {12000, 2000, 2000}, - {24000, 4250, 7200}, - {32000, 8400, 9000}, - {40000, 9400, 11300}, - {48000, 11900, 14700}, - {64000, 14800, 16000}, - {76000, 16000, 16000}, - {360001, 16000, 16000} -}; + {8000, 2000, 2000}, {12000, 2000, 2000}, {24000, 4250, 7200}, + {32000, 8400, 9000}, {40000, 9400, 11300}, {48000, 11900, 14700}, + {64000, 14800, 16000}, {76000, 16000, 16000}, {409601, 16000, 16000}}; static const BANDWIDTH_TAB bandWidthTable_LD_44100[] = { - { 8000, 2000, 2000}, - {24000, 2000, 2000}, - {32000, 4400, 5700}, - {40000, 7400, 8800}, - {48000, 9000, 10700}, - {56000, 11000, 12900}, - {64000, 14400, 15500}, - {80000, 16000, 16200}, - {96000, 16500, 16000}, - {128000, 16000, 16000}, - {360001, 16000, 16000} -}; + {8000, 2000, 2000}, {24000, 2000, 2000}, {32000, 4400, 5700}, + {40000, 7400, 8800}, {48000, 9000, 10700}, {56000, 11000, 12900}, + {64000, 14400, 15500}, {80000, 16000, 16200}, {96000, 16500, 16000}, + {128000, 16000, 16000}, {564481, 16000, 16000}}; static const BANDWIDTH_TAB bandWidthTable_LD_48000[] = { - { 8000, 2000, 2000}, - {24000, 2000, 2000}, - {32000, 4400, 5700}, - {40000, 7400, 8800}, - {48000, 9000, 10700}, - {56000, 11000, 12800}, - {64000, 14300, 15400}, - {80000, 16000, 16200}, - {96000, 16500, 16000}, - {128000, 16000, 16000}, - {360001, 16000, 16000} -}; + {8000, 2000, 2000}, {24000, 2000, 2000}, {32000, 4400, 5700}, + {40000, 7400, 8800}, {48000, 9000, 10700}, {56000, 11000, 12800}, + {64000, 14300, 15400}, {80000, 16000, 16200}, {96000, 16500, 16000}, + {128000, 16000, 16000}, {614401, 16000, 16000}}; -typedef struct{ +typedef struct { AACENC_BITRATE_MODE bitrateMode; int bandWidthMono; int bandWidth2AndMoreChan; } BANDWIDTH_TAB_VBR; -static const BANDWIDTH_TAB_VBR bandWidthTableVBR[]= { - {AACENC_BR_MODE_CBR, 0, 0}, - {AACENC_BR_MODE_VBR_1, 13050, 13050}, - {AACENC_BR_MODE_VBR_2, 13050, 13050}, - {AACENC_BR_MODE_VBR_3, 14260, 14260}, - {AACENC_BR_MODE_VBR_4, 15500, 15500}, - {AACENC_BR_MODE_VBR_5, 48000, 48000}, - {AACENC_BR_MODE_SFR, 0, 0}, - {AACENC_BR_MODE_FF, 0, 0} +static const BANDWIDTH_TAB_VBR bandWidthTableVBR[] = { + {AACENC_BR_MODE_CBR, 0, 0}, + {AACENC_BR_MODE_VBR_1, 13050, 13050}, + {AACENC_BR_MODE_VBR_2, 13050, 13050}, + {AACENC_BR_MODE_VBR_3, 14260, 14260}, + {AACENC_BR_MODE_VBR_4, 15500, 15500}, + {AACENC_BR_MODE_VBR_5, 48000, 48000}, + {AACENC_BR_MODE_SFR, 0, 0}, + {AACENC_BR_MODE_FF, 0, 0} }; -static INT GetBandwidthEntry( - const INT frameLength, - const INT sampleRate, - const INT chanBitRate, - const INT entryNo) -{ +static INT GetBandwidthEntry(const INT frameLength, const INT sampleRate, + const INT chanBitRate, const INT entryNo) { INT bandwidth = -1; const BANDWIDTH_TAB *pBwTab = NULL; INT bwTabSize = 0; switch (frameLength) { + case 960: case 1024: pBwTab = bandWidthTable; - bwTabSize = sizeof(bandWidthTable)/sizeof(BANDWIDTH_TAB); + bwTabSize = sizeof(bandWidthTable) / sizeof(BANDWIDTH_TAB); break; + case 120: + case 128: + case 240: + case 256: case 480: case 512: switch (sampleRate) { @@ -217,26 +186,26 @@ static INT GetBandwidthEntry( case 16000: case 22050: pBwTab = bandWidthTable_LD_22050; - bwTabSize = sizeof(bandWidthTable_LD_22050)/sizeof(BANDWIDTH_TAB); + bwTabSize = sizeof(bandWidthTable_LD_22050) / sizeof(BANDWIDTH_TAB); break; case 24000: pBwTab = bandWidthTable_LD_24000; - bwTabSize = sizeof(bandWidthTable_LD_24000)/sizeof(BANDWIDTH_TAB); + bwTabSize = sizeof(bandWidthTable_LD_24000) / sizeof(BANDWIDTH_TAB); break; case 32000: pBwTab = bandWidthTable_LD_32000; - bwTabSize = sizeof(bandWidthTable_LD_32000)/sizeof(BANDWIDTH_TAB); + bwTabSize = sizeof(bandWidthTable_LD_32000) / sizeof(BANDWIDTH_TAB); break; - case (44100): + case 44100: pBwTab = bandWidthTable_LD_44100; - bwTabSize = sizeof(bandWidthTable_LD_44100)/sizeof(BANDWIDTH_TAB); + bwTabSize = sizeof(bandWidthTable_LD_44100) / sizeof(BANDWIDTH_TAB); break; case 48000: case 64000: case 88200: case 96000: pBwTab = bandWidthTable_LD_48000; - bwTabSize = sizeof(bandWidthTable_LD_48000)/sizeof(BANDWIDTH_TAB); + bwTabSize = sizeof(bandWidthTable_LD_48000) / sizeof(BANDWIDTH_TAB); break; } break; @@ -245,31 +214,38 @@ static INT GetBandwidthEntry( bwTabSize = 0; } - if (pBwTab!=NULL) { + if (pBwTab != NULL) { int i; - for (i=0; i= pBwTab[i].chanBitRate && - chanBitRate < pBwTab[i+1].chanBitRate) - { + chanBitRate < pBwTab[i + 1].chanBitRate) { switch (frameLength) { + case 960: case 1024: - bandwidth = (entryNo==0) - ? pBwTab[i].bandWidthMono - : pBwTab[i].bandWidth2AndMoreChan; + bandwidth = (entryNo == 0) ? pBwTab[i].bandWidthMono + : pBwTab[i].bandWidth2AndMoreChan; break; + case 120: + case 128: + case 240: + case 256: case 480: - case 512: - { - INT q_res = 0; - INT startBw = (entryNo==0) ? pBwTab[i ].bandWidthMono : pBwTab[i ].bandWidth2AndMoreChan; - INT endBw = (entryNo==0) ? pBwTab[i+1].bandWidthMono : pBwTab[i+1].bandWidth2AndMoreChan; - INT startBr = pBwTab[i].chanBitRate; - INT endBr = pBwTab[i+1].chanBitRate; - - FIXP_DBL bwFac_fix = fDivNorm(chanBitRate-startBr, endBr-startBr, &q_res); - bandwidth = (INT)scaleValue(fMult(bwFac_fix, (FIXP_DBL)(endBw-startBw)),q_res) + startBw; - } - break; + case 512: { + INT q_res = 0; + INT startBw = (entryNo == 0) ? pBwTab[i].bandWidthMono + : pBwTab[i].bandWidth2AndMoreChan; + INT endBw = (entryNo == 0) ? pBwTab[i + 1].bandWidthMono + : pBwTab[i + 1].bandWidth2AndMoreChan; + INT startBr = pBwTab[i].chanBitRate; + INT endBr = pBwTab[i + 1].chanBitRate; + + FIXP_DBL bwFac_fix = + fDivNorm(chanBitRate - startBr, endBr - startBr, &q_res); + bandwidth = + (INT)scaleValue(fMult(bwFac_fix, (FIXP_DBL)(endBw - startBw)), + q_res) + + startBw; + } break; default: bandwidth = -1; } @@ -281,99 +257,104 @@ static INT GetBandwidthEntry( return bandwidth; } - -AAC_ENCODER_ERROR FDKaacEnc_DetermineBandWidth(INT* bandWidth, - INT proposedBandWidth, - INT bitrate, - AACENC_BITRATE_MODE bitrateMode, - INT sampleRate, - INT frameLength, - CHANNEL_MAPPING* cm, - CHANNEL_MODE encoderMode) -{ +AAC_ENCODER_ERROR FDKaacEnc_DetermineBandWidth( + const INT proposedBandWidth, const INT bitrate, + const AACENC_BITRATE_MODE bitrateMode, const INT sampleRate, + const INT frameLength, const CHANNEL_MAPPING *const cm, + const CHANNEL_MODE encoderMode, INT *const bandWidth) { AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK; - INT chanBitRate = bitrate/cm->nChannels; - - /* vbr */ - switch(bitrateMode){ - case AACENC_BR_MODE_VBR_1: - case AACENC_BR_MODE_VBR_2: - case AACENC_BR_MODE_VBR_3: - case AACENC_BR_MODE_VBR_4: - case AACENC_BR_MODE_VBR_5: - if (proposedBandWidth != 0){ - /* use given bw */ - *bandWidth = proposedBandWidth; - } else { - /* take bw from table */ - switch(encoderMode){ - case MODE_1: - *bandWidth = bandWidthTableVBR[bitrateMode].bandWidthMono; - break; - case MODE_2: - case MODE_1_2: - case MODE_1_2_1: - case MODE_1_2_2: - case MODE_1_2_2_1: - case MODE_1_2_2_2_1: - case MODE_7_1_REAR_SURROUND: - case MODE_7_1_FRONT_CENTER: - *bandWidth = bandWidthTableVBR[bitrateMode].bandWidth2AndMoreChan; - break; - default: - return AAC_ENC_UNSUPPORTED_CHANNELCONFIG; + INT chanBitRate = bitrate / cm->nChannelsEff; + + switch (bitrateMode) { + case AACENC_BR_MODE_VBR_1: + case AACENC_BR_MODE_VBR_2: + case AACENC_BR_MODE_VBR_3: + case AACENC_BR_MODE_VBR_4: + case AACENC_BR_MODE_VBR_5: + if (proposedBandWidth != 0) { + /* use given bw */ + *bandWidth = proposedBandWidth; + } else { + /* take bw from table */ + switch (encoderMode) { + case MODE_1: + *bandWidth = bandWidthTableVBR[bitrateMode].bandWidthMono; + break; + case MODE_2: + case MODE_1_2: + case MODE_1_2_1: + case MODE_1_2_2: + case MODE_1_2_2_1: + case MODE_6_1: + case MODE_1_2_2_2_1: + case MODE_7_1_REAR_SURROUND: + case MODE_7_1_FRONT_CENTER: + case MODE_7_1_BACK: + case MODE_7_1_TOP_FRONT: + *bandWidth = bandWidthTableVBR[bitrateMode].bandWidth2AndMoreChan; + break; + default: + return AAC_ENC_UNSUPPORTED_CHANNELCONFIG; + } } - } - break; - case AACENC_BR_MODE_CBR: - case AACENC_BR_MODE_SFR: - case AACENC_BR_MODE_FF: - - /* bandwidth limiting */ - if (proposedBandWidth != 0) { - *bandWidth = FDKmin(proposedBandWidth, FDKmin(20000, sampleRate>>1)); - } - else { /* search reasonable bandwidth */ + break; + case AACENC_BR_MODE_CBR: + case AACENC_BR_MODE_SFR: + case AACENC_BR_MODE_FF: - int entryNo = 0; + /* bandwidth limiting */ + if (proposedBandWidth != 0) { + *bandWidth = fMin(proposedBandWidth, fMin(20000, sampleRate >> 1)); + } else { /* search reasonable bandwidth */ - switch(encoderMode){ - case MODE_1: /* mono */ - entryNo = 0; /* use mono bandwith settings */ - break; + int entryNo = 0; - case MODE_2: /* stereo */ - case MODE_1_2: /* sce + cpe */ - case MODE_1_2_1: /* sce + cpe + sce */ - case MODE_1_2_2: /* sce + cpe + cpe */ - case MODE_1_2_2_1: /* (5.1) sce + cpe + cpe + lfe */ - case MODE_1_2_2_2_1: /* (7.1) sce + cpe + cpe + cpe + lfe */ - case MODE_7_1_REAR_SURROUND: - case MODE_7_1_FRONT_CENTER: - entryNo = 1; /* use stereo bandwith settings */ - break; + switch (encoderMode) { + case MODE_1: /* mono */ + entryNo = 0; /* use mono bandwidth settings */ + break; - default: - return AAC_ENC_UNSUPPORTED_CHANNELCONFIG; - } + case MODE_2: /* stereo */ + case MODE_1_2: /* sce + cpe */ + case MODE_1_2_1: /* sce + cpe + sce */ + case MODE_1_2_2: /* sce + cpe + cpe */ + case MODE_1_2_2_1: /* (5.1) sce + cpe + cpe + lfe */ + case MODE_6_1: + case MODE_1_2_2_2_1: + case MODE_7_1_REAR_SURROUND: + case MODE_7_1_FRONT_CENTER: + case MODE_7_1_BACK: + case MODE_7_1_TOP_FRONT: + entryNo = 1; /* use stereo bandwidth settings */ + break; - *bandWidth = GetBandwidthEntry( - frameLength, - sampleRate, - chanBitRate, - entryNo); + default: + return AAC_ENC_UNSUPPORTED_CHANNELCONFIG; + } - if (*bandWidth==-1) { - ErrorStatus = AAC_ENC_INVALID_CHANNEL_BITRATE; + *bandWidth = + GetBandwidthEntry(frameLength, sampleRate, chanBitRate, entryNo); + + if (*bandWidth == -1) { + switch (frameLength) { + case 120: + case 128: + case 240: + case 256: + *bandWidth = 16000; + break; + default: + ErrorStatus = AAC_ENC_INVALID_CHANNEL_BITRATE; + } + } } - } - break; - default: - *bandWidth = 0; - return AAC_ENC_UNSUPPORTED_BITRATE_MODE; + break; + default: + *bandWidth = 0; + return AAC_ENC_UNSUPPORTED_BITRATE_MODE; } - *bandWidth = FDKmin(*bandWidth, sampleRate/2); + *bandWidth = fMin(*bandWidth, sampleRate / 2); - return ErrorStatus;; + return ErrorStatus; } diff --git a/libAACenc/src/bandwidth.h b/libAACenc/src/bandwidth.h index 2e92453..088e829 100644 --- a/libAACenc/src/bandwidth.h +++ b/libAACenc/src/bandwidth.h @@ -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,28 +90,25 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/************************* Fast MPEG AAC Audio Encoder ********************** +/**************************** AAC encoder library ****************************** - Initial author: M. Schug / A. Groeschel - contents/description: bandwidth expert + Author(s): M. Schug / A. Groeschel -******************************************************************************/ + Description: bandwidth expert -#ifndef _BANDWIDTH_H -#define _BANDWIDTH_H +*******************************************************************************/ +#ifndef BANDWIDTH_H +#define BANDWIDTH_H #include "qc_data.h" -AAC_ENCODER_ERROR FDKaacEnc_DetermineBandWidth(INT* bandWidth, - INT proposedBandwidth, - INT bitrate, - AACENC_BITRATE_MODE bitrateMode, - INT sampleRate, - INT frameLength, - CHANNEL_MAPPING* cm, - CHANNEL_MODE encoderMode); +AAC_ENCODER_ERROR FDKaacEnc_DetermineBandWidth( + const INT proposedBandWidth, const INT bitrate, + const AACENC_BITRATE_MODE bitrateMode, const INT sampleRate, + const INT frameLength, const CHANNEL_MAPPING *const cm, + const CHANNEL_MODE encoderMode, INT *const bandWidth); #endif /* BANDWIDTH_H */ diff --git a/libAACenc/src/bit_cnt.cpp b/libAACenc/src/bit_cnt.cpp index 926ee49..579df8c 100644 --- a/libAACenc/src/bit_cnt.cpp +++ b/libAACenc/src/bit_cnt.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,20 +90,21 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Huffman Bitcounter & coder + Description: Huffman Bitcounter & coder -******************************************************************************/ +*******************************************************************************/ #include "bit_cnt.h" #include "aacEnc_ram.h" -#define HI_LTAB(a) (a>>16) +#define HI_LTAB(a) (a >> 16) #define LO_LTAB(a) (a & 0xffff) /***************************************************************************** @@ -106,72 +118,62 @@ amm-info@iis.fraunhofer.de *****************************************************************************/ -static void FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11(const SHORT *RESTRICT values, - const INT width, - INT *bitCount) -{ - +static void FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11(const SHORT *const values, + const INT width, + INT *RESTRICT bitCount) { INT i; - INT bc1_2,bc3_4,bc5_6,bc7_8,bc9_10,bc11,sc; - INT t0,t1,t2,t3; - bc1_2=0; - bc3_4=0; - bc5_6=0; - bc7_8=0; - bc9_10=0; - bc11=0; - sc=0; - - for(i=0;i0)+(t1>0)+(t2>0)+(t3>0); + INT bc1_2, bc3_4, bc5_6, bc7_8, bc9_10, bc11, sc; + INT t0, t1, t2, t3; + bc1_2 = 0; + bc3_4 = 0; + bc5_6 = 0; + bc7_8 = 0; + bc9_10 = 0; + bc11 = 0; + sc = 0; + + DWORD_ALIGNED(values); + + for (i = 0; i < width; i += 4) { + t0 = values[i + 0]; + t1 = values[i + 1]; + t2 = values[i + 2]; + t3 = values[i + 3]; + + bc1_2 += (INT)FDKaacEnc_huff_ltab1_2[t0 + 1][t1 + 1][t2 + 1][t3 + 1]; + bc5_6 += (INT)FDKaacEnc_huff_ltab5_6[t0 + 4][t1 + 4] + + (INT)FDKaacEnc_huff_ltab5_6[t2 + 4][t3 + 4]; + + t0 = fixp_abs(t0); + sc += (t0 > 0); + t1 = fixp_abs(t1); + sc += (t1 > 0); + t2 = fixp_abs(t2); + sc += (t2 > 0); + t3 = fixp_abs(t3); + sc += (t3 > 0); + + bc3_4 += (INT)FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3]; + bc7_8 += (INT)FDKaacEnc_huff_ltab7_8[t0][t1] + + (INT)FDKaacEnc_huff_ltab7_8[t2][t3]; + bc9_10 += (INT)FDKaacEnc_huff_ltab9_10[t0][t1] + + (INT)FDKaacEnc_huff_ltab9_10[t2][t3]; + bc11 += + (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3]; } - - bitCount[1]=HI_LTAB(bc1_2); - bitCount[2]=LO_LTAB(bc1_2); - bitCount[3]=HI_LTAB(bc3_4)+sc; - bitCount[4]=LO_LTAB(bc3_4)+sc; - bitCount[5]=HI_LTAB(bc5_6); - bitCount[6]=LO_LTAB(bc5_6); - bitCount[7]=HI_LTAB(bc7_8)+sc; - bitCount[8]=LO_LTAB(bc7_8)+sc; - bitCount[9]=HI_LTAB(bc9_10)+sc; - bitCount[10]=LO_LTAB(bc9_10)+sc; - bitCount[11]=bc11+sc; - + bitCount[1] = HI_LTAB(bc1_2); + bitCount[2] = LO_LTAB(bc1_2); + bitCount[3] = HI_LTAB(bc3_4) + sc; + bitCount[4] = LO_LTAB(bc3_4) + sc; + bitCount[5] = HI_LTAB(bc5_6); + bitCount[6] = LO_LTAB(bc5_6); + bitCount[7] = HI_LTAB(bc7_8) + sc; + bitCount[8] = LO_LTAB(bc7_8) + sc; + bitCount[9] = HI_LTAB(bc9_10) + sc; + bitCount[10] = LO_LTAB(bc9_10) + sc; + bitCount[11] = bc11 + sc; } - /***************************************************************************** functionname: FDKaacEnc_count3_4_5_6_7_8_9_10_11 @@ -182,66 +184,62 @@ static void FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11(const SHORT *RESTRICT values, *****************************************************************************/ -static void FDKaacEnc_count3_4_5_6_7_8_9_10_11(const SHORT *RESTRICT values, - const INT width, - INT *bitCount) -{ - +static void FDKaacEnc_count3_4_5_6_7_8_9_10_11(const SHORT *const values, + const INT width, + INT *RESTRICT bitCount) { INT i; - INT bc3_4,bc5_6,bc7_8,bc9_10,bc11,sc; - INT t0,t1,t2,t3; - - bc3_4=0; - bc5_6=0; - bc7_8=0; - bc9_10=0; - bc11=0; - sc=0; - - for(i=0;i0)+(t1>0)+(t2>0)+(t3>0); + INT bc3_4, bc5_6, bc7_8, bc9_10, bc11, sc; + INT t0, t1, t2, t3; + + bc3_4 = 0; + bc5_6 = 0; + bc7_8 = 0; + bc9_10 = 0; + bc11 = 0; + sc = 0; + + DWORD_ALIGNED(values); + + for (i = 0; i < width; i += 4) { + t0 = values[i + 0]; + t1 = values[i + 1]; + t2 = values[i + 2]; + t3 = values[i + 3]; + + bc5_6 += (INT)FDKaacEnc_huff_ltab5_6[t0 + 4][t1 + 4] + + (INT)FDKaacEnc_huff_ltab5_6[t2 + 4][t3 + 4]; + + t0 = fixp_abs(t0); + sc += (t0 > 0); + t1 = fixp_abs(t1); + sc += (t1 > 0); + t2 = fixp_abs(t2); + sc += (t2 > 0); + t3 = fixp_abs(t3); + sc += (t3 > 0); + + bc3_4 += (INT)FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3]; + bc7_8 += (INT)FDKaacEnc_huff_ltab7_8[t0][t1] + + (INT)FDKaacEnc_huff_ltab7_8[t2][t3]; + bc9_10 += (INT)FDKaacEnc_huff_ltab9_10[t0][t1] + + (INT)FDKaacEnc_huff_ltab9_10[t2][t3]; + bc11 += + (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3]; } - bitCount[1]=INVALID_BITCOUNT; - bitCount[2]=INVALID_BITCOUNT; - bitCount[3]=HI_LTAB(bc3_4)+sc; - bitCount[4]=LO_LTAB(bc3_4)+sc; - bitCount[5]=HI_LTAB(bc5_6); - bitCount[6]=LO_LTAB(bc5_6); - bitCount[7]=HI_LTAB(bc7_8)+sc; - bitCount[8]=LO_LTAB(bc7_8)+sc; - bitCount[9]=HI_LTAB(bc9_10)+sc; - bitCount[10]=LO_LTAB(bc9_10)+sc; - bitCount[11]=bc11+sc; + bitCount[1] = INVALID_BITCOUNT; + bitCount[2] = INVALID_BITCOUNT; + bitCount[3] = HI_LTAB(bc3_4) + sc; + bitCount[4] = LO_LTAB(bc3_4) + sc; + bitCount[5] = HI_LTAB(bc5_6); + bitCount[6] = LO_LTAB(bc5_6); + bitCount[7] = HI_LTAB(bc7_8) + sc; + bitCount[8] = LO_LTAB(bc7_8) + sc; + bitCount[9] = HI_LTAB(bc9_10) + sc; + bitCount[10] = LO_LTAB(bc9_10) + sc; + bitCount[11] = bc11 + sc; } - - /***************************************************************************** functionname: FDKaacEnc_count5_6_7_8_9_10_11 @@ -252,52 +250,58 @@ static void FDKaacEnc_count3_4_5_6_7_8_9_10_11(const SHORT *RESTRICT values, *****************************************************************************/ - -static void FDKaacEnc_count5_6_7_8_9_10_11(const SHORT *RESTRICT values, - const INT width, - INT *bitCount) -{ - +static void FDKaacEnc_count5_6_7_8_9_10_11(const SHORT *const values, + const INT width, + INT *RESTRICT bitCount) { INT i; - INT bc5_6,bc7_8,bc9_10,bc11,sc; - INT t0,t1; - bc5_6=0; - bc7_8=0; - bc9_10=0; - bc11=0; - sc=0; - - for(i=0;i0)+(t1>0); + INT bc5_6, bc7_8, bc9_10, bc11, sc; + INT t0, t1, t2, t3; + bc5_6 = 0; + bc7_8 = 0; + bc9_10 = 0; + bc11 = 0; + sc = 0; + + DWORD_ALIGNED(values); + + for (i = 0; i < width; i += 4) { + t0 = values[i + 0]; + t1 = values[i + 1]; + t2 = values[i + 2]; + t3 = values[i + 3]; + + bc5_6 += (INT)FDKaacEnc_huff_ltab5_6[t0 + 4][t1 + 4] + + (INT)FDKaacEnc_huff_ltab5_6[t2 + 4][t3 + 4]; + + t0 = fixp_abs(t0); + sc += (t0 > 0); + t1 = fixp_abs(t1); + sc += (t1 > 0); + t2 = fixp_abs(t2); + sc += (t2 > 0); + t3 = fixp_abs(t3); + sc += (t3 > 0); + + bc7_8 += (INT)FDKaacEnc_huff_ltab7_8[t0][t1] + + (INT)FDKaacEnc_huff_ltab7_8[t2][t3]; + bc9_10 += (INT)FDKaacEnc_huff_ltab9_10[t0][t1] + + (INT)FDKaacEnc_huff_ltab9_10[t2][t3]; + bc11 += + (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3]; } - bitCount[1]=INVALID_BITCOUNT; - bitCount[2]=INVALID_BITCOUNT; - bitCount[3]=INVALID_BITCOUNT; - bitCount[4]=INVALID_BITCOUNT; - bitCount[5]=HI_LTAB(bc5_6); - bitCount[6]=LO_LTAB(bc5_6); - bitCount[7]=HI_LTAB(bc7_8)+sc; - bitCount[8]=LO_LTAB(bc7_8)+sc; - bitCount[9]=HI_LTAB(bc9_10)+sc; - bitCount[10]=LO_LTAB(bc9_10)+sc; - bitCount[11]=bc11+sc; - + bitCount[1] = INVALID_BITCOUNT; + bitCount[2] = INVALID_BITCOUNT; + bitCount[3] = INVALID_BITCOUNT; + bitCount[4] = INVALID_BITCOUNT; + bitCount[5] = HI_LTAB(bc5_6); + bitCount[6] = LO_LTAB(bc5_6); + bitCount[7] = HI_LTAB(bc7_8) + sc; + bitCount[8] = LO_LTAB(bc7_8) + sc; + bitCount[9] = HI_LTAB(bc9_10) + sc; + bitCount[10] = LO_LTAB(bc9_10) + sc; + bitCount[11] = bc11 + sc; } - /***************************************************************************** functionname: FDKaacEnc_count7_8_9_10_11 @@ -308,42 +312,54 @@ static void FDKaacEnc_count5_6_7_8_9_10_11(const SHORT *RESTRICT values, *****************************************************************************/ -static void FDKaacEnc_count7_8_9_10_11(const SHORT *RESTRICT values, - const INT width, - INT *bitCount) -{ - +static void FDKaacEnc_count7_8_9_10_11(const SHORT *const values, + const INT width, + INT *RESTRICT bitCount) { INT i; - INT bc7_8,bc9_10,bc11,sc; - INT t0,t1; - - bc7_8=0; - bc9_10=0; - bc11=0; - sc=0; - - for(i=0;i0)+(t1>0); + INT bc7_8, bc9_10, bc11, sc; + INT t0, t1, t2, t3; + + bc7_8 = 0; + bc9_10 = 0; + bc11 = 0; + sc = 0; + + DWORD_ALIGNED(values); + + for (i = 0; i < width; i += 4) { + t0 = values[i + 0]; + t1 = values[i + 1]; + t2 = values[i + 2]; + t3 = values[i + 3]; + + t0 = fixp_abs(t0); + sc += (t0 > 0); + t1 = fixp_abs(t1); + sc += (t1 > 0); + t2 = fixp_abs(t2); + sc += (t2 > 0); + t3 = fixp_abs(t3); + sc += (t3 > 0); + + bc7_8 += (INT)FDKaacEnc_huff_ltab7_8[t0][t1] + + (INT)FDKaacEnc_huff_ltab7_8[t2][t3]; + bc9_10 += (INT)FDKaacEnc_huff_ltab9_10[t0][t1] + + (INT)FDKaacEnc_huff_ltab9_10[t2][t3]; + bc11 += + (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3]; } - bitCount[1]=INVALID_BITCOUNT; - bitCount[2]=INVALID_BITCOUNT; - bitCount[3]=INVALID_BITCOUNT; - bitCount[4]=INVALID_BITCOUNT; - bitCount[5]=INVALID_BITCOUNT; - bitCount[6]=INVALID_BITCOUNT; - bitCount[7]=HI_LTAB(bc7_8)+sc; - bitCount[8]=LO_LTAB(bc7_8)+sc; - bitCount[9]=HI_LTAB(bc9_10)+sc; - bitCount[10]=LO_LTAB(bc9_10)+sc; - bitCount[11]=bc11+sc; - + bitCount[1] = INVALID_BITCOUNT; + bitCount[2] = INVALID_BITCOUNT; + bitCount[3] = INVALID_BITCOUNT; + bitCount[4] = INVALID_BITCOUNT; + bitCount[5] = INVALID_BITCOUNT; + bitCount[6] = INVALID_BITCOUNT; + bitCount[7] = HI_LTAB(bc7_8) + sc; + bitCount[8] = LO_LTAB(bc7_8) + sc; + bitCount[9] = HI_LTAB(bc9_10) + sc; + bitCount[10] = LO_LTAB(bc9_10) + sc; + bitCount[11] = bc11 + sc; } /***************************************************************************** @@ -356,43 +372,50 @@ static void FDKaacEnc_count7_8_9_10_11(const SHORT *RESTRICT values, *****************************************************************************/ - - -static void FDKaacEnc_count9_10_11(const SHORT *RESTRICT values, - const INT width, - INT *bitCount) -{ - +static void FDKaacEnc_count9_10_11(const SHORT *const values, const INT width, + INT *RESTRICT bitCount) { INT i; - INT bc9_10,bc11,sc; - INT t0,t1; - - bc9_10=0; - bc11=0; - sc=0; - - for(i=0;i0)+(t1>0); + INT bc9_10, bc11, sc; + INT t0, t1, t2, t3; + + bc9_10 = 0; + bc11 = 0; + sc = 0; + + DWORD_ALIGNED(values); + + for (i = 0; i < width; i += 4) { + t0 = values[i + 0]; + t1 = values[i + 1]; + t2 = values[i + 2]; + t3 = values[i + 3]; + + t0 = fixp_abs(t0); + sc += (t0 > 0); + t1 = fixp_abs(t1); + sc += (t1 > 0); + t2 = fixp_abs(t2); + sc += (t2 > 0); + t3 = fixp_abs(t3); + sc += (t3 > 0); + + bc9_10 += (INT)FDKaacEnc_huff_ltab9_10[t0][t1] + + (INT)FDKaacEnc_huff_ltab9_10[t2][t3]; + bc11 += + (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3]; } - bitCount[1]=INVALID_BITCOUNT; - bitCount[2]=INVALID_BITCOUNT; - bitCount[3]=INVALID_BITCOUNT; - bitCount[4]=INVALID_BITCOUNT; - bitCount[5]=INVALID_BITCOUNT; - bitCount[6]=INVALID_BITCOUNT; - bitCount[7]=INVALID_BITCOUNT; - bitCount[8]=INVALID_BITCOUNT; - bitCount[9]=HI_LTAB(bc9_10)+sc; - bitCount[10]=LO_LTAB(bc9_10)+sc; - bitCount[11]=bc11+sc; - + bitCount[1] = INVALID_BITCOUNT; + bitCount[2] = INVALID_BITCOUNT; + bitCount[3] = INVALID_BITCOUNT; + bitCount[4] = INVALID_BITCOUNT; + bitCount[5] = INVALID_BITCOUNT; + bitCount[6] = INVALID_BITCOUNT; + bitCount[7] = INVALID_BITCOUNT; + bitCount[8] = INVALID_BITCOUNT; + bitCount[9] = HI_LTAB(bc9_10) + sc; + bitCount[10] = LO_LTAB(bc9_10) + sc; + bitCount[11] = bc11 + sc; } /***************************************************************************** @@ -405,35 +428,47 @@ static void FDKaacEnc_count9_10_11(const SHORT *RESTRICT values, *****************************************************************************/ -static void FDKaacEnc_count11(const SHORT *RESTRICT values, - const INT width, - INT *bitCount) -{ - +static void FDKaacEnc_count11(const SHORT *const values, const INT width, + INT *RESTRICT bitCount) { INT i; - INT bc11,sc; - INT t0,t1; - - bc11=0; - sc=0; - for(i=0;i0)+(t1>0); + INT bc11, sc; + INT t0, t1, t2, t3; + + bc11 = 0; + sc = 0; + + DWORD_ALIGNED(values); + + for (i = 0; i < width; i += 4) { + t0 = values[i + 0]; + t1 = values[i + 1]; + t2 = values[i + 2]; + t3 = values[i + 3]; + + t0 = fixp_abs(t0); + sc += (t0 > 0); + t1 = fixp_abs(t1); + sc += (t1 > 0); + t2 = fixp_abs(t2); + sc += (t2 > 0); + t3 = fixp_abs(t3); + sc += (t3 > 0); + + bc11 += + (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3]; } - bitCount[1]=INVALID_BITCOUNT; - bitCount[2]=INVALID_BITCOUNT; - bitCount[3]=INVALID_BITCOUNT; - bitCount[4]=INVALID_BITCOUNT; - bitCount[5]=INVALID_BITCOUNT; - bitCount[6]=INVALID_BITCOUNT; - bitCount[7]=INVALID_BITCOUNT; - bitCount[8]=INVALID_BITCOUNT; - bitCount[9]=INVALID_BITCOUNT; - bitCount[10]=INVALID_BITCOUNT; - bitCount[11]=bc11+sc; + bitCount[1] = INVALID_BITCOUNT; + bitCount[2] = INVALID_BITCOUNT; + bitCount[3] = INVALID_BITCOUNT; + bitCount[4] = INVALID_BITCOUNT; + bitCount[5] = INVALID_BITCOUNT; + bitCount[6] = INVALID_BITCOUNT; + bitCount[7] = INVALID_BITCOUNT; + bitCount[8] = INVALID_BITCOUNT; + bitCount[9] = INVALID_BITCOUNT; + bitCount[10] = INVALID_BITCOUNT; + bitCount[11] = bc11 + sc; } /***************************************************************************** @@ -446,677 +481,470 @@ static void FDKaacEnc_count11(const SHORT *RESTRICT values, *****************************************************************************/ -static void FDKaacEnc_countEsc(const SHORT *RESTRICT values, - const INT width, - INT *RESTRICT bitCount) -{ - +static void FDKaacEnc_countEsc(const SHORT *const values, const INT width, + INT *RESTRICT bitCount) { INT i; - INT bc11,ec,sc; - INT t0,t1,t00,t01; - - bc11=0; - sc=0; - ec=0; - for(i=0;i0)+(t1>0); - - t00 = fixMin(t0,16); - t01 = fixMin(t1,16); - bc11+= (INT) FDKaacEnc_huff_ltab11[t00][t01]; - - if(t0>=16){ - ec+=5; - while((t0>>=1) >= 16) - ec+=2; + INT bc11, ec, sc; + INT t0, t1, t00, t01; + + bc11 = 0; + sc = 0; + ec = 0; + for (i = 0; i < width; i += 2) { + t0 = fixp_abs(values[i + 0]); + t1 = fixp_abs(values[i + 1]); + + sc += (t0 > 0) + (t1 > 0); + + t00 = fixMin(t0, 16); + t01 = fixMin(t1, 16); + bc11 += (INT)FDKaacEnc_huff_ltab11[t00][t01]; + + if (t0 >= 16) { + ec += 5; + while ((t0 >>= 1) >= 16) ec += 2; } - if(t1>=16){ - ec+=5; - while((t1>>=1) >= 16) - ec+=2; + if (t1 >= 16) { + ec += 5; + while ((t1 >>= 1) >= 16) ec += 2; } } - for (i=0; i<11; i++) - bitCount[i]=INVALID_BITCOUNT; + for (i = 0; i < 11; i++) bitCount[i] = INVALID_BITCOUNT; - bitCount[11]=bc11+sc+ec; + bitCount[11] = bc11 + sc + ec; } - -typedef void (*COUNT_FUNCTION)(const SHORT *RESTRICT values, - const INT width, - INT *RESTRICT bitCount); - -static const COUNT_FUNCTION countFuncTable[CODE_BOOK_ESC_LAV+1] = -{ - - FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11, /* 0 */ - FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11, /* 1 */ - FDKaacEnc_count3_4_5_6_7_8_9_10_11, /* 2 */ - FDKaacEnc_count5_6_7_8_9_10_11, /* 3 */ - FDKaacEnc_count5_6_7_8_9_10_11, /* 4 */ - FDKaacEnc_count7_8_9_10_11, /* 5 */ - FDKaacEnc_count7_8_9_10_11, /* 6 */ - FDKaacEnc_count7_8_9_10_11, /* 7 */ - FDKaacEnc_count9_10_11, /* 8 */ - FDKaacEnc_count9_10_11, /* 9 */ - FDKaacEnc_count9_10_11, /* 10 */ - FDKaacEnc_count9_10_11, /* 11 */ - FDKaacEnc_count9_10_11, /* 12 */ - FDKaacEnc_count11, /* 13 */ - FDKaacEnc_count11, /* 14 */ - FDKaacEnc_count11, /* 15 */ - FDKaacEnc_countEsc /* 16 */ +typedef void (*COUNT_FUNCTION)(const SHORT *const values, const INT width, + INT *RESTRICT bitCount); + +static const COUNT_FUNCTION countFuncTable[CODE_BOOK_ESC_LAV + 1] = { + + FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11, /* 0 */ + FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11, /* 1 */ + FDKaacEnc_count3_4_5_6_7_8_9_10_11, /* 2 */ + FDKaacEnc_count5_6_7_8_9_10_11, /* 3 */ + FDKaacEnc_count5_6_7_8_9_10_11, /* 4 */ + FDKaacEnc_count7_8_9_10_11, /* 5 */ + FDKaacEnc_count7_8_9_10_11, /* 6 */ + FDKaacEnc_count7_8_9_10_11, /* 7 */ + FDKaacEnc_count9_10_11, /* 8 */ + FDKaacEnc_count9_10_11, /* 9 */ + FDKaacEnc_count9_10_11, /* 10 */ + FDKaacEnc_count9_10_11, /* 11 */ + FDKaacEnc_count9_10_11, /* 12 */ + FDKaacEnc_count11, /* 13 */ + FDKaacEnc_count11, /* 14 */ + FDKaacEnc_count11, /* 15 */ + FDKaacEnc_countEsc /* 16 */ }; - - -INT FDKaacEnc_bitCount(const SHORT *values, - const INT width, - INT maxVal, - INT *bitCount) -{ - +INT FDKaacEnc_bitCount(const SHORT *const values, const INT width, + const INT maxVal, INT *const RESTRICT bitCount) { /* check if we can use codebook 0 */ - if(maxVal == 0) - bitCount[0] = 0; - else - bitCount[0] = INVALID_BITCOUNT; - - maxVal = fixMin(maxVal,(INT)CODE_BOOK_ESC_LAV); - countFuncTable[maxVal](values,width,bitCount); - return(0); -} - + bitCount[0] = (maxVal == 0) ? 0 : INVALID_BITCOUNT; + countFuncTable[fixMin(maxVal, (INT)CODE_BOOK_ESC_LAV)](values, width, + bitCount); + return (0); +} /* count difference between actual and zeroed lines */ -INT FDKaacEnc_countValues(SHORT *RESTRICT values, INT width, INT codeBook) -{ - - INT i,t0,t1,t2,t3,t00,t01; - INT codeLength; - INT signLength; - INT bitCnt=0; - - switch(codeBook){ - case CODE_BOOK_ZERO_NO: - break; - - case CODE_BOOK_1_NO: - for(i=0; i=16){ - INT n,p; - n=0; - p=t0; - while((p>>=1) >=16){ - bitCnt++; - n++; +INT FDKaacEnc_countValues(SHORT *RESTRICT values, INT width, INT codeBook) { + INT i, t0, t1, t2, t3; + INT bitCnt = 0; + + switch (codeBook) { + case CODE_BOOK_ZERO_NO: + break; + + case CODE_BOOK_1_NO: + for (i = 0; i < width; i += 4) { + t0 = values[i + 0]; + t1 = values[i + 1]; + t2 = values[i + 2]; + t3 = values[i + 3]; + bitCnt += + HI_LTAB(FDKaacEnc_huff_ltab1_2[t0 + 1][t1 + 1][t2 + 1][t3 + 1]); + } + break; + + case CODE_BOOK_2_NO: + for (i = 0; i < width; i += 4) { + t0 = values[i + 0]; + t1 = values[i + 1]; + t2 = values[i + 2]; + t3 = values[i + 3]; + bitCnt += + LO_LTAB(FDKaacEnc_huff_ltab1_2[t0 + 1][t1 + 1][t2 + 1][t3 + 1]); + } + break; + + case CODE_BOOK_3_NO: + for (i = 0; i < width; i += 4) { + t0 = fixp_abs(values[i + 0]); + bitCnt += (t0 > 0); + t1 = fixp_abs(values[i + 1]); + bitCnt += (t1 > 0); + t2 = fixp_abs(values[i + 2]); + bitCnt += (t2 > 0); + t3 = fixp_abs(values[i + 3]); + bitCnt += (t3 > 0); + bitCnt += HI_LTAB(FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3]); + } + break; + + case CODE_BOOK_4_NO: + for (i = 0; i < width; i += 4) { + t0 = fixp_abs(values[i + 0]); + bitCnt += (t0 > 0); + t1 = fixp_abs(values[i + 1]); + bitCnt += (t1 > 0); + t2 = fixp_abs(values[i + 2]); + bitCnt += (t2 > 0); + t3 = fixp_abs(values[i + 3]); + bitCnt += (t3 > 0); + bitCnt += LO_LTAB(FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3]); + } + break; + + case CODE_BOOK_5_NO: + for (i = 0; i < width; i += 4) { + t0 = values[i + 0]; + t1 = values[i + 1]; + t2 = values[i + 2]; + t3 = values[i + 3]; + bitCnt += HI_LTAB(FDKaacEnc_huff_ltab5_6[t0 + 4][t1 + 4]) + + HI_LTAB(FDKaacEnc_huff_ltab5_6[t2 + 4][t3 + 4]); + } + break; + + case CODE_BOOK_6_NO: + for (i = 0; i < width; i += 4) { + t0 = values[i + 0]; + t1 = values[i + 1]; + t2 = values[i + 2]; + t3 = values[i + 3]; + bitCnt += LO_LTAB(FDKaacEnc_huff_ltab5_6[t0 + 4][t1 + 4]) + + LO_LTAB(FDKaacEnc_huff_ltab5_6[t2 + 4][t3 + 4]); + } + break; + + case CODE_BOOK_7_NO: + for (i = 0; i < width; i += 4) { + t0 = fixp_abs(values[i + 0]); + bitCnt += (t0 > 0); + t1 = fixp_abs(values[i + 1]); + bitCnt += (t1 > 0); + t2 = fixp_abs(values[i + 2]); + bitCnt += (t2 > 0); + t3 = fixp_abs(values[i + 3]); + bitCnt += (t3 > 0); + bitCnt += HI_LTAB(FDKaacEnc_huff_ltab7_8[t0][t1]) + + HI_LTAB(FDKaacEnc_huff_ltab7_8[t2][t3]); + } + break; + + case CODE_BOOK_8_NO: + for (i = 0; i < width; i += 4) { + t0 = fixp_abs(values[i + 0]); + bitCnt += (t0 > 0); + t1 = fixp_abs(values[i + 1]); + bitCnt += (t1 > 0); + t2 = fixp_abs(values[i + 2]); + bitCnt += (t2 > 0); + t3 = fixp_abs(values[i + 3]); + bitCnt += (t3 > 0); + bitCnt += LO_LTAB(FDKaacEnc_huff_ltab7_8[t0][t1]) + + LO_LTAB(FDKaacEnc_huff_ltab7_8[t2][t3]); + } + break; + + case CODE_BOOK_9_NO: + for (i = 0; i < width; i += 4) { + t0 = fixp_abs(values[i + 0]); + bitCnt += (t0 > 0); + t1 = fixp_abs(values[i + 1]); + bitCnt += (t1 > 0); + t2 = fixp_abs(values[i + 2]); + bitCnt += (t2 > 0); + t3 = fixp_abs(values[i + 3]); + bitCnt += (t3 > 0); + bitCnt += HI_LTAB(FDKaacEnc_huff_ltab9_10[t0][t1]) + + HI_LTAB(FDKaacEnc_huff_ltab9_10[t2][t3]); + } + break; + + case CODE_BOOK_10_NO: + for (i = 0; i < width; i += 4) { + t0 = fixp_abs(values[i + 0]); + bitCnt += (t0 > 0); + t1 = fixp_abs(values[i + 1]); + bitCnt += (t1 > 0); + t2 = fixp_abs(values[i + 2]); + bitCnt += (t2 > 0); + t3 = fixp_abs(values[i + 3]); + bitCnt += (t3 > 0); + bitCnt += LO_LTAB(FDKaacEnc_huff_ltab9_10[t0][t1]) + + LO_LTAB(FDKaacEnc_huff_ltab9_10[t2][t3]); + } + break; + + case CODE_BOOK_ESC_NO: + for (i = 0; i < width; i += 2) { + t0 = fixp_abs(values[i + 0]); + bitCnt += (t0 > 0); + t1 = fixp_abs(values[i + 1]); + bitCnt += (t1 > 0); + bitCnt += (INT)FDKaacEnc_huff_ltab11[fixMin(t0, 16)][fixMin(t1, 16)]; + if (t0 >= 16) { + bitCnt += 5; + while ((t0 >>= 1) >= 16) bitCnt += 2; } - bitCnt+=(n+5); - } - if(t1 >=16){ - INT n,p; - n=0; - p=t1; - while((p>>=1) >=16){ - bitCnt++; - n++; + if (t1 >= 16) { + bitCnt += 5; + while ((t1 >>= 1) >= 16) bitCnt += 2; } - bitCnt+=(n+5); } - } - break; + break; - default: - break; + default: + break; } - return(bitCnt); + return (bitCnt); } - - -INT FDKaacEnc_codeValues(SHORT *RESTRICT values, INT width, INT codeBook, HANDLE_FDK_BITSTREAM hBitstream) -{ - - INT i,t0,t1,t2,t3,t00,t01; - INT codeWord,codeLength; - INT sign,signLength; - - switch(codeBook){ - case CODE_BOOK_ZERO_NO: - break; - - case CODE_BOOK_1_NO: - for(i=0; i> 2); i++) { + sign = 0; + signLength = 0; + int index[4]; + for (int j = 0; j < 4; j++) { + int ti = *values++; + int zero = (ti == 0) ? 0 : 1; + signLength += zero; + sign = (sign << zero) + ((UINT)ti >> 31); + index[j] = fixp_abs(ti); } - } - t1 = values[i+1]; - if(t1 != 0){ - signLength++; - sign<<=1; - if(t1 < 0){ - sign|=1; - t1=fixp_abs(t1); - } - } - t2 = values[i+2]; - if(t2 != 0){ - signLength++; - sign<<=1; - if(t2 < 0){ - sign|=1; - t2=fixp_abs(t2); + codeWord = FDKaacEnc_huff_ctab3[index[0]][index[1]][index[2]][index[3]]; + codeLength = HI_LTAB( + FDKaacEnc_huff_ltab3_4[index[0]][index[1]][index[2]][index[3]]); + FDKwriteBits(hBitstream, (codeWord << signLength) | sign, + codeLength + signLength); + } + break; + + case CODE_BOOK_4_NO: + for (i = 0; i < width; i += 4) { + sign = 0; + signLength = 0; + int index[4]; + for (int j = 0; j < 4; j++) { + int ti = *values++; + int zero = (ti == 0) ? 0 : 1; + signLength += zero; + sign = (sign << zero) + ((UINT)ti >> 31); + index[j] = fixp_abs(ti); } - } - t3 = values[i+3]; - if(t3 != 0){ - signLength++; - sign<<=1; - if(t3 < 0){ - sign|=1; - t3=fixp_abs(t3); + codeWord = FDKaacEnc_huff_ctab4[index[0]][index[1]][index[2]][index[3]]; + codeLength = LO_LTAB( + FDKaacEnc_huff_ltab3_4[index[0]][index[1]][index[2]][index[3]]); + FDKwriteBits(hBitstream, (codeWord << signLength) | sign, + codeLength + signLength); + } + break; + + case CODE_BOOK_5_NO: + for (i = 0; i < (width >> 2); i++) { + t0 = *values++ + 4; + t1 = *values++ + 4; + t2 = *values++ + 4; + t3 = *values++ + 4; + codeWord = FDKaacEnc_huff_ctab5[t0][t1]; + codeLength = + HI_LTAB(FDKaacEnc_huff_ltab5_6[t2][t3]); /* length of 2nd cw */ + codeWord = (codeWord << codeLength) + FDKaacEnc_huff_ctab5[t2][t3]; + codeLength += HI_LTAB(FDKaacEnc_huff_ltab5_6[t0][t1]); + FDKwriteBits(hBitstream, codeWord, codeLength); + } + break; + + case CODE_BOOK_6_NO: + for (i = 0; i < (width >> 2); i++) { + t0 = *values++ + 4; + t1 = *values++ + 4; + t2 = *values++ + 4; + t3 = *values++ + 4; + codeWord = FDKaacEnc_huff_ctab6[t0][t1]; + codeLength = + LO_LTAB(FDKaacEnc_huff_ltab5_6[t2][t3]); /* length of 2nd cw */ + codeWord = (codeWord << codeLength) + FDKaacEnc_huff_ctab6[t2][t3]; + codeLength += LO_LTAB(FDKaacEnc_huff_ltab5_6[t0][t1]); + FDKwriteBits(hBitstream, codeWord, codeLength); + } + break; + + case CODE_BOOK_7_NO: + for (i = 0; i < (width >> 1); i++) { + t0 = *values++; + sign = ((UINT)t0 >> 31); + t0 = fixp_abs(t0); + signLength = (t0 == 0) ? 0 : 1; + t1 = *values++; + INT zero = (t1 == 0) ? 0 : 1; + signLength += zero; + sign = (sign << zero) + ((UINT)t1 >> 31); + t1 = fixp_abs(t1); + codeWord = FDKaacEnc_huff_ctab7[t0][t1]; + codeLength = HI_LTAB(FDKaacEnc_huff_ltab7_8[t0][t1]); + FDKwriteBits(hBitstream, (codeWord << signLength) | sign, + codeLength + signLength); + } + break; + + case CODE_BOOK_8_NO: + for (i = 0; i < (width >> 1); i++) { + t0 = *values++; + sign = ((UINT)t0 >> 31); + t0 = fixp_abs(t0); + signLength = (t0 == 0) ? 0 : 1; + t1 = *values++; + INT zero = (t1 == 0) ? 0 : 1; + signLength += zero; + sign = (sign << zero) + ((UINT)t1 >> 31); + t1 = fixp_abs(t1); + codeWord = FDKaacEnc_huff_ctab8[t0][t1]; + codeLength = LO_LTAB(FDKaacEnc_huff_ltab7_8[t0][t1]); + FDKwriteBits(hBitstream, (codeWord << signLength) | sign, + codeLength + signLength); + } + break; + + case CODE_BOOK_9_NO: + for (i = 0; i < (width >> 1); i++) { + t0 = *values++; + sign = ((UINT)t0 >> 31); + t0 = fixp_abs(t0); + signLength = (t0 == 0) ? 0 : 1; + t1 = *values++; + INT zero = (t1 == 0) ? 0 : 1; + signLength += zero; + sign = (sign << zero) + ((UINT)t1 >> 31); + t1 = fixp_abs(t1); + codeWord = FDKaacEnc_huff_ctab9[t0][t1]; + codeLength = HI_LTAB(FDKaacEnc_huff_ltab9_10[t0][t1]); + FDKwriteBits(hBitstream, (codeWord << signLength) | sign, + codeLength + signLength); + } + break; + + case CODE_BOOK_10_NO: + for (i = 0; i < (width >> 1); i++) { + t0 = *values++; + sign = ((UINT)t0 >> 31); + t0 = fixp_abs(t0); + signLength = (t0 == 0) ? 0 : 1; + t1 = *values++; + INT zero = (t1 == 0) ? 0 : 1; + signLength += zero; + sign = (sign << zero) + ((UINT)t1 >> 31); + t1 = fixp_abs(t1); + codeWord = FDKaacEnc_huff_ctab10[t0][t1]; + codeLength = LO_LTAB(FDKaacEnc_huff_ltab9_10[t0][t1]); + FDKwriteBits(hBitstream, (codeWord << signLength) | sign, + codeLength + signLength); + } + break; + + case CODE_BOOK_ESC_NO: + for (i = 0; i < (width >> 1); i++) { + t0 = *values++; + sign = ((UINT)t0 >> 31); + t0 = fixp_abs(t0); + signLength = (t0 == 0) ? 0 : 1; + t1 = *values++; + INT zero = (t1 == 0) ? 0 : 1; + signLength += zero; + sign = (sign << zero) + ((UINT)t1 >> 31); + t1 = fixp_abs(t1); + + t00 = fixMin(t0, 16); + t01 = fixMin(t1, 16); + + codeWord = FDKaacEnc_huff_ctab11[t00][t01]; + codeLength = (INT)FDKaacEnc_huff_ltab11[t00][t01]; + FDKwriteBits(hBitstream, (codeWord << signLength) | sign, + codeLength + signLength); + for (int j = 0; j < 2; j++) { + if (t0 >= 16) { + INT n = 4, p = t0; + for (; (p >>= 1) >= 16;) n++; + FDKwriteBits(hBitstream, + (((1 << (n - 3)) - 2) << n) | (t0 - (1 << n)), + n + n - 3); + } + t0 = t1; } } + break; - codeWord = FDKaacEnc_huff_ctab3[t0][t1][t2][t3]; - codeLength = HI_LTAB(FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3]); - FDKwriteBits(hBitstream,codeWord,codeLength); - FDKwriteBits(hBitstream,sign,signLength); - } - break; - - case CODE_BOOK_4_NO: - for(i=0; i=16){ - INT n,p; - n=0; - p=t0; - while((p>>=1) >=16){ - FDKwriteBits(hBitstream,1,1); - n++; - } - FDKwriteBits(hBitstream,0,1); - FDKwriteBits(hBitstream,t0-(1<<(n+4)),n+4); - } - if(t1 >=16){ - INT n,p; - n=0; - p=t1; - while((p>>=1) >=16){ - FDKwriteBits(hBitstream,1,1); - n++; - } - FDKwriteBits(hBitstream,0,1); - FDKwriteBits(hBitstream,t1-(1<<(n+4)),n+4); - } - } - break; - - default: - break; + default: + break; } - return(0); + return (0); } -INT FDKaacEnc_codeScalefactorDelta(INT delta, HANDLE_FDK_BITSTREAM hBitstream) -{ - INT codeWord,codeLength; +INT FDKaacEnc_codeScalefactorDelta(INT delta, HANDLE_FDK_BITSTREAM hBitstream) { + INT codeWord, codeLength; - if(fixp_abs(delta) >CODE_BOOK_SCF_LAV) - return(1); + if (fixp_abs(delta) > CODE_BOOK_SCF_LAV) return (1); - codeWord = FDKaacEnc_huff_ctabscf[delta+CODE_BOOK_SCF_LAV]; - codeLength = (INT)FDKaacEnc_huff_ltabscf[delta+CODE_BOOK_SCF_LAV]; - FDKwriteBits(hBitstream,codeWord,codeLength); - return(0); + codeWord = FDKaacEnc_huff_ctabscf[delta + CODE_BOOK_SCF_LAV]; + codeLength = (INT)FDKaacEnc_huff_ltabscf[delta + CODE_BOOK_SCF_LAV]; + FDKwriteBits(hBitstream, codeWord, codeLength); + return (0); } - - - diff --git a/libAACenc/src/bit_cnt.h b/libAACenc/src/bit_cnt.h index 7c4b59e..7f4c450 100644 --- a/libAACenc/src/bit_cnt.h +++ b/libAACenc/src/bit_cnt.h @@ -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,46 +90,46 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M.Werner - contents/description: Huffman Bitcounter & coder + Author(s): M.Werner -******************************************************************************/ + Description: Huffman Bitcounter & coder -#ifndef __BITCOUNT_H -#define __BITCOUNT_H +*******************************************************************************/ +#ifndef BIT_CNT_H +#define BIT_CNT_H #include "common_fix.h" #include "FDK_bitstream.h" #include "aacEnc_rom.h" -#define INVALID_BITCOUNT (FDK_INT_MAX/4) +#define INVALID_BITCOUNT (FDK_INT_MAX / 4) /* code book number table */ -enum codeBookNo{ - CODE_BOOK_ZERO_NO= 0, - CODE_BOOK_1_NO= 1, - CODE_BOOK_2_NO= 2, - CODE_BOOK_3_NO= 3, - CODE_BOOK_4_NO= 4, - CODE_BOOK_5_NO= 5, - CODE_BOOK_6_NO= 6, - CODE_BOOK_7_NO= 7, - CODE_BOOK_8_NO= 8, - CODE_BOOK_9_NO= 9, - CODE_BOOK_10_NO= 10, - CODE_BOOK_ESC_NO= 11, - CODE_BOOK_RES_NO= 12, - CODE_BOOK_PNS_NO= 13, - CODE_BOOK_IS_OUT_OF_PHASE_NO= 14, - CODE_BOOK_IS_IN_PHASE_NO= 15 +enum codeBookNo { + CODE_BOOK_ZERO_NO = 0, + CODE_BOOK_1_NO = 1, + CODE_BOOK_2_NO = 2, + CODE_BOOK_3_NO = 3, + CODE_BOOK_4_NO = 4, + CODE_BOOK_5_NO = 5, + CODE_BOOK_6_NO = 6, + CODE_BOOK_7_NO = 7, + CODE_BOOK_8_NO = 8, + CODE_BOOK_9_NO = 9, + CODE_BOOK_10_NO = 10, + CODE_BOOK_ESC_NO = 11, + CODE_BOOK_RES_NO = 12, + CODE_BOOK_PNS_NO = 13, + CODE_BOOK_IS_OUT_OF_PHASE_NO = 14, + CODE_BOOK_IS_IN_PHASE_NO = 15 }; @@ -126,62 +137,64 @@ enum codeBookNo{ code book index table */ -enum codeBookNdx{ - CODE_BOOK_ZERO_NDX, - CODE_BOOK_1_NDX, - CODE_BOOK_2_NDX, - CODE_BOOK_3_NDX, - CODE_BOOK_4_NDX, - CODE_BOOK_5_NDX, - CODE_BOOK_6_NDX, - CODE_BOOK_7_NDX, - CODE_BOOK_8_NDX, - CODE_BOOK_9_NDX, - CODE_BOOK_10_NDX, - CODE_BOOK_ESC_NDX, - CODE_BOOK_RES_NDX, - CODE_BOOK_PNS_NDX, - CODE_BOOK_IS_OUT_OF_PHASE_NDX, - CODE_BOOK_IS_IN_PHASE_NDX, - NUMBER_OF_CODE_BOOKS +enum codeBookNdx { + CODE_BOOK_ZERO_NDX, + CODE_BOOK_1_NDX, + CODE_BOOK_2_NDX, + CODE_BOOK_3_NDX, + CODE_BOOK_4_NDX, + CODE_BOOK_5_NDX, + CODE_BOOK_6_NDX, + CODE_BOOK_7_NDX, + CODE_BOOK_8_NDX, + CODE_BOOK_9_NDX, + CODE_BOOK_10_NDX, + CODE_BOOK_ESC_NDX, + CODE_BOOK_RES_NDX, + CODE_BOOK_PNS_NDX, + CODE_BOOK_IS_OUT_OF_PHASE_NDX, + CODE_BOOK_IS_IN_PHASE_NDX, + NUMBER_OF_CODE_BOOKS }; /* code book lav table */ -enum codeBookLav{ - CODE_BOOK_ZERO_LAV=0, - CODE_BOOK_1_LAV=1, - CODE_BOOK_2_LAV=1, - CODE_BOOK_3_LAV=2, - CODE_BOOK_4_LAV=2, - CODE_BOOK_5_LAV=4, - CODE_BOOK_6_LAV=4, - CODE_BOOK_7_LAV=7, - CODE_BOOK_8_LAV=7, - CODE_BOOK_9_LAV=12, - CODE_BOOK_10_LAV=12, - CODE_BOOK_ESC_LAV=16, - CODE_BOOK_SCF_LAV=60, - CODE_BOOK_PNS_LAV=60 - }; - -INT FDKaacEnc_bitCount(const SHORT *aQuantSpectrum, - const INT noOfSpecLines, - INT maxVal, - INT *bitCountLut); - -INT FDKaacEnc_countValues(SHORT *values, INT width, INT codeBook); - -INT FDKaacEnc_codeValues(SHORT *values, INT width, INT codeBook, HANDLE_FDK_BITSTREAM hBitstream); - -INT FDKaacEnc_codeScalefactorDelta(INT scalefactor, HANDLE_FDK_BITSTREAM hBitstream); - -inline INT FDKaacEnc_bitCountScalefactorDelta(const INT delta) -{ - FDK_ASSERT( (0 <= (delta+CODE_BOOK_SCF_LAV)) && ((delta+CODE_BOOK_SCF_LAV)<(int)(sizeof(FDKaacEnc_huff_ltabscf)/sizeof((FDKaacEnc_huff_ltabscf[0])))) ); - return((INT)FDKaacEnc_huff_ltabscf[delta+CODE_BOOK_SCF_LAV]); +enum codeBookLav { + CODE_BOOK_ZERO_LAV = 0, + CODE_BOOK_1_LAV = 1, + CODE_BOOK_2_LAV = 1, + CODE_BOOK_3_LAV = 2, + CODE_BOOK_4_LAV = 2, + CODE_BOOK_5_LAV = 4, + CODE_BOOK_6_LAV = 4, + CODE_BOOK_7_LAV = 7, + CODE_BOOK_8_LAV = 7, + CODE_BOOK_9_LAV = 12, + CODE_BOOK_10_LAV = 12, + CODE_BOOK_ESC_LAV = 16, + CODE_BOOK_SCF_LAV = 60, + CODE_BOOK_PNS_LAV = 60 +}; + +INT FDKaacEnc_bitCount(const SHORT *aQuantSpectrum, const INT noOfSpecLines, + INT maxVal, INT *bitCountLut); + +INT FDKaacEnc_countValues(SHORT *values, INT width, INT codeBook); + +INT FDKaacEnc_codeValues(SHORT *values, INT width, INT codeBook, + HANDLE_FDK_BITSTREAM hBitstream); + +INT FDKaacEnc_codeScalefactorDelta(INT scalefactor, + HANDLE_FDK_BITSTREAM hBitstream); + +inline INT FDKaacEnc_bitCountScalefactorDelta(const INT delta) { + FDK_ASSERT((0 <= (delta + CODE_BOOK_SCF_LAV)) && + ((delta + CODE_BOOK_SCF_LAV) < + (int)(sizeof(FDKaacEnc_huff_ltabscf) / + sizeof((FDKaacEnc_huff_ltabscf[0]))))); + return ((INT)FDKaacEnc_huff_ltabscf[delta + CODE_BOOK_SCF_LAV]); } #endif diff --git a/libAACenc/src/bitenc.cpp b/libAACenc/src/bitenc.cpp index 8e477aa..652d1fd 100644 --- a/libAACenc/src/bitenc.cpp +++ b/libAACenc/src/bitenc.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,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ - /******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M. Werner - contents/description: Bitstream encoder + Author(s): M. Werner -******************************************************************************/ + Description: Bitstream encoder + +*******************************************************************************/ #include "bitenc.h" #include "bit_cnt.h" @@ -95,14 +107,13 @@ amm-info@iis.fraunhofer.de #include "interface.h" #include "aacEnc_ram.h" - #include "tpenc_lib.h" -#include "FDK_tools_rom.h" /* needed for the bitstream syntax tables */ +#include "FDK_tools_rom.h" /* needed for the bitstream syntax tables */ static const int globalGainOffset = 100; -static const int icsReservedBit = 0; -static const int noiseOffset = 90; +static const int icsReservedBit = 0; +static const int noiseOffset = 90; /***************************************************************************** @@ -113,30 +124,26 @@ static const int noiseOffset = 90; output: *****************************************************************************/ -static INT FDKaacEnc_encodeSpectralData(INT *sfbOffset, - SECTION_DATA *sectionData, - SHORT *quantSpectrum, - HANDLE_FDK_BITSTREAM hBitStream) -{ - INT i,sfb; +static INT FDKaacEnc_encodeSpectralData(INT *sfbOffset, + SECTION_DATA *sectionData, + SHORT *quantSpectrum, + HANDLE_FDK_BITSTREAM hBitStream) { + INT i, sfb; INT dbgVal = FDKgetValidBits(hBitStream); - for(i=0;inoOfSections;i++) - { - if(sectionData->huffsection[i].codeBook != CODE_BOOK_PNS_NO) - { + for (i = 0; i < sectionData->noOfSections; i++) { + if (sectionData->huffsection[i].codeBook != CODE_BOOK_PNS_NO) { /* huffencode spectral data for this huffsection */ - INT tmp = sectionData->huffsection[i].sfbStart+sectionData->huffsection[i].sfbCnt; - for(sfb=sectionData->huffsection[i].sfbStart; sfbhuffsection[i].codeBook, - hBitStream); + INT tmp = sectionData->huffsection[i].sfbStart + + sectionData->huffsection[i].sfbCnt; + for (sfb = sectionData->huffsection[i].sfbStart; sfb < tmp; sfb++) { + FDKaacEnc_codeValues(quantSpectrum + sfbOffset[sfb], + sfbOffset[sfb + 1] - sfbOffset[sfb], + sectionData->huffsection[i].codeBook, hBitStream); } } } - return(FDKgetValidBits(hBitStream)-dbgVal); + return (FDKgetValidBits(hBitStream) - dbgVal); } /***************************************************************************** @@ -148,18 +155,18 @@ static INT FDKaacEnc_encodeSpectralData(INT *sfbOffset, output: *****************************************************************************/ -static INT FDKaacEnc_encodeGlobalGain(INT globalGain, - INT scalefac, +static INT FDKaacEnc_encodeGlobalGain(INT globalGain, INT scalefac, HANDLE_FDK_BITSTREAM hBitStream, - INT mdctScale) -{ + INT mdctScale) { if (hBitStream != NULL) { - FDKwriteBits(hBitStream,globalGain - scalefac + globalGainOffset-4*(LOG_NORM_PCM-mdctScale),8); + FDKwriteBits(hBitStream, + globalGain - scalefac + globalGainOffset - + 4 * (LOG_NORM_PCM - mdctScale), + 8); } return (8); } - /***************************************************************************** functionname:FDKaacEnc_encodeIcsInfo @@ -170,13 +177,10 @@ static INT FDKaacEnc_encodeGlobalGain(INT globalGain, *****************************************************************************/ -static INT FDKaacEnc_encodeIcsInfo(INT blockType, - INT windowShape, - INT groupingMask, - INT maxSfbPerGroup, - HANDLE_FDK_BITSTREAM hBitStream, - UINT syntaxFlags) -{ +static INT FDKaacEnc_encodeIcsInfo(INT blockType, INT windowShape, + INT groupingMask, INT maxSfbPerGroup, + HANDLE_FDK_BITSTREAM hBitStream, + UINT syntaxFlags) { INT statBits; if (blockType == SHORT_WINDOW) { @@ -184,38 +188,38 @@ static INT FDKaacEnc_encodeIcsInfo(INT blockType, } else { if (syntaxFlags & AC_ELD) { statBits = 6; - } else - { + } else { statBits = (!(syntaxFlags & AC_SCALABLE)) ? 11 : 10; } } if (hBitStream != NULL) { - - if (!(syntaxFlags & AC_ELD)){ - FDKwriteBits(hBitStream,icsReservedBit,1); - FDKwriteBits(hBitStream,blockType,2); - FDKwriteBits(hBitStream, (windowShape == LOL_WINDOW) ? KBD_WINDOW : windowShape,1); + if (!(syntaxFlags & AC_ELD)) { + FDKwriteBits(hBitStream, icsReservedBit, 1); + FDKwriteBits(hBitStream, blockType, 2); + FDKwriteBits(hBitStream, + (windowShape == LOL_WINDOW) ? KBD_WINDOW : windowShape, 1); } - switch(blockType){ - case LONG_WINDOW: - case START_WINDOW: - case STOP_WINDOW: - FDKwriteBits(hBitStream,maxSfbPerGroup,6); + switch (blockType) { + case LONG_WINDOW: + case START_WINDOW: + case STOP_WINDOW: + FDKwriteBits(hBitStream, maxSfbPerGroup, 6); - if (!(syntaxFlags & (AC_SCALABLE|AC_ELD)) ) { /* If not scalable syntax then ... */ - /* No predictor data present */ - FDKwriteBits(hBitStream, 0, 1); - } - break; + if (!(syntaxFlags & + (AC_SCALABLE | AC_ELD))) { /* If not scalable syntax then ... */ + /* No predictor data present */ + FDKwriteBits(hBitStream, 0, 1); + } + break; - case SHORT_WINDOW: - FDKwriteBits(hBitStream,maxSfbPerGroup,4); + case SHORT_WINDOW: + FDKwriteBits(hBitStream, maxSfbPerGroup, 4); - /* Write grouping bits */ - FDKwriteBits(hBitStream,groupingMask,TRANS_FAC-1); - break; + /* Write grouping bits */ + FDKwriteBits(hBitStream, groupingMask, TRANS_FAC - 1); + break; } } @@ -234,48 +238,44 @@ static INT FDKaacEnc_encodeIcsInfo(INT blockType, *****************************************************************************/ static INT FDKaacEnc_encodeSectionData(SECTION_DATA *sectionData, HANDLE_FDK_BITSTREAM hBitStream, - UINT useVCB11) -{ + UINT useVCB11) { if (hBitStream != NULL) { - INT sectEscapeVal=0,sectLenBits=0; + INT sectEscapeVal = 0, sectLenBits = 0; INT sectLen; INT i; - INT dbgVal=FDKgetValidBits(hBitStream); + INT dbgVal = FDKgetValidBits(hBitStream); INT sectCbBits = 4; - switch(sectionData->blockType) - { - case LONG_WINDOW: - case START_WINDOW: - case STOP_WINDOW: - sectEscapeVal = SECT_ESC_VAL_LONG; - sectLenBits = SECT_BITS_LONG; - break; - - case SHORT_WINDOW: - sectEscapeVal = SECT_ESC_VAL_SHORT; - sectLenBits = SECT_BITS_SHORT; - break; + switch (sectionData->blockType) { + case LONG_WINDOW: + case START_WINDOW: + case STOP_WINDOW: + sectEscapeVal = SECT_ESC_VAL_LONG; + sectLenBits = SECT_BITS_LONG; + break; + + case SHORT_WINDOW: + sectEscapeVal = SECT_ESC_VAL_SHORT; + sectLenBits = SECT_BITS_SHORT; + break; } - for(i=0;inoOfSections;i++) - { + for (i = 0; i < sectionData->noOfSections; i++) { INT codeBook = sectionData->huffsection[i].codeBook; - FDKwriteBits(hBitStream,codeBook,sectCbBits); + FDKwriteBits(hBitStream, codeBook, sectCbBits); { sectLen = sectionData->huffsection[i].sfbCnt; - while(sectLen >= sectEscapeVal) - { - FDKwriteBits(hBitStream,sectEscapeVal,sectLenBits); - sectLen-=sectEscapeVal; + while (sectLen >= sectEscapeVal) { + FDKwriteBits(hBitStream, sectEscapeVal, sectLenBits); + sectLen -= sectEscapeVal; } - FDKwriteBits(hBitStream,sectLen,sectLenBits); + FDKwriteBits(hBitStream, sectLen, sectLenBits); } } - return(FDKgetValidBits(hBitStream)-dbgVal); + return (FDKgetValidBits(hBitStream) - dbgVal); } return (0); } @@ -289,16 +289,14 @@ static INT FDKaacEnc_encodeSectionData(SECTION_DATA *sectionData, output: *****************************************************************************/ -static INT FDKaacEnc_encodeScaleFactorData(UINT *maxValueInSfb, - SECTION_DATA *sectionData, - INT *scalefac, - HANDLE_FDK_BITSTREAM hBitStream, - INT *RESTRICT noiseNrg, - const INT *isScale, - INT globalGain) -{ +static INT FDKaacEnc_encodeScaleFactorData(UINT *maxValueInSfb, + SECTION_DATA *sectionData, + INT *scalefac, + HANDLE_FDK_BITSTREAM hBitStream, + INT *RESTRICT noiseNrg, + const INT *isScale, INT globalGain) { if (hBitStream != NULL) { - INT i,j,lastValScf,deltaScf; + INT i, j, lastValScf, deltaScf; INT deltaPns; INT lastValPns = 0; INT noisePCMFlag = TRUE; @@ -306,65 +304,65 @@ static INT FDKaacEnc_encodeScaleFactorData(UINT *maxValueInSfb, INT dbgVal = FDKgetValidBits(hBitStream); - lastValScf=scalefac[sectionData->firstScf]; - lastValPns = globalGain-scalefac[sectionData->firstScf]+globalGainOffset-4*LOG_NORM_PCM-noiseOffset; - lastValIs = 0; + lastValScf = scalefac[sectionData->firstScf]; + lastValPns = globalGain - scalefac[sectionData->firstScf] + + globalGainOffset - 4 * LOG_NORM_PCM - noiseOffset; + lastValIs = 0; - for(i=0; inoOfSections; i++){ + for (i = 0; i < sectionData->noOfSections; i++) { if (sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) { - - if ((sectionData->huffsection[i].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) || - (sectionData->huffsection[i].codeBook == CODE_BOOK_IS_IN_PHASE_NO)) - { + if ((sectionData->huffsection[i].codeBook == + CODE_BOOK_IS_OUT_OF_PHASE_NO) || + (sectionData->huffsection[i].codeBook == + CODE_BOOK_IS_IN_PHASE_NO)) { INT sfbStart = sectionData->huffsection[i].sfbStart; INT tmp = sfbStart + sectionData->huffsection[i].sfbCnt; - for(j=sfbStart; jhuffsection[i].codeBook == CODE_BOOK_PNS_NO) { + } else if (sectionData->huffsection[i].codeBook == CODE_BOOK_PNS_NO) { INT sfbStart = sectionData->huffsection[i].sfbStart; INT tmp = sfbStart + sectionData->huffsection[i].sfbCnt; - for(j=sfbStart; jhuffsection[i].sfbStart+sectionData->huffsection[i].sfbCnt; - for(j=sectionData->huffsection[i].sfbStart; jhuffsection[i].sfbStart + + sectionData->huffsection[i].sfbCnt; + for (j = sectionData->huffsection[i].sfbStart; j < tmp; j++) { /* check if we can repeat the last value to save bits */ - if(maxValueInSfb[j] == 0) + if (maxValueInSfb[j] == 0) deltaScf = 0; - else{ - deltaScf = -(scalefac[j]-lastValScf); + else { + deltaScf = -(scalefac[j] - lastValScf); lastValScf = scalefac[j]; } - if(FDKaacEnc_codeScalefactorDelta(deltaScf,hBitStream)){ - return(1); + if (FDKaacEnc_codeScalefactorDelta(deltaScf, hBitStream)) { + return (1); } } /* sfb */ - } /* code scalefactor */ - } /* sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO */ - } /* section loop */ + } /* code scalefactor */ + } /* sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO */ + } /* section loop */ - return(FDKgetValidBits(hBitStream)-dbgVal); + return (FDKgetValidBits(hBitStream) - dbgVal); } /* if (hBitStream != NULL) */ return (0); @@ -379,53 +377,43 @@ static INT FDKaacEnc_encodeScaleFactorData(UINT *maxValueInSfb, output: *****************************************************************************/ -static INT FDKaacEnc_encodeMSInfo(INT sfbCnt, - INT grpSfb, - INT maxSfb, - INT msDigest, - INT *jsFlags, - HANDLE_FDK_BITSTREAM hBitStream) -{ +static INT FDKaacEnc_encodeMSInfo(INT sfbCnt, INT grpSfb, INT maxSfb, + INT msDigest, INT *jsFlags, + HANDLE_FDK_BITSTREAM hBitStream) { INT sfb, sfbOff, msBits = 0; - if (hBitStream != NULL) - { - switch(msDigest) - { - case MS_NONE: - FDKwriteBits(hBitStream,SI_MS_MASK_NONE,2); - msBits += 2; - break; - - case MS_ALL: - FDKwriteBits(hBitStream,SI_MS_MASK_ALL,2); - msBits += 2; - break; - - case MS_SOME: - FDKwriteBits(hBitStream,SI_MS_MASK_SOME,2); - msBits += 2; - for(sfbOff = 0; sfbOff < sfbCnt; sfbOff+=grpSfb) - { - for(sfb=0; sfbnumOfFilters[i]!=0) { - tnsPresent=1; + for (i = 0; i < numOfWindows; i++) { + if (tnsInfo->numOfFilters[i] != 0) { + tnsPresent = 1; break; } } - if (tnsPresent==0) { - FDKwriteBits(hBitStream,0,1); + if (tnsPresent == 0) { + FDKwriteBits(hBitStream, 0, 1); } else { - FDKwriteBits(hBitStream,1,1); + FDKwriteBits(hBitStream, 1, 1); } } return (1); @@ -477,106 +462,108 @@ static INT FDKaacEnc_encodeTnsDataPresent(TNS_INFO *tnsInfo, output: *****************************************************************************/ -static INT FDKaacEnc_encodeTnsData(TNS_INFO *tnsInfo, - INT blockType, - HANDLE_FDK_BITSTREAM hBitStream) -{ +static INT FDKaacEnc_encodeTnsData(TNS_INFO *tnsInfo, INT blockType, + HANDLE_FDK_BITSTREAM hBitStream) { INT tnsBits = 0; - if (tnsInfo!=NULL) { - - INT i,j,k; + if (tnsInfo != NULL) { + INT i, j, k; INT tnsPresent = 0; INT coefBits; - INT numOfWindows=(blockType==SHORT_WINDOW?TRANS_FAC:1); + INT numOfWindows = (blockType == SHORT_WINDOW ? TRANS_FAC : 1); - for (i=0; inumOfFilters[i]!=0) { - tnsPresent=1; + for (i = 0; i < numOfWindows; i++) { + if (tnsInfo->numOfFilters[i] != 0) { + tnsPresent = 1; } } - if (hBitStream != NULL) - { - if (tnsPresent==1) { /* there is data to be written*/ - for (i=0; inumOfFilters[i],(blockType==SHORT_WINDOW?1:2)); - tnsBits += (blockType==SHORT_WINDOW?1:2); + if (hBitStream != NULL) { + if (tnsPresent == 1) { /* there is data to be written*/ + for (i = 0; i < numOfWindows; i++) { + FDKwriteBits(hBitStream, tnsInfo->numOfFilters[i], + (blockType == SHORT_WINDOW ? 1 : 2)); + tnsBits += (blockType == SHORT_WINDOW ? 1 : 2); if (tnsInfo->numOfFilters[i]) { - FDKwriteBits(hBitStream,(tnsInfo->coefRes[i]==4?1:0),1); + FDKwriteBits(hBitStream, (tnsInfo->coefRes[i] == 4 ? 1 : 0), 1); tnsBits += 1; } - for (j=0; jnumOfFilters[i]; j++) { - FDKwriteBits(hBitStream,tnsInfo->length[i][j],(blockType==SHORT_WINDOW?4:6)); - tnsBits += (blockType==SHORT_WINDOW?4:6); + for (j = 0; j < tnsInfo->numOfFilters[i]; j++) { + FDKwriteBits(hBitStream, tnsInfo->length[i][j], + (blockType == SHORT_WINDOW ? 4 : 6)); + tnsBits += (blockType == SHORT_WINDOW ? 4 : 6); FDK_ASSERT(tnsInfo->order[i][j] <= 12); - FDKwriteBits(hBitStream,tnsInfo->order[i][j],(blockType==SHORT_WINDOW?3:5)); - tnsBits += (blockType==SHORT_WINDOW?3:5); - if (tnsInfo->order[i][j]){ - FDKwriteBits(hBitStream,tnsInfo->direction[i][j],1); - tnsBits +=1; /*direction*/ - if(tnsInfo->coefRes[i] == 4) { + FDKwriteBits(hBitStream, tnsInfo->order[i][j], + (blockType == SHORT_WINDOW ? 3 : 5)); + tnsBits += (blockType == SHORT_WINDOW ? 3 : 5); + if (tnsInfo->order[i][j]) { + FDKwriteBits(hBitStream, tnsInfo->direction[i][j], 1); + tnsBits += 1; /*direction*/ + if (tnsInfo->coefRes[i] == 4) { coefBits = 3; - for(k=0; korder[i][j]; k++) { - if (tnsInfo->coef[i][j][k]> 3 || - tnsInfo->coef[i][j][k]< -4) { + for (k = 0; k < tnsInfo->order[i][j]; k++) { + if (tnsInfo->coef[i][j][k] > 3 || + tnsInfo->coef[i][j][k] < -4) { coefBits = 4; break; } } } else { coefBits = 2; - for(k=0; korder[i][j]; k++) { - if ( tnsInfo->coef[i][j][k]> 1 - || tnsInfo->coef[i][j][k]< -2) { + for (k = 0; k < tnsInfo->order[i][j]; k++) { + if (tnsInfo->coef[i][j][k] > 1 || + tnsInfo->coef[i][j][k] < -2) { coefBits = 3; break; } } } - FDKwriteBits(hBitStream,-(coefBits - tnsInfo->coefRes[i]),1); /*coef_compres*/ - tnsBits +=1; /*coef_compression */ - for (k=0; korder[i][j]; k++ ) { - static const INT rmask[] = {0,1,3,7,15}; - FDKwriteBits(hBitStream,tnsInfo->coef[i][j][k] & rmask[coefBits],coefBits); + FDKwriteBits(hBitStream, -(coefBits - tnsInfo->coefRes[i]), + 1); /*coef_compres*/ + tnsBits += 1; /*coef_compression */ + for (k = 0; k < tnsInfo->order[i][j]; k++) { + static const INT rmask[] = {0, 1, 3, 7, 15}; + FDKwriteBits(hBitStream, + tnsInfo->coef[i][j][k] & rmask[coefBits], + coefBits); tnsBits += coefBits; } } } } } - } - else { + } else { if (tnsPresent != 0) { - for (i=0; inumOfFilters[i]) { tnsBits += 1; - for (j=0; jnumOfFilters[i]; j++) { - tnsBits += (blockType==SHORT_WINDOW?4:6); - tnsBits += (blockType==SHORT_WINDOW?3:5); + for (j = 0; j < tnsInfo->numOfFilters[i]; j++) { + tnsBits += (blockType == SHORT_WINDOW ? 4 : 6); + tnsBits += (blockType == SHORT_WINDOW ? 3 : 5); if (tnsInfo->order[i][j]) { - tnsBits +=1; /*direction*/ - tnsBits +=1; /*coef_compression */ + tnsBits += 1; /*direction*/ + tnsBits += 1; /*coef_compression */ if (tnsInfo->coefRes[i] == 4) { - coefBits=3; - for (k=0; korder[i][j]; k++) { - if (tnsInfo->coef[i][j][k]> 3 || tnsInfo->coef[i][j][k]< -4) { + coefBits = 3; + for (k = 0; k < tnsInfo->order[i][j]; k++) { + if (tnsInfo->coef[i][j][k] > 3 || + tnsInfo->coef[i][j][k] < -4) { coefBits = 4; break; } } - } - else { + } else { coefBits = 2; - for (k=0; korder[i][j]; k++) { - if (tnsInfo->coef[i][j][k]> 1 || tnsInfo->coef[i][j][k]< -2) { + for (k = 0; k < tnsInfo->order[i][j]; k++) { + if (tnsInfo->coef[i][j][k] > 1 || + tnsInfo->coef[i][j][k] < -2) { coefBits = 3; break; } } } - for (k=0; korder[i][j]; k++) { + for (k = 0; k < tnsInfo->order[i][j]; k++) { tnsBits += coefBits; } } @@ -599,10 +586,9 @@ static INT FDKaacEnc_encodeTnsData(TNS_INFO *tnsInfo, output: *****************************************************************************/ -static INT FDKaacEnc_encodeGainControlData(HANDLE_FDK_BITSTREAM hBitStream) -{ +static INT FDKaacEnc_encodeGainControlData(HANDLE_FDK_BITSTREAM hBitStream) { if (hBitStream != NULL) { - FDKwriteBits(hBitStream,0,1); + FDKwriteBits(hBitStream, 0, 1); } return (1); } @@ -616,15 +602,13 @@ static INT FDKaacEnc_encodeGainControlData(HANDLE_FDK_BITSTREAM hBitStream) output: *****************************************************************************/ -static INT FDKaacEnc_encodePulseData(HANDLE_FDK_BITSTREAM hBitStream) -{ +static INT FDKaacEnc_encodePulseData(HANDLE_FDK_BITSTREAM hBitStream) { if (hBitStream != NULL) { - FDKwriteBits(hBitStream,0,1); + FDKwriteBits(hBitStream, 0, 1); } return (1); } - /***************************************************************************** functionname: FDKaacEnc_writeExtensionPayload @@ -634,21 +618,18 @@ static INT FDKaacEnc_encodePulseData(HANDLE_FDK_BITSTREAM hBitStream) output: *****************************************************************************/ -static INT FDKaacEnc_writeExtensionPayload( HANDLE_FDK_BITSTREAM hBitStream, - EXT_PAYLOAD_TYPE extPayloadType, - const UCHAR *extPayloadData, - INT extPayloadBits - ) -{ - #define EXT_TYPE_BITS ( 4 ) - #define DATA_EL_VERSION_BITS ( 4 ) - #define FILL_NIBBLE_BITS ( 4 ) - - INT extBitsUsed = 0; - - if (extPayloadBits >= EXT_TYPE_BITS) - { - UCHAR fillByte = 0x00; /* for EXT_FIL and EXT_FILL_DATA */ +static INT FDKaacEnc_writeExtensionPayload(HANDLE_FDK_BITSTREAM hBitStream, + EXT_PAYLOAD_TYPE extPayloadType, + const UCHAR *extPayloadData, + INT extPayloadBits) { +#define EXT_TYPE_BITS (4) +#define DATA_EL_VERSION_BITS (4) +#define FILL_NIBBLE_BITS (4) + + INT extBitsUsed = 0; + + if (extPayloadBits >= EXT_TYPE_BITS) { + UCHAR fillByte = 0x00; /* for EXT_FIL and EXT_FILL_DATA */ if (hBitStream != NULL) { FDKwriteBits(hBitStream, extPayloadType, EXT_TYPE_BITS); @@ -656,50 +637,56 @@ static INT FDKaacEnc_writeExtensionPayload( HANDLE_FDK_BITSTREAM hBitStream, extBitsUsed += EXT_TYPE_BITS; switch (extPayloadType) { - case EXT_DYNAMIC_RANGE: /* case EXT_SAC_DATA: */ + case EXT_LDSAC_DATA: + if (hBitStream != NULL) { + FDKwriteBits(hBitStream, *extPayloadData++, 4); /* nibble */ + } + extBitsUsed += 4; + case EXT_DYNAMIC_RANGE: case EXT_SBR_DATA: case EXT_SBR_DATA_CRC: if (hBitStream != NULL) { int i, writeBits = extPayloadBits; - for (i=0; writeBits >= 8; i++) { - FDKwriteBits(hBitStream, extPayloadData[i], 8); + for (i = 0; writeBits >= 8; i++) { + FDKwriteBits(hBitStream, *extPayloadData++, 8); writeBits -= 8; } if (writeBits > 0) { - FDKwriteBits(hBitStream, extPayloadData[i]>>(8-writeBits), writeBits); + FDKwriteBits(hBitStream, (*extPayloadData) >> (8 - writeBits), + writeBits); } } extBitsUsed += extPayloadBits; break; - case EXT_DATA_ELEMENT: - { - INT dataElementLength = (extPayloadBits+7)>>3; - INT cnt = dataElementLength; - int loopCounter = 1; + case EXT_DATA_ELEMENT: { + INT dataElementLength = (extPayloadBits + 7) >> 3; + INT cnt = dataElementLength; + int loopCounter = 1; - while (dataElementLength >= 255) { - loopCounter++; - dataElementLength -= 255; - } + while (dataElementLength >= 255) { + loopCounter++; + dataElementLength -= 255; + } - if (hBitStream != NULL) { - int i; - FDKwriteBits(hBitStream, 0x00, DATA_EL_VERSION_BITS); /* data_element_version = ANC_DATA */ + if (hBitStream != NULL) { + int i; + FDKwriteBits( + hBitStream, 0x00, + DATA_EL_VERSION_BITS); /* data_element_version = ANC_DATA */ - for (i=1; i= 8) { FDKwriteBits(hBitStream, fillByte, 8); writeBits -= 8; @@ -722,7 +710,6 @@ static INT FDKaacEnc_writeExtensionPayload( HANDLE_FDK_BITSTREAM hBitStream, return (extBitsUsed); } - /***************************************************************************** functionname: FDKaacEnc_writeDataStreamElement @@ -732,39 +719,37 @@ static INT FDKaacEnc_writeExtensionPayload( HANDLE_FDK_BITSTREAM hBitStream, output: ******************************************************************************/ -static INT FDKaacEnc_writeDataStreamElement( HANDLE_TRANSPORTENC hTpEnc, - INT elementInstanceTag, - INT dataPayloadBytes, - UCHAR *dataBuffer, - UINT alignAnchor ) -{ - #define DATA_BYTE_ALIGN_FLAG ( 0 ) - - #define EL_INSTANCE_TAG_BITS ( 4 ) - #define DATA_BYTE_ALIGN_FLAG_BITS ( 1 ) - #define DATA_LEN_COUNT_BITS ( 8 ) - #define DATA_LEN_ESC_COUNT_BITS ( 8 ) - - #define MAX_DATA_ALIGN_BITS ( 7 ) - #define MAX_DSE_DATA_BYTES ( 510 ) - - INT dseBitsUsed = 0; - - while (dataPayloadBytes > 0) - { +static INT FDKaacEnc_writeDataStreamElement(HANDLE_TRANSPORTENC hTpEnc, + INT elementInstanceTag, + INT dataPayloadBytes, + UCHAR *dataBuffer, + UINT alignAnchor) { +#define DATA_BYTE_ALIGN_FLAG (0) + +#define EL_INSTANCE_TAG_BITS (4) +#define DATA_BYTE_ALIGN_FLAG_BITS (1) +#define DATA_LEN_COUNT_BITS (8) +#define DATA_LEN_ESC_COUNT_BITS (8) + +#define MAX_DATA_ALIGN_BITS (7) +#define MAX_DSE_DATA_BYTES (510) + + INT dseBitsUsed = 0; + + while (dataPayloadBytes > 0) { int esc_count = -1; int cnt = 0; INT crcReg = -1; - dseBitsUsed += EL_ID_BITS + EL_INSTANCE_TAG_BITS - + DATA_BYTE_ALIGN_FLAG_BITS + DATA_LEN_COUNT_BITS; + dseBitsUsed += EL_ID_BITS + EL_INSTANCE_TAG_BITS + + DATA_BYTE_ALIGN_FLAG_BITS + DATA_LEN_COUNT_BITS; if (DATA_BYTE_ALIGN_FLAG) { dseBitsUsed += MAX_DATA_ALIGN_BITS; } cnt = fixMin(MAX_DSE_DATA_BYTES, dataPayloadBytes); - if ( cnt >= 255 ) { + if (cnt >= 255) { esc_count = cnt - 255; dseBitsUsed += DATA_LEN_ESC_COUNT_BITS; } @@ -784,7 +769,7 @@ static INT FDKaacEnc_writeDataStreamElement( HANDLE_TRANSPORTENC hTpEnc, FDKwriteBits(hBitStream, DATA_BYTE_ALIGN_FLAG, DATA_BYTE_ALIGN_FLAG_BITS); /* write length field(s) */ - if ( esc_count >= 0 ) { + if (esc_count >= 0) { FDKwriteBits(hBitStream, 255, DATA_LEN_COUNT_BITS); FDKwriteBits(hBitStream, esc_count, DATA_LEN_ESC_COUNT_BITS); } else { @@ -795,11 +780,12 @@ static INT FDKaacEnc_writeDataStreamElement( HANDLE_TRANSPORTENC hTpEnc, INT tmp = (INT)FDKgetValidBits(hBitStream); FDKbyteAlign(hBitStream, alignAnchor); /* count actual bits */ - dseBitsUsed += (INT)FDKgetValidBits(hBitStream) - tmp - MAX_DATA_ALIGN_BITS; + dseBitsUsed += + (INT)FDKgetValidBits(hBitStream) - tmp - MAX_DATA_ALIGN_BITS; } /* write payload */ - for (i=0; inPayloadBits; @@ -840,106 +822,53 @@ INT FDKaacEnc_writeExtensionData( HANDLE_TRANSPORTENC hTpEnc, hBitStream = transportEnc_GetBitstream(hTpEnc); } - if (syntaxFlags & (AC_SCALABLE|AC_ER)) - { - if ( syntaxFlags & AC_DRM ) - { /* CAUTION: The caller has to assure that fill - data is written before the SBR payload. */ - UCHAR *extPayloadData = pExtension->pPayload; - - switch (pExtension->type) - { - case EXT_SBR_DATA: - case EXT_SBR_DATA_CRC: - /* SBR payload is written in reverse */ - if (hBitStream != NULL) { - int i, writeBits = payloadBits; - - FDKpushFor(hBitStream, payloadBits-1); /* Does a cache sync internally */ - - for (i=0; writeBits >= 8; i++) { - FDKwriteBitsBwd(hBitStream, extPayloadData[i], 8); - writeBits -= 8; - } - if (writeBits > 0) { - FDKwriteBitsBwd(hBitStream, extPayloadData[i]>>(8-writeBits), writeBits); - } - - FDKsyncCacheBwd (hBitStream); - FDKpushFor (hBitStream, payloadBits+1); - } - extBitsUsed += payloadBits; - break; - - case EXT_FILL_DATA: - case EXT_FIL: - default: - if (hBitStream != NULL) { - int writeBits = payloadBits; - while (writeBits >= 8) { - FDKwriteBits(hBitStream, 0x00, 8); - writeBits -= 8; - } - FDKwriteBits(hBitStream, 0x00, writeBits); - } - extBitsUsed += payloadBits; - break; - } - } - else { - if ( (syntaxFlags & AC_ELD) && ((pExtension->type==EXT_SBR_DATA) || (pExtension->type==EXT_SBR_DATA_CRC)) ) { - + if (syntaxFlags & (AC_SCALABLE | AC_ER)) { + { + if ((syntaxFlags & AC_ELD) && ((pExtension->type == EXT_SBR_DATA) || + (pExtension->type == EXT_SBR_DATA_CRC))) { if (hBitStream != NULL) { int i, writeBits = payloadBits; UCHAR *extPayloadData = pExtension->pPayload; - for (i=0; writeBits >= 8; i++) { + for (i = 0; writeBits >= 8; i++) { FDKwriteBits(hBitStream, extPayloadData[i], 8); writeBits -= 8; } if (writeBits > 0) { - FDKwriteBits(hBitStream, extPayloadData[i]>>(8-writeBits), writeBits); + FDKwriteBits(hBitStream, extPayloadData[i] >> (8 - writeBits), + writeBits); } } extBitsUsed += payloadBits; - } - else - { + } else { /* ER or scalable syntax -> write extension en bloc */ - extBitsUsed += FDKaacEnc_writeExtensionPayload( hBitStream, - pExtension->type, - pExtension->pPayload, - payloadBits ); + extBitsUsed += FDKaacEnc_writeExtensionPayload( + hBitStream, pExtension->type, pExtension->pPayload, payloadBits); } } - } - else { + } else { /* We have normal GA bitstream payload (AOT 2,5,29) so pack the data into a fill elements or DSEs */ - if ( pExtension->type == EXT_DATA_ELEMENT ) - { - extBitsUsed += FDKaacEnc_writeDataStreamElement( hTpEnc, - elInstanceTag, - pExtension->nPayloadBits>>3, - pExtension->pPayload, - alignAnchor ); - } - else { + if (pExtension->type == EXT_DATA_ELEMENT) { + extBitsUsed += FDKaacEnc_writeDataStreamElement( + hTpEnc, elInstanceTag, pExtension->nPayloadBits >> 3, + pExtension->pPayload, alignAnchor); + } else { while (payloadBits >= (EL_ID_BITS + FILL_EL_COUNT_BITS)) { - INT cnt, esc_count=-1, alignBits=7; + INT cnt, esc_count = -1, alignBits = 7; - if ( (pExtension->type == EXT_FILL_DATA) || (pExtension->type == EXT_FIL) ) - { + if ((pExtension->type == EXT_FILL_DATA) || + (pExtension->type == EXT_FIL)) { payloadBits -= EL_ID_BITS + FILL_EL_COUNT_BITS; - if (payloadBits >= 15*8) { + if (payloadBits >= 15 * 8) { payloadBits -= FILL_EL_ESC_COUNT_BITS; - esc_count = 0; /* write esc_count even if cnt becomes smaller 15 */ + esc_count = 0; /* write esc_count even if cnt becomes smaller 15 */ } alignBits = 0; } - cnt = fixMin(MAX_FILL_DATA_BYTES, (payloadBits+alignBits)>>3); + cnt = fixMin(MAX_FILL_DATA_BYTES, (payloadBits + alignBits) >> 3); if (cnt >= 15) { esc_count = cnt - 15 + 1; @@ -956,13 +885,12 @@ INT FDKaacEnc_writeExtensionData( HANDLE_TRANSPORTENC hTpEnc, } } - extBitsUsed += EL_ID_BITS + FILL_EL_COUNT_BITS + ((esc_count>=0) ? FILL_EL_ESC_COUNT_BITS : 0); + extBitsUsed += EL_ID_BITS + FILL_EL_COUNT_BITS + + ((esc_count >= 0) ? FILL_EL_ESC_COUNT_BITS : 0); - cnt = fixMin(cnt*8, payloadBits); /* convert back to bits */ - extBitsUsed += FDKaacEnc_writeExtensionPayload( hBitStream, - pExtension->type, - pExtension->pPayload, - cnt ); + cnt = fixMin(cnt * 8, payloadBits); /* convert back to bits */ + extBitsUsed += FDKaacEnc_writeExtensionPayload( + hBitStream, pExtension->type, pExtension->pPayload, cnt); payloadBits -= cnt; } } @@ -971,7 +899,6 @@ INT FDKaacEnc_writeExtensionData( HANDLE_TRANSPORTENC hTpEnc, return (extBitsUsed); } - /***************************************************************************** functionname: FDKaacEnc_ByteAlignment @@ -981,50 +908,43 @@ INT FDKaacEnc_writeExtensionData( HANDLE_TRANSPORTENC hTpEnc, output: *****************************************************************************/ -static void FDKaacEnc_ByteAlignment(HANDLE_FDK_BITSTREAM hBitStream, int alignBits) -{ +static void FDKaacEnc_ByteAlignment(HANDLE_FDK_BITSTREAM hBitStream, + int alignBits) { FDKwriteBits(hBitStream, 0, alignBits); } -AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite( HANDLE_TRANSPORTENC hTpEnc, - ELEMENT_INFO *pElInfo, - QC_OUT_CHANNEL *qcOutChannel[(2)], - PSY_OUT_ELEMENT *psyOutElement, - PSY_OUT_CHANNEL *psyOutChannel[(2)], - UINT syntaxFlags, - AUDIO_OBJECT_TYPE aot, - SCHAR epConfig, - INT *pBitDemand, - UCHAR minCnt - ) -{ +AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite( + HANDLE_TRANSPORTENC hTpEnc, ELEMENT_INFO *pElInfo, + QC_OUT_CHANNEL *qcOutChannel[(2)], PSY_OUT_ELEMENT *psyOutElement, + PSY_OUT_CHANNEL *psyOutChannel[(2)], UINT syntaxFlags, + AUDIO_OBJECT_TYPE aot, SCHAR epConfig, INT *pBitDemand, UCHAR minCnt) { AAC_ENCODER_ERROR error = AAC_ENC_OK; HANDLE_FDK_BITSTREAM hBitStream = NULL; - INT bitDemand = 0; - const element_list_t *list; - int i, ch, decision_bit; - INT crcReg1 = -1, crcReg2 = -1; - UCHAR numberOfChannels; + INT bitDemand = 0; + const element_list_t *list; + int i, ch, decision_bit; + INT crcReg1 = -1, crcReg2 = -1; + UCHAR numberOfChannels; if (hTpEnc != NULL) { /* Get bitstream handle */ hBitStream = transportEnc_GetBitstream(hTpEnc); } - if ( (pElInfo->elType==ID_SCE) || (pElInfo->elType==ID_LFE) ) { + if ((pElInfo->elType == ID_SCE) || (pElInfo->elType == ID_LFE)) { numberOfChannels = 1; } else { numberOfChannels = 2; } /* Get channel element sequence table */ - list = getBitstreamElementList(aot, epConfig, numberOfChannels, 0); + list = getBitstreamElementList(aot, epConfig, numberOfChannels, 0, 0); if (list == NULL) { error = AAC_ENC_UNSUPPORTED_AOT; goto bail; } - if (!(syntaxFlags & (AC_SCALABLE|AC_ER))) { + if (!(syntaxFlags & (AC_SCALABLE | AC_ER))) { if (hBitStream != NULL) { FDKwriteBits(hBitStream, pElInfo->elType, EL_ID_BITS); } @@ -1038,225 +958,205 @@ AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite( HANDLE_TRANSPORTENC hTpEnc, do { /* some tmp values */ SECTION_DATA *pChSectionData = NULL; - INT *pChScf = NULL; + INT *pChScf = NULL; UINT *pChMaxValueInSfb = NULL; - TNS_INFO *pTnsInfo = NULL; - INT chGlobalGain = 0; - INT chBlockType = 0; - INT chMaxSfbPerGrp = 0; - INT chSfbPerGrp = 0; - INT chSfbCnt = 0; - INT chFirstScf = 0; - - if (minCnt==0) { - if ( qcOutChannel!=NULL ) { - pChSectionData = &(qcOutChannel[ch]->sectionData); - pChScf = qcOutChannel[ch]->scf; - chGlobalGain = qcOutChannel[ch]->globalGain; - pChMaxValueInSfb = qcOutChannel[ch]->maxValueInSfb; - chBlockType = pChSectionData->blockType; - chMaxSfbPerGrp = pChSectionData->maxSfbPerGroup; - chSfbPerGrp = pChSectionData->sfbPerGroup; - chSfbCnt = pChSectionData->sfbCnt; - chFirstScf = pChScf[pChSectionData->firstScf]; - } - else { + TNS_INFO *pTnsInfo = NULL; + INT chGlobalGain = 0; + INT chBlockType = 0; + INT chMaxSfbPerGrp = 0; + INT chSfbPerGrp = 0; + INT chSfbCnt = 0; + INT chFirstScf = 0; + + if (minCnt == 0) { + if (qcOutChannel != NULL) { + pChSectionData = &(qcOutChannel[ch]->sectionData); + pChScf = qcOutChannel[ch]->scf; + chGlobalGain = qcOutChannel[ch]->globalGain; + pChMaxValueInSfb = qcOutChannel[ch]->maxValueInSfb; + chBlockType = pChSectionData->blockType; + chMaxSfbPerGrp = pChSectionData->maxSfbPerGroup; + chSfbPerGrp = pChSectionData->sfbPerGroup; + chSfbCnt = pChSectionData->sfbCnt; + chFirstScf = pChScf[pChSectionData->firstScf]; + } else { /* get values from PSY */ - chSfbCnt = psyOutChannel[ch]->sfbCnt; - chSfbPerGrp = psyOutChannel[ch]->sfbPerGroup; + chSfbCnt = psyOutChannel[ch]->sfbCnt; + chSfbPerGrp = psyOutChannel[ch]->sfbPerGroup; chMaxSfbPerGrp = psyOutChannel[ch]->maxSfbPerGroup; } pTnsInfo = &psyOutChannel[ch]->tnsInfo; } /* minCnt==0 */ - if ( qcOutChannel==NULL ) { - chBlockType = psyOutChannel[ch]->lastWindowSequence; + if (qcOutChannel == NULL) { + chBlockType = psyOutChannel[ch]->lastWindowSequence; } - switch (list->id[i]) - { - case element_instance_tag: - /* Write element instance tag */ - if (hBitStream != NULL) { - FDKwriteBits(hBitStream, pElInfo->instanceTag, 4); - } - bitDemand += 4; - break; - - case common_window: - /* Write common window flag */ - decision_bit = psyOutElement->commonWindow; - if (hBitStream != NULL) { - FDKwriteBits(hBitStream, psyOutElement->commonWindow, 1); - } - bitDemand += 1; - break; - - case ics_info: - /* Write individual channel info */ - bitDemand += FDKaacEnc_encodeIcsInfo( chBlockType, - psyOutChannel[ch]->windowShape, - psyOutChannel[ch]->groupingMask, - chMaxSfbPerGrp, - hBitStream, - syntaxFlags); - break; - - case ltp_data_present: - /* Write LTP data present flag */ - if (hBitStream != NULL) { - FDKwriteBits(hBitStream, 0, 1); - } - bitDemand += 1; - break; - - case ltp_data: - /* Predictor data not supported. - Nothing to do here. */ - break; - - case ms: - /* Write MS info */ - bitDemand += FDKaacEnc_encodeMSInfo( chSfbCnt, - chSfbPerGrp, - chMaxSfbPerGrp, - (minCnt==0) ? psyOutElement->toolsInfo.msDigest : MS_NONE, - psyOutElement->toolsInfo.msMask, - hBitStream); - break; - - case global_gain: - bitDemand += FDKaacEnc_encodeGlobalGain( chGlobalGain, - chFirstScf, - hBitStream, - psyOutChannel[ch]->mdctScale ); - break; - - case section_data: - { - INT siBits = FDKaacEnc_encodeSectionData(pChSectionData, hBitStream, (syntaxFlags & AC_ER_VCB11)?1:0); + switch (list->id[i]) { + case element_instance_tag: + /* Write element instance tag */ + if (hBitStream != NULL) { + FDKwriteBits(hBitStream, pElInfo->instanceTag, 4); + } + bitDemand += 4; + break; + + case common_window: + /* Write common window flag */ + decision_bit = psyOutElement->commonWindow; + if (hBitStream != NULL) { + FDKwriteBits(hBitStream, psyOutElement->commonWindow, 1); + } + bitDemand += 1; + break; + + case ics_info: + /* Write individual channel info */ + bitDemand += + FDKaacEnc_encodeIcsInfo(chBlockType, psyOutChannel[ch]->windowShape, + psyOutChannel[ch]->groupingMask, + chMaxSfbPerGrp, hBitStream, syntaxFlags); + break; + + case ltp_data_present: + /* Write LTP data present flag */ + if (hBitStream != NULL) { + FDKwriteBits(hBitStream, 0, 1); + } + bitDemand += 1; + break; + + case ltp_data: + /* Predictor data not supported. + Nothing to do here. */ + break; + + case ms: + /* Write MS info */ + bitDemand += FDKaacEnc_encodeMSInfo( + chSfbCnt, chSfbPerGrp, chMaxSfbPerGrp, + (minCnt == 0) ? psyOutElement->toolsInfo.msDigest : MS_NONE, + psyOutElement->toolsInfo.msMask, hBitStream); + break; + + case global_gain: + bitDemand += FDKaacEnc_encodeGlobalGain( + chGlobalGain, chFirstScf, hBitStream, psyOutChannel[ch]->mdctScale); + break; + + case section_data: { + INT siBits = FDKaacEnc_encodeSectionData( + pChSectionData, hBitStream, (syntaxFlags & AC_ER_VCB11) ? 1 : 0); if (hBitStream != NULL) { if (siBits != qcOutChannel[ch]->sectionData.sideInfoBits) { error = AAC_ENC_WRITE_SEC_ERROR; } } bitDemand += siBits; - } - break; - - case scale_factor_data: - { - INT sfDataBits = FDKaacEnc_encodeScaleFactorData( pChMaxValueInSfb, - pChSectionData, - pChScf, - hBitStream, - psyOutChannel[ch]->noiseNrg, - psyOutChannel[ch]->isScale, - chGlobalGain ); - if ( (hBitStream != NULL) - && (sfDataBits != (qcOutChannel[ch]->sectionData.scalefacBits + qcOutChannel[ch]->sectionData.noiseNrgBits)) ) { - error = AAC_ENC_WRITE_SCAL_ERROR; + } break; + + case scale_factor_data: { + INT sfDataBits = FDKaacEnc_encodeScaleFactorData( + pChMaxValueInSfb, pChSectionData, pChScf, hBitStream, + psyOutChannel[ch]->noiseNrg, psyOutChannel[ch]->isScale, + chGlobalGain); + if ((hBitStream != NULL) && + (sfDataBits != (qcOutChannel[ch]->sectionData.scalefacBits + + qcOutChannel[ch]->sectionData.noiseNrgBits))) { + error = AAC_ENC_WRITE_SCAL_ERROR; } bitDemand += sfDataBits; - } - break; + } break; - case esc2_rvlc: - if (syntaxFlags & AC_ER_RVLC) { - /* write RVLC data into bitstream (error sens. cat. 2) */ - error = AAC_ENC_UNSUPPORTED_AOT; - } - break; - - case pulse: - /* Write pulse data */ - bitDemand += FDKaacEnc_encodePulseData(hBitStream); - break; - - case tns_data_present: - /* Write TNS data present flag */ - bitDemand += FDKaacEnc_encodeTnsDataPresent(pTnsInfo, - chBlockType, - hBitStream); - break; - case tns_data: - /* Write TNS data */ - bitDemand += FDKaacEnc_encodeTnsData(pTnsInfo, - chBlockType, - hBitStream); - break; - - case gain_control_data: - /* Nothing to do here */ - break; - - case gain_control_data_present: - bitDemand += FDKaacEnc_encodeGainControlData(hBitStream); - break; - - - case esc1_hcr: - if (syntaxFlags & AC_ER_HCR) - { - error = AAC_ENC_UNKNOWN; - } - break; + case esc2_rvlc: + if (syntaxFlags & AC_ER_RVLC) { + /* write RVLC data into bitstream (error sens. cat. 2) */ + error = AAC_ENC_UNSUPPORTED_AOT; + } + break; - case spectral_data: - if (hBitStream != NULL) - { - INT spectralBits = 0; + case pulse: + /* Write pulse data */ + bitDemand += FDKaacEnc_encodePulseData(hBitStream); + break; + + case tns_data_present: + /* Write TNS data present flag */ + bitDemand += + FDKaacEnc_encodeTnsDataPresent(pTnsInfo, chBlockType, hBitStream); + break; + case tns_data: + /* Write TNS data */ + bitDemand += FDKaacEnc_encodeTnsData(pTnsInfo, chBlockType, hBitStream); + break; + + case gain_control_data: + /* Nothing to do here */ + break; - spectralBits = FDKaacEnc_encodeSpectralData( psyOutChannel[ch]->sfbOffsets, - pChSectionData, - qcOutChannel[ch]->quantSpec, - hBitStream ); + case gain_control_data_present: + bitDemand += FDKaacEnc_encodeGainControlData(hBitStream); + break; - if (spectralBits != qcOutChannel[ch]->sectionData.huffmanBits) { - return AAC_ENC_WRITE_SPEC_ERROR; + case esc1_hcr: + if (syntaxFlags & AC_ER_HCR) { + error = AAC_ENC_UNKNOWN; } - bitDemand += spectralBits; - } - break; + break; - /* Non data cases */ - case adtscrc_start_reg1: - if (hTpEnc != NULL) { - crcReg1 = transportEnc_CrcStartReg(hTpEnc, 192); - } - break; - case adtscrc_start_reg2: - if (hTpEnc != NULL) { - crcReg2 = transportEnc_CrcStartReg(hTpEnc, 128); - } - break; - case adtscrc_end_reg1: - case drmcrc_end_reg: - if (hTpEnc != NULL) { - transportEnc_CrcEndReg(hTpEnc, crcReg1); - } - break; - case adtscrc_end_reg2: - if (hTpEnc != NULL) { - transportEnc_CrcEndReg(hTpEnc, crcReg2); - } - break; - case drmcrc_start_reg: - if (hTpEnc != NULL) { - crcReg1 = transportEnc_CrcStartReg(hTpEnc, 0); - } - break; - case next_channel: - ch = (ch + 1) % numberOfChannels; - break; - case link_sequence: - list = list->next[decision_bit]; - i=-1; - break; - - default: - error = AAC_ENC_UNKNOWN; - break; + case spectral_data: + if (hBitStream != NULL) { + INT spectralBits = 0; + + spectralBits = FDKaacEnc_encodeSpectralData( + psyOutChannel[ch]->sfbOffsets, pChSectionData, + qcOutChannel[ch]->quantSpec, hBitStream); + + if (spectralBits != qcOutChannel[ch]->sectionData.huffmanBits) { + return AAC_ENC_WRITE_SPEC_ERROR; + } + bitDemand += spectralBits; + } + break; + + /* Non data cases */ + case adtscrc_start_reg1: + if (hTpEnc != NULL) { + crcReg1 = transportEnc_CrcStartReg(hTpEnc, 192); + } + break; + case adtscrc_start_reg2: + if (hTpEnc != NULL) { + crcReg2 = transportEnc_CrcStartReg(hTpEnc, 128); + } + break; + case adtscrc_end_reg1: + case drmcrc_end_reg: + if (hTpEnc != NULL) { + transportEnc_CrcEndReg(hTpEnc, crcReg1); + } + break; + case adtscrc_end_reg2: + if (hTpEnc != NULL) { + transportEnc_CrcEndReg(hTpEnc, crcReg2); + } + break; + case drmcrc_start_reg: + if (hTpEnc != NULL) { + crcReg1 = transportEnc_CrcStartReg(hTpEnc, 0); + } + break; + case next_channel: + ch = (ch + 1) % numberOfChannels; + break; + case link_sequence: + list = list->next[decision_bit]; + i = -1; + break; + + default: + error = AAC_ENC_UNKNOWN; + break; } if (error != AAC_ENC_OK) { @@ -1275,24 +1175,19 @@ bail: return error; } - //----------------------------------------------------------------------------------------------- AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc, CHANNEL_MAPPING *channelMapping, - QC_OUT *qcOut, - PSY_OUT* psyOut, + QC_OUT *qcOut, PSY_OUT *psyOut, QC_STATE *qcKernel, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig - ) -{ + AUDIO_OBJECT_TYPE aot, + UINT syntaxFlags, SCHAR epConfig) { HANDLE_FDK_BITSTREAM hBs = transportEnc_GetBitstream(hTpEnc); AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK; - int i, n, doByteAlign = 1; - INT bitMarkUp; - INT frameBits; + int i, n, doByteAlign = 1; + INT bitMarkUp; + INT frameBits; /* Get first bit of raw data block. In case of ADTS+PCE, AU would start at PCE. This is okay because PCE assures alignment. */ @@ -1300,160 +1195,112 @@ AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc, frameBits = bitMarkUp = alignAnchor; - /* Channel element loop */ - for (i=0; inElements; i++) { - + for (i = 0; i < channelMapping->nElements; i++) { ELEMENT_INFO elInfo = channelMapping->elInfo[i]; INT elementUsedBits = 0; - switch (elInfo.elType) - { - case ID_SCE: /* single channel */ - case ID_CPE: /* channel pair */ - case ID_LFE: /* low freq effects channel */ - { - if ( AAC_ENC_OK != (ErrorStatus = FDKaacEnc_ChannelElementWrite( hTpEnc, - &elInfo, - qcOut->qcElement[i]->qcOutChannel, - psyOut->psyOutElement[i], - psyOut->psyOutElement[i]->psyOutChannel, - syntaxFlags, /* syntaxFlags (ER tools ...) */ - aot, /* aot: AOT_AAC_LC, AOT_SBR, AOT_PS */ - epConfig, /* epConfig -1, 0, 1 */ - NULL, - 0 )) ) - { - return ErrorStatus; - } + switch (elInfo.elType) { + case ID_SCE: /* single channel */ + case ID_CPE: /* channel pair */ + case ID_LFE: /* low freq effects channel */ + { + if (AAC_ENC_OK != + (ErrorStatus = FDKaacEnc_ChannelElementWrite( + hTpEnc, &elInfo, qcOut->qcElement[i]->qcOutChannel, + psyOut->psyOutElement[i], + psyOut->psyOutElement[i]->psyOutChannel, + syntaxFlags, /* syntaxFlags (ER tools ...) */ + aot, /* aot: AOT_AAC_LC, AOT_SBR, AOT_PS */ + epConfig, /* epConfig -1, 0, 1 */ + NULL, 0))) { + return ErrorStatus; + } - if ( !(syntaxFlags & AC_ER) ) - { - /* Write associated extension payload */ - for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) { - FDKaacEnc_writeExtensionData( hTpEnc, - &qcOut->qcElement[i]->extension[n], - 0, - alignAnchor, - syntaxFlags, - aot, - epConfig ); - } + if (!(syntaxFlags & AC_ER)) { + /* Write associated extension payload */ + for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) { + FDKaacEnc_writeExtensionData( + hTpEnc, &qcOut->qcElement[i]->extension[n], 0, alignAnchor, + syntaxFlags, aot, epConfig); } } - break; + } break; - /* In FDK, DSE signalling explicit done in elDSE. See channel_map.cpp */ - default: - return AAC_ENC_INVALID_ELEMENTINFO_TYPE; + /* In FDK, DSE signalling explicit done in elDSE. See channel_map.cpp */ + default: + return AAC_ENC_INVALID_ELEMENTINFO_TYPE; - } /* switch */ + } /* switch */ - if(elInfo.elType != ID_DSE) { + if (elInfo.elType != ID_DSE) { elementUsedBits -= bitMarkUp; - bitMarkUp = FDKgetValidBits(hBs); + bitMarkUp = FDKgetValidBits(hBs); elementUsedBits += bitMarkUp; - frameBits += elementUsedBits; + frameBits += elementUsedBits; } } /* for (i=0; inElements; i++) { + if (syntaxFlags & AC_ELD) { + for (i = 0; i < channelMapping->nElements; i++) { for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) { - - if ( (qcOut->qcElement[i]->extension[n].type==EXT_SBR_DATA) - || (qcOut->qcElement[i]->extension[n].type==EXT_SBR_DATA_CRC) ) - { + if ((qcOut->qcElement[i]->extension[n].type == EXT_SBR_DATA) || + (qcOut->qcElement[i]->extension[n].type == EXT_SBR_DATA_CRC)) { /* Write sbr extension payload */ - FDKaacEnc_writeExtensionData( hTpEnc, - &qcOut->qcElement[i]->extension[n], - 0, - alignAnchor, - syntaxFlags, - aot, - epConfig ); + FDKaacEnc_writeExtensionData( + hTpEnc, &qcOut->qcElement[i]->extension[n], 0, alignAnchor, + syntaxFlags, aot, epConfig); channelElementExtensionWritten[i][n] = 1; } /* SBR */ - } /* n */ - } /* i */ - } /* AC_ELD */ + } /* n */ + } /* i */ + } /* AC_ELD */ - for (i=0; inElements; i++) { + for (i = 0; i < channelMapping->nElements; i++) { for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) { - - if (channelElementExtensionWritten[i][n]==0) - { + if (channelElementExtensionWritten[i][n] == 0) { /* Write all ramaining extension payloads in element */ - FDKaacEnc_writeExtensionData( hTpEnc, - &qcOut->qcElement[i]->extension[n], - 0, - alignAnchor, - syntaxFlags, - aot, - epConfig ); + FDKaacEnc_writeExtensionData(hTpEnc, + &qcOut->qcElement[i]->extension[n], 0, + alignAnchor, syntaxFlags, aot, epConfig); } } /* n */ - } /* i */ - } /* if AC_ER */ + } /* i */ + } /* if AC_ER */ /* Extend global extension payload table with fill bits */ - if ( syntaxFlags & AC_DRM ) - { - /* Exception for Drm */ - for (n = 0; n < qcOut->nExtensions; n++) { - if ( (qcOut->extension[n].type == EXT_SBR_DATA) - || (qcOut->extension[n].type == EXT_SBR_DATA_CRC) ) { - /* SBR data must be the last extension! */ - FDKmemcpy(&qcOut->extension[qcOut->nExtensions], &qcOut->extension[n], sizeof(QC_OUT_EXTENSION)); - break; - } - } - /* Do byte alignment after AAC (+ MPS) payload. - Assure that MPS has been written as channel assigned extension payload! */ - if (((FDKgetValidBits(hBs)-alignAnchor+(UINT)qcOut->totFillBits)&0x7)!=(UINT)qcOut->alignBits) { - return AAC_ENC_WRITTEN_BITS_ERROR; - } - FDKaacEnc_ByteAlignment(hBs, qcOut->alignBits); - doByteAlign = 0; - - } /* AC_DRM */ + n = qcOut->nExtensions; /* Add fill data / stuffing bits */ - n = qcOut->nExtensions; qcOut->extension[n].type = EXT_FILL_DATA; qcOut->extension[n].nPayloadBits = qcOut->totFillBits; qcOut->nExtensions++; /* Write global extension payload and fill data */ - for (n = 0; (n < qcOut->nExtensions) && (n < (2+2)); n++) - { - FDKaacEnc_writeExtensionData( hTpEnc, - &qcOut->extension[n], - 0, - alignAnchor, - syntaxFlags, - aot, - epConfig ); - - /* For EXT_FIL or EXT_FILL_DATA we could do an additional sanity check here */ + for (n = 0; (n < qcOut->nExtensions) && (n < (2 + 2)); n++) { + FDKaacEnc_writeExtensionData(hTpEnc, &qcOut->extension[n], 0, alignAnchor, + syntaxFlags, aot, epConfig); + + /* For EXT_FIL or EXT_FILL_DATA we could do an additional sanity check here + */ } - if (!(syntaxFlags & (AC_SCALABLE|AC_ER))) { + if (!(syntaxFlags & (AC_SCALABLE | AC_ER))) { FDKwriteBits(hBs, ID_END, EL_ID_BITS); } if (doByteAlign) { /* Assure byte alignment*/ - if (((alignAnchor-FDKgetValidBits(hBs))&0x7)!=(UINT)qcOut->alignBits) { + if (((FDKgetValidBits(hBs) - alignAnchor + qcOut->alignBits) & 0x7) != 0) { return AAC_ENC_WRITTEN_BITS_ERROR; } @@ -1465,10 +1312,9 @@ AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc, transportEnc_EndAccessUnit(hTpEnc, &frameBits); - if (frameBits != qcOut->totalBits + qcKernel->globHdrBits){ + if (frameBits != qcOut->totalBits + qcKernel->globHdrBits) { return AAC_ENC_WRITTEN_BITS_ERROR; } return ErrorStatus; } - diff --git a/libAACenc/src/bitenc.h b/libAACenc/src/bitenc.h index 498be7c..75dc068 100644 --- a/libAACenc/src/bitenc.h +++ b/libAACenc/src/bitenc.h @@ -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,74 +90,70 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M. Werner - contents/description: Bitstream encoder + Author(s): M. Werner -******************************************************************************/ + Description: Bitstream encoder -#ifndef _BITENC_H -#define _BITENC_H +*******************************************************************************/ +#ifndef BITENC_H +#define BITENC_H #include "qc_data.h" #include "aacenc_tns.h" #include "channel_map.h" -#include "interface.h" /* obsolete, when PSY_OUT is thrown out of the WritBS-call! */ +#include "interface.h" /* obsolete, when PSY_OUT is thrown out of the WritBS-call! */ #include "FDK_audio.h" #include "aacenc.h" #include "tpenc_lib.h" -typedef enum{ - MAX_ENCODER_CHANNELS = 9, - MAX_BLOCK_TYPES = 4, - MAX_AAC_LAYERS = 9, - MAX_LAYERS = MAX_AAC_LAYERS , /* only one core layer if present */ - FIRST_LAY = 1 /* default layer number for AAC nonscalable */ +typedef enum { + MAX_ENCODER_CHANNELS = 9, + MAX_BLOCK_TYPES = 4, + MAX_AAC_LAYERS = 9, + MAX_LAYERS = MAX_AAC_LAYERS, /* only one core layer if present */ + FIRST_LAY = 1 /* default layer number for AAC nonscalable */ } _MAX_CONST; -#define BUFFER_MX_HUFFCB_SIZE (32*sizeof(INT)) /* our FDK_bitbuffer needs size of power 2 */ - -#define EL_ID_BITS ( 3 ) +#define BUFFER_MX_HUFFCB_SIZE \ + (32 * sizeof(INT)) /* our FDK_bitbuffer needs size of power 2 */ +#define EL_ID_BITS (3) /** - * \brief Arbitrary order bitstream writer. This function can either assemble a bit stream - * and write into the bit buffer of hTpEnc or calculate the number of static bits (signal independent) - * TpEnc handle must be NULL in this case. Or also Calculate the minimum possible number of - * static bits which by disabling all tools e.g. MS, TNS and sbfCnt=0. The minCnt parameter - * has to be 1 in this latter case. - * \param hTpEnc Transport encoder handle. If NULL, the number of static bits will be returned into - * *pBitDemand. + * \brief Arbitrary order bitstream writer. This function can either assemble a + * bit stream and write into the bit buffer of hTpEnc or calculate the number of + * static bits (signal independent) TpEnc handle must be NULL in this + * case. Or also Calculate the minimum possible number of static bits + * which by disabling all tools e.g. MS, TNS and sbfCnt=0. The minCnt + * parameter has to be 1 in this latter case. + * \param hTpEnc Transport encoder handle. If NULL, the number of static bits + * will be returned into *pBitDemand. * \param pElInfo * \param qcOutChannel * \param hReorderInfo * \param psyOutElement * \param psyOutChannel - * \param syntaxFlags Bit stream syntax flags as defined in FDK_audio.h (Audio Codec flags). + * \param syntaxFlags Bit stream syntax flags as defined in FDK_audio.h (Audio + * Codec flags). * \param aot * \param epConfig - * \param pBitDemand Pointer to an int where the amount of bits is returned into. The returned value - * depends on if hTpEnc is NULL and minCnt. - * \param minCnt If non-zero the value returned into *pBitDemand is the absolute minimum required amount of - * static bits in order to write a valid bit stream. + * \param pBitDemand Pointer to an int where the amount of bits is returned + * into. The returned value depends on if hTpEnc is NULL and minCnt. + * \param minCnt If non-zero the value returned into *pBitDemand is the absolute + * minimum required amount of static bits in order to write a valid bit stream. * \return AAC_ENCODER_ERROR error code */ -AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite( HANDLE_TRANSPORTENC hTpEnc, - ELEMENT_INFO *pElInfo, - QC_OUT_CHANNEL *qcOutChannel[(2)], - PSY_OUT_ELEMENT *psyOutElement, - PSY_OUT_CHANNEL *psyOutChannel[(2)], - UINT syntaxFlags, - AUDIO_OBJECT_TYPE aot, - SCHAR epConfig, - INT *pBitDemand, - UCHAR minCnt - ); +AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite( + HANDLE_TRANSPORTENC hTpEnc, ELEMENT_INFO *pElInfo, + QC_OUT_CHANNEL *qcOutChannel[(2)], PSY_OUT_ELEMENT *psyOutElement, + PSY_OUT_CHANNEL *psyOutChannel[(2)], UINT syntaxFlags, + AUDIO_OBJECT_TYPE aot, SCHAR epConfig, INT *pBitDemand, UCHAR minCnt); /** * \brief Write bit stream or account static bits * \param hTpEnc transport encoder handle. If NULL, the function will @@ -161,23 +168,17 @@ AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite( HANDLE_TRANSPORTENC hTpEnc, * \param syntaxFlags Flags indicating format specific detail * \param epConfig Error protection config */ -AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream (HANDLE_TRANSPORTENC hTpEnc, - CHANNEL_MAPPING *channelMapping, - QC_OUT* qcOut, - PSY_OUT* psyOut, - QC_STATE* qcKernel, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig - ); - -INT FDKaacEnc_writeExtensionData( HANDLE_TRANSPORTENC hTpEnc, - QC_OUT_EXTENSION *pExtension, - INT elInstanceTag, - UINT alignAnchor, - UINT syntaxFlags, - AUDIO_OBJECT_TYPE aot, - SCHAR epConfig - ); - -#endif /* _BITENC_H */ +AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc, + CHANNEL_MAPPING *channelMapping, + QC_OUT *qcOut, PSY_OUT *psyOut, + QC_STATE *qcKernel, + AUDIO_OBJECT_TYPE aot, + UINT syntaxFlags, SCHAR epConfig); + +INT FDKaacEnc_writeExtensionData(HANDLE_TRANSPORTENC hTpEnc, + QC_OUT_EXTENSION *pExtension, + INT elInstanceTag, UINT alignAnchor, + UINT syntaxFlags, AUDIO_OBJECT_TYPE aot, + SCHAR epConfig); + +#endif /* BITENC_H */ diff --git a/libAACenc/src/block_switch.cpp b/libAACenc/src/block_switch.cpp index 7b3e275..c132253 100644 --- a/libAACenc/src/block_switch.cpp +++ b/libAACenc/src/block_switch.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,460 +90,488 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Encoder ************************** +/**************************** AAC encoder library ****************************** Author(s): M. Werner, Tobias Chalupka + Description: Block switching -******************************************************************************/ +*******************************************************************************/ /****************** Includes *****************************/ #include "block_switch.h" #include "genericStds.h" - #define LOWOV_WINDOW _LOWOV_WINDOW /**************** internal function prototypes ***********/ -static FIXP_DBL FDKaacEnc_GetWindowEnergy(const FIXP_DBL in[], const INT blSwWndIdx); +static FIXP_DBL FDKaacEnc_GetWindowEnergy(const FIXP_DBL in[], + const INT blSwWndIdx); static void FDKaacEnc_CalcWindowEnergy( - BLOCK_SWITCHING_CONTROL *RESTRICT blockSwitchingControl, - INT windowLen, - const INT_PCM *pTimeSignal - ); + BLOCK_SWITCHING_CONTROL *RESTRICT blockSwitchingControl, INT windowLen, + const INT_PCM *pTimeSignal); /****************** Constants *****************************/ -/* LONG START SHORT STOP LOWOV */ -static const INT blockType2windowShape[2][5] = { {SINE_WINDOW, KBD_WINDOW, WRONG_WINDOW, SINE_WINDOW, KBD_WINDOW}, /* LD */ - {KBD_WINDOW, SINE_WINDOW, SINE_WINDOW, KBD_WINDOW, WRONG_WINDOW} }; /* LC */ +/* LONG START + * SHORT STOP LOWOV */ +static const INT blockType2windowShape[2][5] = { + {SINE_WINDOW, KBD_WINDOW, WRONG_WINDOW, SINE_WINDOW, KBD_WINDOW}, /* LD */ + {KBD_WINDOW, SINE_WINDOW, SINE_WINDOW, KBD_WINDOW, WRONG_WINDOW}}; /* LC */ /* IIR high pass coeffs */ #ifndef SINETABLE_16BIT -static const FIXP_DBL hiPassCoeff[BLOCK_SWITCHING_IIR_LEN]= -{ - FL2FXCONST_DBL(-0.5095),FL2FXCONST_DBL(0.7548) -}; +static const FIXP_DBL hiPassCoeff[BLOCK_SWITCHING_IIR_LEN] = { + FL2FXCONST_DBL(-0.5095), FL2FXCONST_DBL(0.7548)}; -static const FIXP_DBL accWindowNrgFac = FL2FXCONST_DBL(0.3f); /* factor for accumulating filtered window energies */ +static const FIXP_DBL accWindowNrgFac = + FL2FXCONST_DBL(0.3f); /* factor for accumulating filtered window energies */ static const FIXP_DBL oneMinusAccWindowNrgFac = FL2FXCONST_DBL(0.7f); -/* static const float attackRatio = 10.0; */ /* lower ratio limit for attacks */ -static const FIXP_DBL invAttackRatio = FL2FXCONST_DBL(0.1f); /* inverted lower ratio limit for attacks */ +/* static const float attackRatio = 10.0; */ /* lower ratio limit for attacks */ +static const FIXP_DBL invAttackRatio = + FL2FXCONST_DBL(0.1f); /* inverted lower ratio limit for attacks */ -/* The next constants are scaled, because they are used for comparison with scaled values*/ +/* The next constants are scaled, because they are used for comparison with + * scaled values*/ /* minimum energy for attacks */ -static const FIXP_DBL minAttackNrg = (FL2FXCONST_DBL(1e+6f*NORM_PCM_ENERGY)>>BLOCK_SWITCH_ENERGY_SHIFT); /* minimum energy for attacks */ +static const FIXP_DBL minAttackNrg = + (FL2FXCONST_DBL(1e+6f * NORM_PCM_ENERGY) >> + BLOCK_SWITCH_ENERGY_SHIFT); /* minimum energy for attacks */ #else -static const FIXP_SGL hiPassCoeff[BLOCK_SWITCHING_IIR_LEN]= -{ - FL2FXCONST_SGL(-0.5095),FL2FXCONST_SGL(0.7548) -}; +static const FIXP_SGL hiPassCoeff[BLOCK_SWITCHING_IIR_LEN] = { + FL2FXCONST_SGL(-0.5095), FL2FXCONST_SGL(0.7548)}; -static const FIXP_DBL accWindowNrgFac = FL2FXCONST_DBL(0.3f); /* factor for accumulating filtered window energies */ +static const FIXP_DBL accWindowNrgFac = + FL2FXCONST_DBL(0.3f); /* factor for accumulating filtered window energies */ static const FIXP_SGL oneMinusAccWindowNrgFac = FL2FXCONST_SGL(0.7f); -/* static const float attackRatio = 10.0; */ /* lower ratio limit for attacks */ -static const FIXP_SGL invAttackRatio = FL2FXCONST_SGL(0.1f); /* inverted lower ratio limit for attacks */ +/* static const float attackRatio = 10.0; */ /* lower ratio limit for attacks */ +static const FIXP_SGL invAttackRatio = + FL2FXCONST_SGL(0.1f); /* inverted lower ratio limit for attacks */ /* minimum energy for attacks */ -static const FIXP_DBL minAttackNrg = (FL2FXCONST_DBL(1e+6f*NORM_PCM_ENERGY)>>BLOCK_SWITCH_ENERGY_SHIFT); /* minimum energy for attacks */ +static const FIXP_DBL minAttackNrg = + (FL2FXCONST_DBL(1e+6f * NORM_PCM_ENERGY) >> + BLOCK_SWITCH_ENERGY_SHIFT); /* minimum energy for attacks */ #endif /**************** internal function prototypes ***********/ /****************** Routines ****************************/ -void FDKaacEnc_InitBlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl, INT isLowDelay) -{ - FDKmemclear (blockSwitchingControl, sizeof(BLOCK_SWITCHING_CONTROL)); +void FDKaacEnc_InitBlockSwitching( + BLOCK_SWITCHING_CONTROL *blockSwitchingControl, INT isLowDelay) { + FDKmemclear(blockSwitchingControl, sizeof(BLOCK_SWITCHING_CONTROL)); - if (isLowDelay) - { + if (isLowDelay) { blockSwitchingControl->nBlockSwitchWindows = 4; - blockSwitchingControl->allowShortFrames = 0; - blockSwitchingControl->allowLookAhead = 0; - } - else - { + blockSwitchingControl->allowShortFrames = 0; + blockSwitchingControl->allowLookAhead = 0; + } else { blockSwitchingControl->nBlockSwitchWindows = 8; - blockSwitchingControl->allowShortFrames = 1; - blockSwitchingControl->allowLookAhead = 1; + blockSwitchingControl->allowShortFrames = 1; + blockSwitchingControl->allowLookAhead = 1; } - blockSwitchingControl->noOfGroups = MAX_NO_OF_GROUPS; + blockSwitchingControl->noOfGroups = MAX_NO_OF_GROUPS; /* Initialize startvalue for blocktype */ - blockSwitchingControl->lastWindowSequence = LONG_WINDOW; - blockSwitchingControl->windowShape = blockType2windowShape[blockSwitchingControl->allowShortFrames][blockSwitchingControl->lastWindowSequence]; - + blockSwitchingControl->lastWindowSequence = LONG_WINDOW; + blockSwitchingControl->windowShape = + blockType2windowShape[blockSwitchingControl->allowShortFrames] + [blockSwitchingControl->lastWindowSequence]; } -static const INT suggestedGroupingTable[TRANS_FAC][MAX_NO_OF_GROUPS] = -{ - /* Attack in Window 0 */ {1, 3, 3, 1}, - /* Attack in Window 1 */ {1, 1, 3, 3}, - /* Attack in Window 2 */ {2, 1, 3, 2}, - /* Attack in Window 3 */ {3, 1, 3, 1}, - /* Attack in Window 4 */ {3, 1, 1, 3}, - /* Attack in Window 5 */ {3, 2, 1, 2}, - /* Attack in Window 6 */ {3, 3, 1, 1}, - /* Attack in Window 7 */ {3, 3, 1, 1} -}; - -/* change block type depending on current blocktype and whether there's an attack */ +static const INT suggestedGroupingTable[TRANS_FAC][MAX_NO_OF_GROUPS] = { + /* Attack in Window 0 */ {1, 3, 3, 1}, + /* Attack in Window 1 */ {1, 1, 3, 3}, + /* Attack in Window 2 */ {2, 1, 3, 2}, + /* Attack in Window 3 */ {3, 1, 3, 1}, + /* Attack in Window 4 */ {3, 1, 1, 3}, + /* Attack in Window 5 */ {3, 2, 1, 2}, + /* Attack in Window 6 */ {3, 3, 1, 1}, + /* Attack in Window 7 */ {3, 3, 1, 1}}; + +/* change block type depending on current blocktype and whether there's an + * attack */ /* assume no look-ahead */ -static const INT chgWndSq[2][N_BLOCKTYPES] = -{ - /* LONG WINDOW START_WINDOW SHORT_WINDOW STOP_WINDOW, LOWOV_WINDOW, WRONG_WINDOW */ - /*no attack*/ {LONG_WINDOW, STOP_WINDOW, WRONG_WINDOW, LONG_WINDOW, STOP_WINDOW , WRONG_WINDOW }, - /*attack */ {START_WINDOW, LOWOV_WINDOW, WRONG_WINDOW, START_WINDOW, LOWOV_WINDOW, WRONG_WINDOW } -}; - -/* change block type depending on current blocktype and whether there's an attack */ +static const INT chgWndSq[2][N_BLOCKTYPES] = { + /* LONG WINDOW START_WINDOW SHORT_WINDOW STOP_WINDOW, + LOWOV_WINDOW, WRONG_WINDOW */ + /*no attack*/ {LONG_WINDOW, STOP_WINDOW, WRONG_WINDOW, LONG_WINDOW, + STOP_WINDOW, WRONG_WINDOW}, + /*attack */ {START_WINDOW, LOWOV_WINDOW, WRONG_WINDOW, START_WINDOW, + LOWOV_WINDOW, WRONG_WINDOW}}; + +/* change block type depending on current blocktype and whether there's an + * attack */ /* assume look-ahead */ -static const INT chgWndSqLkAhd[2][2][N_BLOCKTYPES] = -{ - /*attack LONG WINDOW START_WINDOW SHORT_WINDOW STOP_WINDOW LOWOV_WINDOW, WRONG_WINDOW */ /* last attack */ - /*no attack*/ { {LONG_WINDOW, SHORT_WINDOW, STOP_WINDOW, LONG_WINDOW, WRONG_WINDOW, WRONG_WINDOW}, /* no attack */ - /*attack */ {START_WINDOW, SHORT_WINDOW, SHORT_WINDOW, START_WINDOW, WRONG_WINDOW, WRONG_WINDOW} }, /* no attack */ - /*no attack*/ { {LONG_WINDOW, SHORT_WINDOW, SHORT_WINDOW, LONG_WINDOW, WRONG_WINDOW, WRONG_WINDOW}, /* attack */ - /*attack */ {START_WINDOW, SHORT_WINDOW, SHORT_WINDOW, START_WINDOW, WRONG_WINDOW, WRONG_WINDOW} } /* attack */ +static const INT chgWndSqLkAhd[2][2][N_BLOCKTYPES] = { + /*attack LONG WINDOW START_WINDOW SHORT_WINDOW STOP_WINDOW LOWOV_WINDOW, WRONG_WINDOW */ /* last attack */ + /*no attack*/ { + {LONG_WINDOW, SHORT_WINDOW, STOP_WINDOW, LONG_WINDOW, WRONG_WINDOW, + WRONG_WINDOW}, /* no attack */ + /*attack */ {START_WINDOW, SHORT_WINDOW, SHORT_WINDOW, START_WINDOW, + WRONG_WINDOW, WRONG_WINDOW}}, /* no attack */ + /*no attack*/ {{LONG_WINDOW, SHORT_WINDOW, SHORT_WINDOW, LONG_WINDOW, + WRONG_WINDOW, WRONG_WINDOW}, /* attack */ + /*attack */ {START_WINDOW, SHORT_WINDOW, SHORT_WINDOW, + START_WINDOW, WRONG_WINDOW, + WRONG_WINDOW}} /* attack */ }; -int FDKaacEnc_BlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl, const INT granuleLength, const int isLFE, const INT_PCM *pTimeSignal) -{ - UINT i; - FIXP_DBL enM1, enMax; - - UINT nBlockSwitchWindows = blockSwitchingControl->nBlockSwitchWindows; - - /* for LFE : only LONG window allowed */ - if (isLFE) { - - /* case LFE: */ - /* only long blocks, always use sine windows (MPEG2 AAC, MPEG4 AAC) */ - blockSwitchingControl->lastWindowSequence = LONG_WINDOW; - blockSwitchingControl->windowShape = SINE_WINDOW; - blockSwitchingControl->noOfGroups = 1; - blockSwitchingControl->groupLen[0] = 1; - - return(0); - }; - - /* Save current attack index as last attack index */ - blockSwitchingControl->lastattack = blockSwitchingControl->attack; - blockSwitchingControl->lastAttackIndex = blockSwitchingControl->attackIndex; - - /* Save current window energy as last window energy */ - FDKmemcpy(blockSwitchingControl->windowNrg[0], blockSwitchingControl->windowNrg[1], sizeof(blockSwitchingControl->windowNrg[0])); - FDKmemcpy(blockSwitchingControl->windowNrgF[0], blockSwitchingControl->windowNrgF[1], sizeof(blockSwitchingControl->windowNrgF[0])); - - if (blockSwitchingControl->allowShortFrames) - { - /* Calculate suggested grouping info for the last frame */ - - /* Reset grouping info */ - FDKmemclear (blockSwitchingControl->groupLen, sizeof(blockSwitchingControl->groupLen)); - - /* Set grouping info */ - blockSwitchingControl->noOfGroups = MAX_NO_OF_GROUPS; - - FDKmemcpy(blockSwitchingControl->groupLen, suggestedGroupingTable[blockSwitchingControl->lastAttackIndex], sizeof(blockSwitchingControl->groupLen)); - - if (blockSwitchingControl->attack == TRUE) - blockSwitchingControl->maxWindowNrg = FDKaacEnc_GetWindowEnergy(blockSwitchingControl->windowNrg[0], blockSwitchingControl->lastAttackIndex); - else - blockSwitchingControl->maxWindowNrg = FL2FXCONST_DBL(0.0); - - } - - - /* Calculate unfiltered and filtered energies in subwindows and combine to segments */ - FDKaacEnc_CalcWindowEnergy(blockSwitchingControl, granuleLength>>(nBlockSwitchWindows==4? 2:3 ), pTimeSignal); - - /* now calculate if there is an attack */ - - /* reset attack */ - blockSwitchingControl->attack = FALSE; +int FDKaacEnc_BlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl, + const INT granuleLength, const int isLFE, + const INT_PCM *pTimeSignal) { + UINT i; + FIXP_DBL enM1, enMax; + + UINT nBlockSwitchWindows = blockSwitchingControl->nBlockSwitchWindows; + + /* for LFE : only LONG window allowed */ + if (isLFE) { + /* case LFE: */ + /* only long blocks, always use sine windows (MPEG2 AAC, MPEG4 AAC) */ + blockSwitchingControl->lastWindowSequence = LONG_WINDOW; + blockSwitchingControl->windowShape = SINE_WINDOW; + blockSwitchingControl->noOfGroups = 1; + blockSwitchingControl->groupLen[0] = 1; + + return (0); + }; + + /* Save current attack index as last attack index */ + blockSwitchingControl->lastattack = blockSwitchingControl->attack; + blockSwitchingControl->lastAttackIndex = blockSwitchingControl->attackIndex; + + /* Save current window energy as last window energy */ + FDKmemcpy(blockSwitchingControl->windowNrg[0], + blockSwitchingControl->windowNrg[1], + sizeof(blockSwitchingControl->windowNrg[0])); + FDKmemcpy(blockSwitchingControl->windowNrgF[0], + blockSwitchingControl->windowNrgF[1], + sizeof(blockSwitchingControl->windowNrgF[0])); + + if (blockSwitchingControl->allowShortFrames) { + /* Calculate suggested grouping info for the last frame */ + + /* Reset grouping info */ + FDKmemclear(blockSwitchingControl->groupLen, + sizeof(blockSwitchingControl->groupLen)); + + /* Set grouping info */ + blockSwitchingControl->noOfGroups = MAX_NO_OF_GROUPS; + + FDKmemcpy(blockSwitchingControl->groupLen, + suggestedGroupingTable[blockSwitchingControl->lastAttackIndex], + sizeof(blockSwitchingControl->groupLen)); + + if (blockSwitchingControl->attack == TRUE) + blockSwitchingControl->maxWindowNrg = + FDKaacEnc_GetWindowEnergy(blockSwitchingControl->windowNrg[0], + blockSwitchingControl->lastAttackIndex); + else + blockSwitchingControl->maxWindowNrg = FL2FXCONST_DBL(0.0); + } - /* look for attack */ - enMax = FL2FXCONST_DBL(0.0f); - enM1 = blockSwitchingControl->windowNrgF[0][nBlockSwitchWindows-1]; + /* Calculate unfiltered and filtered energies in subwindows and combine to + * segments */ + FDKaacEnc_CalcWindowEnergy( + blockSwitchingControl, + granuleLength >> (nBlockSwitchWindows == 4 ? 2 : 3), pTimeSignal); - for (i=0; iaccWindowNrg); - blockSwitchingControl->accWindowNrg = fMultAdd(tmp, accWindowNrgFac, enM1) ; + /* now calculate if there is an attack */ - if (fMult(blockSwitchingControl->windowNrgF[1][i],invAttackRatio) > blockSwitchingControl->accWindowNrg ) { - blockSwitchingControl->attack = TRUE; - blockSwitchingControl->attackIndex = i; - } - enM1 = blockSwitchingControl->windowNrgF[1][i]; - enMax = fixMax(enMax, enM1); - } + /* reset attack */ + blockSwitchingControl->attack = FALSE; + /* look for attack */ + enMax = FL2FXCONST_DBL(0.0f); + enM1 = blockSwitchingControl->windowNrgF[0][nBlockSwitchWindows - 1]; - if (enMax < minAttackNrg) blockSwitchingControl->attack = FALSE; + for (i = 0; i < nBlockSwitchWindows; i++) { + FIXP_DBL tmp = + fMultDiv2(oneMinusAccWindowNrgFac, blockSwitchingControl->accWindowNrg); + blockSwitchingControl->accWindowNrg = fMultAdd(tmp, accWindowNrgFac, enM1); - /* Check if attack spreads over frame border */ - if((blockSwitchingControl->attack == FALSE) && (blockSwitchingControl->lastattack == TRUE)) { - /* if attack is in last window repeat SHORT_WINDOW */ - if ( ((blockSwitchingControl->windowNrgF[0][nBlockSwitchWindows-1]>>4) > fMult((FIXP_DBL)(10<<(DFRACT_BITS-1-4)), blockSwitchingControl->windowNrgF[1][1])) - && (blockSwitchingControl->lastAttackIndex == (INT)nBlockSwitchWindows-1) - ) - { - blockSwitchingControl->attack = TRUE; - blockSwitchingControl->attackIndex = 0; - } + if (fMult(blockSwitchingControl->windowNrgF[1][i], invAttackRatio) > + blockSwitchingControl->accWindowNrg) { + blockSwitchingControl->attack = TRUE; + blockSwitchingControl->attackIndex = i; } + enM1 = blockSwitchingControl->windowNrgF[1][i]; + enMax = fixMax(enMax, enM1); + } - - if(blockSwitchingControl->allowLookAhead) - { - - - blockSwitchingControl->lastWindowSequence = - chgWndSqLkAhd[blockSwitchingControl->lastattack][blockSwitchingControl->attack][blockSwitchingControl->lastWindowSequence]; - } - else - { - /* Low Delay */ - blockSwitchingControl->lastWindowSequence = - chgWndSq[blockSwitchingControl->attack][blockSwitchingControl->lastWindowSequence]; + if (enMax < minAttackNrg) blockSwitchingControl->attack = FALSE; + + /* Check if attack spreads over frame border */ + if ((blockSwitchingControl->attack == FALSE) && + (blockSwitchingControl->lastattack == TRUE)) { + /* if attack is in last window repeat SHORT_WINDOW */ + if (((blockSwitchingControl->windowNrgF[0][nBlockSwitchWindows - 1] >> 4) > + fMult((FIXP_DBL)(10 << (DFRACT_BITS - 1 - 4)), + blockSwitchingControl->windowNrgF[1][1])) && + (blockSwitchingControl->lastAttackIndex == + (INT)nBlockSwitchWindows - 1)) { + blockSwitchingControl->attack = TRUE; + blockSwitchingControl->attackIndex = 0; } + } + if (blockSwitchingControl->allowLookAhead) { + blockSwitchingControl->lastWindowSequence = + chgWndSqLkAhd[blockSwitchingControl->lastattack] + [blockSwitchingControl->attack] + [blockSwitchingControl->lastWindowSequence]; + } else { + /* Low Delay */ + blockSwitchingControl->lastWindowSequence = + chgWndSq[blockSwitchingControl->attack] + [blockSwitchingControl->lastWindowSequence]; + } - /* update window shape */ - blockSwitchingControl->windowShape = blockType2windowShape[blockSwitchingControl->allowShortFrames][blockSwitchingControl->lastWindowSequence]; + /* update window shape */ + blockSwitchingControl->windowShape = + blockType2windowShape[blockSwitchingControl->allowShortFrames] + [blockSwitchingControl->lastWindowSequence]; - return(0); + return (0); } - - -static FIXP_DBL FDKaacEnc_GetWindowEnergy(const FIXP_DBL in[], const INT blSwWndIdx) -{ -/* For coherency, change FDKaacEnc_GetWindowEnergy() to calcluate the energy for a block switching analysis windows, - not for a short block. The same is done FDKaacEnc_CalcWindowEnergy(). The result of FDKaacEnc_GetWindowEnergy() - is used for a comparision of the max energy of left/right channel. */ +static FIXP_DBL FDKaacEnc_GetWindowEnergy(const FIXP_DBL in[], + const INT blSwWndIdx) { + /* For coherency, change FDKaacEnc_GetWindowEnergy() to calcluate the energy + for a block switching analysis windows, not for a short block. The same is + done FDKaacEnc_CalcWindowEnergy(). The result of + FDKaacEnc_GetWindowEnergy() is used for a comparision of the max energy of + left/right channel. */ return in[blSwWndIdx]; - } -static void FDKaacEnc_CalcWindowEnergy(BLOCK_SWITCHING_CONTROL *RESTRICT blockSwitchingControl, INT windowLen, const INT_PCM *pTimeSignal) -{ - INT i; - UINT w; - - FIXP_SGL hiPassCoeff0 = hiPassCoeff[0]; - FIXP_SGL hiPassCoeff1 = hiPassCoeff[1]; +static void FDKaacEnc_CalcWindowEnergy( + BLOCK_SWITCHING_CONTROL *RESTRICT blockSwitchingControl, INT windowLen, + const INT_PCM *pTimeSignal) { + INT i; + UINT w; - /* sum up scalarproduct of timesignal as windowed Energies */ - for (w=0; w < blockSwitchingControl->nBlockSwitchWindows; w++) { +#ifndef SINETABLE_16BIT + const FIXP_DBL hiPassCoeff0 = hiPassCoeff[0]; + const FIXP_DBL hiPassCoeff1 = hiPassCoeff[1]; +#else + const FIXP_SGL hiPassCoeff0 = hiPassCoeff[0]; + const FIXP_SGL hiPassCoeff1 = hiPassCoeff[1]; +#endif - FIXP_DBL temp_windowNrg = FL2FXCONST_DBL(0.0f); - FIXP_DBL temp_windowNrgF = FL2FXCONST_DBL(0.0f); - FIXP_DBL temp_iirState0 = blockSwitchingControl->iirStates[0]; - FIXP_DBL temp_iirState1 = blockSwitchingControl->iirStates[1]; + FIXP_DBL temp_iirState0 = blockSwitchingControl->iirStates[0]; + FIXP_DBL temp_iirState1 = blockSwitchingControl->iirStates[1]; - /* windowNrg = sum(timesample^2) */ - for(i=0;inBlockSwitchWindows; w++) { + ULONG temp_windowNrg = 0x0; + ULONG temp_windowNrgF = 0x0; - FIXP_DBL tempUnfiltered, tempFiltred, t1, t2; - /* tempUnfiltered is scaled with 1 to prevent overflows during calculation of tempFiltred */ + /* windowNrg = sum(timesample^2) */ + for (i = 0; i < windowLen; i++) { + FIXP_DBL tempUnfiltered, t1, t2; + /* tempUnfiltered is scaled with 1 to prevent overflows during calculation + * of tempFiltred */ #if SAMPLE_BITS == DFRACT_BITS - tempUnfiltered = (FIXP_DBL) *pTimeSignal++ >> 1; + tempUnfiltered = (FIXP_DBL)*pTimeSignal++ >> 1; #else - tempUnfiltered = (FIXP_DBL) *pTimeSignal++ << (DFRACT_BITS-SAMPLE_BITS-1); + tempUnfiltered = (FIXP_DBL)*pTimeSignal++ + << (DFRACT_BITS - SAMPLE_BITS - 1); #endif - t1 = fMultDiv2(hiPassCoeff1, tempUnfiltered-temp_iirState0); - t2 = fMultDiv2(hiPassCoeff0, temp_iirState1); - tempFiltred = (t1 - t2) << 1; - - temp_iirState0 = tempUnfiltered; - temp_iirState1 = tempFiltred; - - /* subtract 2 from overallscaling (BLOCK_SWITCH_ENERGY_SHIFT) - * because tempUnfiltered was already scaled with 1 (is 2 after squaring) - * subtract 1 from overallscaling (BLOCK_SWITCH_ENERGY_SHIFT) - * because of fMultDiv2 is doing a scaling by one */ - temp_windowNrg += fPow2Div2(tempUnfiltered) >> (BLOCK_SWITCH_ENERGY_SHIFT - 1 - 2); - temp_windowNrgF += fPow2Div2(tempFiltred) >> (BLOCK_SWITCH_ENERGY_SHIFT - 1 - 2); - } - blockSwitchingControl->windowNrg[1][w] = temp_windowNrg; - blockSwitchingControl->windowNrgF[1][w] = temp_windowNrgF; - blockSwitchingControl->iirStates[0] = temp_iirState0; - blockSwitchingControl->iirStates[1] = temp_iirState1; + t1 = fMultDiv2(hiPassCoeff1, tempUnfiltered - temp_iirState0); + t2 = fMultDiv2(hiPassCoeff0, temp_iirState1); + temp_iirState0 = tempUnfiltered; + temp_iirState1 = (t1 - t2) << 1; + + temp_windowNrg += (LONG)fPow2Div2(temp_iirState0) >> + (BLOCK_SWITCH_ENERGY_SHIFT - 1 - 2); + temp_windowNrgF += (LONG)fPow2Div2(temp_iirState1) >> + (BLOCK_SWITCH_ENERGY_SHIFT - 1 - 2); } + blockSwitchingControl->windowNrg[1][w] = + (LONG)fMin(temp_windowNrg, (UINT)MAXVAL_DBL); + blockSwitchingControl->windowNrgF[1][w] = + (LONG)fMin(temp_windowNrgF, (UINT)MAXVAL_DBL); + } + blockSwitchingControl->iirStates[0] = temp_iirState0; + blockSwitchingControl->iirStates[1] = temp_iirState1; } - -static const UCHAR synchronizedBlockTypeTable[5][5] = -{ - /* LONG_WINDOW START_WINDOW SHORT_WINDOW STOP_WINDOW LOWOV_WINDOW*/ - /* LONG_WINDOW */ {LONG_WINDOW, START_WINDOW, SHORT_WINDOW, STOP_WINDOW, LOWOV_WINDOW}, - /* START_WINDOW */ {START_WINDOW, START_WINDOW, SHORT_WINDOW, SHORT_WINDOW, LOWOV_WINDOW}, - /* SHORT_WINDOW */ {SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW, WRONG_WINDOW}, - /* STOP_WINDOW */ {STOP_WINDOW, SHORT_WINDOW, SHORT_WINDOW, STOP_WINDOW, LOWOV_WINDOW}, - /* LOWOV_WINDOW */ {LOWOV_WINDOW, LOWOV_WINDOW, WRONG_WINDOW, LOWOV_WINDOW, LOWOV_WINDOW}, +static const UCHAR synchronizedBlockTypeTable[5][5] = { + /* LONG_WINDOW START_WINDOW SHORT_WINDOW STOP_WINDOW + LOWOV_WINDOW*/ + /* LONG_WINDOW */ {LONG_WINDOW, START_WINDOW, SHORT_WINDOW, STOP_WINDOW, + LOWOV_WINDOW}, + /* START_WINDOW */ + {START_WINDOW, START_WINDOW, SHORT_WINDOW, SHORT_WINDOW, LOWOV_WINDOW}, + /* SHORT_WINDOW */ + {SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW, WRONG_WINDOW}, + /* STOP_WINDOW */ + {STOP_WINDOW, SHORT_WINDOW, SHORT_WINDOW, STOP_WINDOW, LOWOV_WINDOW}, + /* LOWOV_WINDOW */ + {LOWOV_WINDOW, LOWOV_WINDOW, WRONG_WINDOW, LOWOV_WINDOW, LOWOV_WINDOW}, }; -int FDKaacEnc_SyncBlockSwitching ( - BLOCK_SWITCHING_CONTROL *blockSwitchingControlLeft, - BLOCK_SWITCHING_CONTROL *blockSwitchingControlRight, - const INT nChannels, - const INT commonWindow ) -{ +int FDKaacEnc_SyncBlockSwitching( + BLOCK_SWITCHING_CONTROL *blockSwitchingControlLeft, + BLOCK_SWITCHING_CONTROL *blockSwitchingControlRight, const INT nChannels, + const INT commonWindow) { UCHAR patchType = LONG_WINDOW; - if( nChannels == 2 && commonWindow == TRUE) - { + if (nChannels == 2 && commonWindow == TRUE) { /* could be better with a channel loop (need a handle to psy_data) */ /* get suggested Block Types and synchronize */ - patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlLeft->lastWindowSequence]; - patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlRight->lastWindowSequence]; + patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlLeft + ->lastWindowSequence]; + patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlRight + ->lastWindowSequence]; - /* sanity check (no change from low overlap window to short winow and vice versa) */ - if (patchType == WRONG_WINDOW) - return -1; /* mixed up AAC-LC and AAC-LD */ + /* sanity check (no change from low overlap window to short winow and vice + * versa) */ + if (patchType == WRONG_WINDOW) return -1; /* mixed up AAC-LC and AAC-LD */ /* Set synchronized Blocktype */ - blockSwitchingControlLeft->lastWindowSequence = patchType; + blockSwitchingControlLeft->lastWindowSequence = patchType; blockSwitchingControlRight->lastWindowSequence = patchType; /* update window shape */ - blockSwitchingControlLeft->windowShape = blockType2windowShape[blockSwitchingControlLeft->allowShortFrames][blockSwitchingControlLeft->lastWindowSequence]; - blockSwitchingControlRight->windowShape = blockType2windowShape[blockSwitchingControlLeft->allowShortFrames][blockSwitchingControlRight->lastWindowSequence]; + blockSwitchingControlLeft->windowShape = + blockType2windowShape[blockSwitchingControlLeft->allowShortFrames] + [blockSwitchingControlLeft->lastWindowSequence]; + blockSwitchingControlRight->windowShape = + blockType2windowShape[blockSwitchingControlLeft->allowShortFrames] + [blockSwitchingControlRight->lastWindowSequence]; } - if (blockSwitchingControlLeft->allowShortFrames) - { + if (blockSwitchingControlLeft->allowShortFrames) { int i; - if( nChannels == 2 ) - { - if (commonWindow == TRUE) - { + if (nChannels == 2) { + if (commonWindow == TRUE) { /* Synchronize grouping info */ - int windowSequenceLeftOld = blockSwitchingControlLeft->lastWindowSequence; - int windowSequenceRightOld = blockSwitchingControlRight->lastWindowSequence; + int windowSequenceLeftOld = + blockSwitchingControlLeft->lastWindowSequence; + int windowSequenceRightOld = + blockSwitchingControlRight->lastWindowSequence; /* Long Blocks */ - if(patchType != SHORT_WINDOW) { + if (patchType != SHORT_WINDOW) { /* Set grouping info */ - blockSwitchingControlLeft->noOfGroups = 1; - blockSwitchingControlRight->noOfGroups = 1; - blockSwitchingControlLeft->groupLen[0] = 1; + blockSwitchingControlLeft->noOfGroups = 1; + blockSwitchingControlRight->noOfGroups = 1; + blockSwitchingControlLeft->groupLen[0] = 1; blockSwitchingControlRight->groupLen[0] = 1; - for (i = 1; i < MAX_NO_OF_GROUPS; i++) - { - blockSwitchingControlLeft->groupLen[i] = 0; + for (i = 1; i < MAX_NO_OF_GROUPS; i++) { + blockSwitchingControlLeft->groupLen[i] = 0; blockSwitchingControlRight->groupLen[i] = 0; } } /* Short Blocks */ else { - /* in case all two channels were detected as short-blocks before syncing, use the grouping of channel with higher maxWindowNrg */ - if( (windowSequenceLeftOld == SHORT_WINDOW) && - (windowSequenceRightOld == SHORT_WINDOW) ) - { - if(blockSwitchingControlLeft->maxWindowNrg > blockSwitchingControlRight->maxWindowNrg) { - /* Left Channel wins */ - blockSwitchingControlRight->noOfGroups = blockSwitchingControlLeft->noOfGroups; - for (i = 0; i < MAX_NO_OF_GROUPS; i++){ - blockSwitchingControlRight->groupLen[i] = blockSwitchingControlLeft->groupLen[i]; - } + /* in case all two channels were detected as short-blocks before + * syncing, use the grouping of channel with higher maxWindowNrg */ + if ((windowSequenceLeftOld == SHORT_WINDOW) && + (windowSequenceRightOld == SHORT_WINDOW)) { + if (blockSwitchingControlLeft->maxWindowNrg > + blockSwitchingControlRight->maxWindowNrg) { + /* Left Channel wins */ + blockSwitchingControlRight->noOfGroups = + blockSwitchingControlLeft->noOfGroups; + for (i = 0; i < MAX_NO_OF_GROUPS; i++) { + blockSwitchingControlRight->groupLen[i] = + blockSwitchingControlLeft->groupLen[i]; + } + } else { + /* Right Channel wins */ + blockSwitchingControlLeft->noOfGroups = + blockSwitchingControlRight->noOfGroups; + for (i = 0; i < MAX_NO_OF_GROUPS; i++) { + blockSwitchingControlLeft->groupLen[i] = + blockSwitchingControlRight->groupLen[i]; + } } - else { - /* Right Channel wins */ - blockSwitchingControlLeft->noOfGroups = blockSwitchingControlRight->noOfGroups; - for (i = 0; i < MAX_NO_OF_GROUPS; i++){ - blockSwitchingControlLeft->groupLen[i] = blockSwitchingControlRight->groupLen[i]; - } - } - } - else if ( (windowSequenceLeftOld == SHORT_WINDOW) && - (windowSequenceRightOld != SHORT_WINDOW) ) - { + } else if ((windowSequenceLeftOld == SHORT_WINDOW) && + (windowSequenceRightOld != SHORT_WINDOW)) { /* else use grouping of short-block channel */ - blockSwitchingControlRight->noOfGroups = blockSwitchingControlLeft->noOfGroups; - for (i = 0; i < MAX_NO_OF_GROUPS; i++){ - blockSwitchingControlRight->groupLen[i] = blockSwitchingControlLeft->groupLen[i]; + blockSwitchingControlRight->noOfGroups = + blockSwitchingControlLeft->noOfGroups; + for (i = 0; i < MAX_NO_OF_GROUPS; i++) { + blockSwitchingControlRight->groupLen[i] = + blockSwitchingControlLeft->groupLen[i]; } - } - else if ( (windowSequenceRightOld == SHORT_WINDOW) && - (windowSequenceLeftOld != SHORT_WINDOW) ) - { - blockSwitchingControlLeft->noOfGroups = blockSwitchingControlRight->noOfGroups; - for (i = 0; i < MAX_NO_OF_GROUPS; i++){ - blockSwitchingControlLeft->groupLen[i] = blockSwitchingControlRight->groupLen[i]; + } else if ((windowSequenceRightOld == SHORT_WINDOW) && + (windowSequenceLeftOld != SHORT_WINDOW)) { + blockSwitchingControlLeft->noOfGroups = + blockSwitchingControlRight->noOfGroups; + for (i = 0; i < MAX_NO_OF_GROUPS; i++) { + blockSwitchingControlLeft->groupLen[i] = + blockSwitchingControlRight->groupLen[i]; } } else { /* syncing a start and stop window ... */ - blockSwitchingControlLeft->noOfGroups = blockSwitchingControlRight->noOfGroups = 2; - blockSwitchingControlLeft->groupLen[0] = blockSwitchingControlRight->groupLen[0] = 4; - blockSwitchingControlLeft->groupLen[1] = blockSwitchingControlRight->groupLen[1] = 4; + blockSwitchingControlLeft->noOfGroups = + blockSwitchingControlRight->noOfGroups = 2; + blockSwitchingControlLeft->groupLen[0] = + blockSwitchingControlRight->groupLen[0] = 4; + blockSwitchingControlLeft->groupLen[1] = + blockSwitchingControlRight->groupLen[1] = 4; } } /* Short Blocks */ - } - else { + } else { /* stereo, no common window */ - if (blockSwitchingControlLeft->lastWindowSequence!=SHORT_WINDOW){ - blockSwitchingControlLeft->noOfGroups = 1; + if (blockSwitchingControlLeft->lastWindowSequence != SHORT_WINDOW) { + blockSwitchingControlLeft->noOfGroups = 1; blockSwitchingControlLeft->groupLen[0] = 1; - for (i = 1; i < MAX_NO_OF_GROUPS; i++) - { + for (i = 1; i < MAX_NO_OF_GROUPS; i++) { blockSwitchingControlLeft->groupLen[i] = 0; } } - if (blockSwitchingControlRight->lastWindowSequence!=SHORT_WINDOW){ - blockSwitchingControlRight->noOfGroups = 1; + if (blockSwitchingControlRight->lastWindowSequence != SHORT_WINDOW) { + blockSwitchingControlRight->noOfGroups = 1; blockSwitchingControlRight->groupLen[0] = 1; - for (i = 1; i < MAX_NO_OF_GROUPS; i++) - { + for (i = 1; i < MAX_NO_OF_GROUPS; i++) { blockSwitchingControlRight->groupLen[i] = 0; } } } /* common window */ } else { /* Mono */ - if (blockSwitchingControlLeft->lastWindowSequence!=SHORT_WINDOW){ - blockSwitchingControlLeft->noOfGroups = 1; + if (blockSwitchingControlLeft->lastWindowSequence != SHORT_WINDOW) { + blockSwitchingControlLeft->noOfGroups = 1; blockSwitchingControlLeft->groupLen[0] = 1; - for (i = 1; i < MAX_NO_OF_GROUPS; i++) - { + for (i = 1; i < MAX_NO_OF_GROUPS; i++) { blockSwitchingControlLeft->groupLen[i] = 0; } } } } /* allowShortFrames */ - /* Translate LOWOV_WINDOW block type to a meaningful window shape. */ - if ( ! blockSwitchingControlLeft->allowShortFrames ) { - if ( blockSwitchingControlLeft->lastWindowSequence != LONG_WINDOW - && blockSwitchingControlLeft->lastWindowSequence != STOP_WINDOW ) - { + if (!blockSwitchingControlLeft->allowShortFrames) { + if (blockSwitchingControlLeft->lastWindowSequence != LONG_WINDOW && + blockSwitchingControlLeft->lastWindowSequence != STOP_WINDOW) { blockSwitchingControlLeft->lastWindowSequence = LONG_WINDOW; blockSwitchingControlLeft->windowShape = LOL_WINDOW; } } if (nChannels == 2) { - if ( ! blockSwitchingControlRight->allowShortFrames ) { - if ( blockSwitchingControlRight->lastWindowSequence != LONG_WINDOW - && blockSwitchingControlRight->lastWindowSequence != STOP_WINDOW ) - { + if (!blockSwitchingControlRight->allowShortFrames) { + if (blockSwitchingControlRight->lastWindowSequence != LONG_WINDOW && + blockSwitchingControlRight->lastWindowSequence != STOP_WINDOW) { blockSwitchingControlRight->lastWindowSequence = LONG_WINDOW; blockSwitchingControlRight->windowShape = LOL_WINDOW; } @@ -541,5 +580,3 @@ int FDKaacEnc_SyncBlockSwitching ( return 0; } - - diff --git a/libAACenc/src/block_switch.h b/libAACenc/src/block_switch.h index e94b6f5..ff20f84 100644 --- a/libAACenc/src/block_switch.h +++ b/libAACenc/src/block_switch.h @@ -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,68 +90,73 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Encoder ************************** +/**************************** AAC encoder library ****************************** Author(s): M. Werner + Description: Block switching -******************************************************************************/ +*******************************************************************************/ -#ifndef _BLOCK_SWITCH_H -#define _BLOCK_SWITCH_H +#ifndef BLOCK_SWITCH_H +#define BLOCK_SWITCH_H #include "common_fix.h" #include "psy_const.h" /****************** Defines ******************************/ - #define BLOCK_SWITCH_WINDOWS 8 /* number of windows for energy calculation */ +#define BLOCK_SWITCH_WINDOWS 8 /* number of windows for energy calculation */ -#define BLOCK_SWITCHING_IIR_LEN 2 /* Length of HighPass-IIR-Filter for Attack-Detection */ -#define BLOCK_SWITCH_ENERGY_SHIFT 7 /* should be logDualis(BLOCK_SWITCH_WINDOW_LEN) to avoid overflow in windowNrgs. */ +#define BLOCK_SWITCHING_IIR_LEN \ + 2 /* Length of HighPass-IIR-Filter for Attack-Detection */ +#define BLOCK_SWITCH_ENERGY_SHIFT \ + 7 /* should be logDualis(BLOCK_SWITCH_WINDOW_LEN) to avoid overflow in \ + windowNrgs. */ #define LAST_WINDOW 0 #define THIS_WINDOW 1 - /****************** Structures ***************************/ -typedef struct{ - INT lastWindowSequence; - INT windowShape; - INT lastWindowShape; - UINT nBlockSwitchWindows; /* number of windows for energy calculation */ - INT attack; - INT lastattack; - INT attackIndex; - INT lastAttackIndex; - INT allowShortFrames; /* for Low Delay, don't allow short frames */ - INT allowLookAhead; /* for Low Delay, don't do look-ahead */ - INT noOfGroups; - INT groupLen[MAX_NO_OF_GROUPS]; - FIXP_DBL maxWindowNrg; /* max energy in subwindows */ - - FIXP_DBL windowNrg[2][BLOCK_SWITCH_WINDOWS]; /* time signal energy in Subwindows (last and current) */ - FIXP_DBL windowNrgF[2][BLOCK_SWITCH_WINDOWS]; /* filtered time signal energy in segments (last and current) */ - FIXP_DBL accWindowNrg; /* recursively accumulated windowNrgF */ - - FIXP_DBL iirStates[BLOCK_SWITCHING_IIR_LEN]; /* filter delay-line */ +typedef struct { + INT lastWindowSequence; + INT windowShape; + INT lastWindowShape; + UINT nBlockSwitchWindows; /* number of windows for energy calculation */ + INT attack; + INT lastattack; + INT attackIndex; + INT lastAttackIndex; + INT allowShortFrames; /* for Low Delay, don't allow short frames */ + INT allowLookAhead; /* for Low Delay, don't do look-ahead */ + INT noOfGroups; + INT groupLen[MAX_NO_OF_GROUPS]; + FIXP_DBL maxWindowNrg; /* max energy in subwindows */ + + FIXP_DBL + windowNrg[2][BLOCK_SWITCH_WINDOWS]; /* time signal energy in Subwindows + (last and current) */ + FIXP_DBL windowNrgF[2][BLOCK_SWITCH_WINDOWS]; /* filtered time signal energy + in segments (last and + current) */ + FIXP_DBL accWindowNrg; /* recursively accumulated windowNrgF */ + + FIXP_DBL iirStates[BLOCK_SWITCHING_IIR_LEN]; /* filter delay-line */ } BLOCK_SWITCHING_CONTROL; +void FDKaacEnc_InitBlockSwitching( + BLOCK_SWITCHING_CONTROL *blockSwitchingControl, INT isLowDelay); - - - -void FDKaacEnc_InitBlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl, INT isLowDelay); - -int FDKaacEnc_BlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl, const INT granuleLength, const int isLFE, const INT_PCM *pTimeSignal); +int FDKaacEnc_BlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl, + const INT granuleLength, const int isLFE, + const INT_PCM *pTimeSignal); int FDKaacEnc_SyncBlockSwitching( - BLOCK_SWITCHING_CONTROL *blockSwitchingControlLeft, - BLOCK_SWITCHING_CONTROL *blockSwitchingControlRight, - const INT noOfChannels, - const INT commonWindow); + BLOCK_SWITCHING_CONTROL *blockSwitchingControlLeft, + BLOCK_SWITCHING_CONTROL *blockSwitchingControlRight, const INT noOfChannels, + const INT commonWindow); -#endif /* #ifndef _BLOCK_SWITCH_H */ +#endif /* #ifndef BLOCK_SWITCH_H */ diff --git a/libAACenc/src/channel_map.cpp b/libAACenc/src/channel_map.cpp index 559a4ce..6ee91d5 100644 --- a/libAACenc/src/channel_map.cpp +++ b/libAACenc/src/channel_map.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,21 +90,22 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/************************* Fast MPEG AAC Audio Encoder ********************** + Author(s): A. Groeschel - Initial author: A. Groeschel - contents/description: channel mapping functionality + Description: channel mapping functionality -******************************************************************************/ +*******************************************************************************/ #include "channel_map.h" #include "bitenc.h" #include "psy_const.h" #include "qc_data.h" #include "aacEnc_ram.h" - +#include "FDK_tools_rom.h" /* channel_assignment treats the relationship of Input file channels to the encoder channels. @@ -121,369 +133,464 @@ amm-info@iis.fraunhofer.de LFE 3 5 (LFE) */ -typedef struct { - - CHANNEL_MODE encoderMode; - INT channel_assignment[/*(8)*/12]; - -} CHANNEL_ASSIGNMENT_INFO_TAB; - - -static const CHANNEL_ASSIGNMENT_INFO_TAB assignmentInfoTabMpeg[] = -{ - { MODE_INVALID, {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} }, /* invalid */ - { MODE_1, { 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} }, /* mono */ - { MODE_2, { 0, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} }, /* stereo */ - { MODE_1_2, { 0, 1, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1} }, /* 3ch */ - { MODE_1_2_1, { 0, 1, 2, 3,-1,-1,-1,-1,-1,-1,-1,-1} }, /* 4ch */ - { MODE_1_2_2, { 0, 1, 2, 3, 4,-1,-1,-1,-1,-1,-1,-1} }, /* 5ch */ - { MODE_1_2_2_1, { 0, 1, 2, 3, 4, 5,-1,-1,-1,-1,-1,-1} }, /* 5.1ch */ - { MODE_1_2_2_2_1, { 0, 1, 2, 3, 4, 5, 6, 7,-1,-1,-1,-1} }, /* 7.1ch */ - { MODE_7_1_REAR_SURROUND, { 0, 1, 2, 3, 4, 5, 6, 7,-1,-1,-1,-1} }, /* 7.1ch */ - { MODE_7_1_FRONT_CENTER, { 0, 1, 2, 3, 4, 5, 6, 7,-1,-1,-1,-1} } /* 7.1ch */ -}; - -static const CHANNEL_ASSIGNMENT_INFO_TAB assignmentInfoTabWav[] = -{ - { MODE_INVALID, {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} }, /* invalid */ - { MODE_1, { 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} }, /* mono */ - { MODE_2, { 0, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} }, /* stereo */ - { MODE_1_2, { 2, 0, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1} }, /* 3ch */ - { MODE_1_2_1, { 2, 0, 1, 3,-1,-1,-1,-1,-1,-1,-1,-1} }, /* 4ch */ - { MODE_1_2_2, { 2, 0, 1, 3, 4,-1,-1,-1,-1,-1,-1,-1} }, /* 5ch */ - { MODE_1_2_2_1, { 2, 0, 1, 4, 5, 3,-1,-1,-1,-1,-1,-1} }, /* 5.1ch */ - { MODE_1_2_2_2_1, { 2, 6, 7, 0, 1, 4, 5, 3,-1,-1,-1,-1} }, /* 7.1ch */ - { MODE_7_1_REAR_SURROUND, { 2, 0, 1, 6, 7, 4, 5, 3,-1,-1,-1,-1} }, /* 7.1ch */ - { MODE_7_1_FRONT_CENTER, { 2, 6, 7, 0, 1, 4, 5, 3,-1,-1,-1,-1} }, /* 7.1ch */ -}; - /* Channel mode configuration tab provides, corresponding number of channels and elements */ -static const CHANNEL_MODE_CONFIG_TAB channelModeConfig[] = -{ - { MODE_1, 1, 1, 1 }, /* SCE */ - { MODE_2, 2, 2, 1 }, /* CPE */ - { MODE_1_2, 3, 3, 2 }, /* SCE,CPE */ - { MODE_1_2_1, 4, 4, 3 }, /* SCE,CPE,SCE */ - { MODE_1_2_2, 5, 5, 3 }, /* SCE,CPE,CPE */ - { MODE_1_2_2_1, 6, 5, 4 }, /* SCE,CPE,CPE,LFE */ - { MODE_1_2_2_2_1, 8, 7, 5 }, /* SCE,CPE,CPE,CPE,LFE */ - { MODE_7_1_REAR_SURROUND, 8, 7, 5 }, - { MODE_7_1_FRONT_CENTER, 8, 7, 5 }, -}; +static const CHANNEL_MODE_CONFIG_TAB channelModeConfig[] = { + {MODE_1, 1, 1, 1}, /* chCfg 1, SCE */ + {MODE_2, 2, 2, 1}, /* chCfg 2, CPE */ + {MODE_1_2, 3, 3, 2}, /* chCfg 3, SCE,CPE */ + {MODE_1_2_1, 4, 4, 3}, /* chCfg 4, SCE,CPE,SCE */ + {MODE_1_2_2, 5, 5, 3}, /* chCfg 5, SCE,CPE,CPE */ + {MODE_1_2_2_1, 6, 5, 4}, /* chCfg 6, SCE,CPE,CPE,LFE */ + {MODE_1_2_2_2_1, 8, 7, 5}, /* chCfg 7, SCE,CPE,CPE,CPE,LFE */ + {MODE_6_1, 7, 6, 5}, /* chCfg 11, SCE,CPE,CPE,SCE,LFE */ + {MODE_7_1_BACK, 8, 7, 5}, /* chCfg 12, SCE,CPE,CPE,CPE,LFE */ + {MODE_7_1_TOP_FRONT, 8, 7, 5}, /* chCfg 14, SCE,CPE,CPE,LFE,CPE */ + {MODE_7_1_REAR_SURROUND, 8, 7, + 5}, /* same as MODE_7_1_BACK, SCE,CPE,CPE,CPE,LFE */ + {MODE_7_1_FRONT_CENTER, 8, 7, + 5}, /* same as MODE_1_2_2_2_1, SCE,CPE,CPE,CPE,LFE */ -#define MAX_MODES (sizeof(assignmentInfoTabWav)/sizeof(CHANNEL_ASSIGNMENT_INFO_TAB)) - -const INT* FDKaacEnc_getChannelAssignment(CHANNEL_MODE encMode, CHANNEL_ORDER co) -{ - const CHANNEL_ASSIGNMENT_INFO_TAB *pTab; - int i; - - if (co == CH_ORDER_MPEG) - pTab = assignmentInfoTabMpeg; - else - pTab = assignmentInfoTabWav; - - for(i=MAX_MODES-1; i>0; i--) { - if (encMode== pTab[i].encoderMode) { - break; - } - } - return (pTab[i].channel_assignment); -} +}; -AAC_ENCODER_ERROR FDKaacEnc_DetermineEncoderMode(CHANNEL_MODE* mode, INT nChannels) -{ +AAC_ENCODER_ERROR FDKaacEnc_DetermineEncoderMode(CHANNEL_MODE* mode, + INT nChannels) { INT i; CHANNEL_MODE encMode = MODE_INVALID; - if (*mode==MODE_UNKNOWN) { - for (i=0; i<(INT)sizeof(channelModeConfig)/(INT)sizeof(CHANNEL_MODE_CONFIG_TAB); i++) { - if (channelModeConfig[i].nChannels==nChannels) { - encMode = channelModeConfig[i].encMode; - break; + if (*mode == MODE_UNKNOWN) { + for (i = 0; i < (INT)sizeof(channelModeConfig) / + (INT)sizeof(CHANNEL_MODE_CONFIG_TAB); + i++) { + if (channelModeConfig[i].nChannels == nChannels) { + encMode = channelModeConfig[i].encMode; + break; } } *mode = encMode; - } - else { + } else { /* check if valid channel configuration */ - if (FDKaacEnc_GetChannelModeConfiguration(*mode)->nChannels==nChannels) { - encMode = *mode; + if (FDKaacEnc_GetChannelModeConfiguration(*mode)->nChannels == nChannels) { + encMode = *mode; } } - if (encMode==MODE_INVALID) { + if (encMode == MODE_INVALID) { return AAC_ENC_UNSUPPORTED_CHANNELCONFIG; } return AAC_ENC_OK; } -static INT FDKaacEnc_initElement (ELEMENT_INFO* elInfo, MP4_ELEMENT_ID elType, INT* cnt, CHANNEL_MODE mode, CHANNEL_ORDER co, INT* it_cnt, const FIXP_DBL relBits) { - - INT error=0; - INT counter =*cnt; +static INT FDKaacEnc_initElement(ELEMENT_INFO* elInfo, MP4_ELEMENT_ID elType, + INT* cnt, FDK_channelMapDescr* mapDescr, + UINT mapIdx, INT* it_cnt, + const FIXP_DBL relBits) { + INT error = 0; + INT counter = *cnt; - const INT *assign = FDKaacEnc_getChannelAssignment(mode, co); - - elInfo->elType=elType; + elInfo->elType = elType; elInfo->relativeBits = relBits; - switch(elInfo->elType) { - case ID_SCE: case ID_LFE: case ID_CCE: - elInfo->nChannelsInEl=1; - elInfo->ChannelIndex[0]=assign[counter++]; - elInfo->instanceTag=it_cnt[elType]++; - - break; - case ID_CPE: - elInfo->nChannelsInEl=2; - elInfo->ChannelIndex[0]=assign[counter++]; - elInfo->ChannelIndex[1]=assign[counter++]; - elInfo->instanceTag=it_cnt[elType]++; - break; - case ID_DSE: - elInfo->nChannelsInEl=0; - elInfo->ChannelIndex[0]=0; - elInfo->ChannelIndex[1]=0; - elInfo->instanceTag=it_cnt[elType]++; - break; - default: error=1; + switch (elInfo->elType) { + case ID_SCE: + case ID_LFE: + case ID_CCE: + elInfo->nChannelsInEl = 1; + elInfo->ChannelIndex[0] = + FDK_chMapDescr_getMapValue(mapDescr, counter++, mapIdx); + elInfo->instanceTag = it_cnt[elType]++; + break; + case ID_CPE: + elInfo->nChannelsInEl = 2; + elInfo->ChannelIndex[0] = + FDK_chMapDescr_getMapValue(mapDescr, counter++, mapIdx); + elInfo->ChannelIndex[1] = + FDK_chMapDescr_getMapValue(mapDescr, counter++, mapIdx); + elInfo->instanceTag = it_cnt[elType]++; + break; + case ID_DSE: + elInfo->nChannelsInEl = 0; + elInfo->ChannelIndex[0] = 0; + elInfo->ChannelIndex[1] = 0; + elInfo->instanceTag = it_cnt[elType]++; + break; + default: + error = 1; }; *cnt = counter; return error; - } -AAC_ENCODER_ERROR FDKaacEnc_InitChannelMapping(CHANNEL_MODE mode, CHANNEL_ORDER co, CHANNEL_MAPPING* cm) -{ - INT count=0; /* count through coder channels */ - INT it_cnt[ID_END+1]; +AAC_ENCODER_ERROR FDKaacEnc_InitChannelMapping(CHANNEL_MODE mode, + CHANNEL_ORDER co, + CHANNEL_MAPPING* cm) { + INT count = 0; /* count through coder channels */ + INT it_cnt[ID_END + 1]; INT i; + UINT mapIdx; + FDK_channelMapDescr mapDescr; - for (i=0; iencMode = channelModeConfig[i].encMode; - cm->nChannels = channelModeConfig[i].nChannels; - cm->nChannelsEff = channelModeConfig[i].nChannelsEff; - cm->nElements = channelModeConfig[i].nElements; + for (i = 0; i < (INT)sizeof(channelModeConfig) / + (INT)sizeof(CHANNEL_MODE_CONFIG_TAB); + i++) { + if (channelModeConfig[i].encMode == mode) { + cm->encMode = channelModeConfig[i].encMode; + cm->nChannels = channelModeConfig[i].nChannels; + cm->nChannelsEff = channelModeConfig[i].nChannelsEff; + cm->nElements = channelModeConfig[i].nElements; - break; + break; } } + /* init map descriptor */ + FDK_chMapDescr_init(&mapDescr, NULL, 0, (co == CH_ORDER_MPEG) ? 1 : 0); + switch (mode) { + case MODE_7_1_REAR_SURROUND: /* MODE_7_1_REAR_SURROUND is equivalent to + MODE_7_1_BACK */ + mapIdx = (INT)MODE_7_1_BACK; + break; + case MODE_7_1_FRONT_CENTER: /* MODE_7_1_FRONT_CENTER is equivalent to + MODE_1_2_2_2_1 */ + mapIdx = (INT)MODE_1_2_2_2_1; + break; + default: + mapIdx = + (INT)mode > 14 + ? 0 + : (INT) + mode; /* if channel config > 14 MPEG mapping will be used */ + } + /* init element info struct */ - switch(mode) { + switch (mode) { case MODE_1: /* (mono) sce */ - FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, mode, co, it_cnt, (FIXP_DBL)MAXVAL_DBL); + FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx, + it_cnt, (FIXP_DBL)MAXVAL_DBL); break; case MODE_2: /* (stereo) cpe */ - FDKaacEnc_initElement(&cm->elInfo[0], ID_CPE, &count, mode, co, it_cnt, (FIXP_DBL)MAXVAL_DBL); + FDKaacEnc_initElement(&cm->elInfo[0], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, (FIXP_DBL)MAXVAL_DBL); break; case MODE_1_2: /* sce + cpe */ - FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.4f)); - FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.6f)); + FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.4f)); + FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.6f)); break; case MODE_1_2_1: /* sce + cpe + sce */ - FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.3f)); - FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.4f)); - FDKaacEnc_initElement(&cm->elInfo[2], ID_SCE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.3f)); + FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.3f)); + FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.4f)); + FDKaacEnc_initElement(&cm->elInfo[2], ID_SCE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.3f)); break; case MODE_1_2_2: /* sce + cpe + cpe */ - FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.26f)); - FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.37f)); - FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.37f)); + FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.26f)); + FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.37f)); + FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.37f)); break; case MODE_1_2_2_1: /* (5.1) sce + cpe + cpe + lfe */ - FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.24f)); - FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.35f)); - FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.35f)); - FDKaacEnc_initElement(&cm->elInfo[3], ID_LFE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.06f)); + FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.24f)); + FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.35f)); + FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.35f)); + FDKaacEnc_initElement(&cm->elInfo[3], ID_LFE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.06f)); + break; + + case MODE_6_1: + /* (6.1) sce + cpe + cpe + sce + lfe */ + FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.2f)); + FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.275f)); + FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.275f)); + FDKaacEnc_initElement(&cm->elInfo[3], ID_SCE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.2f)); + FDKaacEnc_initElement(&cm->elInfo[4], ID_LFE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.05f)); break; case MODE_1_2_2_2_1: + case MODE_7_1_BACK: + case MODE_7_1_TOP_FRONT: case MODE_7_1_REAR_SURROUND: - case MODE_7_1_FRONT_CENTER: + case MODE_7_1_FRONT_CENTER: { /* (7.1) sce + cpe + cpe + cpe + lfe */ - FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.18f)); - FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.26f)); - FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.26f)); - FDKaacEnc_initElement(&cm->elInfo[3], ID_CPE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.26f)); - FDKaacEnc_initElement(&cm->elInfo[4], ID_LFE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.04f)); + /* (7.1 top) sce + cpe + cpe + lfe + cpe */ + + FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.18f)); + FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.26f)); + FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.26f)); + if (mode != MODE_7_1_TOP_FRONT) { + FDKaacEnc_initElement(&cm->elInfo[3], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.26f)); + FDKaacEnc_initElement(&cm->elInfo[4], ID_LFE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.04f)); + } else { + FDKaacEnc_initElement(&cm->elInfo[3], ID_LFE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.04f)); + FDKaacEnc_initElement(&cm->elInfo[4], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.26f)); + } break; + } + default: //*chMap=0; return AAC_ENC_UNSUPPORTED_CHANNELCONFIG; }; - - FDK_ASSERT(cm->nElements<=(8)); - + FDK_ASSERT(cm->nElements <= ((8))); return AAC_ENC_OK; } -AAC_ENCODER_ERROR FDKaacEnc_InitElementBits(QC_STATE *hQC, - CHANNEL_MAPPING *cm, - INT bitrateTot, - INT averageBitsTot, - INT maxChannelBits) -{ +AAC_ENCODER_ERROR FDKaacEnc_InitElementBits(QC_STATE* hQC, CHANNEL_MAPPING* cm, + INT bitrateTot, INT averageBitsTot, + INT maxChannelBits) { int sc_brTot = CountLeadingBits(bitrateTot); - switch(cm->encMode) { - case MODE_1: - hQC->elementBits[0]->chBitrateEl = bitrateTot; + switch (cm->encMode) { + case MODE_1: + hQC->elementBits[0]->chBitrateEl = bitrateTot; - hQC->elementBits[0]->maxBitsEl = maxChannelBits; + hQC->elementBits[0]->maxBitsEl = maxChannelBits; - hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; - break; + hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; + break; - case MODE_2: - hQC->elementBits[0]->chBitrateEl = bitrateTot>>1; + case MODE_2: + hQC->elementBits[0]->chBitrateEl = bitrateTot >> 1; - hQC->elementBits[0]->maxBitsEl = 2*maxChannelBits; + hQC->elementBits[0]->maxBitsEl = 2 * maxChannelBits; - hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; - break; - case MODE_1_2: { - hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; - hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits; - FIXP_DBL sceRate = cm->elInfo[0].relativeBits; - FIXP_DBL cpeRate = cm->elInfo[1].relativeBits; + hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; + break; + case MODE_1_2: { + hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; + hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits; + FIXP_DBL sceRate = cm->elInfo[0].relativeBits; + FIXP_DBL cpeRate = cm->elInfo[1].relativeBits; + + hQC->elementBits[0]->chBitrateEl = + fMult(sceRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot; + hQC->elementBits[1]->chBitrateEl = + fMult(cpeRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + + hQC->elementBits[0]->maxBitsEl = maxChannelBits; + hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits; + break; + } + case MODE_1_2_1: { + /* sce + cpe + sce */ + hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; + hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits; + hQC->elementBits[2]->relativeBitsEl = cm->elInfo[2].relativeBits; + FIXP_DBL sce1Rate = cm->elInfo[0].relativeBits; + FIXP_DBL cpeRate = cm->elInfo[1].relativeBits; + FIXP_DBL sce2Rate = cm->elInfo[2].relativeBits; + + hQC->elementBits[0]->chBitrateEl = + fMult(sce1Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot; + hQC->elementBits[1]->chBitrateEl = + fMult(cpeRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + hQC->elementBits[2]->chBitrateEl = + fMult(sce2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot; + + hQC->elementBits[0]->maxBitsEl = maxChannelBits; + hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits; + hQC->elementBits[2]->maxBitsEl = maxChannelBits; + break; + } + case MODE_1_2_2: { + /* sce + cpe + cpe */ + hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; + hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits; + hQC->elementBits[2]->relativeBitsEl = cm->elInfo[2].relativeBits; + FIXP_DBL sceRate = cm->elInfo[0].relativeBits; + FIXP_DBL cpe1Rate = cm->elInfo[1].relativeBits; + FIXP_DBL cpe2Rate = cm->elInfo[2].relativeBits; + + hQC->elementBits[0]->chBitrateEl = + fMult(sceRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot; + hQC->elementBits[1]->chBitrateEl = + fMult(cpe1Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + hQC->elementBits[2]->chBitrateEl = + fMult(cpe2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + + hQC->elementBits[0]->maxBitsEl = maxChannelBits; + hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits; + hQC->elementBits[2]->maxBitsEl = 2 * maxChannelBits; + break; + } + case MODE_1_2_2_1: { + /* (5.1) sce + cpe + cpe + lfe */ + hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; + hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits; + hQC->elementBits[2]->relativeBitsEl = cm->elInfo[2].relativeBits; + hQC->elementBits[3]->relativeBitsEl = cm->elInfo[3].relativeBits; + FIXP_DBL sceRate = cm->elInfo[0].relativeBits; + FIXP_DBL cpe1Rate = cm->elInfo[1].relativeBits; + FIXP_DBL cpe2Rate = cm->elInfo[2].relativeBits; + FIXP_DBL lfeRate = cm->elInfo[3].relativeBits; + + int maxBitsTot = + maxChannelBits * 5; /* LFE does not add to bit reservoir */ + int sc = CountLeadingBits(fixMax(maxChannelBits, averageBitsTot)); + int maxLfeBits = (int)fMax( + (INT)((fMult(lfeRate, (FIXP_DBL)(maxChannelBits << sc)) >> sc) << 1), + (INT)((fMult(FL2FXCONST_DBL(1.1f / 2.f), + fMult(lfeRate, (FIXP_DBL)(averageBitsTot << sc))) + << 1) >> + sc)); + + maxChannelBits = (maxBitsTot - maxLfeBits); + sc = CountLeadingBits(maxChannelBits); + + maxChannelBits = + fMult((FIXP_DBL)maxChannelBits << sc, GetInvInt(5)) >> sc; + + hQC->elementBits[0]->chBitrateEl = + fMult(sceRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot; + hQC->elementBits[1]->chBitrateEl = + fMult(cpe1Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + hQC->elementBits[2]->chBitrateEl = + fMult(cpe2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + hQC->elementBits[3]->chBitrateEl = + fMult(lfeRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot; + + hQC->elementBits[0]->maxBitsEl = maxChannelBits; + hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits; + hQC->elementBits[2]->maxBitsEl = 2 * maxChannelBits; + hQC->elementBits[3]->maxBitsEl = maxLfeBits; - hQC->elementBits[0]->chBitrateEl = fMult(sceRate, (FIXP_DBL)(bitrateTot<>sc_brTot; - hQC->elementBits[1]->chBitrateEl = fMult(cpeRate, (FIXP_DBL)(bitrateTot<>(sc_brTot+1); + break; + } + case MODE_6_1: { + /* (6.1) sce + cpe + cpe + sce + lfe */ + FIXP_DBL sceRate = hQC->elementBits[0]->relativeBitsEl = + cm->elInfo[0].relativeBits; + FIXP_DBL cpe1Rate = hQC->elementBits[1]->relativeBitsEl = + cm->elInfo[1].relativeBits; + FIXP_DBL cpe2Rate = hQC->elementBits[2]->relativeBitsEl = + cm->elInfo[2].relativeBits; + FIXP_DBL sce2Rate = hQC->elementBits[3]->relativeBitsEl = + cm->elInfo[3].relativeBits; + FIXP_DBL lfeRate = hQC->elementBits[4]->relativeBitsEl = + cm->elInfo[4].relativeBits; + + int maxBitsTot = + maxChannelBits * 6; /* LFE does not add to bit reservoir */ + int sc = CountLeadingBits(fixMax(maxChannelBits, averageBitsTot)); + int maxLfeBits = (int)fMax( + (INT)((fMult(lfeRate, (FIXP_DBL)(maxChannelBits << sc)) >> sc) << 1), + (INT)((fMult(FL2FXCONST_DBL(1.1f / 2.f), + fMult(lfeRate, (FIXP_DBL)(averageBitsTot << sc))) + << 1) >> + sc)); + + maxChannelBits = (maxBitsTot - maxLfeBits) / 6; + + hQC->elementBits[0]->chBitrateEl = + fMult(sceRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot; + hQC->elementBits[1]->chBitrateEl = + fMult(cpe1Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + hQC->elementBits[2]->chBitrateEl = + fMult(cpe2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + hQC->elementBits[3]->chBitrateEl = + fMult(sce2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + hQC->elementBits[4]->chBitrateEl = + fMult(lfeRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot; + + hQC->elementBits[0]->maxBitsEl = maxChannelBits; + hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits; + hQC->elementBits[2]->maxBitsEl = 2 * maxChannelBits; + hQC->elementBits[3]->maxBitsEl = maxChannelBits; + hQC->elementBits[4]->maxBitsEl = maxLfeBits; + break; + } + case MODE_7_1_TOP_FRONT: + case MODE_7_1_BACK: + case MODE_7_1_REAR_SURROUND: + case MODE_7_1_FRONT_CENTER: + case MODE_1_2_2_2_1: { + int cpe3Idx = (cm->encMode != MODE_7_1_TOP_FRONT) ? 3 : 4; + int lfeIdx = (cm->encMode != MODE_7_1_TOP_FRONT) ? 4 : 3; - hQC->elementBits[0]->maxBitsEl = maxChannelBits; - hQC->elementBits[1]->maxBitsEl = 2*maxChannelBits; - break; - } - case MODE_1_2_1: { - /* sce + cpe + sce */ - hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; - hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits; - hQC->elementBits[2]->relativeBitsEl = cm->elInfo[2].relativeBits; - FIXP_DBL sce1Rate = cm->elInfo[0].relativeBits; - FIXP_DBL cpeRate = cm->elInfo[1].relativeBits; - FIXP_DBL sce2Rate = cm->elInfo[2].relativeBits; - - hQC->elementBits[0]->chBitrateEl = fMult(sce1Rate, (FIXP_DBL)(bitrateTot<>sc_brTot; - hQC->elementBits[1]->chBitrateEl = fMult(cpeRate, (FIXP_DBL)(bitrateTot<>(sc_brTot+1); - hQC->elementBits[2]->chBitrateEl = fMult(sce2Rate, (FIXP_DBL)(bitrateTot<>sc_brTot; - - hQC->elementBits[0]->maxBitsEl = maxChannelBits; - hQC->elementBits[1]->maxBitsEl = 2*maxChannelBits; - hQC->elementBits[2]->maxBitsEl = maxChannelBits; - break; - } - case MODE_1_2_2: { - /* sce + cpe + cpe */ - hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; - hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits; - hQC->elementBits[2]->relativeBitsEl = cm->elInfo[2].relativeBits; - FIXP_DBL sceRate = cm->elInfo[0].relativeBits; - FIXP_DBL cpe1Rate = cm->elInfo[1].relativeBits; - FIXP_DBL cpe2Rate = cm->elInfo[2].relativeBits; - - hQC->elementBits[0]->chBitrateEl = fMult(sceRate, (FIXP_DBL)(bitrateTot<>sc_brTot; - hQC->elementBits[1]->chBitrateEl = fMult(cpe1Rate, (FIXP_DBL)(bitrateTot<>(sc_brTot+1); - hQC->elementBits[2]->chBitrateEl = fMult(cpe2Rate, (FIXP_DBL)(bitrateTot<>(sc_brTot+1); - - hQC->elementBits[0]->maxBitsEl = maxChannelBits; - hQC->elementBits[1]->maxBitsEl = 2*maxChannelBits; - hQC->elementBits[2]->maxBitsEl = 2*maxChannelBits; - break; - } + /* (7.1) sce + cpe + cpe + cpe + lfe */ + FIXP_DBL sceRate = hQC->elementBits[0]->relativeBitsEl = + cm->elInfo[0].relativeBits; + FIXP_DBL cpe1Rate = hQC->elementBits[1]->relativeBitsEl = + cm->elInfo[1].relativeBits; + FIXP_DBL cpe2Rate = hQC->elementBits[2]->relativeBitsEl = + cm->elInfo[2].relativeBits; + FIXP_DBL cpe3Rate = hQC->elementBits[cpe3Idx]->relativeBitsEl = + cm->elInfo[cpe3Idx].relativeBits; + FIXP_DBL lfeRate = hQC->elementBits[lfeIdx]->relativeBitsEl = + cm->elInfo[lfeIdx].relativeBits; + + int maxBitsTot = + maxChannelBits * 7; /* LFE does not add to bit reservoir */ + int sc = CountLeadingBits(fixMax(maxChannelBits, averageBitsTot)); + int maxLfeBits = (int)fMax( + (INT)((fMult(lfeRate, (FIXP_DBL)(maxChannelBits << sc)) >> sc) << 1), + (INT)((fMult(FL2FXCONST_DBL(1.1f / 2.f), + fMult(lfeRate, (FIXP_DBL)(averageBitsTot << sc))) + << 1) >> + sc)); + + maxChannelBits = (maxBitsTot - maxLfeBits) / 7; + + hQC->elementBits[0]->chBitrateEl = + fMult(sceRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot; + hQC->elementBits[1]->chBitrateEl = + fMult(cpe1Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + hQC->elementBits[2]->chBitrateEl = + fMult(cpe2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + hQC->elementBits[cpe3Idx]->chBitrateEl = + fMult(cpe3Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + hQC->elementBits[lfeIdx]->chBitrateEl = + fMult(lfeRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot; + + hQC->elementBits[0]->maxBitsEl = maxChannelBits; + hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits; + hQC->elementBits[2]->maxBitsEl = 2 * maxChannelBits; + hQC->elementBits[cpe3Idx]->maxBitsEl = 2 * maxChannelBits; + hQC->elementBits[lfeIdx]->maxBitsEl = maxLfeBits; + break; + } - case MODE_1_2_2_1: { - /* (5.1) sce + cpe + cpe + lfe */ - hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; - hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits; - hQC->elementBits[2]->relativeBitsEl = cm->elInfo[2].relativeBits; - hQC->elementBits[3]->relativeBitsEl = cm->elInfo[3].relativeBits; - FIXP_DBL sceRate = cm->elInfo[0].relativeBits; - FIXP_DBL cpe1Rate = cm->elInfo[1].relativeBits; - FIXP_DBL cpe2Rate = cm->elInfo[2].relativeBits; - FIXP_DBL lfeRate = cm->elInfo[3].relativeBits; - - int maxBitsTot = maxChannelBits * 5; /* LFE does not add to bit reservoir */ - int sc = CountLeadingBits(fixMax(maxChannelBits,averageBitsTot)); - int maxLfeBits = (int) FDKmax ( (INT)((fMult(lfeRate,(FIXP_DBL)(maxChannelBits<>sc)<<1), - (INT)((fMult(FL2FXCONST_DBL(1.1f/2.f),fMult(lfeRate,(FIXP_DBL)(averageBitsTot<>sc) ); - - maxChannelBits = (maxBitsTot - maxLfeBits); - sc = CountLeadingBits(maxChannelBits); - - maxChannelBits = fMult((FIXP_DBL)maxChannelBits<>sc; - - hQC->elementBits[0]->chBitrateEl = fMult(sceRate, (FIXP_DBL)(bitrateTot<>sc_brTot; - hQC->elementBits[1]->chBitrateEl = fMult(cpe1Rate, (FIXP_DBL)(bitrateTot<>(sc_brTot+1); - hQC->elementBits[2]->chBitrateEl = fMult(cpe2Rate, (FIXP_DBL)(bitrateTot<>(sc_brTot+1); - hQC->elementBits[3]->chBitrateEl = fMult(lfeRate, (FIXP_DBL)(bitrateTot<>sc_brTot; - - hQC->elementBits[0]->maxBitsEl = maxChannelBits; - hQC->elementBits[1]->maxBitsEl = 2*maxChannelBits; - hQC->elementBits[2]->maxBitsEl = 2*maxChannelBits; - hQC->elementBits[3]->maxBitsEl = maxLfeBits; - - break; - } - case MODE_7_1_REAR_SURROUND: - case MODE_7_1_FRONT_CENTER: - case MODE_1_2_2_2_1: { - int cpe3Idx = 3; - int lfeIdx = 4; - - /* (7.1) sce + cpe + cpe + cpe + lfe */ - FIXP_DBL sceRate = hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; - FIXP_DBL cpe1Rate = hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits; - FIXP_DBL cpe2Rate = hQC->elementBits[2]->relativeBitsEl = cm->elInfo[2].relativeBits; - FIXP_DBL cpe3Rate = hQC->elementBits[cpe3Idx]->relativeBitsEl = cm->elInfo[cpe3Idx].relativeBits; - FIXP_DBL lfeRate = hQC->elementBits[lfeIdx]->relativeBitsEl = cm->elInfo[lfeIdx].relativeBits; - - int maxBitsTot = maxChannelBits * 7; /* LFE does not add to bit reservoir */ - int sc = CountLeadingBits(fixMax(maxChannelBits,averageBitsTot)); - int maxLfeBits = (int) FDKmax ( (INT)((fMult(lfeRate,(FIXP_DBL)(maxChannelBits<>sc)<<1), - (INT)((fMult(FL2FXCONST_DBL(1.1f/2.f),fMult(lfeRate,(FIXP_DBL)(averageBitsTot<>sc) ); - - maxChannelBits = (maxBitsTot - maxLfeBits) / 7; - - hQC->elementBits[0]->chBitrateEl = fMult(sceRate, (FIXP_DBL)(bitrateTot<>sc_brTot; - hQC->elementBits[1]->chBitrateEl = fMult(cpe1Rate, (FIXP_DBL)(bitrateTot<>(sc_brTot+1); - hQC->elementBits[2]->chBitrateEl = fMult(cpe2Rate, (FIXP_DBL)(bitrateTot<>(sc_brTot+1); - hQC->elementBits[cpe3Idx]->chBitrateEl = fMult(cpe3Rate, (FIXP_DBL)(bitrateTot<>(sc_brTot+1); - hQC->elementBits[lfeIdx]->chBitrateEl = fMult(lfeRate, (FIXP_DBL)(bitrateTot<>sc_brTot; - - hQC->elementBits[0]->maxBitsEl = maxChannelBits; - hQC->elementBits[1]->maxBitsEl = 2*maxChannelBits; - hQC->elementBits[2]->maxBitsEl = 2*maxChannelBits; - hQC->elementBits[cpe3Idx]->maxBitsEl = 2*maxChannelBits; - hQC->elementBits[lfeIdx]->maxBitsEl = maxLfeBits; - break; - } - default: - return AAC_ENC_UNSUPPORTED_CHANNELCONFIG; + default: + return AAC_ENC_UNSUPPORTED_CHANNELCONFIG; } return AAC_ENC_OK; @@ -491,61 +598,66 @@ AAC_ENCODER_ERROR FDKaacEnc_InitElementBits(QC_STATE *hQC, /********************************************************************************/ /* */ -/* function: GetMonoStereoMODE(const CHANNEL_MODE mode) */ +/* function: GetMonoStereoMODE(const CHANNEL_MODE mode) */ /* */ -/* description: Determines encoder setting from channel mode. */ -/* Multichannel modes are mapped to mono or stereo modes */ +/* description: Determines encoder setting from channel mode. */ +/* Multichannel modes are mapped to mono or stereo modes */ /* returns MODE_MONO in case of mono, */ /* MODE_STEREO in case of stereo */ /* MODE_INVALID in case of error */ /* */ -/* input: CHANNEL_MODE mode: Encoder mode (see qc_data.h). */ -/* output: return: CM_STEREO_MODE monoStereoSetting */ +/* input: CHANNEL_MODE mode: Encoder mode (see qc_data.h). */ +/* output: return: CM_STEREO_MODE monoStereoSetting */ /* (MODE_INVALID: error, */ /* MODE_MONO: mono */ /* MODE_STEREO: stereo). */ /* */ -/* misc: No memory is allocated. */ +/* misc: No memory is allocated. */ /* */ /********************************************************************************/ -ELEMENT_MODE FDKaacEnc_GetMonoStereoMode(const CHANNEL_MODE mode){ - +ELEMENT_MODE FDKaacEnc_GetMonoStereoMode(const CHANNEL_MODE mode) { ELEMENT_MODE monoStereoSetting = EL_MODE_INVALID; - switch(mode){ - case MODE_1: /* mono setups */ - monoStereoSetting = EL_MODE_MONO; - break; - case MODE_2: /* stereo setups */ - case MODE_1_2: - case MODE_1_2_1: - case MODE_1_2_2: - case MODE_1_2_2_1: - case MODE_1_2_2_2_1: - case MODE_7_1_REAR_SURROUND: - case MODE_7_1_FRONT_CENTER: - monoStereoSetting = EL_MODE_STEREO; - break; - default: /* error */ - monoStereoSetting = EL_MODE_INVALID; - break; + switch (mode) { + case MODE_1: /* mono setups */ + monoStereoSetting = EL_MODE_MONO; + break; + + case MODE_2: /* stereo setups */ + case MODE_1_2: + case MODE_1_2_1: + case MODE_1_2_2: + case MODE_1_2_2_1: + case MODE_6_1: + case MODE_1_2_2_2_1: + case MODE_7_1_REAR_SURROUND: + case MODE_7_1_FRONT_CENTER: + case MODE_7_1_BACK: + case MODE_7_1_TOP_FRONT: + monoStereoSetting = EL_MODE_STEREO; + break; + + default: /* error */ + monoStereoSetting = EL_MODE_INVALID; + break; } return monoStereoSetting; } -const CHANNEL_MODE_CONFIG_TAB* FDKaacEnc_GetChannelModeConfiguration(const CHANNEL_MODE mode) -{ +const CHANNEL_MODE_CONFIG_TAB* FDKaacEnc_GetChannelModeConfiguration( + const CHANNEL_MODE mode) { INT i; - const CHANNEL_MODE_CONFIG_TAB *cm_config = NULL; + const CHANNEL_MODE_CONFIG_TAB* cm_config = NULL; /* get channel mode config */ - for (i=0; i<(INT)sizeof(channelModeConfig)/(INT)sizeof(CHANNEL_MODE_CONFIG_TAB); i++) { - if (channelModeConfig[i].encMode==mode) - { - cm_config = &channelModeConfig[i]; - break; + for (i = 0; i < (INT)sizeof(channelModeConfig) / + (INT)sizeof(CHANNEL_MODE_CONFIG_TAB); + i++) { + if (channelModeConfig[i].encMode == mode) { + cm_config = &channelModeConfig[i]; + break; } } return cm_config; diff --git a/libAACenc/src/channel_map.h b/libAACenc/src/channel_map.h index 2cfb486..f9154cd 100644 --- a/libAACenc/src/channel_map.h +++ b/libAACenc/src/channel_map.h @@ -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,18 +90,18 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/************************* Fast MPEG AAC Audio Encoder ********************** +/**************************** AAC encoder library ****************************** - Initial author: A. Groeschel - contents/description: channel mapping functionality + Author(s): A. Groeschel -******************************************************************************/ + Description: channel mapping functionality -#ifndef _CHANNEL_MAP_H -#define _CHANNEL_MAP_H +*******************************************************************************/ +#ifndef CHANNEL_MAP_H +#define CHANNEL_MAP_H #include "aacenc.h" #include "psy_const.h" @@ -103,14 +114,8 @@ typedef struct { INT nElements; } CHANNEL_MODE_CONFIG_TAB; - /* Element mode */ -typedef enum { - EL_MODE_INVALID = 0, - EL_MODE_MONO, - EL_MODE_STEREO -} ELEMENT_MODE; - +typedef enum { EL_MODE_INVALID = 0, EL_MODE_MONO, EL_MODE_STEREO } ELEMENT_MODE; AAC_ENCODER_ERROR FDKaacEnc_DetermineEncoderMode(CHANNEL_MODE* mode, INT nChannels); @@ -119,14 +124,13 @@ AAC_ENCODER_ERROR FDKaacEnc_InitChannelMapping(CHANNEL_MODE mode, CHANNEL_ORDER co, CHANNEL_MAPPING* chMap); -AAC_ENCODER_ERROR FDKaacEnc_InitElementBits(QC_STATE *hQC, - CHANNEL_MAPPING *cm, - INT bitrateTot, - INT averageBitsTot, +AAC_ENCODER_ERROR FDKaacEnc_InitElementBits(QC_STATE* hQC, CHANNEL_MAPPING* cm, + INT bitrateTot, INT averageBitsTot, INT maxChannelBits); ELEMENT_MODE FDKaacEnc_GetMonoStereoMode(const CHANNEL_MODE mode); -const CHANNEL_MODE_CONFIG_TAB* FDKaacEnc_GetChannelModeConfiguration(const CHANNEL_MODE mode); +const CHANNEL_MODE_CONFIG_TAB* FDKaacEnc_GetChannelModeConfiguration( + const CHANNEL_MODE mode); #endif /* CHANNEL_MAP_H */ diff --git a/libAACenc/src/chaosmeasure.cpp b/libAACenc/src/chaosmeasure.cpp index 4e56e9e..664284b 100644 --- a/libAACenc/src/chaosmeasure.cpp +++ b/libAACenc/src/chaosmeasure.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,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Werner - Initial author: M. Werner - contents/description: Chaos measure calculation + Description: Chaos measure calculation -******************************************************************************/ +*******************************************************************************/ #include "chaosmeasure.h" @@ -94,40 +106,63 @@ amm-info@iis.fraunhofer.de functionname: FDKaacEnc_FDKaacEnc_CalculateChaosMeasurePeakFast description: Eberlein method of chaos measure calculation by high-pass filtering amplitude spectrum - A special case of FDKaacEnc_CalculateChaosMeasureTonalGeneric -- - highly optimized + A special case of FDKaacEnc_CalculateChaosMeasureTonalGeneric +-- highly optimized *****************************************************************************/ -static void -FDKaacEnc_FDKaacEnc_CalculateChaosMeasurePeakFast( FIXP_DBL *RESTRICT paMDCTDataNM0, - INT numberOfLines, - FIXP_DBL *RESTRICT chaosMeasure ) -{ +static void FDKaacEnc_FDKaacEnc_CalculateChaosMeasurePeakFast( + FIXP_DBL *RESTRICT paMDCTDataNM0, INT numberOfLines, + FIXP_DBL *RESTRICT chaosMeasure) { INT i, j; /* calculate chaos measure by "peak filter" */ - for (i=0; i<2; i++) { - /* make even and odd pass through data */ - FIXP_DBL left,center; /* left, center tap of filter */ - - left = (FIXP_DBL)((LONG)paMDCTDataNM0[i]^((LONG)paMDCTDataNM0[i]>>(DFRACT_BITS-1))); - center = (FIXP_DBL)((LONG)paMDCTDataNM0[i+2]^((LONG)paMDCTDataNM0[i+2]>>(DFRACT_BITS-1))); - - for (j = i+2; j < numberOfLines - 2; j+=2) { - FIXP_DBL right = (FIXP_DBL)((LONG)paMDCTDataNM0[j+2]^((LONG)paMDCTDataNM0[j+2]>>(DFRACT_BITS-1))); - FIXP_DBL tmp = (left>>1)+(right>>1); - - if (tmp < center ) { - INT leadingBits = CntLeadingZeros(center)-1; - tmp = schur_div(tmp<> (DFRACT_BITS - 1))) >> + 1); + left_1_div2 = (FIXP_DBL)(((LONG)paMDCTDataNM0[1] ^ + ((LONG)paMDCTDataNM0[1] >> (DFRACT_BITS - 1))) >> + 1); + center_0 = (FIXP_DBL)((LONG)paMDCTDataNM0[2] ^ + ((LONG)paMDCTDataNM0[2] >> (DFRACT_BITS - 1))); + center_1 = (FIXP_DBL)((LONG)paMDCTDataNM0[3] ^ + ((LONG)paMDCTDataNM0[3] >> (DFRACT_BITS - 1))); + + for (j = 2; j < numberOfLines - 2; j += 2) { + FIXP_DBL right_0 = + (FIXP_DBL)((LONG)paMDCTDataNM0[j + 2] ^ + ((LONG)paMDCTDataNM0[j + 2] >> (DFRACT_BITS - 1))); + FIXP_DBL tmp_0 = left_0_div2 + (right_0 >> 1); + FIXP_DBL right_1 = + (FIXP_DBL)((LONG)paMDCTDataNM0[j + 3] ^ + ((LONG)paMDCTDataNM0[j + 3] >> (DFRACT_BITS - 1))); + FIXP_DBL tmp_1 = left_1_div2 + (right_1 >> 1); + + if (tmp_0 < center_0) { + INT leadingBits = CntLeadingZeros(center_0) - 1; + tmp_0 = schur_div(tmp_0 << leadingBits, center_0 << leadingBits, 8); + tmp_0 = fMult(tmp_0, tmp_0); + } else { + tmp_0 = (FIXP_DBL)MAXVAL_DBL; + } + chaosMeasure[j + 0] = tmp_0; + left_0_div2 = center_0 >> 1; + center_0 = right_0; + + if (tmp_1 < center_1) { + INT leadingBits = CntLeadingZeros(center_1) - 1; + tmp_1 = schur_div(tmp_1 << leadingBits, center_1 << leadingBits, 8); + tmp_1 = fMult(tmp_1, tmp_1); + } else { + tmp_1 = (FIXP_DBL)MAXVAL_DBL; } + + left_1_div2 = center_1 >> 1; + center_1 = right_1; + chaosMeasure[j + 1] = tmp_1; } /* provide chaos measure for first few lines */ @@ -135,11 +170,10 @@ FDKaacEnc_FDKaacEnc_CalculateChaosMeasurePeakFast( FIXP_DBL *RESTRICT paMDCTDat chaosMeasure[1] = chaosMeasure[2]; /* provide chaos measure for last few lines */ - for (i = (numberOfLines-3); i < numberOfLines; i++) + for (i = (numberOfLines - 3); i < numberOfLines; i++) chaosMeasure[i] = FL2FXCONST_DBL(0.5); } - /***************************************************************************** functionname: FDKaacEnc_CalculateChaosMeasure description: calculates a chaosmeasure for every line, different methods @@ -148,14 +182,10 @@ FDKaacEnc_FDKaacEnc_CalculateChaosMeasurePeakFast( FIXP_DBL *RESTRICT paMDCTDat input: MDCT data, number of lines output: chaosMeasure *****************************************************************************/ -void -FDKaacEnc_CalculateChaosMeasure( FIXP_DBL *paMDCTDataNM0, - INT numberOfLines, - FIXP_DBL *chaosMeasure ) +void FDKaacEnc_CalculateChaosMeasure(FIXP_DBL *paMDCTDataNM0, INT numberOfLines, + FIXP_DBL *chaosMeasure) { - FDKaacEnc_FDKaacEnc_CalculateChaosMeasurePeakFast( paMDCTDataNM0, - numberOfLines, - chaosMeasure ); + FDKaacEnc_FDKaacEnc_CalculateChaosMeasurePeakFast( + paMDCTDataNM0, numberOfLines, chaosMeasure); } - diff --git a/libAACenc/src/chaosmeasure.h b/libAACenc/src/chaosmeasure.h index 44301c5..60d4137 100644 --- a/libAACenc/src/chaosmeasure.h +++ b/libAACenc/src/chaosmeasure.h @@ -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,25 +90,23 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M. Werner - contents/description: Chaos measure calculation + Author(s): M. Werner -******************************************************************************/ + Description: Chaos measure calculation -#ifndef __CHAOSMEASURE_H -#define __CHAOSMEASURE_H +*******************************************************************************/ -#include "common_fix.h" +#ifndef CHAOSMEASURE_H +#define CHAOSMEASURE_H +#include "common_fix.h" #include "psy_const.h" -void -FDKaacEnc_CalculateChaosMeasure( FIXP_DBL *paMDCTDataNM0, - INT numberOfLines, - FIXP_DBL *chaosMeasure ); +void FDKaacEnc_CalculateChaosMeasure(FIXP_DBL *paMDCTDataNM0, INT numberOfLines, + FIXP_DBL *chaosMeasure); -#endif +#endif /* CHAOSMEASURE_H */ diff --git a/libAACenc/src/dyn_bits.cpp b/libAACenc/src/dyn_bits.cpp index 0c07109..74baeb8 100644 --- a/libAACenc/src/dyn_bits.cpp +++ b/libAACenc/src/dyn_bits.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,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Noiseless coder module + Description: Noiseless coder module -******************************************************************************/ +*******************************************************************************/ #include "dyn_bits.h" #include "bit_cnt.h" @@ -97,18 +109,15 @@ amm-info@iis.fraunhofer.de typedef INT (*lookUpTable)[CODE_BOOK_ESC_NDX + 1]; -static INT FDKaacEnc_getSideInfoBits( - const SECTION_INFO* const huffsection, - const SHORT* const sideInfoTab, - const INT useHCR - ) -{ +static INT FDKaacEnc_getSideInfoBits(const SECTION_INFO* const huffsection, + const SHORT* const sideInfoTab, + const INT useHCR) { INT sideInfoBits; - if ( useHCR && ((huffsection->codeBook == 11) || (huffsection->codeBook >= 16)) ) { + if (useHCR && + ((huffsection->codeBook == 11) || (huffsection->codeBook >= 16))) { sideInfoBits = 5; - } - else { + } else { sideInfoBits = sideInfoTab[huffsection->sfbCnt]; } @@ -117,43 +126,32 @@ static INT FDKaacEnc_getSideInfoBits( /* count bits using all possible tables */ static void FDKaacEnc_buildBitLookUp( - const SHORT* const quantSpectrum, - const INT maxSfb, - const INT* const sfbOffset, - const UINT* const sfbMax, - INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], - SECTION_INFO* const huffsection - ) -{ + const SHORT* const quantSpectrum, const INT maxSfb, + const INT* const sfbOffset, const UINT* const sfbMax, + INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], + SECTION_INFO* const huffsection) { INT i, sfbWidth; - for (i = 0; i < maxSfb; i++) - { + for (i = 0; i < maxSfb; i++) { huffsection[i].sfbCnt = 1; huffsection[i].sfbStart = i; huffsection[i].sectionBits = INVALID_BITCOUNT; huffsection[i].codeBook = -1; sfbWidth = sfbOffset[i + 1] - sfbOffset[i]; - FDKaacEnc_bitCount(quantSpectrum + sfbOffset[i], sfbWidth, sfbMax[i], bitLookUp[i]); + FDKaacEnc_bitCount(quantSpectrum + sfbOffset[i], sfbWidth, sfbMax[i], + bitLookUp[i]); } } /* essential helper functions */ -static INT FDKaacEnc_findBestBook( - const INT* const bc, - INT* const book, - const INT useVCB11 - ) -{ +static inline INT FDKaacEnc_findBestBook(const INT* const bc, INT* const book, + const INT useVCB11) { INT minBits = INVALID_BITCOUNT, j; int end = CODE_BOOK_ESC_NDX; - - for (j = 0; j <= end; j++) - { - if (bc[j] < minBits) - { + for (j = 0; j <= end; j++) { + if (bc[j] < minBits) { minBits = bc[j]; *book = j; } @@ -161,114 +159,94 @@ static INT FDKaacEnc_findBestBook( return (minBits); } -static INT FDKaacEnc_findMinMergeBits( - const INT* const bc1, - const INT* const bc2, - const INT useVCB11 - ) -{ +static inline INT FDKaacEnc_findMinMergeBits(const INT* const bc1, + const INT* const bc2, + const INT useVCB11) { INT minBits = INVALID_BITCOUNT, j; - int end = CODE_BOOK_ESC_NDX; - + DWORD_ALIGNED(bc1); + DWORD_ALIGNED(bc2); - for (j = 0; j <= end; j++) - { - if (bc1[j] + bc2[j] < minBits) - { - minBits = bc1[j] + bc2[j]; - } + for (j = 0; j <= CODE_BOOK_ESC_NDX; j++) { + minBits = fixMin(minBits, bc1[j] + bc2[j]); } return (minBits); } -static void FDKaacEnc_mergeBitLookUp( - INT* const bc1, - const INT* const bc2 - ) -{ +static inline void FDKaacEnc_mergeBitLookUp(INT* const RESTRICT bc1, + const INT* const RESTRICT bc2) { int j; - for (j = 0; j <= CODE_BOOK_ESC_NDX; j++) - { + for (j = 0; j <= CODE_BOOK_ESC_NDX; j++) { + FDK_ASSERT(INVALID_BITCOUNT == 0x1FFFFFFF); bc1[j] = fixMin(bc1[j] + bc2[j], INVALID_BITCOUNT); } } -static INT FDKaacEnc_findMaxMerge( - const INT* const mergeGainLookUp, - const SECTION_INFO* const huffsection, - const INT maxSfb, - INT* const maxNdx - ) -{ +static inline INT FDKaacEnc_findMaxMerge(const INT* const mergeGainLookUp, + const SECTION_INFO* const huffsection, + const INT maxSfb, INT* const maxNdx) { INT i, maxMergeGain = 0; + int lastMaxNdx = 0; - for (i = 0; i + huffsection[i].sfbCnt < maxSfb; i += huffsection[i].sfbCnt) - { - if (mergeGainLookUp[i] > maxMergeGain) - { + for (i = 0; i + huffsection[i].sfbCnt < maxSfb; i += huffsection[i].sfbCnt) { + if (mergeGainLookUp[i] > maxMergeGain) { maxMergeGain = mergeGainLookUp[i]; - *maxNdx = i; + lastMaxNdx = i; } } + *maxNdx = lastMaxNdx; return (maxMergeGain); } -static INT FDKaacEnc_CalcMergeGain( - const SECTION_INFO* const huffsection, - const INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], - const SHORT* const sideInfoTab, - const INT ndx1, - const INT ndx2, - const INT useVCB11 - ) -{ +static inline INT FDKaacEnc_CalcMergeGain( + const SECTION_INFO* const huffsection, + const INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], + const SHORT* const sideInfoTab, const INT ndx1, const INT ndx2, + const INT useVCB11) { INT MergeGain, MergeBits, SplitBits; - MergeBits = sideInfoTab[huffsection[ndx1].sfbCnt + huffsection[ndx2].sfbCnt] + FDKaacEnc_findMinMergeBits(bitLookUp[ndx1], bitLookUp[ndx2], useVCB11); - SplitBits = huffsection[ndx1].sectionBits + huffsection[ndx2].sectionBits; /* Bit amount for splitted huffsections */ + MergeBits = + sideInfoTab[huffsection[ndx1].sfbCnt + huffsection[ndx2].sfbCnt] + + FDKaacEnc_findMinMergeBits(bitLookUp[ndx1], bitLookUp[ndx2], useVCB11); + SplitBits = + huffsection[ndx1].sectionBits + + huffsection[ndx2].sectionBits; /* Bit amount for splitted huffsections */ MergeGain = SplitBits - MergeBits; - if ( (huffsection[ndx1].codeBook==CODE_BOOK_PNS_NO)||(huffsection[ndx2].codeBook==CODE_BOOK_PNS_NO) - || (huffsection[ndx1].codeBook==CODE_BOOK_IS_OUT_OF_PHASE_NO)||(huffsection[ndx2].codeBook==CODE_BOOK_IS_OUT_OF_PHASE_NO) - || (huffsection[ndx1].codeBook==CODE_BOOK_IS_IN_PHASE_NO)||(huffsection[ndx2].codeBook==CODE_BOOK_IS_IN_PHASE_NO) - ) - { + if ((huffsection[ndx1].codeBook == CODE_BOOK_PNS_NO) || + (huffsection[ndx2].codeBook == CODE_BOOK_PNS_NO) || + (huffsection[ndx1].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) || + (huffsection[ndx2].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) || + (huffsection[ndx1].codeBook == CODE_BOOK_IS_IN_PHASE_NO) || + (huffsection[ndx2].codeBook == CODE_BOOK_IS_IN_PHASE_NO)) { MergeGain = -1; } return (MergeGain); } - /* sectioning Stage 0:find minimum codbooks */ static void FDKaacEnc_gmStage0( - SECTION_INFO* const RESTRICT huffsection, - const INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], - const INT maxSfb, - const INT* const noiseNrg, - const INT* const isBook - ) -{ + SECTION_INFO* const RESTRICT huffsection, + const INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], const INT maxSfb, + const INT* const noiseNrg, const INT* const isBook) { INT i; - for (i = 0; i < maxSfb; i++) - { + for (i = 0; i < maxSfb; i++) { /* Side-Info bits will be calculated in Stage 1! */ - if (huffsection[i].sectionBits == INVALID_BITCOUNT) - { + if (huffsection[i].sectionBits == INVALID_BITCOUNT) { /* intensity and pns codebooks are already allocated in bitcount.c */ - if(noiseNrg[i] != NO_NOISE_PNS){ - huffsection[i].codeBook=CODE_BOOK_PNS_NO; + if (noiseNrg[i] != NO_NOISE_PNS) { + huffsection[i].codeBook = CODE_BOOK_PNS_NO; huffsection[i].sectionBits = 0; - } - else if( isBook[i] ) { - huffsection[i].codeBook=isBook[i]; + } else if (isBook[i]) { + huffsection[i].codeBook = isBook[i]; huffsection[i].sectionBits = 0; - } - else { - huffsection[i].sectionBits = FDKaacEnc_findBestBook(bitLookUp[i], &(huffsection[i].codeBook), 0); /* useVCB11 must be 0!!! */ + } else { + huffsection[i].sectionBits = + FDKaacEnc_findBestBook(bitLookUp[i], &(huffsection[i].codeBook), + 0); /* useVCB11 must be 0!!! */ } } } @@ -279,24 +257,18 @@ static void FDKaacEnc_gmStage0( calculate side info */ static void FDKaacEnc_gmStage1( - SECTION_INFO* const RESTRICT huffsection, - INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], - const INT maxSfb, - const SHORT* const sideInfoTab, - const INT useVCB11 - ) -{ + SECTION_INFO* const RESTRICT huffsection, + INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], const INT maxSfb, + const SHORT* const sideInfoTab, const INT useVCB11) { INT mergeStart = 0, mergeEnd; - do - { - for (mergeEnd = mergeStart + 1; mergeEnd < maxSfb; mergeEnd++) - { + do { + for (mergeEnd = mergeStart + 1; mergeEnd < maxSfb; mergeEnd++) { if (huffsection[mergeStart].codeBook != huffsection[mergeEnd].codeBook) break; - - /* we can merge. update tables, side info bits will be updated outside of this loop */ + /* we can merge. update tables, side info bits will be updated outside of + * this loop */ huffsection[mergeStart].sfbCnt++; huffsection[mergeStart].sectionBits += huffsection[mergeEnd].sectionBits; @@ -305,8 +277,10 @@ static void FDKaacEnc_gmStage1( } /* add side info info bits */ - huffsection[mergeStart].sectionBits += FDKaacEnc_getSideInfoBits(&huffsection[mergeStart], sideInfoTab, useVCB11); - huffsection[mergeEnd - 1].sfbStart = huffsection[mergeStart].sfbStart; /* speed up prev search */ + huffsection[mergeStart].sectionBits += FDKaacEnc_getSideInfoBits( + &huffsection[mergeStart], sideInfoTab, useVCB11); + huffsection[mergeEnd - 1].sfbStart = + huffsection[mergeStart].sfbStart; /* speed up prev search */ mergeStart = mergeEnd; @@ -317,132 +291,101 @@ static void FDKaacEnc_gmStage1( sectioning Stage 2:greedy merge algorithm, merge connected sections with maximum bit gain until no more gain is possible */ -static void -FDKaacEnc_gmStage2( - SECTION_INFO* const RESTRICT huffsection, - INT* const RESTRICT mergeGainLookUp, - INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], - const INT maxSfb, - const SHORT* const sideInfoTab, - const INT useVCB11 - ) -{ +static inline void FDKaacEnc_gmStage2( + SECTION_INFO* const RESTRICT huffsection, + INT* const RESTRICT mergeGainLookUp, + INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], const INT maxSfb, + const SHORT* const sideInfoTab, const INT useVCB11) { INT i; - for (i = 0; i + huffsection[i].sfbCnt < maxSfb; i += huffsection[i].sfbCnt) - { - mergeGainLookUp[i] = FDKaacEnc_CalcMergeGain(huffsection, - bitLookUp, - sideInfoTab, - i, - i + huffsection[i].sfbCnt, - useVCB11); + for (i = 0; i + huffsection[i].sfbCnt < maxSfb; i += huffsection[i].sfbCnt) { + mergeGainLookUp[i] = + FDKaacEnc_CalcMergeGain(huffsection, bitLookUp, sideInfoTab, i, + i + huffsection[i].sfbCnt, useVCB11); } - while (TRUE) - { - INT maxMergeGain, maxNdx = 0, maxNdxNext, maxNdxLast; + while (TRUE) { + INT maxMergeGain, maxNdx, maxNdxNext, maxNdxLast; - maxMergeGain = FDKaacEnc_findMaxMerge(mergeGainLookUp, huffsection, maxSfb, &maxNdx); + maxMergeGain = + FDKaacEnc_findMaxMerge(mergeGainLookUp, huffsection, maxSfb, &maxNdx); /* exit while loop if no more gain is possible */ - if (maxMergeGain <= 0) - break; + if (maxMergeGain <= 0) break; maxNdxNext = maxNdx + huffsection[maxNdx].sfbCnt; /* merge sections with maximum bit gain */ huffsection[maxNdx].sfbCnt += huffsection[maxNdxNext].sfbCnt; - huffsection[maxNdx].sectionBits += huffsection[maxNdxNext].sectionBits - maxMergeGain; + huffsection[maxNdx].sectionBits += + huffsection[maxNdxNext].sectionBits - maxMergeGain; /* update bit look up table for merged huffsection */ FDKaacEnc_mergeBitLookUp(bitLookUp[maxNdx], bitLookUp[maxNdxNext]); /* update mergeLookUpTable */ - if (maxNdx != 0) - { + if (maxNdx != 0) { maxNdxLast = huffsection[maxNdx - 1].sfbStart; - mergeGainLookUp[maxNdxLast] = FDKaacEnc_CalcMergeGain(huffsection, - bitLookUp, - sideInfoTab, - maxNdxLast, - maxNdx, - useVCB11); - + mergeGainLookUp[maxNdxLast] = FDKaacEnc_CalcMergeGain( + huffsection, bitLookUp, sideInfoTab, maxNdxLast, maxNdx, useVCB11); } maxNdxNext = maxNdx + huffsection[maxNdx].sfbCnt; huffsection[maxNdxNext - 1].sfbStart = huffsection[maxNdx].sfbStart; if (maxNdxNext < maxSfb) - mergeGainLookUp[maxNdx] = FDKaacEnc_CalcMergeGain(huffsection, - bitLookUp, - sideInfoTab, - maxNdx, - maxNdxNext, - useVCB11); - + mergeGainLookUp[maxNdx] = FDKaacEnc_CalcMergeGain( + huffsection, bitLookUp, sideInfoTab, maxNdx, maxNdxNext, useVCB11); } } /* count bits used by the noiseless coder */ static void FDKaacEnc_noiselessCounter( - SECTION_DATA* const RESTRICT sectionData, - INT mergeGainLookUp[MAX_SFB_LONG], - INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], - const SHORT* const quantSpectrum, - const UINT* const maxValueInSfb, - const INT* const sfbOffset, - const INT blockType, - const INT* const noiseNrg, - const INT* const isBook, - const INT useVCB11 - ) -{ + SECTION_DATA* const RESTRICT sectionData, INT mergeGainLookUp[MAX_SFB_LONG], + INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], + const SHORT* const quantSpectrum, const UINT* const maxValueInSfb, + const INT* const sfbOffset, const INT blockType, const INT* const noiseNrg, + const INT* const isBook, const INT useVCB11) { INT grpNdx, i; - const SHORT *sideInfoTab = NULL; - SECTION_INFO *huffsection; + const SHORT* sideInfoTab = NULL; + SECTION_INFO* huffsection; /* use appropriate side info table */ - switch (blockType) - { - case LONG_WINDOW: - case START_WINDOW: - case STOP_WINDOW: - sideInfoTab = FDKaacEnc_sideInfoTabLong; - break; - case SHORT_WINDOW: - sideInfoTab = FDKaacEnc_sideInfoTabShort; - break; + switch (blockType) { + case LONG_WINDOW: + case START_WINDOW: + case STOP_WINDOW: + default: + sideInfoTab = FDKaacEnc_sideInfoTabLong; + break; + case SHORT_WINDOW: + sideInfoTab = FDKaacEnc_sideInfoTabShort; + break; } sectionData->noOfSections = 0; sectionData->huffmanBits = 0; sectionData->sideInfoBits = 0; - - if (sectionData->maxSfbPerGroup == 0) - return; + if (sectionData->maxSfbPerGroup == 0) return; /* loop trough groups */ - for (grpNdx = 0; grpNdx < sectionData->sfbCnt; grpNdx += sectionData->sfbPerGroup) - { + for (grpNdx = 0; grpNdx < sectionData->sfbCnt; + grpNdx += sectionData->sfbPerGroup) { huffsection = sectionData->huffsection + sectionData->noOfSections; /* count bits in this group */ - FDKaacEnc_buildBitLookUp(quantSpectrum, - sectionData->maxSfbPerGroup, - sfbOffset + grpNdx, - maxValueInSfb + grpNdx, - bitLookUp, - huffsection); + FDKaacEnc_buildBitLookUp(quantSpectrum, sectionData->maxSfbPerGroup, + sfbOffset + grpNdx, maxValueInSfb + grpNdx, + bitLookUp, huffsection); /* 0.Stage :Find minimum Codebooks */ - FDKaacEnc_gmStage0(huffsection, bitLookUp, sectionData->maxSfbPerGroup, noiseNrg+grpNdx, isBook+grpNdx); + FDKaacEnc_gmStage0(huffsection, bitLookUp, sectionData->maxSfbPerGroup, + noiseNrg + grpNdx, isBook + grpNdx); /* 1.Stage :Merge all connected regions with the same code book */ - FDKaacEnc_gmStage1(huffsection, bitLookUp, sectionData->maxSfbPerGroup, sideInfoTab, useVCB11); - + FDKaacEnc_gmStage1(huffsection, bitLookUp, sectionData->maxSfbPerGroup, + sideInfoTab, useVCB11); /* 2.Stage @@ -450,14 +393,8 @@ static void FDKaacEnc_noiselessCounter( gain until no more gain is possible */ - FDKaacEnc_gmStage2(huffsection, - mergeGainLookUp, - bitLookUp, - sectionData->maxSfbPerGroup, - sideInfoTab, - useVCB11); - - + FDKaacEnc_gmStage2(huffsection, mergeGainLookUp, bitLookUp, + sectionData->maxSfbPerGroup, sideInfoTab, useVCB11); /* compress output, calculate total huff and side bits @@ -465,31 +402,33 @@ static void FDKaacEnc_noiselessCounter( to save time, we must set it here for later use in bitenc */ - for (i = 0; i < sectionData->maxSfbPerGroup; i += huffsection[i].sfbCnt) - { - if ((huffsection[i].codeBook==CODE_BOOK_PNS_NO) || - (huffsection[i].codeBook==CODE_BOOK_IS_OUT_OF_PHASE_NO) || - (huffsection[i].codeBook==CODE_BOOK_IS_IN_PHASE_NO)) - { - huffsection[i].sectionBits=0; + for (i = 0; i < sectionData->maxSfbPerGroup; i += huffsection[i].sfbCnt) { + if ((huffsection[i].codeBook == CODE_BOOK_PNS_NO) || + (huffsection[i].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) || + (huffsection[i].codeBook == CODE_BOOK_IS_IN_PHASE_NO)) { + huffsection[i].sectionBits = 0; } else { - /* the sections in the sectionData are now marked with the optimal code book */ + /* the sections in the sectionData are now marked with the optimal code + * book */ - FDKaacEnc_findBestBook(bitLookUp[i], &(huffsection[i].codeBook), useVCB11); + FDKaacEnc_findBestBook(bitLookUp[i], &(huffsection[i].codeBook), + useVCB11); - sectionData->huffmanBits += huffsection[i].sectionBits - FDKaacEnc_getSideInfoBits(&huffsection[i], sideInfoTab, useVCB11); + sectionData->huffmanBits += + huffsection[i].sectionBits - + FDKaacEnc_getSideInfoBits(&huffsection[i], sideInfoTab, useVCB11); } huffsection[i].sfbStart += grpNdx; /* sum up side info bits (section data bits) */ - sectionData->sideInfoBits += FDKaacEnc_getSideInfoBits(&huffsection[i], sideInfoTab, useVCB11); + sectionData->sideInfoBits += + FDKaacEnc_getSideInfoBits(&huffsection[i], sideInfoTab, useVCB11); sectionData->huffsection[sectionData->noOfSections++] = huffsection[i]; } } } - /******************************************************************************* functionname: FDKaacEnc_scfCount @@ -525,80 +464,68 @@ static void FDKaacEnc_noiselessCounter( scalfacGain (75) and the future scalefacGain (5) is 70. ********************************************************************************/ -static void FDKaacEnc_scfCount( - const INT* const scalefacGain, - const UINT* const maxValueInSfb, - SECTION_DATA* const RESTRICT sectionData, - const INT* const isScale - ) -{ +static void FDKaacEnc_scfCount(const INT* const scalefacGain, + const UINT* const maxValueInSfb, + SECTION_DATA* const RESTRICT sectionData, + const INT* const isScale) { INT i, j, k, m, n; - INT lastValScf = 0; - INT deltaScf = 0; - INT found = 0; + INT lastValScf = 0; + INT deltaScf = 0; + INT found = 0; INT scfSkipCounter = 0; - INT lastValIs = 0; + INT lastValIs = 0; sectionData->scalefacBits = 0; - if (scalefacGain == NULL) - return; + if (scalefacGain == NULL) return; sectionData->firstScf = 0; - for (i=0; inoOfSections; i++) - { - if (sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) - { + for (i = 0; i < sectionData->noOfSections; i++) { + if (sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) { sectionData->firstScf = sectionData->huffsection[i].sfbStart; lastValScf = scalefacGain[sectionData->firstScf]; break; } } - for (i=0; inoOfSections; i++) - { - if ((sectionData->huffsection[i].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) || - (sectionData->huffsection[i].codeBook == CODE_BOOK_IS_IN_PHASE_NO)) - { + for (i = 0; i < sectionData->noOfSections; i++) { + if ((sectionData->huffsection[i].codeBook == + CODE_BOOK_IS_OUT_OF_PHASE_NO) || + (sectionData->huffsection[i].codeBook == CODE_BOOK_IS_IN_PHASE_NO)) { for (j = sectionData->huffsection[i].sfbStart; - j < sectionData->huffsection[i].sfbStart + sectionData->huffsection[i].sfbCnt; - j++) - { - INT deltaIs = isScale[j]-lastValIs; - lastValIs = isScale[j]; - sectionData->scalefacBits+=FDKaacEnc_bitCountScalefactorDelta(deltaIs); + j < sectionData->huffsection[i].sfbStart + + sectionData->huffsection[i].sfbCnt; + j++) { + INT deltaIs = isScale[j] - lastValIs; + lastValIs = isScale[j]; + sectionData->scalefacBits += + FDKaacEnc_bitCountScalefactorDelta(deltaIs); } } /* Intensity */ else if ((sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) && - (sectionData->huffsection[i].codeBook != CODE_BOOK_PNS_NO)) - { - INT tmp = sectionData->huffsection[i].sfbStart + sectionData->huffsection[i].sfbCnt; - for (j = sectionData->huffsection[i].sfbStart; jhuffsection[i].codeBook != CODE_BOOK_PNS_NO)) { + INT tmp = sectionData->huffsection[i].sfbStart + + sectionData->huffsection[i].sfbCnt; + for (j = sectionData->huffsection[i].sfbStart; j < tmp; j++) { /* check if we can repeat the last value to save bits */ - if (maxValueInSfb[j] == 0) - { + if (maxValueInSfb[j] == 0) { found = 0; /* are scalefactors skipped? */ - if (scfSkipCounter == 0) - { + if (scfSkipCounter == 0) { /* end of section */ - if (j == (tmp - 1) ) - found = 0; /* search in other sections for maxValueInSfb != 0 */ - else - { + if (j == (tmp - 1)) + found = 0; /* search in other sections for maxValueInSfb != 0 */ + else { /* search in this section for the next maxValueInSfb[] != 0 */ - for (k = (j+1); k < tmp; k++) - { - if (maxValueInSfb[k] != 0) - { + for (k = (j + 1); k < tmp; k++) { + if (maxValueInSfb[k] != 0) { found = 1; - if ( (fixp_abs(scalefacGain[k] - lastValScf)) <= CODE_BOOK_SCF_LAV) - deltaScf = 0; /* save bits */ - else - { + if ((fixp_abs(scalefacGain[k] - lastValScf)) <= + CODE_BOOK_SCF_LAV) + deltaScf = 0; /* save bits */ + else { /* do not save bits */ deltaScf = lastValScf - scalefacGain[j]; lastValScf = scalefacGain[j]; @@ -612,20 +539,19 @@ static void FDKaacEnc_scfCount( } /* search for the next maxValueInSfb[] != 0 in all other sections */ - for (m=(i+1); (m < sectionData->noOfSections) && (found == 0); m++) - { - if ((sectionData->huffsection[m].codeBook != CODE_BOOK_ZERO_NO) && (sectionData->huffsection[m].codeBook != CODE_BOOK_PNS_NO)) - { - INT end = sectionData->huffsection[m].sfbStart + sectionData->huffsection[m].sfbCnt; - for (n = sectionData->huffsection[m].sfbStart; nnoOfSections) && (found == 0); + m++) { + if ((sectionData->huffsection[m].codeBook != CODE_BOOK_ZERO_NO) && + (sectionData->huffsection[m].codeBook != CODE_BOOK_PNS_NO)) { + INT end = sectionData->huffsection[m].sfbStart + + sectionData->huffsection[m].sfbCnt; + for (n = sectionData->huffsection[m].sfbStart; n < end; n++) { + if (maxValueInSfb[n] != 0) { found = 1; - if (fixp_abs(scalefacGain[n] - lastValScf) <= CODE_BOOK_SCF_LAV) - deltaScf = 0; /* save bits */ - else - { + if (fixp_abs(scalefacGain[n] - lastValScf) <= + CODE_BOOK_SCF_LAV) + deltaScf = 0; /* save bits */ + else { /* do not save bits */ deltaScf = lastValScf - scalefacGain[j]; lastValScf = scalefacGain[j]; @@ -639,64 +565,29 @@ static void FDKaacEnc_scfCount( } } /* no maxValueInSfb[] != 0 found */ - if (found == 0) - { + if (found == 0) { deltaScf = 0; scfSkipCounter = 0; } - } - else { + } else { /* consider skipped scalefactors */ deltaScf = 0; scfSkipCounter--; } - } - else { + } else { deltaScf = lastValScf - scalefacGain[j]; lastValScf = scalefacGain[j]; } - sectionData->scalefacBits += FDKaacEnc_bitCountScalefactorDelta(deltaScf); + sectionData->scalefacBits += + FDKaacEnc_bitCountScalefactorDelta(deltaScf); } } } /* for (i=0; inoOfSections; i++) */ } -#ifdef PNS_PRECOUNT_ENABLE -/* - preCount bits used pns -*/ -/* estimate bits used by pns for correction of static bits */ -/* no codebook switch estimation, see AAC LD FASTENC */ -INT noisePreCount(const INT *noiseNrg, INT maxSfb) -{ - INT noisePCMFlag = TRUE; - INT lastValPns = 0, deltaPns; - int i, bits=0; - - for (i = 0; i < maxSfb; i++) { - if (noiseNrg[i] != NO_NOISE_PNS) { - - if (noisePCMFlag) { - bits+=PNS_PCM_BITS; - lastValPns = noiseNrg[i]; - noisePCMFlag = FALSE; - }else { - deltaPns = noiseNrg[i]-lastValPns; - lastValPns = noiseNrg[i]; - bits+=FDKaacEnc_bitCountScalefactorDelta(deltaPns); - } - } - } - return ( bits ); -} -#endif /* PNS_PRECOUNT_ENABLE */ - /* count bits used by pns */ -static void FDKaacEnc_noiseCount( - SECTION_DATA* const RESTRICT sectionData, - const INT* const noiseNrg - ) -{ +static void FDKaacEnc_noiseCount(SECTION_DATA* const RESTRICT sectionData, + const INT* const noiseNrg) { INT noisePCMFlag = TRUE; INT lastValPns = 0, deltaPns; int i, j; @@ -707,99 +598,66 @@ static void FDKaacEnc_noiseCount( if (sectionData->huffsection[i].codeBook == CODE_BOOK_PNS_NO) { int sfbStart = sectionData->huffsection[i].sfbStart; int sfbEnd = sfbStart + sectionData->huffsection[i].sfbCnt; - for (j=sfbStart; jnoiseNrgBits+=PNS_PCM_BITS; - lastValPns = noiseNrg[j]; + sectionData->noiseNrgBits += PNS_PCM_BITS; + lastValPns = noiseNrg[j]; noisePCMFlag = FALSE; } else { - deltaPns = noiseNrg[j]-lastValPns; - lastValPns = noiseNrg[j]; - sectionData->noiseNrgBits+=FDKaacEnc_bitCountScalefactorDelta(deltaPns); + deltaPns = noiseNrg[j] - lastValPns; + lastValPns = noiseNrg[j]; + sectionData->noiseNrgBits += + FDKaacEnc_bitCountScalefactorDelta(deltaPns); } } } } } -INT FDKaacEnc_dynBitCount( - BITCNTR_STATE* const hBC, - const SHORT* const quantSpectrum, - const UINT* const maxValueInSfb, - const INT* const scalefac, - const INT blockType, - const INT sfbCnt, - const INT maxSfbPerGroup, - const INT sfbPerGroup, - const INT* const sfbOffset, - SECTION_DATA* const RESTRICT sectionData, - const INT* const noiseNrg, - const INT* const isBook, - const INT* const isScale, - const UINT syntaxFlags - ) -{ - sectionData->blockType = blockType; - sectionData->sfbCnt = sfbCnt; - sectionData->sfbPerGroup = sfbPerGroup; - sectionData->noOfGroups = sfbCnt / sfbPerGroup; +INT FDKaacEnc_dynBitCount(BITCNTR_STATE* const hBC, + const SHORT* const quantSpectrum, + const UINT* const maxValueInSfb, + const INT* const scalefac, const INT blockType, + const INT sfbCnt, const INT maxSfbPerGroup, + const INT sfbPerGroup, const INT* const sfbOffset, + SECTION_DATA* const RESTRICT sectionData, + const INT* const noiseNrg, const INT* const isBook, + const INT* const isScale, const UINT syntaxFlags) { + sectionData->blockType = blockType; + sectionData->sfbCnt = sfbCnt; + sectionData->sfbPerGroup = sfbPerGroup; + sectionData->noOfGroups = sfbCnt / sfbPerGroup; sectionData->maxSfbPerGroup = maxSfbPerGroup; - FDKaacEnc_noiselessCounter( - sectionData, - hBC->mergeGainLookUp, - (lookUpTable)hBC->bitLookUp, - quantSpectrum, - maxValueInSfb, - sfbOffset, - blockType, - noiseNrg, - isBook, - (syntaxFlags & AC_ER_VCB11)?1:0); - - FDKaacEnc_scfCount( - scalefac, - maxValueInSfb, - sectionData, - isScale); - - FDKaacEnc_noiseCount(sectionData, - noiseNrg); - - return (sectionData->huffmanBits + - sectionData->sideInfoBits + - sectionData->scalefacBits + - sectionData->noiseNrgBits); + FDKaacEnc_noiselessCounter(sectionData, hBC->mergeGainLookUp, + (lookUpTable)hBC->bitLookUp, quantSpectrum, + maxValueInSfb, sfbOffset, blockType, noiseNrg, + isBook, (syntaxFlags & AC_ER_VCB11) ? 1 : 0); + + FDKaacEnc_scfCount(scalefac, maxValueInSfb, sectionData, isScale); + + FDKaacEnc_noiseCount(sectionData, noiseNrg); + + return (sectionData->huffmanBits + sectionData->sideInfoBits + + sectionData->scalefacBits + sectionData->noiseNrgBits); } -INT FDKaacEnc_BCNew(BITCNTR_STATE **phBC - ,UCHAR* dynamic_RAM - ) -{ - BITCNTR_STATE *hBC = GetRam_aacEnc_BitCntrState(); +INT FDKaacEnc_BCNew(BITCNTR_STATE** phBC, UCHAR* dynamic_RAM) { + BITCNTR_STATE* hBC = GetRam_aacEnc_BitCntrState(); - if (hBC) - { + if (hBC) { *phBC = hBC; - hBC->bitLookUp = GetRam_aacEnc_BitLookUp(0,dynamic_RAM); - hBC->mergeGainLookUp = GetRam_aacEnc_MergeGainLookUp(0,dynamic_RAM); - if (hBC->bitLookUp == 0 || - hBC->mergeGainLookUp == 0) - { + hBC->bitLookUp = GetRam_aacEnc_BitLookUp(0, dynamic_RAM); + hBC->mergeGainLookUp = GetRam_aacEnc_MergeGainLookUp(0, dynamic_RAM); + if (hBC->bitLookUp == 0 || hBC->mergeGainLookUp == 0) { return 1; } } return (hBC == 0) ? 1 : 0; } -void FDKaacEnc_BCClose(BITCNTR_STATE **phBC) -{ - if (*phBC!=NULL) { - +void FDKaacEnc_BCClose(BITCNTR_STATE** phBC) { + if (*phBC != NULL) { FreeRam_aacEnc_BitCntrState(phBC); } } - - - diff --git a/libAACenc/src/dyn_bits.h b/libAACenc/src/dyn_bits.h index ae78a4c..a727a30 100644 --- a/libAACenc/src/dyn_bits.h +++ b/libAACenc/src/dyn_bits.h @@ -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,42 +90,40 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Noiseless coder module + Description: Noiseless coder module -******************************************************************************/ +*******************************************************************************/ -#ifndef __DYN_BITS_H -#define __DYN_BITS_H +#ifndef DYN_BITS_H +#define DYN_BITS_H #include "common_fix.h" #include "psy_const.h" #include "aacenc_tns.h" -#define MAX_SECTIONS MAX_GROUPED_SFB -#define SECT_ESC_VAL_LONG 31 -#define SECT_ESC_VAL_SHORT 7 -#define CODE_BOOK_BITS 4 -#define SECT_BITS_LONG 5 -#define SECT_BITS_SHORT 3 -#define PNS_PCM_BITS 9 +#define MAX_SECTIONS MAX_GROUPED_SFB +#define SECT_ESC_VAL_LONG 31 +#define SECT_ESC_VAL_SHORT 7 +#define CODE_BOOK_BITS 4 +#define SECT_BITS_LONG 5 +#define SECT_BITS_SHORT 3 +#define PNS_PCM_BITS 9 -typedef struct -{ +typedef struct { INT codeBook; INT sfbStart; INT sfbCnt; - INT sectionBits; /* huff + si ! */ + INT sectionBits; /* huff + si ! */ } SECTION_INFO; - -typedef struct -{ +typedef struct { INT blockType; INT noOfGroups; INT sfbCnt; @@ -122,46 +131,30 @@ typedef struct INT sfbPerGroup; INT noOfSections; SECTION_INFO huffsection[MAX_SECTIONS]; - INT sideInfoBits; /* sectioning bits */ - INT huffmanBits; /* huffman coded bits */ - INT scalefacBits; /* scalefac coded bits */ - INT noiseNrgBits; /* noiseEnergy coded bits */ - INT firstScf; /* first scf to be coded */ + INT sideInfoBits; /* sectioning bits */ + INT huffmanBits; /* huffman coded bits */ + INT scalefacBits; /* scalefac coded bits */ + INT noiseNrgBits; /* noiseEnergy coded bits */ + INT firstScf; /* first scf to be coded */ } SECTION_DATA; - -struct BITCNTR_STATE -{ - INT *bitLookUp; - INT *mergeGainLookUp; +struct BITCNTR_STATE { + INT* bitLookUp; + INT* mergeGainLookUp; }; +INT FDKaacEnc_BCNew(BITCNTR_STATE** phBC, UCHAR* dynamic_RAM); -INT FDKaacEnc_BCNew(BITCNTR_STATE **phBC - ,UCHAR* dynamic_RAM - ); - -void FDKaacEnc_BCClose(BITCNTR_STATE **phBC); - -#if defined(PNS_PRECOUNT_ENABLE) -INT noisePreCount(const INT *noiseNrg, INT maxSfb); -#endif +void FDKaacEnc_BCClose(BITCNTR_STATE** phBC); -INT FDKaacEnc_dynBitCount( - BITCNTR_STATE* const hBC, - const SHORT* const quantSpectrum, - const UINT* const maxValueInSfb, - const INT* const scalefac, - const INT blockType, - const INT sfbCnt, - const INT maxSfbPerGroup, - const INT sfbPerGroup, - const INT* const sfbOffset, - SECTION_DATA* const RESTRICT sectionData, - const INT* const noiseNrg, - const INT* const isBook, - const INT* const isScale, - const UINT syntaxFlags - ); +INT FDKaacEnc_dynBitCount(BITCNTR_STATE* const hBC, + const SHORT* const quantSpectrum, + const UINT* const maxValueInSfb, + const INT* const scalefac, const INT blockType, + const INT sfbCnt, const INT maxSfbPerGroup, + const INT sfbPerGroup, const INT* const sfbOffset, + SECTION_DATA* const RESTRICT sectionData, + const INT* const noiseNrg, const INT* const isBook, + const INT* const isScale, const UINT syntaxFlags); #endif diff --git a/libAACenc/src/grp_data.cpp b/libAACenc/src/grp_data.cpp index 465865f..bc9d85f 100644 --- a/libAACenc/src/grp_data.cpp +++ b/libAACenc/src/grp_data.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,194 +90,175 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** + + Author(s): M.Werner -/******************************** MPEG Audio Encoder ************************** + Description: Short block grouping - Initial author: M.Werner - contents/description: Short block grouping +*******************************************************************************/ -******************************************************************************/ #include "psy_const.h" #include "interface.h" /* -* this routine does not work in-place -*/ + * this routine does not work in-place + */ +/* + * Don't use fAddSaturate2() because it looses one bit accuracy which is + * usefull for quality. + */ static inline FIXP_DBL nrgAddSaturate(const FIXP_DBL a, const FIXP_DBL b) { - return ( (a>=(FIXP_DBL)MAXVAL_DBL-b) ? (FIXP_DBL)MAXVAL_DBL : (a + b) ); + return ((a >= (FIXP_DBL)MAXVAL_DBL - b) ? (FIXP_DBL)MAXVAL_DBL : (a + b)); } -void -FDKaacEnc_groupShortData(FIXP_DBL *mdctSpectrum, /* in-out */ - SFB_THRESHOLD *sfbThreshold, /* in-out */ - SFB_ENERGY *sfbEnergy, /* in-out */ - SFB_ENERGY *sfbEnergyMS, /* in-out */ - SFB_ENERGY *sfbSpreadEnergy, - const INT sfbCnt, - const INT sfbActive, - const INT *sfbOffset, - const FIXP_DBL *sfbMinSnrLdData, - INT *groupedSfbOffset, /* out */ - INT *maxSfbPerGroup, /* out */ - FIXP_DBL *groupedSfbMinSnrLdData, - const INT noOfGroups, - const INT *groupLen, - const INT granuleLength) -{ - INT i,j; - INT line; /* counts through lines */ - INT sfb; /* counts through scalefactor bands */ - INT grp; /* counts through groups */ - INT wnd; /* counts through windows in a group */ - INT offset; /* needed in sfbOffset grouping */ +void FDKaacEnc_groupShortData(FIXP_DBL *mdctSpectrum, /* in-out */ + SFB_THRESHOLD *sfbThreshold, /* in-out */ + SFB_ENERGY *sfbEnergy, /* in-out */ + SFB_ENERGY *sfbEnergyMS, /* in-out */ + SFB_ENERGY *sfbSpreadEnergy, const INT sfbCnt, + const INT sfbActive, const INT *sfbOffset, + const FIXP_DBL *sfbMinSnrLdData, + INT *groupedSfbOffset, /* out */ + INT *maxSfbPerGroup, /* out */ + FIXP_DBL *groupedSfbMinSnrLdData, + const INT noOfGroups, const INT *groupLen, + const INT granuleLength) { + INT i, j; + INT line; /* counts through lines */ + INT sfb; /* counts through scalefactor bands */ + INT grp; /* counts through groups */ + INT wnd; /* counts through windows in a group */ + INT offset; /* needed in sfbOffset grouping */ INT highestSfb; + INT granuleLength_short = granuleLength / TRANS_FAC; - INT granuleLength_short = granuleLength/TRANS_FAC; + C_ALLOC_SCRATCH_START(tmpSpectrum, FIXP_DBL, (1024)) /* for short blocks: regroup spectrum and */ /* group energies and thresholds according to grouping */ - C_ALLOC_SCRATCH_START(tmpSpectrum, FIXP_DBL, (1024)); /* calculate maxSfbPerGroup */ highestSfb = 0; - for (wnd = 0; wnd < TRANS_FAC; wnd++) - { - for (sfb = sfbActive-1; sfb >= highestSfb; sfb--) - { - for (line = sfbOffset[sfb+1]-1; line >= sfbOffset[sfb]; line--) - { - if ( mdctSpectrum[wnd*granuleLength_short+line] != FL2FXCONST_SPC(0.0) ) break; /* this band is not completely zero */ + for (wnd = 0; wnd < TRANS_FAC; wnd++) { + for (sfb = sfbActive - 1; sfb >= highestSfb; sfb--) { + for (line = sfbOffset[sfb + 1] - 1; line >= sfbOffset[sfb]; line--) { + if (mdctSpectrum[wnd * granuleLength_short + line] != + FL2FXCONST_SPC(0.0)) + break; /* this band is not completely zero */ } - if (line >= sfbOffset[sfb]) break; /* this band was not completely zero */ + if (line >= sfbOffset[sfb]) break; /* this band was not completely zero */ } highestSfb = fixMax(highestSfb, sfb); } highestSfb = highestSfb > 0 ? highestSfb : 0; - *maxSfbPerGroup = highestSfb+1; + *maxSfbPerGroup = highestSfb + 1; /* calculate groupedSfbOffset */ i = 0; offset = 0; - for (grp = 0; grp < noOfGroups; grp++) - { - for (sfb = 0; sfb < sfbActive+1; sfb++) - { - groupedSfbOffset[i++] = offset + sfbOffset[sfb] * groupLen[grp]; - } - i += sfbCnt-sfb; - offset += groupLen[grp] * granuleLength_short; + for (grp = 0; grp < noOfGroups; grp++) { + for (sfb = 0; sfb < sfbActive + 1; sfb++) { + groupedSfbOffset[i++] = offset + sfbOffset[sfb] * groupLen[grp]; + } + i += sfbCnt - sfb; + offset += groupLen[grp] * granuleLength_short; } groupedSfbOffset[i++] = granuleLength; /* calculate groupedSfbMinSnr */ i = 0; - for (grp = 0; grp < noOfGroups; grp++) - { - for (sfb = 0; sfb < sfbActive; sfb++) - { + for (grp = 0; grp < noOfGroups; grp++) { + for (sfb = 0; sfb < sfbActive; sfb++) { groupedSfbMinSnrLdData[i++] = sfbMinSnrLdData[sfb]; } - i += sfbCnt-sfb; + i += sfbCnt - sfb; } /* sum up sfbThresholds */ wnd = 0; i = 0; - for (grp = 0; grp < noOfGroups; grp++) - { - for (sfb = 0; sfb < sfbActive; sfb++) - { + for (grp = 0; grp < noOfGroups; grp++) { + for (sfb = 0; sfb < sfbActive; sfb++) { FIXP_DBL thresh = sfbThreshold->Short[wnd][sfb]; - for (j=1; jShort[wnd+j][sfb]); + for (j = 1; j < groupLen[grp]; j++) { + thresh = nrgAddSaturate(thresh, sfbThreshold->Short[wnd + j][sfb]); } sfbThreshold->Long[i++] = thresh; } - i += sfbCnt-sfb; + i += sfbCnt - sfb; wnd += groupLen[grp]; } /* sum up sfbEnergies left/right */ wnd = 0; i = 0; - for (grp = 0; grp < noOfGroups; grp++) - { - for (sfb = 0; sfb < sfbActive; sfb++) - { + for (grp = 0; grp < noOfGroups; grp++) { + for (sfb = 0; sfb < sfbActive; sfb++) { FIXP_DBL energy = sfbEnergy->Short[wnd][sfb]; - for (j=1; jShort[wnd+j][sfb]); + for (j = 1; j < groupLen[grp]; j++) { + energy = nrgAddSaturate(energy, sfbEnergy->Short[wnd + j][sfb]); } sfbEnergy->Long[i++] = energy; } - i += sfbCnt-sfb; + i += sfbCnt - sfb; wnd += groupLen[grp]; } /* sum up sfbEnergies mid/side */ wnd = 0; i = 0; - for (grp = 0; grp < noOfGroups; grp++) - { - for (sfb = 0; sfb < sfbActive; sfb++) - { + for (grp = 0; grp < noOfGroups; grp++) { + for (sfb = 0; sfb < sfbActive; sfb++) { FIXP_DBL energy = sfbEnergyMS->Short[wnd][sfb]; - for (j=1; jShort[wnd+j][sfb]); + for (j = 1; j < groupLen[grp]; j++) { + energy = nrgAddSaturate(energy, sfbEnergyMS->Short[wnd + j][sfb]); } sfbEnergyMS->Long[i++] = energy; } - i += sfbCnt-sfb; + i += sfbCnt - sfb; wnd += groupLen[grp]; } /* sum up sfbSpreadEnergies */ wnd = 0; i = 0; - for (grp = 0; grp < noOfGroups; grp++) - { - for (sfb = 0; sfb < sfbActive; sfb++) - { + for (grp = 0; grp < noOfGroups; grp++) { + for (sfb = 0; sfb < sfbActive; sfb++) { FIXP_DBL energy = sfbSpreadEnergy->Short[wnd][sfb]; - for (j=1; jShort[wnd+j][sfb]); + for (j = 1; j < groupLen[grp]; j++) { + energy = nrgAddSaturate(energy, sfbSpreadEnergy->Short[wnd + j][sfb]); } sfbSpreadEnergy->Long[i++] = energy; } - i += sfbCnt-sfb; + i += sfbCnt - sfb; wnd += groupLen[grp]; } /* re-group spectrum */ wnd = 0; i = 0; - for (grp = 0; grp < noOfGroups; grp++) - { - for (sfb = 0; sfb < sfbActive; sfb++) - { - int width = sfbOffset[sfb+1]-sfbOffset[sfb]; - FIXP_DBL *pMdctSpectrum = &mdctSpectrum[sfbOffset[sfb]] + wnd*granuleLength_short; - for (j = 0; j < groupLen[grp]; j++) - { + for (grp = 0; grp < noOfGroups; grp++) { + for (sfb = 0; sfb < sfbActive; sfb++) { + int width = sfbOffset[sfb + 1] - sfbOffset[sfb]; + FIXP_DBL *pMdctSpectrum = + &mdctSpectrum[sfbOffset[sfb]] + wnd * granuleLength_short; + for (j = 0; j < groupLen[grp]; j++) { FIXP_DBL *pTmp = pMdctSpectrum; - for (line = width; line > 0; line--) - { + for (line = width; line > 0; line--) { tmpSpectrum[i++] = *pTmp++; } pMdctSpectrum += granuleLength_short; } } - i += (groupLen[grp]*(sfbOffset[sfbCnt]-sfbOffset[sfb])); + i += (groupLen[grp] * (sfbOffset[sfbCnt] - sfbOffset[sfb])); wnd += groupLen[grp]; } - FDKmemcpy(mdctSpectrum, tmpSpectrum, granuleLength*sizeof(FIXP_DBL)); + FDKmemcpy(mdctSpectrum, tmpSpectrum, granuleLength * sizeof(FIXP_DBL)); C_ALLOC_SCRATCH_END(tmpSpectrum, FIXP_DBL, (1024)) } diff --git a/libAACenc/src/grp_data.h b/libAACenc/src/grp_data.h index f061855..3e1a708 100644 --- a/libAACenc/src/grp_data.h +++ b/libAACenc/src/grp_data.h @@ -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,37 +90,34 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Short block grouping + Description: Short block grouping -******************************************************************************/ -#ifndef __GRP_DATA_H__ -#define __GRP_DATA_H__ +*******************************************************************************/ + +#ifndef GRP_DATA_H +#define GRP_DATA_H #include "common_fix.h" #include "psy_data.h" - -void -FDKaacEnc_groupShortData(FIXP_DBL *mdctSpectrum, /* in-out */ - SFB_THRESHOLD *sfbThreshold, /* in-out */ - SFB_ENERGY *sfbEnergy, /* in-out */ - SFB_ENERGY *sfbEnergyMS, /* in-out */ - SFB_ENERGY *sfbSpreadEnergy, - const INT sfbCnt, - const INT sfbActive, - const INT *sfbOffset, - const FIXP_DBL *sfbMinSnrLdData, - INT *groupedSfbOffset, /* out */ - INT *maxSfbPerGroup, - FIXP_DBL *groupedSfbMinSnrLdData, - const INT noOfGroups, - const INT *groupLen, - const INT granuleLength); +void FDKaacEnc_groupShortData(FIXP_DBL *mdctSpectrum, /* in-out */ + SFB_THRESHOLD *sfbThreshold, /* in-out */ + SFB_ENERGY *sfbEnergy, /* in-out */ + SFB_ENERGY *sfbEnergyMS, /* in-out */ + SFB_ENERGY *sfbSpreadEnergy, const INT sfbCnt, + const INT sfbActive, const INT *sfbOffset, + const FIXP_DBL *sfbMinSnrLdData, + INT *groupedSfbOffset, /* out */ + INT *maxSfbPerGroup, + FIXP_DBL *groupedSfbMinSnrLdData, + const INT noOfGroups, const INT *groupLen, + const INT granuleLength); #endif /* _INTERFACE_H */ diff --git a/libAACenc/src/intensity.cpp b/libAACenc/src/intensity.cpp index b45b27b..a160a4f 100644 --- a/libAACenc/src/intensity.cpp +++ b/libAACenc/src/intensity.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,82 +90,94 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): A. Horndasch (code originally from lwr) / Josef Hoepfl (FDK) - Initial author: A. Horndasch (code originally from lwr) / Josef Hoepfl (FDK) - contents/description: intensity stereo processing + Description: intensity stereo processing -******************************************************************************/ +*******************************************************************************/ #include "intensity.h" + #include "interface.h" #include "psy_configuration.h" #include "psy_const.h" #include "qc_main.h" #include "bit_cnt.h" -/* only set an IS seed it left/right channel correlation is above IS_CORR_THRESH */ -#define IS_CORR_THRESH FL2FXCONST_DBL(0.95f) +/* only set an IS seed it left/right channel correlation is above IS_CORR_THRESH + */ +#define IS_CORR_THRESH FL2FXCONST_DBL(0.95f) /* when expanding the IS region to more SFBs only accept an error that is * not more than IS_TOTAL_ERROR_THRESH overall and * not more than IS_LOCAL_ERROR_THRESH for the current SFB */ -#define IS_TOTAL_ERROR_THRESH FL2FXCONST_DBL(0.04f) -#define IS_LOCAL_ERROR_THRESH FL2FXCONST_DBL(0.01f) +#define IS_TOTAL_ERROR_THRESH FL2FXCONST_DBL(0.04f) +#define IS_LOCAL_ERROR_THRESH FL2FXCONST_DBL(0.01f) -/* the maximum allowed change of the intensity direction (unit: IS scale) - scaled with factor 0.25 - */ +/* the maximum allowed change of the intensity direction (unit: IS scale) - + * scaled with factor 0.25 - */ #define IS_DIRECTION_DEVIATION_THRESH_SF 2 -#define IS_DIRECTION_DEVIATION_THRESH FL2FXCONST_DBL(2.0f/(1< no IS if the panning angle is not far from the middle, MS will do */ /* this is equivalent to a scale of +/-1.02914634566 */ -#define IS_LEFT_RIGHT_RATIO_THRESH FL2FXCONST_DBL(0.7f) +#define IS_LEFT_RIGHT_RATIO_THRESH FL2FXCONST_DBL(0.7f) /* scalefactor of realScale */ -#define REAL_SCALE_SF 1 +#define REAL_SCALE_SF 1 /* scalefactor overallLoudness */ -#define OVERALL_LOUDNESS_SF 6 +#define OVERALL_LOUDNESS_SF 6 /* scalefactor for sum over max samples per goup */ -#define MAX_SFB_PER_GROUP_SF 6 +#define MAX_SFB_PER_GROUP_SF 6 /* scalefactor for sum of mdct spectrum */ -#define MDCT_SPEC_SF 6 - - -typedef struct -{ +#define MDCT_SPEC_SF 6 - FIXP_DBL corr_thresh; /*!< Only set an IS seed it left/right channel correlation is above corr_thresh */ +typedef struct { + FIXP_DBL corr_thresh; /*!< Only set an IS seed it left/right channel + correlation is above corr_thresh */ - FIXP_DBL total_error_thresh; /*!< When expanding the IS region to more SFBs only accept an error that is - not more than 'total_error_thresh' overall. */ + FIXP_DBL total_error_thresh; /*!< When expanding the IS region to more SFBs + only accept an error that is not more than + 'total_error_thresh' overall. */ - FIXP_DBL local_error_thresh; /*!< When expanding the IS region to more SFBs only accept an error that is - not more than 'local_error_thresh' for the current SFB. */ + FIXP_DBL local_error_thresh; /*!< When expanding the IS region to more SFBs + only accept an error that is not more than + 'local_error_thresh' for the current SFB. */ - FIXP_DBL direction_deviation_thresh; /*!< The maximum allowed change of the intensity direction (unit: IS scale) */ + FIXP_DBL direction_deviation_thresh; /*!< The maximum allowed change of the + intensity direction (unit: IS scale) + */ - FIXP_DBL is_region_min_loudness; /*!< IS regions need to have a minimal percentage of the overall loudness, e.g. 0.06 == 6% */ + FIXP_DBL is_region_min_loudness; /*!< IS regions need to have a minimal + percentage of the overall loudness, e.g. + 0.06 == 6% */ - INT min_is_sfbs; /*!< Only perform IS if 'min_is_sfbs' neighboring SFBs can be processed */ + INT min_is_sfbs; /*!< Only perform IS if 'min_is_sfbs' neighboring SFBs can be + processed */ - FIXP_DBL left_right_ratio_threshold; /*!< No IS if the panning angle is not far from the middle, MS will do */ + FIXP_DBL left_right_ratio_threshold; /*!< No IS if the panning angle is not + far from the middle, MS will do */ } INTENSITY_PARAMETERS; - /***************************************************************************** functionname: calcSfbMaxScale @@ -170,25 +193,22 @@ typedef struct returns: scalefactor *****************************************************************************/ -static INT -calcSfbMaxScale(const FIXP_DBL *mdctSpectrum, - const INT l1, - const INT l2) -{ +static INT calcSfbMaxScale(const FIXP_DBL *mdctSpectrum, const INT l1, + const INT l2) { INT i; INT sfbMaxScale; FIXP_DBL maxSpc; maxSpc = FL2FXCONST_DBL(0.0); - for (i=l1; icorr_thresh = IS_CORR_THRESH; - isParams->total_error_thresh = IS_TOTAL_ERROR_THRESH; - isParams->local_error_thresh = IS_LOCAL_ERROR_THRESH; +static void FDKaacEnc_initIsParams(INTENSITY_PARAMETERS *isParams) { + isParams->corr_thresh = IS_CORR_THRESH; + isParams->total_error_thresh = IS_TOTAL_ERROR_THRESH; + isParams->local_error_thresh = IS_LOCAL_ERROR_THRESH; isParams->direction_deviation_thresh = IS_DIRECTION_DEVIATION_THRESH; - isParams->is_region_min_loudness = IS_REGION_MIN_LOUDNESS; - isParams->min_is_sfbs = IS_MIN_SFBS; + isParams->is_region_min_loudness = IS_REGION_MIN_LOUDNESS; + isParams->min_is_sfbs = IS_MIN_SFBS; isParams->left_right_ratio_threshold = IS_LEFT_RIGHT_RATIO_THRESH; } - /***************************************************************************** functionname: FDKaacEnc_prepareIntensityDecision @@ -238,24 +255,14 @@ FDKaacEnc_initIsParams(INTENSITY_PARAMETERS *isParams) returns: none *****************************************************************************/ -static void -FDKaacEnc_prepareIntensityDecision(const FIXP_DBL *sfbEnergyLeft, - const FIXP_DBL *sfbEnergyRight, - const FIXP_DBL *sfbEnergyLdDataLeft, - const FIXP_DBL *sfbEnergyLdDataRight, - const FIXP_DBL *mdctSpectrumLeft, - const FIXP_DBL *mdctSpectrumRight, - const INTENSITY_PARAMETERS *isParams, - FIXP_DBL *hrrErr, - INT *isMask, - FIXP_DBL *realScale, - FIXP_DBL *normSfbLoudness, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup, - const INT *sfbOffset) -{ - INT j,sfb,sfboffs; +static void FDKaacEnc_prepareIntensityDecision( + const FIXP_DBL *sfbEnergyLeft, const FIXP_DBL *sfbEnergyRight, + const FIXP_DBL *sfbEnergyLdDataLeft, const FIXP_DBL *sfbEnergyLdDataRight, + const FIXP_DBL *mdctSpectrumLeft, const FIXP_DBL *mdctSpectrumRight, + const INTENSITY_PARAMETERS *isParams, FIXP_DBL *hrrErr, INT *isMask, + FIXP_DBL *realScale, FIXP_DBL *normSfbLoudness, const INT sfbCnt, + const INT sfbPerGroup, const INT maxSfbPerGroup, const INT *sfbOffset) { + INT j, sfb, sfboffs; INT grpCounter; /* temporary variables to compute loudness */ @@ -269,149 +276,192 @@ FDKaacEnc_prepareIntensityDecision(const FIXP_DBL *sfbEnergyLeft, FIXP_DBL tmp_l, tmp_r; FIXP_DBL inv_n; - FDKmemclear(channelCorr, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); - FDKmemclear(normSfbLoudness, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); - FDKmemclear(overallLoudness, MAX_NO_OF_GROUPS*sizeof(FIXP_DBL)); - FDKmemclear(realScale, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); + FDKmemclear(channelCorr, MAX_GROUPED_SFB * sizeof(FIXP_DBL)); + FDKmemclear(normSfbLoudness, MAX_GROUPED_SFB * sizeof(FIXP_DBL)); + FDKmemclear(overallLoudness, MAX_NO_OF_GROUPS * sizeof(FIXP_DBL)); + FDKmemclear(realScale, MAX_GROUPED_SFB * sizeof(FIXP_DBL)); - for (grpCounter = 0, sfboffs = 0; sfboffs < sfbCnt; sfboffs += sfbPerGroup, grpCounter++) { + for (grpCounter = 0, sfboffs = 0; sfboffs < sfbCnt; + sfboffs += sfbPerGroup, grpCounter++) { overallLoudness[grpCounter] = FL2FXCONST_DBL(0.0f); for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { - INT sL,sR,s; - FIXP_DBL isValue = sfbEnergyLdDataLeft[sfb+sfboffs]-sfbEnergyLdDataRight[sfb+sfboffs]; + INT sL, sR, s; + FIXP_DBL isValue = sfbEnergyLdDataLeft[sfb + sfboffs] - + sfbEnergyLdDataRight[sfb + sfboffs]; /* delimitate intensity scale value to representable range */ - realScale[sfb + sfboffs] = fixMin(FL2FXCONST_DBL(60.f/(1<<(REAL_SCALE_SF+LD_DATA_SHIFT))), fixMax(FL2FXCONST_DBL(-60.f/(1<<(REAL_SCALE_SF+LD_DATA_SHIFT))), isValue)); - - sL = fixMax(0,(CntLeadingZeros(sfbEnergyLeft[sfb + sfboffs])-1)); - sR = fixMax(0,(CntLeadingZeros(sfbEnergyRight[sfb + sfboffs])-1)); - s = (fixMin(sL,sR)>>2)<<2; - normSfbLoudness[sfb + sfboffs] = sqrtFixp(sqrtFixp(((sfbEnergyLeft[sfb + sfboffs]<> 1) + ((sfbEnergyRight[sfb + sfboffs]<> 1))) >> (s>>2); - - overallLoudness[grpCounter] += normSfbLoudness[sfb + sfboffs] >> OVERALL_LOUDNESS_SF; + realScale[sfb + sfboffs] = fixMin( + FL2FXCONST_DBL(60.f / (1 << (REAL_SCALE_SF + LD_DATA_SHIFT))), + fixMax(FL2FXCONST_DBL(-60.f / (1 << (REAL_SCALE_SF + LD_DATA_SHIFT))), + isValue)); + + sL = fixMax(0, (CntLeadingZeros(sfbEnergyLeft[sfb + sfboffs]) - 1)); + sR = fixMax(0, (CntLeadingZeros(sfbEnergyRight[sfb + sfboffs]) - 1)); + s = (fixMin(sL, sR) >> 2) << 2; + normSfbLoudness[sfb + sfboffs] = + sqrtFixp(sqrtFixp(((sfbEnergyLeft[sfb + sfboffs] << s) >> 1) + + ((sfbEnergyRight[sfb + sfboffs] << s) >> 1))) >> + (s >> 2); + + overallLoudness[grpCounter] += + normSfbLoudness[sfb + sfboffs] >> OVERALL_LOUDNESS_SF; /* don't do intensity if * - panning angle is too close to the middle or * - one channel is non-existent or * - if it is dual mono */ - if( (sfbEnergyLeft[sfb + sfboffs] >= fMult(isParams->left_right_ratio_threshold,sfbEnergyRight[sfb + sfboffs])) - && (fMult(isParams->left_right_ratio_threshold,sfbEnergyLeft[sfb + sfboffs]) <= sfbEnergyRight[sfb + sfboffs]) ) { - - /* this will prevent post processing from considering this SFB for merging */ - hrrErr[sfb + sfboffs] = FL2FXCONST_DBL(1.0/8.0); + if ((sfbEnergyLeft[sfb + sfboffs] >= + fMult(isParams->left_right_ratio_threshold, + sfbEnergyRight[sfb + sfboffs])) && + (fMult(isParams->left_right_ratio_threshold, + sfbEnergyLeft[sfb + sfboffs]) <= + sfbEnergyRight[sfb + sfboffs])) { + /* this will prevent post processing from considering this SFB for + * merging */ + hrrErr[sfb + sfboffs] = FL2FXCONST_DBL(1.0 / 8.0); } } } - for (grpCounter = 0, sfboffs = 0; sfboffs < sfbCnt; sfboffs += sfbPerGroup, grpCounter++) { + for (grpCounter = 0, sfboffs = 0; sfboffs < sfbCnt; + sfboffs += sfbPerGroup, grpCounter++) { INT invOverallLoudnessSF; FIXP_DBL invOverallLoudness; if (overallLoudness[grpCounter] == FL2FXCONST_DBL(0.0)) { invOverallLoudness = FL2FXCONST_DBL(0.0); invOverallLoudnessSF = 0; + } else { + invOverallLoudness = + fDivNorm((FIXP_DBL)MAXVAL_DBL, overallLoudness[grpCounter], + &invOverallLoudnessSF); + invOverallLoudnessSF = + invOverallLoudnessSF - OVERALL_LOUDNESS_SF + + 1; /* +1: compensate fMultDiv2() in subsequent loop */ } - else { - invOverallLoudness = fDivNorm((FIXP_DBL)MAXVAL_DBL, overallLoudness[grpCounter],&invOverallLoudnessSF); - invOverallLoudnessSF = invOverallLoudnessSF - OVERALL_LOUDNESS_SF + 1; /* +1: compensate fMultDiv2() in subsequent loop */ - } - invOverallLoudnessSF = fixMin(fixMax(invOverallLoudnessSF,-(DFRACT_BITS-1)),DFRACT_BITS-1); + invOverallLoudnessSF = fixMin( + fixMax(invOverallLoudnessSF, -(DFRACT_BITS - 1)), DFRACT_BITS - 1); for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { FIXP_DBL tmp; - tmp = fMultDiv2((normSfbLoudness[sfb + sfboffs]>>OVERALL_LOUDNESS_SF)<> OVERALL_LOUDNESS_SF) + << OVERALL_LOUDNESS_SF, + invOverallLoudness); normSfbLoudness[sfb + sfboffs] = scaleValue(tmp, invOverallLoudnessSF); channelCorr[sfb + sfboffs] = FL2FXCONST_DBL(0.0f); /* max width of scalefactorband is 96; width's are always even */ - /* inv_n is scaled with factor 2 to compensate fMultDiv2() in subsequent loops */ - inv_n = GetInvInt((sfbOffset[sfb + sfboffs + 1] - sfbOffset[sfb + sfboffs])>>1); + /* inv_n is scaled with factor 2 to compensate fMultDiv2() in subsequent + * loops */ + inv_n = GetInvInt( + (sfbOffset[sfb + sfboffs + 1] - sfbOffset[sfb + sfboffs]) >> 1); if (inv_n > FL2FXCONST_DBL(0.0f)) { - INT s,sL,sR; + INT s, sL, sR; /* correlation := Pearson's product-moment coefficient */ - /* compute correlation between channels and check if it is over threshold */ - ml = FL2FXCONST_DBL(0.0f); - mr = FL2FXCONST_DBL(0.0f); - prod_lr = FL2FXCONST_DBL(0.0f); + /* compute correlation between channels and check if it is over + * threshold */ + ml = FL2FXCONST_DBL(0.0f); + mr = FL2FXCONST_DBL(0.0f); + prod_lr = FL2FXCONST_DBL(0.0f); square_l = FL2FXCONST_DBL(0.0f); square_r = FL2FXCONST_DBL(0.0f); - sL = calcSfbMaxScale(mdctSpectrumLeft,sfbOffset[sfb+sfboffs],sfbOffset[sfb+sfboffs+1]); - sR = calcSfbMaxScale(mdctSpectrumRight,sfbOffset[sfb+sfboffs],sfbOffset[sfb+sfboffs+1]); - s = fixMin(sL,sR); - - for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; j++) { - ml += fMultDiv2((mdctSpectrumLeft[j] << s),inv_n); // scaled with mdctScale - s + inv_n - mr += fMultDiv2((mdctSpectrumRight[j] << s),inv_n); // scaled with mdctScale - s + inv_n + sL = calcSfbMaxScale(mdctSpectrumLeft, sfbOffset[sfb + sfboffs], + sfbOffset[sfb + sfboffs + 1]); + sR = calcSfbMaxScale(mdctSpectrumRight, sfbOffset[sfb + sfboffs], + sfbOffset[sfb + sfboffs + 1]); + s = fixMin(sL, sR); + + for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; + j++) { + ml += fMultDiv2((mdctSpectrumLeft[j] << s), + inv_n); // scaled with mdctScale - s + inv_n + mr += fMultDiv2((mdctSpectrumRight[j] << s), + inv_n); // scaled with mdctScale - s + inv_n } - ml = fMultDiv2(ml,inv_n); // scaled with mdctScale - s + inv_n - mr = fMultDiv2(mr,inv_n); // scaled with mdctScale - s + inv_n - - for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; j++) { - tmp_l = fMultDiv2((mdctSpectrumLeft[j] << s),inv_n) - ml; // scaled with mdctScale - s + inv_n - tmp_r = fMultDiv2((mdctSpectrumRight[j] << s),inv_n) - mr; // scaled with mdctScale - s + inv_n - - prod_lr += fMultDiv2(tmp_l,tmp_r); // scaled with 2*(mdctScale - s + inv_n) + 1 - square_l += fPow2Div2(tmp_l); // scaled with 2*(mdctScale - s + inv_n) + 1 - square_r += fPow2Div2(tmp_r); // scaled with 2*(mdctScale - s + inv_n) + 1 + ml = fMultDiv2(ml, inv_n); // scaled with mdctScale - s + inv_n + mr = fMultDiv2(mr, inv_n); // scaled with mdctScale - s + inv_n + + for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; + j++) { + tmp_l = fMultDiv2((mdctSpectrumLeft[j] << s), inv_n) - + ml; // scaled with mdctScale - s + inv_n + tmp_r = fMultDiv2((mdctSpectrumRight[j] << s), inv_n) - + mr; // scaled with mdctScale - s + inv_n + + prod_lr += fMultDiv2( + tmp_l, tmp_r); // scaled with 2*(mdctScale - s + inv_n) + 1 + square_l += + fPow2Div2(tmp_l); // scaled with 2*(mdctScale - s + inv_n) + 1 + square_r += + fPow2Div2(tmp_r); // scaled with 2*(mdctScale - s + inv_n) + 1 } - prod_lr = prod_lr << 1; // scaled with 2*(mdctScale - s + inv_n) - square_l = square_l << 1; // scaled with 2*(mdctScale - s + inv_n) - square_r = square_r << 1; // scaled with 2*(mdctScale - s + inv_n) + prod_lr = prod_lr << 1; // scaled with 2*(mdctScale - s + inv_n) + square_l = square_l << 1; // scaled with 2*(mdctScale - s + inv_n) + square_r = square_r << 1; // scaled with 2*(mdctScale - s + inv_n) - if (square_l > FL2FXCONST_DBL(0.0f) && square_r > FL2FXCONST_DBL(0.0f)) { + if (square_l > FL2FXCONST_DBL(0.0f) && + square_r > FL2FXCONST_DBL(0.0f)) { INT channelCorrSF = 0; - /* local scaling of square_l and square_r is compensated after sqrt calculation */ - sL = fixMax(0,(CntLeadingZeros(square_l)-1)); - sR = fixMax(0,(CntLeadingZeros(square_r)-1)); - s = ((sL + sR)>>1)<<1; - sL = fixMin(sL,s); - sR = s-sL; - tmp = fMult(square_l<> 1) << 1; + sL = fixMin(sL, s); + sR = s - sL; + tmp = fMult(square_l << sL, square_r << sR); tmp = sqrtFixp(tmp); FDK_ASSERT(tmp > FL2FXCONST_DBL(0.0f)); /* numerator and denominator have the same scaling */ - if (prod_lr < FL2FXCONST_DBL(0.0f) ) { - channelCorr[sfb + sfboffs] = -(fDivNorm(-prod_lr,tmp,&channelCorrSF)); + if (prod_lr < FL2FXCONST_DBL(0.0f)) { + channelCorr[sfb + sfboffs] = + -(fDivNorm(-prod_lr, tmp, &channelCorrSF)); + } else { + channelCorr[sfb + sfboffs] = + (fDivNorm(prod_lr, tmp, &channelCorrSF)); } - else { - channelCorr[sfb + sfboffs] = (fDivNorm( prod_lr,tmp,&channelCorrSF)); - } - channelCorrSF = fixMin(fixMax(( channelCorrSF + ((sL+sR)>>1)),-(DFRACT_BITS-1)),DFRACT_BITS-1); + channelCorrSF = fixMin( + fixMax((channelCorrSF + ((sL + sR) >> 1)), -(DFRACT_BITS - 1)), + DFRACT_BITS - 1); if (channelCorrSF < 0) { - channelCorr[sfb + sfboffs] = channelCorr[sfb + sfboffs] >> (-channelCorrSF); - } - else { + channelCorr[sfb + sfboffs] = + channelCorr[sfb + sfboffs] >> (-channelCorrSF); + } else { /* avoid overflows due to limited computational accuracy */ - if ( fAbs(channelCorr[sfb + sfboffs]) > (((FIXP_DBL)MAXVAL_DBL)>>channelCorrSF) ) { + if (fAbs(channelCorr[sfb + sfboffs]) > + (((FIXP_DBL)MAXVAL_DBL) >> channelCorrSF)) { if (channelCorr[sfb + sfboffs] < FL2FXCONST_DBL(0.0f)) - channelCorr[sfb + sfboffs] = -(FIXP_DBL) MAXVAL_DBL; + channelCorr[sfb + sfboffs] = -(FIXP_DBL)MAXVAL_DBL; else - channelCorr[sfb + sfboffs] = (FIXP_DBL) MAXVAL_DBL; - } - else { - channelCorr[sfb + sfboffs] = channelCorr[sfb + sfboffs] << channelCorrSF; + channelCorr[sfb + sfboffs] = (FIXP_DBL)MAXVAL_DBL; + } else { + channelCorr[sfb + sfboffs] = channelCorr[sfb + sfboffs] + << channelCorrSF; } } } } - /* for post processing: hrrErr is the error in terms of (too little) correlation - * weighted with the loudness of the SFB; SFBs with small hrrErr can be merged */ - if (hrrErr[sfb + sfboffs] == FL2FXCONST_DBL(1.0/8.0)) { + /* for post processing: hrrErr is the error in terms of (too little) + * correlation weighted with the loudness of the SFB; SFBs with small + * hrrErr can be merged */ + if (hrrErr[sfb + sfboffs] == FL2FXCONST_DBL(1.0 / 8.0)) { continue; } - hrrErr[sfb + sfboffs] = fMultDiv2((FL2FXCONST_DBL(0.25f)-(channelCorr[sfb + sfboffs]>>2)),normSfbLoudness[sfb + sfboffs]); + hrrErr[sfb + sfboffs] = + fMultDiv2((FL2FXCONST_DBL(0.25f) - (channelCorr[sfb + sfboffs] >> 2)), + normSfbLoudness[sfb + sfboffs]); /* set IS mask/vector to 1, if correlation is high enough */ if (fAbs(channelCorr[sfb + sfboffs]) >= isParams->corr_thresh) { @@ -421,7 +471,6 @@ FDKaacEnc_prepareIntensityDecision(const FIXP_DBL *sfbEnergyLeft, } } - /***************************************************************************** functionname: FDKaacEnc_finalizeIntensityDecision @@ -438,17 +487,11 @@ FDKaacEnc_prepareIntensityDecision(const FIXP_DBL *sfbEnergyLeft, returns: none *****************************************************************************/ -static void -FDKaacEnc_finalizeIntensityDecision(const FIXP_DBL *hrrErr, - INT *isMask, - const FIXP_DBL *realIsScale, - const FIXP_DBL *normSfbLoudness, - const INTENSITY_PARAMETERS *isParams, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup) -{ - INT sfb,sfboffs, j; +static void FDKaacEnc_finalizeIntensityDecision( + const FIXP_DBL *hrrErr, INT *isMask, const FIXP_DBL *realIsScale, + const FIXP_DBL *normSfbLoudness, const INTENSITY_PARAMETERS *isParams, + const INT sfbCnt, const INT sfbPerGroup, const INT maxSfbPerGroup) { + INT sfb, sfboffs, j; FIXP_DBL isScaleLast = FL2FXCONST_DBL(0.0f); INT isStartValueFound = 0; @@ -464,26 +507,30 @@ FDKaacEnc_finalizeIntensityDecision(const FIXP_DBL *hrrErr, if (currentIsSfbCount == 0) { startIsSfb = sfboffs + sfb; } - if (isStartValueFound==0) { + if (isStartValueFound == 0) { isScaleLast = realIsScale[sfboffs + sfb]; isStartValueFound = 1; } inIsBlock = 1; currentIsSfbCount++; - overallHrrError += hrrErr[sfboffs + sfb] >> (MAX_SFB_PER_GROUP_SF-3); - isRegionLoudness += normSfbLoudness[sfboffs + sfb] >> MAX_SFB_PER_GROUP_SF; - } - else { + overallHrrError += hrrErr[sfboffs + sfb] >> (MAX_SFB_PER_GROUP_SF - 3); + isRegionLoudness += + normSfbLoudness[sfboffs + sfb] >> MAX_SFB_PER_GROUP_SF; + } else { /* based on correlation, IS should not be used * -> use it anyway, if overall error is below threshold * and if local error does not exceed threshold * otherwise: check if there are enough IS SFBs */ if (inIsBlock) { - overallHrrError += hrrErr[sfboffs + sfb] >> (MAX_SFB_PER_GROUP_SF-3); - isRegionLoudness += normSfbLoudness[sfboffs + sfb] >> MAX_SFB_PER_GROUP_SF; - - if ( (hrrErr[sfboffs + sfb] < (isParams->local_error_thresh>>3)) && (overallHrrError < (isParams->total_error_thresh>>MAX_SFB_PER_GROUP_SF)) ) { + overallHrrError += + hrrErr[sfboffs + sfb] >> (MAX_SFB_PER_GROUP_SF - 3); + isRegionLoudness += + normSfbLoudness[sfboffs + sfb] >> MAX_SFB_PER_GROUP_SF; + + if ((hrrErr[sfboffs + sfb] < (isParams->local_error_thresh >> 3)) && + (overallHrrError < + (isParams->total_error_thresh >> MAX_SFB_PER_GROUP_SF))) { currentIsSfbCount++; /* overwrite correlation based decision */ isMask[sfboffs + sfb] = 1; @@ -494,10 +541,12 @@ FDKaacEnc_finalizeIntensityDecision(const FIXP_DBL *hrrErr, } /* check for large direction deviation */ if (inIsBlock) { - if( fAbs(isScaleLast-realIsScale[sfboffs + sfb]) < (isParams->direction_deviation_thresh>>(REAL_SCALE_SF+LD_DATA_SHIFT-IS_DIRECTION_DEVIATION_THRESH_SF)) ) { + if (fAbs(isScaleLast - realIsScale[sfboffs + sfb]) < + (isParams->direction_deviation_thresh >> + (REAL_SCALE_SF + LD_DATA_SHIFT - + IS_DIRECTION_DEVIATION_THRESH_SF))) { isScaleLast = realIsScale[sfboffs + sfb]; - } - else{ + } else { isMask[sfboffs + sfb] = 0; inIsBlock = 0; currentIsSfbCount--; @@ -506,14 +555,16 @@ FDKaacEnc_finalizeIntensityDecision(const FIXP_DBL *hrrErr, if (currentIsSfbCount > 0 && (!inIsBlock || sfb == maxSfbPerGroup - 1)) { /* not enough SFBs -> do not use IS */ - if (currentIsSfbCount < isParams->min_is_sfbs || (isRegionLoudness < isParams->is_region_min_loudness>>MAX_SFB_PER_GROUP_SF)) { - for(j = startIsSfb; j <= sfboffs + sfb; j++) { + if (currentIsSfbCount < isParams->min_is_sfbs || + (isRegionLoudnessis_region_min_loudness>> + MAX_SFB_PER_GROUP_SF)) { + for (j = startIsSfb; j <= sfboffs + sfb; j++) { isMask[j] = 0; } isScaleLast = FL2FXCONST_DBL(0.0f); isStartValueFound = 0; - for (j=0; j < startIsSfb; j++) { - if (isMask[j]!=0) { + for (j = 0; j < startIsSfb; j++) { + if (isMask[j] != 0) { isScaleLast = realIsScale[j]; isStartValueFound = 1; } @@ -527,7 +578,6 @@ FDKaacEnc_finalizeIntensityDecision(const FIXP_DBL *hrrErr, } } - /***************************************************************************** functionname: FDKaacEnc_IntensityStereoProcessing @@ -555,36 +605,23 @@ FDKaacEnc_finalizeIntensityDecision(const FIXP_DBL *hrrErr, sfbSpreadEnRight zeroed where isBook!=0 sfbThresholdRight zeroed where isBook!=0 sfbEnergyLdDataRight FL2FXCONST_DBL(-1.0) where isBook!=0 - sfbThresholdLdDataRight FL2FXCONST_DBL(-0.515625f) where isBook!=0 + sfbThresholdLdDataRight FL2FXCONST_DBL(-0.515625f) where +isBook!=0 returns: none *****************************************************************************/ void FDKaacEnc_IntensityStereoProcessing( - FIXP_DBL *sfbEnergyLeft, - FIXP_DBL *sfbEnergyRight, - FIXP_DBL *mdctSpectrumLeft, - FIXP_DBL *mdctSpectrumRight, - FIXP_DBL *sfbThresholdLeft, - FIXP_DBL *sfbThresholdRight, - FIXP_DBL *sfbThresholdLdDataRight, - FIXP_DBL *sfbSpreadEnLeft, - FIXP_DBL *sfbSpreadEnRight, - FIXP_DBL *sfbEnergyLdDataLeft, - FIXP_DBL *sfbEnergyLdDataRight, - INT *msDigest, - INT *msMask, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup, - const INT *sfbOffset, - const INT allowIS, - INT *isBook, - INT *isScale, - PNS_DATA *RESTRICT pnsData[2] - ) -{ - INT sfb,sfboffs, j; + FIXP_DBL *sfbEnergyLeft, FIXP_DBL *sfbEnergyRight, + FIXP_DBL *mdctSpectrumLeft, FIXP_DBL *mdctSpectrumRight, + FIXP_DBL *sfbThresholdLeft, FIXP_DBL *sfbThresholdRight, + FIXP_DBL *sfbThresholdLdDataRight, FIXP_DBL *sfbSpreadEnLeft, + FIXP_DBL *sfbSpreadEnRight, FIXP_DBL *sfbEnergyLdDataLeft, + FIXP_DBL *sfbEnergyLdDataRight, INT *msDigest, INT *msMask, + const INT sfbCnt, const INT sfbPerGroup, const INT maxSfbPerGroup, + const INT *sfbOffset, const INT allowIS, INT *isBook, INT *isScale, + PNS_DATA *RESTRICT pnsData[2]) { + INT sfb, sfboffs, j; FIXP_DBL scale; FIXP_DBL lr; FIXP_DBL hrrErr[MAX_GROUPED_SFB]; @@ -593,14 +630,13 @@ void FDKaacEnc_IntensityStereoProcessing( INTENSITY_PARAMETERS isParams; INT isMask[MAX_GROUPED_SFB]; - FDKmemclear((void*)isBook,sfbCnt*sizeof(INT)); - FDKmemclear((void*)isMask,sfbCnt*sizeof(INT)); - FDKmemclear((void*)realIsScale,sfbCnt*sizeof(FIXP_DBL)); - FDKmemclear((void*)isScale,sfbCnt*sizeof(INT)); - FDKmemclear((void*)hrrErr,sfbCnt*sizeof(FIXP_DBL)); + FDKmemclear((void *)isBook, sfbCnt * sizeof(INT)); + FDKmemclear((void *)isMask, sfbCnt * sizeof(INT)); + FDKmemclear((void *)realIsScale, sfbCnt * sizeof(FIXP_DBL)); + FDKmemclear((void *)isScale, sfbCnt * sizeof(INT)); + FDKmemclear((void *)hrrErr, sfbCnt * sizeof(FIXP_DBL)); - if (!allowIS) - return; + if (!allowIS) return; FDKaacEnc_initIsParams(&isParams); @@ -611,150 +647,164 @@ void FDKaacEnc_IntensityStereoProcessing( * + normalization: division by sum of all SFB loudnesses * - isMask (is set to 0 if channels are the same or one is 0) */ - FDKaacEnc_prepareIntensityDecision(sfbEnergyLeft, - sfbEnergyRight, - sfbEnergyLdDataLeft, - sfbEnergyLdDataRight, - mdctSpectrumLeft, - mdctSpectrumRight, - &isParams, - hrrErr, - isMask, - realIsScale, - normSfbLoudness, - sfbCnt, - sfbPerGroup, - maxSfbPerGroup, - sfbOffset); - - FDKaacEnc_finalizeIntensityDecision(hrrErr, - isMask, - realIsScale, - normSfbLoudness, - &isParams, - sfbCnt, - sfbPerGroup, - maxSfbPerGroup); - - for (sfb=0; sfb sfbThresholdRight[sfb+sfboffs]) ) { + if ((sfbEnergyLeft[sfb + sfboffs] < sfbThresholdLeft[sfb + sfboffs]) && + (fMult(FL2FXCONST_DBL(1.0f / 1.5f), sfbEnergyRight[sfb + sfboffs]) > + sfbThresholdRight[sfb + sfboffs])) { continue; } /* NEW: if there is a big-enough IS region, switch off PNS */ if (pnsData[0]) { - if(pnsData[0]->pnsFlag[sfb+sfboffs]) { - pnsData[0]->pnsFlag[sfb+sfboffs] = 0; + if (pnsData[0]->pnsFlag[sfb + sfboffs]) { + pnsData[0]->pnsFlag[sfb + sfboffs] = 0; } - if(pnsData[1]->pnsFlag[sfb+sfboffs]) { - pnsData[1]->pnsFlag[sfb+sfboffs] = 0; + if (pnsData[1]->pnsFlag[sfb + sfboffs]) { + pnsData[1]->pnsFlag[sfb + sfboffs] = 0; } } - inv_n = GetInvInt((sfbOffset[sfb + sfboffs + 1] - sfbOffset[sfb + sfboffs])>>1); // scaled with 2 to compensate fMultDiv2() in subsequent loop - sL = calcSfbMaxScale(mdctSpectrumLeft,sfbOffset[sfb+sfboffs],sfbOffset[sfb+sfboffs+1]); - sR = calcSfbMaxScale(mdctSpectrumRight,sfbOffset[sfb+sfboffs],sfbOffset[sfb+sfboffs+1]); + inv_n = GetInvInt( + (sfbOffset[sfb + sfboffs + 1] - sfbOffset[sfb + sfboffs]) >> + 1); // scaled with 2 to compensate fMultDiv2() in subsequent loop + sL = calcSfbMaxScale(mdctSpectrumLeft, sfbOffset[sfb + sfboffs], + sfbOffset[sfb + sfboffs + 1]); + sR = calcSfbMaxScale(mdctSpectrumRight, sfbOffset[sfb + sfboffs], + sfbOffset[sfb + sfboffs + 1]); lr = FL2FXCONST_DBL(0.0f); - for (j=sfbOffset[sfb+sfboffs]; j>1) - ((mdctSpectrumRight[j]<>1); - ed += fMultDiv2(d,d)>>(MDCT_SPEC_SF-1); + s0 = fixMin(sL, sR); + for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; + j++) { + d = ((mdctSpectrumLeft[j] << s0) >> 1) - + ((mdctSpectrumRight[j] << s0) >> 1); + ed += fMultDiv2(d, d) >> (MDCT_SPEC_SF - 1); } - msMask[sfb+sfboffs] = 1; - tmp = fDivNorm(sfbEnergyLeft[sfb+sfboffs],ed,&s1); - s2 = (s1) + (2*s0) - 2 - MDCT_SPEC_SF; + msMask[sfb + sfboffs] = 1; + tmp = fDivNorm(sfbEnergyLeft[sfb + sfboffs], ed, &s1); + s2 = (s1) + (2 * s0) - 2 - MDCT_SPEC_SF; if (s2 & 1) { - tmp = tmp>>1; - s2 = s2+1; + tmp = tmp >> 1; + s2 = s2 + 1; } - s2 = (s2>>1) + 1; // +1 compensate fMultDiv2() in subsequent loop - s2 = fixMin(fixMax(s2,-(DFRACT_BITS-1)),(DFRACT_BITS-1)); + s2 = (s2 >> 1) + 1; // +1 compensate fMultDiv2() in subsequent loop + s2 = fixMin(fixMax(s2, -(DFRACT_BITS - 1)), (DFRACT_BITS - 1)); scale = sqrtFixp(tmp); if (s2 < 0) { s2 = -s2; - for (j=sfbOffset[sfb+sfboffs]; j> s2; + for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; + j++) { + mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j], scale) - + fMultDiv2(mdctSpectrumRight[j], scale)) >> + s2; mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f); } - } - else { - for (j=sfbOffset[sfb+sfboffs]; j>1) + ((mdctSpectrumRight[j]<>1); - es += fMultDiv2(s,s)>>(MDCT_SPEC_SF-1); // scaled 2*(mdctScale - s0 + 1) + MDCT_SPEC_SF + s0 = fixMin(sL, sR); + for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; + j++) { + s = ((mdctSpectrumLeft[j] << s0) >> 1) + + ((mdctSpectrumRight[j] << s0) >> 1); + es += fMultDiv2(s, s) >> + (MDCT_SPEC_SF - + 1); // scaled 2*(mdctScale - s0 + 1) + MDCT_SPEC_SF } - msMask[sfb+sfboffs] = 0; - tmp = fDivNorm(sfbEnergyLeft[sfb+sfboffs],es,&s1); - s2 = (s1) + (2*s0) - 2 - MDCT_SPEC_SF; + msMask[sfb + sfboffs] = 0; + tmp = fDivNorm(sfbEnergyLeft[sfb + sfboffs], es, &s1); + s2 = (s1) + (2 * s0) - 2 - MDCT_SPEC_SF; if (s2 & 1) { - tmp = tmp>>1; + tmp = tmp >> 1; s2 = s2 + 1; } - s2 = (s2>>1) + 1; // +1 compensate fMultDiv2() in subsequent loop - s2 = fixMin(fixMax(s2,-(DFRACT_BITS-1)),(DFRACT_BITS-1)); + s2 = (s2 >> 1) + 1; // +1 compensate fMultDiv2() in subsequent loop + s2 = fixMin(fixMax(s2, -(DFRACT_BITS - 1)), (DFRACT_BITS - 1)); scale = sqrtFixp(tmp); if (s2 < 0) { s2 = -s2; - for (j=sfbOffset[sfb+sfboffs]; j> s2; + for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; + j++) { + mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j], scale) + + fMultDiv2(mdctSpectrumRight[j], scale)) >> + s2; mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f); } - } - else { - for (j=sfbOffset[sfb+sfboffs]; j>1)-FL2FXCONST_DBL(0.5f/(1<<(REAL_SCALE_SF+LD_DATA_SHIFT+1))))>>(DFRACT_BITS-1-REAL_SCALE_SF-LD_DATA_SHIFT-1)) + 1; - } - else { - isScale[sfb+sfboffs] = (INT)(((realIsScale[sfb+sfboffs]>>1)+FL2FXCONST_DBL(0.5f/(1<<(REAL_SCALE_SF+LD_DATA_SHIFT+1))))>>(DFRACT_BITS-1-REAL_SCALE_SF-LD_DATA_SHIFT-1)); + isBook[sfb + sfboffs] = CODE_BOOK_IS_IN_PHASE_NO; + + if (realIsScale[sfb + sfboffs] < FL2FXCONST_DBL(0.0f)) { + isScale[sfb + sfboffs] = + (INT)(((realIsScale[sfb + sfboffs] >> 1) - + FL2FXCONST_DBL( + 0.5f / (1 << (REAL_SCALE_SF + LD_DATA_SHIFT + 1)))) >> + (DFRACT_BITS - 1 - REAL_SCALE_SF - LD_DATA_SHIFT - 1)) + + 1; + } else { + isScale[sfb + sfboffs] = + (INT)(((realIsScale[sfb + sfboffs] >> 1) + + FL2FXCONST_DBL( + 0.5f / (1 << (REAL_SCALE_SF + LD_DATA_SHIFT + 1)))) >> + (DFRACT_BITS - 1 - REAL_SCALE_SF - LD_DATA_SHIFT - 1)); } - sfbEnergyRight[sfb+sfboffs] = FL2FXCONST_DBL(0.0f); - sfbEnergyLdDataRight[sfb+sfboffs] = FL2FXCONST_DBL(-1.0f); - sfbThresholdRight[sfb+sfboffs] = FL2FXCONST_DBL(0.0f); - sfbThresholdLdDataRight[sfb+sfboffs] = FL2FXCONST_DBL(-0.515625f); - sfbSpreadEnRight[sfb+sfboffs] = FL2FXCONST_DBL(0.0f); + sfbEnergyRight[sfb + sfboffs] = FL2FXCONST_DBL(0.0f); + sfbEnergyLdDataRight[sfb + sfboffs] = FL2FXCONST_DBL(-1.0f); + sfbThresholdRight[sfb + sfboffs] = FL2FXCONST_DBL(0.0f); + sfbThresholdLdDataRight[sfb + sfboffs] = FL2FXCONST_DBL(-0.515625f); + sfbSpreadEnRight[sfb + sfboffs] = FL2FXCONST_DBL(0.0f); *msDigest = MS_SOME; } } } - diff --git a/libAACenc/src/intensity.h b/libAACenc/src/intensity.h index 2acc292..70f23d5 100644 --- a/libAACenc/src/intensity.h +++ b/libAACenc/src/intensity.h @@ -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,44 +90,32 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: A. Horndasch (code originally from lwr and rtb) / Josef Höpfl (FDK) - contents/description: intensity stereo prototype + Author(s): A. Horndasch (code originally from lwr and rtb) / Josef Hoepfl +(FDK) -******************************************************************************/ + Description: intensity stereo prototype -#ifndef _INTENSITY_H -#define _INTENSITY_H +*******************************************************************************/ -#include "aacenc_pns.h" +#ifndef INTENSITY_H +#define INTENSITY_H +#include "aacenc_pns.h" +#include "common_fix.h" void FDKaacEnc_IntensityStereoProcessing( - FIXP_DBL *sfbEnergyLeft, - FIXP_DBL *sfbEnergyRight, - FIXP_DBL *mdctSpectrumLeft, - FIXP_DBL *mdctSpectrumRight, - FIXP_DBL *sfbThresholdLeft, - FIXP_DBL *sfbThresholdRight, - FIXP_DBL *sfbThresholdLdDataRight, - FIXP_DBL *sfbSpreadEnLeft, - FIXP_DBL *sfbSpreadEnRight, - FIXP_DBL *sfbEnergyLdDataLeft, - FIXP_DBL *sfbEnergyLdDataRight, - INT *msDigest, - INT *msMask, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup, - const INT *sfbOffset, - const INT allowIS, - INT *isBook, - INT *isScale, - PNS_DATA *RESTRICT pnsData[2] - ); - -#endif /* _INTENSITY_H */ - + FIXP_DBL *sfbEnergyLeft, FIXP_DBL *sfbEnergyRight, + FIXP_DBL *mdctSpectrumLeft, FIXP_DBL *mdctSpectrumRight, + FIXP_DBL *sfbThresholdLeft, FIXP_DBL *sfbThresholdRight, + FIXP_DBL *sfbThresholdLdDataRight, FIXP_DBL *sfbSpreadEnLeft, + FIXP_DBL *sfbSpreadEnRight, FIXP_DBL *sfbEnergyLdDataLeft, + FIXP_DBL *sfbEnergyLdDataRight, INT *msDigest, INT *msMask, + const INT sfbCnt, const INT sfbPerGroup, const INT maxSfbPerGroup, + const INT *sfbOffset, const INT allowIS, INT *isBook, INT *isScale, + PNS_DATA *RESTRICT pnsData[2]); + +#endif /* INTENSITY_H */ diff --git a/libAACenc/src/interface.h b/libAACenc/src/interface.h index 51fb72a..b1a31ef 100644 --- a/libAACenc/src/interface.h +++ b/libAACenc/src/interface.h @@ -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,17 +90,18 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Interface psychoaccoustic/quantizer + Description: Interface psychoaccoustic/quantizer -******************************************************************************/ +*******************************************************************************/ -#ifndef _INTERFACE_H -#define _INTERFACE_H +#ifndef INTERFACE_H +#define INTERFACE_H #include "common_fix.h" #include "FDK_audio.h" @@ -97,73 +109,60 @@ amm-info@iis.fraunhofer.de #include "psy_data.h" #include "aacenc_tns.h" -enum -{ - MS_NONE = 0, - MS_SOME = 1, - MS_ALL = 2 -}; +enum { MS_NONE = 0, MS_SOME = 1, MS_ALL = 2 }; -enum -{ - MS_ON = 1 -}; +enum { MS_ON = 1 }; struct TOOLSINFO { - INT msDigest; /* 0 = no MS; 1 = some MS, 2 = all MS */ + INT msDigest; /* 0 = no MS; 1 = some MS, 2 = all MS */ INT msMask[MAX_GROUPED_SFB]; }; - -typedef struct { - INT sfbCnt; - INT sfbPerGroup; - INT maxSfbPerGroup; - INT lastWindowSequence; - INT windowShape; - INT groupingMask; - INT sfbOffsets[MAX_GROUPED_SFB+1]; - - INT mdctScale; /* number of transform shifts */ - INT groupLen[MAX_NO_OF_GROUPS]; - - TNS_INFO tnsInfo; - INT noiseNrg[MAX_GROUPED_SFB]; - INT isBook[MAX_GROUPED_SFB]; - INT isScale[MAX_GROUPED_SFB]; +typedef struct { + INT sfbCnt; + INT sfbPerGroup; + INT maxSfbPerGroup; + INT lastWindowSequence; + INT windowShape; + INT groupingMask; + INT sfbOffsets[MAX_GROUPED_SFB + 1]; + + INT mdctScale; /* number of transform shifts */ + INT groupLen[MAX_NO_OF_GROUPS]; + + TNS_INFO tnsInfo; + INT noiseNrg[MAX_GROUPED_SFB]; + INT isBook[MAX_GROUPED_SFB]; + INT isScale[MAX_GROUPED_SFB]; /* memory located in QC_OUT_CHANNEL */ - FIXP_DBL *mdctSpectrum; - FIXP_DBL *sfbEnergy; - FIXP_DBL *sfbSpreadEnergy; - FIXP_DBL *sfbThresholdLdData; - FIXP_DBL *sfbMinSnrLdData; - FIXP_DBL *sfbEnergyLdData; - + FIXP_DBL *mdctSpectrum; + FIXP_DBL *sfbEnergy; + FIXP_DBL *sfbSpreadEnergy; + FIXP_DBL *sfbThresholdLdData; + FIXP_DBL *sfbMinSnrLdData; + FIXP_DBL *sfbEnergyLdData; - }PSY_OUT_CHANNEL; +} PSY_OUT_CHANNEL; typedef struct { - /* information specific to each channel */ - PSY_OUT_CHANNEL* psyOutChannel[(2)]; + PSY_OUT_CHANNEL *psyOutChannel[(2)]; /* information shared by both channels */ - INT commonWindow; + INT commonWindow; struct TOOLSINFO toolsInfo; } PSY_OUT_ELEMENT; typedef struct { + PSY_OUT_ELEMENT *psyOutElement[((8))]; + PSY_OUT_CHANNEL *pPsyOutChannels[(8)]; - PSY_OUT_ELEMENT* psyOutElement[(8)]; - PSY_OUT_CHANNEL* pPsyOutChannels[(8)]; - -}PSY_OUT; +} PSY_OUT; -inline int isLowDelay( AUDIO_OBJECT_TYPE aot ) -{ - return (aot==AOT_ER_AAC_LD || aot==AOT_ER_AAC_ELD); +inline int isLowDelay(AUDIO_OBJECT_TYPE aot) { + return (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD); } -#endif /* _INTERFACE_H */ +#endif /* INTERFACE_H */ diff --git a/libAACenc/src/line_pe.cpp b/libAACenc/src/line_pe.cpp index f3c0dab..47734e5 100644 --- a/libAACenc/src/line_pe.cpp +++ b/libAACenc/src/line_pe.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,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Werner - Initial author: M. Werner - contents/description: Perceptual entropie module + Description: Perceptual entropie module -******************************************************************************/ +*******************************************************************************/ #include "line_pe.h" #include "sf_estim.h" @@ -94,42 +106,47 @@ amm-info@iis.fraunhofer.de #include "genericStds.h" -static const FIXP_DBL C1LdData = FL2FXCONST_DBL(3.0/LD_DATA_SCALING); /* C1 = 3.0 = log(8.0)/log(2) */ -static const FIXP_DBL C2LdData = FL2FXCONST_DBL(1.3219281/LD_DATA_SCALING); /* C2 = 1.3219281 = log(2.5)/log(2) */ -static const FIXP_DBL C3LdData = FL2FXCONST_DBL(0.5593573); /* 1-C2/C1 */ - +static const FIXP_DBL C1LdData = + FL2FXCONST_DBL(3.0 / LD_DATA_SCALING); /* C1 = 3.0 = log(8.0)/log(2) */ +static const FIXP_DBL C2LdData = FL2FXCONST_DBL( + 1.3219281 / LD_DATA_SCALING); /* C2 = 1.3219281 = log(2.5)/log(2) */ +static const FIXP_DBL C3LdData = FL2FXCONST_DBL(0.5593573); /* 1-C2/C1 */ /* constants that do not change during successive pe calculations */ -void FDKaacEnc_prepareSfbPe(PE_CHANNEL_DATA *peChanData, - const FIXP_DBL *sfbEnergyLdData, - const FIXP_DBL *sfbThresholdLdData, - const FIXP_DBL *sfbFormFactorLdData, - const INT *sfbOffset, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup) -{ - INT sfbGrp,sfb; - INT sfbWidth; - FIXP_DBL avgFormFactorLdData; - const FIXP_DBL formFacScaling = FL2FXCONST_DBL((float)FORM_FAC_SHIFT/LD_DATA_SCALING); - - for (sfbGrp = 0;sfbGrp < sfbCnt;sfbGrp+=sfbPerGroup) { - for (sfb=0; sfb (FIXP_DBL)sfbThresholdLdData[sfbGrp+sfb]) { - sfbWidth = sfbOffset[sfbGrp+sfb+1] - sfbOffset[sfbGrp+sfb]; - /* estimate number of active lines */ - avgFormFactorLdData = ((-sfbEnergyLdData[sfbGrp+sfb]>>1) + (CalcLdInt(sfbWidth)>>1))>>1; - peChanData->sfbNLines[sfbGrp+sfb] = - (INT)CalcInvLdData( (sfbFormFactorLdData[sfbGrp+sfb] + formFacScaling) + avgFormFactorLdData); - /* Make sure sfbNLines is never greater than sfbWidth due to unaccuracies (e.g. sfbEnergyLdData[sfbGrp+sfb] = 0x80000000) */ - peChanData->sfbNLines[sfbGrp+sfb] = fMin(sfbWidth, peChanData->sfbNLines[sfbGrp+sfb]); - } - else { - peChanData->sfbNLines[sfbGrp+sfb] = 0; +void FDKaacEnc_prepareSfbPe(PE_CHANNEL_DATA *RESTRICT const peChanData, + const FIXP_DBL *RESTRICT const sfbEnergyLdData, + const FIXP_DBL *RESTRICT const sfbThresholdLdData, + const FIXP_DBL *RESTRICT const sfbFormFactorLdData, + const INT *RESTRICT const sfbOffset, + const INT sfbCnt, const INT sfbPerGroup, + const INT maxSfbPerGroup) { + INT sfbGrp, sfb; + INT sfbWidth; + FIXP_DBL avgFormFactorLdData; + const FIXP_DBL formFacScaling = + FL2FXCONST_DBL((float)FORM_FAC_SHIFT / LD_DATA_SCALING); + + for (sfbGrp = 0; sfbGrp < sfbCnt; sfbGrp += sfbPerGroup) { + for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { + if ((FIXP_DBL)sfbEnergyLdData[sfbGrp + sfb] > + (FIXP_DBL)sfbThresholdLdData[sfbGrp + sfb]) { + sfbWidth = sfbOffset[sfbGrp + sfb + 1] - sfbOffset[sfbGrp + sfb]; + /* estimate number of active lines */ + avgFormFactorLdData = ((-sfbEnergyLdData[sfbGrp + sfb] >> 1) + + (CalcLdInt(sfbWidth) >> 1)) >> + 1; + peChanData->sfbNLines[sfbGrp + sfb] = (INT)CalcInvLdData( + (sfbFormFactorLdData[sfbGrp + sfb] + formFacScaling) + + avgFormFactorLdData); + /* Make sure sfbNLines is never greater than sfbWidth due to + * unaccuracies (e.g. sfbEnergyLdData[sfbGrp+sfb] = 0x80000000) */ + peChanData->sfbNLines[sfbGrp + sfb] = + fMin(sfbWidth, peChanData->sfbNLines[sfbGrp + sfb]); + } else { + peChanData->sfbNLines[sfbGrp + sfb] = 0; } } - } + } } /* @@ -141,69 +158,77 @@ void FDKaacEnc_prepareSfbPe(PE_CHANNEL_DATA *peChanData, constPart is sfbPe without the threshold part n*ld(thr) or n*C3*ld(thr) */ -void FDKaacEnc_calcSfbPe(PE_CHANNEL_DATA *RESTRICT peChanData, - const FIXP_DBL *RESTRICT sfbEnergyLdData, - const FIXP_DBL *RESTRICT sfbThresholdLdData, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup, - const INT *isBook, - const INT *isScale) -{ - INT sfbGrp,sfb; - INT nLines; - FIXP_DBL logDataRatio; - INT lastValIs = 0; - - peChanData->pe = 0; - peChanData->constPart = 0; - peChanData->nActiveLines = 0; - - for(sfbGrp = 0;sfbGrp < sfbCnt;sfbGrp+=sfbPerGroup){ - for (sfb=0; sfb (FIXP_DBL)sfbThresholdLdData[sfbGrp+sfb]) { - logDataRatio = (FIXP_DBL)(sfbEnergyLdData[sfbGrp+sfb] - sfbThresholdLdData[sfbGrp+sfb]); - nLines = peChanData->sfbNLines[sfbGrp+sfb]; - if (logDataRatio >= C1LdData) { - /* scale sfbPe and sfbConstPart with PE_CONSTPART_SHIFT */ - peChanData->sfbPe[sfbGrp+sfb] = fMultDiv2(logDataRatio, (FIXP_DBL)(nLines<<(LD_DATA_SHIFT+PE_CONSTPART_SHIFT+1))); - peChanData->sfbConstPart[sfbGrp+sfb] = - fMultDiv2(sfbEnergyLdData[sfbGrp+sfb], (FIXP_DBL)(nLines<<(LD_DATA_SHIFT+PE_CONSTPART_SHIFT+1))); ; - - } - else { - /* scale sfbPe and sfbConstPart with PE_CONSTPART_SHIFT */ - peChanData->sfbPe[sfbGrp+sfb] = - fMultDiv2(((FIXP_DBL)C2LdData + fMult(C3LdData,logDataRatio)), (FIXP_DBL)(nLines<<(LD_DATA_SHIFT+PE_CONSTPART_SHIFT+1))); - - peChanData->sfbConstPart[sfbGrp+sfb] = - fMultDiv2(((FIXP_DBL)C2LdData + fMult(C3LdData,sfbEnergyLdData[sfbGrp+sfb])), - (FIXP_DBL)(nLines<<(LD_DATA_SHIFT+PE_CONSTPART_SHIFT+1))) ; - - nLines = fMultI(C3LdData, nLines); - } - peChanData->sfbNActiveLines[sfbGrp+sfb] = nLines; - } - else if( isBook[sfbGrp+sfb] ) { +void FDKaacEnc_calcSfbPe(PE_CHANNEL_DATA *RESTRICT const peChanData, + const FIXP_DBL *RESTRICT const sfbEnergyLdData, + const FIXP_DBL *RESTRICT const sfbThresholdLdData, + const INT sfbCnt, const INT sfbPerGroup, + const INT maxSfbPerGroup, + const INT *RESTRICT const isBook, + const INT *RESTRICT const isScale) { + INT sfbGrp, sfb, thisSfb; + INT nLines; + FIXP_DBL logDataRatio; + FIXP_DBL scaleLd = (FIXP_DBL)0; + INT lastValIs = 0; + + FIXP_DBL pe = 0; + FIXP_DBL constPart = 0; + FIXP_DBL nActiveLines = 0; + + FIXP_DBL tmpPe, tmpConstPart, tmpNActiveLines; + + for (sfbGrp = 0; sfbGrp < sfbCnt; sfbGrp += sfbPerGroup) { + for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { + tmpPe = (FIXP_DBL)0; + tmpConstPart = (FIXP_DBL)0; + tmpNActiveLines = (FIXP_DBL)0; + + thisSfb = sfbGrp + sfb; + + if (sfbEnergyLdData[thisSfb] > sfbThresholdLdData[thisSfb]) { + logDataRatio = sfbEnergyLdData[thisSfb] - sfbThresholdLdData[thisSfb]; + nLines = peChanData->sfbNLines[thisSfb]; + + FIXP_DBL factor = nLines << (LD_DATA_SHIFT + PE_CONSTPART_SHIFT + 1); + if (logDataRatio >= C1LdData) { + /* scale sfbPe and sfbConstPart with PE_CONSTPART_SHIFT */ + tmpPe = fMultDiv2(logDataRatio, factor); + tmpConstPart = fMultDiv2(sfbEnergyLdData[thisSfb] + scaleLd, factor); + } else { + /* scale sfbPe and sfbConstPart with PE_CONSTPART_SHIFT */ + tmpPe = fMultDiv2( + ((FIXP_DBL)C2LdData + fMult(C3LdData, logDataRatio)), factor); + tmpConstPart = + fMultDiv2(((FIXP_DBL)C2LdData + + fMult(C3LdData, sfbEnergyLdData[thisSfb] + scaleLd)), + factor); + + nLines = fMultI(C3LdData, nLines); + } + tmpNActiveLines = (FIXP_DBL)nLines; + } else if (isBook[thisSfb]) { /* provide for cost of scale factor for Intensity */ - INT delta = isScale[sfbGrp+sfb] - lastValIs; - lastValIs = isScale[sfbGrp+sfb]; - peChanData->sfbPe[sfbGrp+sfb] = FDKaacEnc_bitCountScalefactorDelta(delta)<sfbConstPart[sfbGrp+sfb] = 0; - peChanData->sfbNActiveLines[sfbGrp+sfb] = 0; - } - else { - peChanData->sfbPe[sfbGrp+sfb] = 0; - peChanData->sfbConstPart[sfbGrp+sfb] = 0; - peChanData->sfbNActiveLines[sfbGrp+sfb] = 0; + INT delta = isScale[thisSfb] - lastValIs; + lastValIs = isScale[thisSfb]; + peChanData->sfbPe[thisSfb] = FDKaacEnc_bitCountScalefactorDelta(delta) + << PE_CONSTPART_SHIFT; + peChanData->sfbConstPart[thisSfb] = 0; + peChanData->sfbNActiveLines[thisSfb] = 0; } + peChanData->sfbPe[thisSfb] = tmpPe; + peChanData->sfbConstPart[thisSfb] = tmpConstPart; + peChanData->sfbNActiveLines[thisSfb] = tmpNActiveLines; + /* sum up peChanData values */ - peChanData->pe += peChanData->sfbPe[sfbGrp+sfb]; - peChanData->constPart += peChanData->sfbConstPart[sfbGrp+sfb]; - peChanData->nActiveLines += peChanData->sfbNActiveLines[sfbGrp+sfb]; + pe += tmpPe; + constPart += tmpConstPart; + nActiveLines += tmpNActiveLines; } - } - /* correct scaled pe and constPart values */ - peChanData->pe>>=PE_CONSTPART_SHIFT; - peChanData->constPart>>=PE_CONSTPART_SHIFT; + } + + /* correct scaled pe and constPart values */ + peChanData->pe = pe >> PE_CONSTPART_SHIFT; + peChanData->constPart = constPart >> PE_CONSTPART_SHIFT; + + peChanData->nActiveLines = nActiveLines; } diff --git a/libAACenc/src/line_pe.h b/libAACenc/src/line_pe.h index 3d5cfd5..ecc2388 100644 --- a/libAACenc/src/line_pe.h +++ b/libAACenc/src/line_pe.h @@ -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,61 +90,59 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Werner - Initial author: M. Werner - contents/description: Perceptual entropie module + Description: Perceptual entropie module -******************************************************************************/ -#ifndef __LINE_PE_H -#define __LINE_PE_H +*******************************************************************************/ +#ifndef LINE_PE_H +#define LINE_PE_H #include "common_fix.h" #include "psy_const.h" -#define PE_CONSTPART_SHIFT FRACT_BITS +#define PE_CONSTPART_SHIFT FRACT_BITS typedef struct { - /* calculated by FDKaacEnc_prepareSfbPe */ - INT sfbNLines[MAX_GROUPED_SFB]; /* number of relevant lines in sfb */ - /* the rest is calculated by FDKaacEnc_calcSfbPe */ - INT sfbPe[MAX_GROUPED_SFB]; /* pe for each sfb */ - INT sfbConstPart[MAX_GROUPED_SFB]; /* constant part for each sfb */ - INT sfbNActiveLines[MAX_GROUPED_SFB]; /* number of active lines in sfb */ - INT pe; /* sum of sfbPe */ - INT constPart; /* sum of sfbConstPart */ - INT nActiveLines; /* sum of sfbNActiveLines */ + /* calculated by FDKaacEnc_prepareSfbPe */ + INT sfbNLines[MAX_GROUPED_SFB]; /* number of relevant lines in sfb */ + /* the rest is calculated by FDKaacEnc_calcSfbPe */ + INT sfbPe[MAX_GROUPED_SFB]; /* pe for each sfb */ + INT sfbConstPart[MAX_GROUPED_SFB]; /* constant part for each sfb */ + INT sfbNActiveLines[MAX_GROUPED_SFB]; /* number of active lines in sfb */ + INT pe; /* sum of sfbPe */ + INT constPart; /* sum of sfbConstPart */ + INT nActiveLines; /* sum of sfbNActiveLines */ } PE_CHANNEL_DATA; typedef struct { - PE_CHANNEL_DATA peChannelData[(2)]; - INT pe; - INT constPart; - INT nActiveLines; - INT offset; + PE_CHANNEL_DATA peChannelData[(2)]; + INT pe; + INT constPart; + INT nActiveLines; + INT offset; } PE_DATA; - -void FDKaacEnc_prepareSfbPe(PE_CHANNEL_DATA *peChanData, - const FIXP_DBL *sfbEnergyLdData, - const FIXP_DBL *sfbThresholdLdData, - const FIXP_DBL *sfbFormFactorLdData, - const INT *sfbOffset, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup); - -void FDKaacEnc_calcSfbPe(PE_CHANNEL_DATA *RESTRICT peChanData, - const FIXP_DBL *RESTRICT sfbEnergyLdData, - const FIXP_DBL *RESTRICT sfbThresholdLdData, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup, - const INT *isBook, - const INT *isScale); +void FDKaacEnc_prepareSfbPe(PE_CHANNEL_DATA *RESTRICT const peChanData, + const FIXP_DBL *RESTRICT const sfbEnergyLdData, + const FIXP_DBL *RESTRICT const sfbThresholdLdData, + const FIXP_DBL *RESTRICT const sfbFormFactorLdData, + const INT *RESTRICT const sfbOffset, + const INT sfbCnt, const INT sfbPerGroup, + const INT maxSfbPerGroup); + +void FDKaacEnc_calcSfbPe(PE_CHANNEL_DATA *RESTRICT const peChanData, + const FIXP_DBL *RESTRICT const sfbEnergyLdData, + const FIXP_DBL *RESTRICT const sfbThresholdLdData, + const INT sfbCnt, const INT sfbPerGroup, + const INT maxSfbPerGroup, + const INT *RESTRICT const isBook, + const INT *RESTRICT const isScale); #endif diff --git a/libAACenc/src/metadata_compressor.cpp b/libAACenc/src/metadata_compressor.cpp index 68a64ae..bdac80a 100644 --- a/libAACenc/src/metadata_compressor.cpp +++ b/libAACenc/src/metadata_compressor.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,39 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/********************** Fraunhofer IIS FDK AAC Encoder lib ****************** +/**************************** AAC encoder library ****************************** - Author(s): M. Neusinger - Description: Compressor for AAC Metadata Generator + Author(s): M. Neusinger -******************************************************************************/ + Description: Compressor for AAC Metadata Generator +*******************************************************************************/ #include "metadata_compressor.h" #include "channel_map.h" - -#define LOG2 0.69314718056f /* natural logarithm of 2 */ -#define ILOG2 1.442695041f /* 1/LOG2 */ -#define FIXP_ILOG2_DIV2 (FL2FXCONST_DBL(ILOG2/2)) +#define LOG2 0.69314718056f /* natural logarithm of 2 */ +#define ILOG2 1.442695041f /* 1/LOG2 */ +#define FIXP_ILOG2_DIV2 (FL2FXCONST_DBL(ILOG2 / 2)) /*----------------- defines ----------------------*/ -#define MAX_DRC_CHANNELS (8) /*!< Max number of audio input channels. */ -#define DOWNMIX_SHIFT (3) /*!< Max 8 channel. */ -#define WEIGHTING_FILTER_SHIFT (2) /*!< Scaling used in weighting filter. */ +#define MAX_DRC_CHANNELS (8) /*!< Max number of audio input channels. */ +#define DOWNMIX_SHIFT (3) /*!< Max 8 channel. */ +#define WEIGHTING_FILTER_SHIFT (2) /*!< Scaling used in weighting filter. */ -#define METADATA_INT_BITS 10 -#define METADATA_LINT_BITS 20 -#define METADATA_INT_SCALE (INT64(1)<<(METADATA_INT_BITS)) -#define METADATA_FRACT_BITS (DFRACT_BITS-1-METADATA_INT_BITS) -#define METADATA_FRACT_SCALE (INT64(1)<<(METADATA_FRACT_BITS)) +#define METADATA_INT_BITS 10 +#define METADATA_LINT_BITS 20 +#define METADATA_INT_SCALE (INT64(1) << (METADATA_INT_BITS)) +#define METADATA_FRACT_BITS (DFRACT_BITS - 1 - METADATA_INT_BITS) +#define METADATA_FRACT_SCALE (INT64(1) << (METADATA_FRACT_BITS)) /** * Enum for channel assignment. */ -enum { - L = 0, - R = 1, - C = 2, - LFE = 3, - LS = 4, - RS = 5, - S = 6, - LS2 = 7, - RS2 = 8 -}; +enum { L = 0, R = 1, C = 2, LFE = 3, LS = 4, RS = 5, S = 6, LS2 = 7, RS2 = 8 }; /*--------------- structure definitions --------------------*/ @@ -130,61 +130,62 @@ enum { * Structure holds weighting filter filter states. */ struct WEIGHTING_STATES { - FIXP_DBL x1; - FIXP_DBL x2; - FIXP_DBL y1; - FIXP_DBL y2; + FIXP_DBL x1; + FIXP_DBL x2; + FIXP_DBL y1; + FIXP_DBL y2; }; /** * Dynamic Range Control compressor structure. */ struct DRC_COMP { - - FIXP_DBL maxBoostThr[2]; /*!< Max boost threshold. */ - FIXP_DBL boostThr[2]; /*!< Boost threshold. */ - FIXP_DBL earlyCutThr[2]; /*!< Early cut threshold. */ - FIXP_DBL cutThr[2]; /*!< Cut threshold. */ - FIXP_DBL maxCutThr[2]; /*!< Max cut threshold. */ - - FIXP_DBL boostFac[2]; /*!< Precalculated factor for boost compression. */ - FIXP_DBL earlyCutFac[2]; /*!< Precalculated factor for early cut compression. */ - FIXP_DBL cutFac[2]; /*!< Precalculated factor for cut compression. */ - - FIXP_DBL maxBoost[2]; /*!< Maximum boost. */ - FIXP_DBL maxCut[2]; /*!< Maximum cut. */ - FIXP_DBL maxEarlyCut[2]; /*!< Maximum early cut. */ - - FIXP_DBL fastAttack[2]; /*!< Fast attack coefficient. */ - FIXP_DBL fastDecay[2]; /*!< Fast release coefficient. */ - FIXP_DBL slowAttack[2]; /*!< Slow attack coefficient. */ - FIXP_DBL slowDecay[2]; /*!< Slow release coefficient. */ - UINT holdOff[2]; /*!< Hold time in blocks. */ - - FIXP_DBL attackThr[2]; /*!< Slow/fast attack threshold. */ - FIXP_DBL decayThr[2]; /*!< Slow/fast release threshold. */ - - DRC_PROFILE profile[2]; /*!< DRC profile. */ - INT blockLength; /*!< Block length in samples. */ - UINT sampleRate; /*!< Sample rate. */ - CHANNEL_MODE chanConfig; /*!< Channel configuration. */ - - UCHAR useWeighting; /*!< Use weighting filter. */ - - UINT channels; /*!< Number of channels. */ - UINT fullChannels; /*!< Number of full range channels. */ - INT channelIdx[9]; /*!< Offsets of interleaved channel samples (L, R, C, LFE, Ls, Rs, S, Ls2, Rs2). */ - - FIXP_DBL smoothLevel[2]; /*!< level smoothing states */ - FIXP_DBL smoothGain[2]; /*!< gain smoothing states */ - UINT holdCnt[2]; /*!< hold counter */ - - FIXP_DBL limGain[2]; /*!< limiter gain */ - FIXP_DBL limDecay; /*!< limiter decay (linear) */ - FIXP_DBL prevPeak[2]; /*!< max peak of previous block (stereo/mono)*/ - - WEIGHTING_STATES filter[MAX_DRC_CHANNELS]; /*!< array holds weighting filter states */ - + FIXP_DBL maxBoostThr[2]; /*!< Max boost threshold. */ + FIXP_DBL boostThr[2]; /*!< Boost threshold. */ + FIXP_DBL earlyCutThr[2]; /*!< Early cut threshold. */ + FIXP_DBL cutThr[2]; /*!< Cut threshold. */ + FIXP_DBL maxCutThr[2]; /*!< Max cut threshold. */ + + FIXP_DBL boostFac[2]; /*!< Precalculated factor for boost compression. */ + FIXP_DBL + earlyCutFac[2]; /*!< Precalculated factor for early cut compression. */ + FIXP_DBL cutFac[2]; /*!< Precalculated factor for cut compression. */ + + FIXP_DBL maxBoost[2]; /*!< Maximum boost. */ + FIXP_DBL maxCut[2]; /*!< Maximum cut. */ + FIXP_DBL maxEarlyCut[2]; /*!< Maximum early cut. */ + + FIXP_DBL fastAttack[2]; /*!< Fast attack coefficient. */ + FIXP_DBL fastDecay[2]; /*!< Fast release coefficient. */ + FIXP_DBL slowAttack[2]; /*!< Slow attack coefficient. */ + FIXP_DBL slowDecay[2]; /*!< Slow release coefficient. */ + UINT holdOff[2]; /*!< Hold time in blocks. */ + + FIXP_DBL attackThr[2]; /*!< Slow/fast attack threshold. */ + FIXP_DBL decayThr[2]; /*!< Slow/fast release threshold. */ + + DRC_PROFILE profile[2]; /*!< DRC profile. */ + INT blockLength; /*!< Block length in samples. */ + UINT sampleRate; /*!< Sample rate. */ + CHANNEL_MODE chanConfig; /*!< Channel configuration. */ + + UCHAR useWeighting; /*!< Use weighting filter. */ + + UINT channels; /*!< Number of channels. */ + UINT fullChannels; /*!< Number of full range channels. */ + INT channelIdx[9]; /*!< Offsets of interleaved channel samples (L, R, C, LFE, + Ls, Rs, S, Ls2, Rs2). */ + + FIXP_DBL smoothLevel[2]; /*!< level smoothing states */ + FIXP_DBL smoothGain[2]; /*!< gain smoothing states */ + UINT holdCnt[2]; /*!< hold counter */ + + FIXP_DBL limGain[2]; /*!< limiter gain */ + FIXP_DBL limDecay; /*!< limiter decay (linear) */ + FIXP_DBL prevPeak[2]; /*!< max peak of previous block (stereo/mono)*/ + + WEIGHTING_STATES + filter[MAX_DRC_CHANNELS]; /*!< array holds weighting filter states */ }; /*---------------- constants -----------------------*/ @@ -193,143 +194,110 @@ struct DRC_COMP { * Profile tables. */ static const FIXP_DBL tabMaxBoostThr[] = { - (FIXP_DBL)(int)((unsigned)-43<blockLength; i++) { + const INT_PCM* pSamples = &inSamples[i * drcComp->channels]; + + /* single channels */ + for (c = 0; c < (int)drcComp->channels; c++) { + maxSample = fMax(maxSample, (INT_PCM)fAbs(pSamples[c])); } + } + peak[0] = fixMax(peak[0], FX_PCM2FX_DBL(maxSample) >> DOWNMIX_SHIFT); + + /* 7.1/6.1 to 5.1 downmixes */ + if (drcComp->fullChannels > 5) { + for (i = 0; i < drcComp->blockLength; i++) { + const INT_PCM* pSamples = &inSamples[i * drcComp->channels]; + + /* channel 1 (L, Ls,...) */ + tmp = FL2FXCONST_DBL(0.f); + switch (drcComp->chanConfig) { + case MODE_6_1: + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >> + (DOWNMIX_SHIFT - 1); /* Cs */ + break; + case MODE_7_1_BACK: + case MODE_7_1_REAR_SURROUND: + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lrs / Lss */ + break; + case MODE_1_2_2_2_1: + case MODE_7_1_FRONT_CENTER: + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> + DOWNMIX_SHIFT); /* L */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lc */ + break; + case MODE_7_1_TOP_FRONT: + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> + (DOWNMIX_SHIFT - 1); /* L */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lvh */ + break; + default: + break; + } + peak[0] = fixMax(peak[0], fixp_abs(tmp)); + + /* channel 2 (R, Rs,...) */ + tmp = FL2FXCONST_DBL(0.f); + switch (drcComp->chanConfig) { + case MODE_6_1: + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >> + (DOWNMIX_SHIFT - 1); /* Cs */ + break; + case MODE_7_1_BACK: + case MODE_7_1_REAR_SURROUND: + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rrs / Rss */ + break; + case MODE_1_2_2_2_1: + case MODE_7_1_FRONT_CENTER: + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> + DOWNMIX_SHIFT); /* R */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rc */ + break; + case MODE_7_1_TOP_FRONT: + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> + (DOWNMIX_SHIFT - 1); /* R */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rvh */ + break; + default: + break; + } + peak[0] = fixMax(peak[0], fixp_abs(tmp)); + + /* channel 3 (C) */ + tmp = FL2FXCONST_DBL(0.f); + switch (drcComp->chanConfig) { + case MODE_1_2_2_2_1: + case MODE_7_1_FRONT_CENTER: + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + DOWNMIX_SHIFT); /* C */ + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lc */ + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rc */ + break; + default: + break; + } + peak[0] = fixMax(peak[0], fixp_abs(tmp)); - /* allocate memory */ - hDcComp = (HDRC_COMP)FDKcalloc(1, sizeof(DRC_COMP)); + } /* for (blocklength) */ - if (hDcComp == NULL) { - err = -1; - goto bail; + /* take downmix gain into accout */ + peak[0] = fMult(dmxGain5, peak[0]) + << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + + /* 7.1 / 5.1 to stereo downmixes */ + if (drcComp->fullChannels > 2) { + /* Lt/Rt downmix */ + for (i = 0; i < drcComp->blockLength; i++) { + const INT_PCM* pSamples = &inSamples[i * drcComp->channels]; + + /* Lt */ + tmp = FL2FXCONST_DBL(0.f); + if (drcComp->channelIdx[LS] >= 0) + tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + if (drcComp->channelIdx[LS2] >= 0) + tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >> + (DOWNMIX_SHIFT - 1); /* Ls2 */ + if (drcComp->channelIdx[RS] >= 0) + tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + if (drcComp->channelIdx[RS2] >= 0) + tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >> + (DOWNMIX_SHIFT - 1); /* Rs2 */ + if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) + tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ + if (drcComp->channelIdx[S] >= 0) + tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[S]]) >> + (DOWNMIX_SHIFT - 1); /* S */ + if (drcComp->channelIdx[C] >= 0) + tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >> + DOWNMIX_SHIFT); /* L */ + + /* apply scaling of downmix gains */ + /* only for positive values only, as legacy decoders might not know this + * parameter */ + if (dmxGain2 > FL2FXCONST_DBL(0.f)) { + if (drcComp->fullChannels > 5) { + tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + peak[0] = fixMax(peak[0], fixp_abs(tmp)); + + /* Rt */ + tmp = FL2FXCONST_DBL(0.f); + if (drcComp->channelIdx[LS] >= 0) + tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + if (drcComp->channelIdx[LS2] >= 0) + tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >> + (DOWNMIX_SHIFT - 1); /* Ls2 */ + if (drcComp->channelIdx[RS] >= 0) + tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + if (drcComp->channelIdx[RS2] >= 0) + tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >> + (DOWNMIX_SHIFT - 1); /* Rs2 */ + if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) + tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ + if (drcComp->channelIdx[S] >= 0) + tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[S]]) >> + (DOWNMIX_SHIFT - 1); /* S */ + if (drcComp->channelIdx[C] >= 0) + tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >> + DOWNMIX_SHIFT); /* R */ + + /* apply scaling of downmix gains */ + /* only for positive values only, as legacy decoders might not know this + * parameter */ + if (dmxGain2 > FL2FXCONST_DBL(0.f)) { + if (drcComp->fullChannels > 5) { + tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + peak[0] = fixMax(peak[0], fixp_abs(tmp)); } - FDKmemclear(hDcComp, sizeof(DRC_COMP)); + /* Lo/Ro downmix */ + for (i = 0; i < drcComp->blockLength; i++) { + const INT_PCM* pSamples = &inSamples[i * drcComp->channels]; + + /* Lo */ + tmp = FL2FXCONST_DBL(0.f); + switch (drcComp->chanConfig) { + case MODE_6_1: + tmp += fMultDiv2(fMult(slev, ext_leva), + (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + tmp += fMultDiv2(fMult(slev, ext_levb), + (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >> + (DOWNMIX_SHIFT - 1); /* Cs */ + tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> + DOWNMIX_SHIFT); /* L */ + tmp += + fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + case MODE_7_1_BACK: + case MODE_7_1_REAR_SURROUND: + tmp += fMultDiv2(fMult(slev, ext_leva), + (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + tmp += fMultDiv2(fMult(slev, ext_levb), + (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lrs / Lss*/ + tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> + DOWNMIX_SHIFT); /* L */ + tmp += + fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + case MODE_1_2_2_2_1: + case MODE_7_1_FRONT_CENTER: + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> + DOWNMIX_SHIFT); /* L */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lc */ + tmp += fMultDiv2(fMult(ext_leva, clev), + (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lc - second path*/ + tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + tmp += + fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + case MODE_7_1_TOP_FRONT: + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> + (DOWNMIX_SHIFT - 1); /* L */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lvh */ + tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + tmp += + fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + default: + if (drcComp->channelIdx[LS] >= 0) + tmp += + fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + if (drcComp->channelIdx[LS2] >= 0) + tmp += + fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >> + (DOWNMIX_SHIFT - 1); /* Ls2 */ + if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) + tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ + if (drcComp->channelIdx[S] >= 0) + tmp += + fMultDiv2(slev, + fMult(FL2FXCONST_DBL(0.7f), + (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >> + (DOWNMIX_SHIFT - 1); /* S */ + if (drcComp->channelIdx[C] >= 0) + tmp += + fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + if (drcComp->channelIdx[3] >= 0) + tmp += fMultDiv2(lfe_lev, + (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >> + DOWNMIX_SHIFT); /* L */ + break; + } - /* Return drc compressor instance */ - *phDrcComp = hDcComp; - return err; -bail: - FDK_DRC_Generator_Close(&hDcComp); - return err; -} + /* apply scaling of downmix gains */ + /* only for positive values only, as legacy decoders might not know this + * parameter */ + if (dmxGain2 > FL2FXCONST_DBL(0.f)) { + if (drcComp->fullChannels > 5) { + tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + peak[0] = fixMax(peak[0], fixp_abs(tmp)); + + /* Ro */ + tmp = FL2FXCONST_DBL(0.f); + switch (drcComp->chanConfig) { + case MODE_6_1: + tmp += fMultDiv2(fMult(slev, ext_leva), + (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + tmp += fMultDiv2(fMult(slev, ext_levb), + (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >> + (DOWNMIX_SHIFT - 1); /* Cs */ + tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> + DOWNMIX_SHIFT); /* R */ + tmp += + fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + case MODE_7_1_BACK: + case MODE_7_1_REAR_SURROUND: + tmp += fMultDiv2(fMult(slev, ext_leva), + (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + tmp += fMultDiv2(fMult(slev, ext_levb), + (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rrs / Rss*/ + tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> + DOWNMIX_SHIFT); /* R */ + tmp += + fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + case MODE_1_2_2_2_1: + case MODE_7_1_FRONT_CENTER: + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> + DOWNMIX_SHIFT); /* R */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rc */ + tmp += fMultDiv2(fMult(ext_leva, clev), + (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rc - second path*/ + tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + tmp += + fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + case MODE_7_1_TOP_FRONT: + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> + (DOWNMIX_SHIFT - 1); /* R */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rvh */ + tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + tmp += + fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + default: + if (drcComp->channelIdx[RS] >= 0) + tmp += + fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + if (drcComp->channelIdx[RS2] >= 0) + tmp += + fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >> + (DOWNMIX_SHIFT - 1); /* Rs2 */ + if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) + tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ + if (drcComp->channelIdx[S] >= 0) + tmp += + fMultDiv2(slev, + fMult(FL2FXCONST_DBL(0.7f), + (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >> + (DOWNMIX_SHIFT - 1); /* S */ + if (drcComp->channelIdx[C] >= 0) + tmp += + fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + if (drcComp->channelIdx[3] >= 0) + tmp += fMultDiv2(lfe_lev, + (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >> + DOWNMIX_SHIFT); /* R */ + } -INT FDK_DRC_Generator_Close( - HDRC_COMP *phDrcComp - ) -{ - if (phDrcComp == NULL) { - return -1; + /* apply scaling of downmix gains */ + /* only for positive values only, as legacy decoders might not know this + * parameter */ + if (dmxGain2 > FL2FXCONST_DBL(0.f)) { + if (drcComp->fullChannels > 5) { + tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + peak[0] = fixMax(peak[0], fixp_abs(tmp)); } - if (*phDrcComp != NULL) { - FDKfree(*phDrcComp); - *phDrcComp = NULL; + } + + peak[1] = fixMax(peak[0], peak[1]); + + /* Mono Downmix - for comp_val only */ + if (drcComp->fullChannels > 1) { + for (i = 0; i < drcComp->blockLength; i++) { + const INT_PCM* pSamples = &inSamples[i * drcComp->channels]; + + tmp = FL2FXCONST_DBL(0.f); + switch (drcComp->chanConfig) { + case MODE_6_1: + tmp += fMultDiv2(fMult(slev, ext_leva), + (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + tmp += fMultDiv2(fMult(slev, ext_leva), + (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + tmp += fMult(fMult(slev, ext_levb), + (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >> + (DOWNMIX_SHIFT - 1); /* Cs */ + tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> + DOWNMIX_SHIFT); /* L */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> + DOWNMIX_SHIFT); /* R */ + tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + case MODE_7_1_BACK: + case MODE_7_1_REAR_SURROUND: + tmp += fMultDiv2(fMult(slev, ext_leva), + (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + tmp += fMultDiv2(fMult(slev, ext_leva), + (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + tmp += fMultDiv2(fMult(slev, ext_levb), + (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lrs / Lss*/ + tmp += fMultDiv2(fMult(slev, ext_levb), + (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rrs / Rss*/ + tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> + DOWNMIX_SHIFT); /* L */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> + DOWNMIX_SHIFT); /* R */ + tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + case MODE_1_2_2_2_1: + case MODE_7_1_FRONT_CENTER: + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> + DOWNMIX_SHIFT); /* L */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> + DOWNMIX_SHIFT); /* R */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lc */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rc */ + tmp += fMultDiv2(fMult(ext_leva, clev), + (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lc - second path*/ + tmp += fMultDiv2(fMult(ext_leva, clev), + (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rc - second path*/ + tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + case MODE_7_1_TOP_FRONT: + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> + (DOWNMIX_SHIFT - 1); /* L */ + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> + (DOWNMIX_SHIFT - 1); /* R */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lvh */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rvh */ + tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + default: + if (drcComp->channelIdx[LS] >= 0) + tmp += + fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + if (drcComp->channelIdx[LS2] >= 0) + tmp += + fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >> + (DOWNMIX_SHIFT - 1); /* Ls2 */ + if (drcComp->channelIdx[RS] >= 0) + tmp += + fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + if (drcComp->channelIdx[RS2] >= 0) + tmp += + fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >> + (DOWNMIX_SHIFT - 1); /* Rs2 */ + if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) + tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ + /*if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp *=0.707f;*/ /* 7.1ch */ + if (drcComp->channelIdx[S] >= 0) + tmp += + fMultDiv2(slev, + fMult(FL2FXCONST_DBL(0.7f), + (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >> + (DOWNMIX_SHIFT - 1); /* S */ + if (drcComp->channelIdx[C] >= 0) + tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >> + (DOWNMIX_SHIFT - 1); /* C (2*clev) */ + if (drcComp->channelIdx[3] >= 0) + tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >> + DOWNMIX_SHIFT); /* L */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >> + DOWNMIX_SHIFT); /* R */ + } + + /* apply scaling of downmix gains */ + /* only for positive values only, as legacy decoders might not know this + * parameter */ + if (dmxGain2 > FL2FXCONST_DBL(0.f)) { + if (drcComp->fullChannels > 5) { + tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + peak[1] = fixMax(peak[1], fixp_abs(tmp)); } - return 0; + } } +INT FDK_DRC_Generator_Open(HDRC_COMP* phDrcComp) { + INT err = 0; + HDRC_COMP hDcComp = NULL; -INT FDK_DRC_Generator_Initialize( - HDRC_COMP drcComp, - const DRC_PROFILE profileLine, - const DRC_PROFILE profileRF, - const INT blockLength, - const UINT sampleRate, - const CHANNEL_MODE channelMode, - const CHANNEL_ORDER channelOrder, - const UCHAR useWeighting - ) -{ - int i; - CHANNEL_MAPPING channelMapping; - - drcComp->limDecay = FL2FXCONST_DBL( ((0.006f / 256) * blockLength) / METADATA_INT_SCALE ); - - /* Save parameters. */ - drcComp->blockLength = blockLength; - drcComp->sampleRate = sampleRate; - drcComp->chanConfig = channelMode; - drcComp->useWeighting = useWeighting; - - if (FDK_DRC_Generator_setDrcProfile(drcComp, profileLine, profileRF)!=0) { /* expects initialized blockLength and sampleRate */ - return (-1); - } + if (phDrcComp == NULL) { + err = -1; + goto bail; + } - /* Set number of channels and channel offsets. */ - if (FDKaacEnc_InitChannelMapping(channelMode, channelOrder, &channelMapping)!=AAC_ENC_OK) { - return (-2); - } + /* allocate memory */ + hDcComp = (HDRC_COMP)FDKcalloc(1, sizeof(DRC_COMP)); + + if (hDcComp == NULL) { + err = -1; + goto bail; + } - for (i = 0; i < 9; i++) drcComp->channelIdx[i] = -1; + FDKmemclear(hDcComp, sizeof(DRC_COMP)); - switch (channelMode) { + /* Return drc compressor instance */ + *phDrcComp = hDcComp; + return err; +bail: + FDK_DRC_Generator_Close(&hDcComp); + return err; +} + +INT FDK_DRC_Generator_Close(HDRC_COMP* phDrcComp) { + if (phDrcComp == NULL) { + return -1; + } + if (*phDrcComp != NULL) { + FDKfree(*phDrcComp); + *phDrcComp = NULL; + } + return 0; +} + +INT FDK_DRC_Generator_Initialize(HDRC_COMP drcComp, + const DRC_PROFILE profileLine, + const DRC_PROFILE profileRF, + const INT blockLength, const UINT sampleRate, + const CHANNEL_MODE channelMode, + const CHANNEL_ORDER channelOrder, + const UCHAR useWeighting) { + int i; + CHANNEL_MAPPING channelMapping; + + drcComp->limDecay = + FL2FXCONST_DBL(((0.006f / 256) * blockLength) / METADATA_INT_SCALE); + + /* Save parameters. */ + drcComp->blockLength = blockLength; + drcComp->sampleRate = sampleRate; + drcComp->chanConfig = channelMode; + drcComp->useWeighting = useWeighting; + + if (FDK_DRC_Generator_setDrcProfile(drcComp, profileLine, profileRF) != + 0) { /* expects initialized blockLength and sampleRate */ + return (-1); + } + + /* Set number of channels and channel offsets. */ + if (FDKaacEnc_InitChannelMapping(channelMode, channelOrder, + &channelMapping) != AAC_ENC_OK) { + return (-2); + } + + for (i = 0; i < 9; i++) drcComp->channelIdx[i] = -1; + + switch (channelMode) { case MODE_1: /* mono */ - drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; - break; + drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; + break; case MODE_2: /* stereo */ - drcComp->channelIdx[L] = channelMapping.elInfo[0].ChannelIndex[0]; - drcComp->channelIdx[R] = channelMapping.elInfo[0].ChannelIndex[1]; - break; + drcComp->channelIdx[L] = channelMapping.elInfo[0].ChannelIndex[0]; + drcComp->channelIdx[R] = channelMapping.elInfo[0].ChannelIndex[1]; + break; case MODE_1_2: /* 3ch */ - drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; - drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; - drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; - break; + drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; + drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; + drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; + break; case MODE_1_2_1: /* 4ch */ - drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; - drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; - drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; - drcComp->channelIdx[S] = channelMapping.elInfo[2].ChannelIndex[0]; - break; + drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; + drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; + drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; + drcComp->channelIdx[S] = channelMapping.elInfo[2].ChannelIndex[0]; + break; case MODE_1_2_2: /* 5ch */ - drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; - drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; - drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; - drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0]; - drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1]; - break; - case MODE_1_2_2_1: /* 5.1 ch */ - drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; - drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; - drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; - drcComp->channelIdx[LFE] = channelMapping.elInfo[3].ChannelIndex[0]; - drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0]; - drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1]; - break; + drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; + drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; + drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; + drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0]; + drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1]; + break; + case MODE_1_2_2_1: /* 5.1 ch */ + drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; + drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; + drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; + drcComp->channelIdx[LFE] = channelMapping.elInfo[3].ChannelIndex[0]; + drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0]; + drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1]; + break; case MODE_1_2_2_2_1: /* 7.1 ch */ case MODE_7_1_FRONT_CENTER: - drcComp->channelIdx[L] = channelMapping.elInfo[2].ChannelIndex[0]; /* l */ - drcComp->channelIdx[R] = channelMapping.elInfo[2].ChannelIndex[1]; /* r */ - drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */ - drcComp->channelIdx[LFE] = channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */ - drcComp->channelIdx[LS] = channelMapping.elInfo[3].ChannelIndex[0]; /* ls */ - drcComp->channelIdx[RS] = channelMapping.elInfo[3].ChannelIndex[1]; /* rs */ - drcComp->channelIdx[LS2] = channelMapping.elInfo[1].ChannelIndex[0]; /* lc */ - drcComp->channelIdx[RS2] = channelMapping.elInfo[1].ChannelIndex[1]; /* rc */ - break; + drcComp->channelIdx[L] = channelMapping.elInfo[2].ChannelIndex[0]; /* l */ + drcComp->channelIdx[R] = channelMapping.elInfo[2].ChannelIndex[1]; /* r */ + drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */ + drcComp->channelIdx[LFE] = + channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */ + drcComp->channelIdx[LS] = + channelMapping.elInfo[3].ChannelIndex[0]; /* ls */ + drcComp->channelIdx[RS] = + channelMapping.elInfo[3].ChannelIndex[1]; /* rs */ + drcComp->channelIdx[LS2] = + channelMapping.elInfo[1].ChannelIndex[0]; /* lc */ + drcComp->channelIdx[RS2] = + channelMapping.elInfo[1].ChannelIndex[1]; /* rc */ + break; + case MODE_7_1_BACK: case MODE_7_1_REAR_SURROUND: - drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */ - drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */ - drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */ - drcComp->channelIdx[LFE] = channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */ - drcComp->channelIdx[LS] = channelMapping.elInfo[3].ChannelIndex[0]; /* lrear */ - drcComp->channelIdx[RS] = channelMapping.elInfo[3].ChannelIndex[1]; /* rrear */ - drcComp->channelIdx[LS2] = channelMapping.elInfo[2].ChannelIndex[0]; /* ls */ - drcComp->channelIdx[RS2] = channelMapping.elInfo[2].ChannelIndex[1]; /* rs */ - break; - case MODE_1_1: - case MODE_1_1_1_1: - case MODE_1_1_1_1_1_1: - case MODE_1_1_1_1_1_1_1_1: - case MODE_1_1_1_1_1_1_1_1_1_1_1_1: - case MODE_2_2: - case MODE_2_2_2: - case MODE_2_2_2_2: - case MODE_2_2_2_2_2_2: + drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */ + drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */ + drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */ + drcComp->channelIdx[LFE] = + channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */ + drcComp->channelIdx[LS] = + channelMapping.elInfo[3].ChannelIndex[0]; /* lrear */ + drcComp->channelIdx[RS] = + channelMapping.elInfo[3].ChannelIndex[1]; /* rrear */ + drcComp->channelIdx[LS2] = + channelMapping.elInfo[2].ChannelIndex[0]; /* ls */ + drcComp->channelIdx[RS2] = + channelMapping.elInfo[2].ChannelIndex[1]; /* rs */ + break; + case MODE_6_1: + drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */ + drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */ + drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */ + drcComp->channelIdx[LFE] = + channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */ + drcComp->channelIdx[LS] = + channelMapping.elInfo[2].ChannelIndex[0]; /* ls */ + drcComp->channelIdx[RS] = + channelMapping.elInfo[2].ChannelIndex[1]; /* rs */ + drcComp->channelIdx[S] = channelMapping.elInfo[3].ChannelIndex[0]; /* s */ + break; + case MODE_7_1_TOP_FRONT: + drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */ + drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */ + drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */ + drcComp->channelIdx[LFE] = + channelMapping.elInfo[3].ChannelIndex[0]; /* lfe */ + drcComp->channelIdx[LS] = + channelMapping.elInfo[2].ChannelIndex[0]; /* ls */ + drcComp->channelIdx[RS] = + channelMapping.elInfo[2].ChannelIndex[1]; /* rs */ + drcComp->channelIdx[LS2] = + channelMapping.elInfo[4].ChannelIndex[0]; /* lvh2 */ + drcComp->channelIdx[RS2] = + channelMapping.elInfo[4].ChannelIndex[1]; /* rvh2 */ + break; default: - return (-1); - } + return (-1); + } - drcComp->fullChannels = channelMapping.nChannelsEff; - drcComp->channels = channelMapping.nChannels; + drcComp->fullChannels = channelMapping.nChannelsEff; + drcComp->channels = channelMapping.nChannels; - /* Init states. */ - drcComp->smoothLevel[0] = drcComp->smoothLevel[1] = (FIXP_DBL)(int)((unsigned)-135<smoothLevel[0] = drcComp->smoothLevel[1] = + (FIXP_DBL)(-(135 << METADATA_FRACT_BITS)); - FDKmemclear(drcComp->smoothGain, sizeof(drcComp->smoothGain)); - FDKmemclear(drcComp->holdCnt, sizeof(drcComp->holdCnt)); - FDKmemclear(drcComp->limGain, sizeof(drcComp->limGain)); - FDKmemclear(drcComp->prevPeak, sizeof(drcComp->prevPeak)); - FDKmemclear(drcComp->filter, sizeof(drcComp->filter)); + FDKmemclear(drcComp->smoothGain, sizeof(drcComp->smoothGain)); + FDKmemclear(drcComp->holdCnt, sizeof(drcComp->holdCnt)); + FDKmemclear(drcComp->limGain, sizeof(drcComp->limGain)); + FDKmemclear(drcComp->prevPeak, sizeof(drcComp->prevPeak)); + FDKmemclear(drcComp->filter, sizeof(drcComp->filter)); - return (0); + return (0); } +INT FDK_DRC_Generator_setDrcProfile(HDRC_COMP drcComp, + const DRC_PROFILE profileLine, + const DRC_PROFILE profileRF) { + int profileIdx, i; + + drcComp->profile[0] = profileLine; + drcComp->profile[1] = profileRF; + + for (i = 0; i < 2; i++) { + /* get profile index */ + switch (drcComp->profile[i]) { + case DRC_NONE: + case DRC_NOT_PRESENT: + case DRC_FILMSTANDARD: + profileIdx = 0; + break; + case DRC_FILMLIGHT: + profileIdx = 1; + break; + case DRC_MUSICSTANDARD: + profileIdx = 2; + break; + case DRC_MUSICLIGHT: + profileIdx = 3; + break; + case DRC_SPEECH: + profileIdx = 4; + break; + case DRC_DELAY_TEST: + profileIdx = 5; + break; + default: + return (-1); + } -INT FDK_DRC_Generator_setDrcProfile( - HDRC_COMP drcComp, - const DRC_PROFILE profileLine, - const DRC_PROFILE profileRF - ) -{ - int profileIdx, i; + /* get parameters for selected profile */ + if (profileIdx >= 0) { + drcComp->maxBoostThr[i] = tabMaxBoostThr[profileIdx]; + drcComp->boostThr[i] = tabBoostThr[profileIdx]; + drcComp->earlyCutThr[i] = tabEarlyCutThr[profileIdx]; + drcComp->cutThr[i] = tabCutThr[profileIdx]; + drcComp->maxCutThr[i] = tabMaxCutThr[profileIdx]; + + drcComp->boostFac[i] = tabBoostRatio[profileIdx]; + drcComp->earlyCutFac[i] = tabEarlyCutRatio[profileIdx]; + drcComp->cutFac[i] = tabCutRatio[profileIdx]; + + drcComp->maxBoost[i] = tabMaxBoost[profileIdx]; + drcComp->maxCut[i] = tabMaxCut[profileIdx]; + drcComp->maxEarlyCut[i] = + -fMult((drcComp->cutThr[i] - drcComp->earlyCutThr[i]), + drcComp->earlyCutFac[i]); /* no scaling after mult needed, + earlyCutFac is in FIXP_DBL */ + + drcComp->fastAttack[i] = tc2Coeff( + tabFastAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength); + drcComp->fastDecay[i] = tc2Coeff( + tabFastDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength); + drcComp->slowAttack[i] = tc2Coeff( + tabSlowAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength); + drcComp->slowDecay[i] = tc2Coeff( + tabSlowDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength); + drcComp->holdOff[i] = tabHoldOff[profileIdx] * 256 / drcComp->blockLength; + + drcComp->attackThr[i] = tabAttackThr[profileIdx]; + drcComp->decayThr[i] = tabDecayThr[profileIdx]; + } - drcComp->profile[0] = profileLine; - drcComp->profile[1] = profileRF; + drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f); + } + return (0); +} - for (i = 0; i < 2; i++) { - /* get profile index */ - switch (drcComp->profile[i]) { - case DRC_NONE: - case DRC_FILMSTANDARD: profileIdx = 0; break; - case DRC_FILMLIGHT: profileIdx = 1; break; - case DRC_MUSICSTANDARD: profileIdx = 2; break; - case DRC_MUSICLIGHT: profileIdx = 3; break; - case DRC_SPEECH: profileIdx = 4; break; - case DRC_DELAY_TEST: profileIdx = 5; break; - default: return (-1); - } +INT FDK_DRC_Generator_Calc(HDRC_COMP drcComp, const INT_PCM* const inSamples, + const UINT inSamplesBufSize, const INT dialnorm, + const INT drc_TargetRefLevel, + const INT comp_TargetRefLevel, const FIXP_DBL clev, + const FIXP_DBL slev, const FIXP_DBL ext_leva, + const FIXP_DBL ext_levb, const FIXP_DBL lfe_lev, + const INT dmxGain5, const INT dmxGain2, + INT* const pDynrng, INT* const pCompr) { + int i, c; + FIXP_DBL peak[2]; + + /************************************************************************** + * compressor + **************************************************************************/ + if ((drcComp->profile[0] != DRC_NONE) || (drcComp->profile[1] != DRC_NONE)) { + /* Calc loudness level */ + FIXP_DBL level_b = FL2FXCONST_DBL(0.f); + int level_e = DFRACT_BITS - 1; + + /* Increase energy time resolution with shorter processing blocks. 16 is an + * empiric value. */ + const int granuleLength = fixMin(16, drcComp->blockLength); + + if (drcComp->useWeighting) { + FIXP_DBL x1, x2, y, y1, y2; + /* sum of filter coefficients about 2.5 -> squared value is 6.25 + WEIGHTING_FILTER_SHIFT is 2 -> scaling about 16, therefore reduce + granuleShift by 1. + */ + const int granuleShift = getShiftFactor(granuleLength) - 1; - /* get parameters for selected profile */ - if (profileIdx >= 0) { - drcComp->maxBoostThr[i] = tabMaxBoostThr[profileIdx]; - drcComp->boostThr[i] = tabBoostThr[profileIdx]; - drcComp->earlyCutThr[i] = tabEarlyCutThr[profileIdx]; - drcComp->cutThr[i] = tabCutThr[profileIdx]; - drcComp->maxCutThr[i] = tabMaxCutThr[profileIdx]; - - drcComp->boostFac[i] = tabBoostRatio[profileIdx]; - drcComp->earlyCutFac[i] = tabEarlyCutRatio[profileIdx]; - drcComp->cutFac[i] = tabCutRatio[profileIdx]; - - drcComp->maxBoost[i] = tabMaxBoost[profileIdx]; - drcComp->maxCut[i] = tabMaxCut[profileIdx]; - drcComp->maxEarlyCut[i] = - fMult((drcComp->cutThr[i] - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]); /* no scaling after mult needed, earlyCutFac is in FIXP_DBL */ - - drcComp->fastAttack[i] = tc2Coeff(tabFastAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength); - drcComp->fastDecay[i] = tc2Coeff(tabFastDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength); - drcComp->slowAttack[i] = tc2Coeff(tabSlowAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength); - drcComp->slowDecay[i] = tc2Coeff(tabSlowDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength); - drcComp->holdOff[i] = tabHoldOff[profileIdx] * 256 / drcComp->blockLength; - - drcComp->attackThr[i] = tabAttackThr[profileIdx]; - drcComp->decayThr[i] = tabDecayThr[profileIdx]; + for (c = 0; c < (int)drcComp->channels; c++) { + const INT_PCM* pSamples = inSamples + c * inSamplesBufSize; + + if (c == drcComp->channelIdx[LFE]) { + continue; /* skip LFE */ } - drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f); - } - return (0); -} + /* get filter states */ + x1 = drcComp->filter[c].x1; + x2 = drcComp->filter[c].x2; + y1 = drcComp->filter[c].y1; + y2 = drcComp->filter[c].y2; + i = 0; -INT FDK_DRC_Generator_Calc( - HDRC_COMP drcComp, - const INT_PCM * const inSamples, - const INT dialnorm, - const INT drc_TargetRefLevel, - const INT comp_TargetRefLevel, - FIXP_DBL clev, - FIXP_DBL slev, - INT * const pDynrng, - INT * const pCompr - ) -{ - int i, c; - FIXP_DBL peak[2]; + do { + int offset = i; + FIXP_DBL accu = FL2FXCONST_DBL(0.f); + for (i = offset; + i < fixMin(offset + granuleLength, drcComp->blockLength); i++) { + /* apply weighting filter */ + FIXP_DBL x = + FX_PCM2FX_DBL((FIXP_PCM)pSamples[i]) >> WEIGHTING_FILTER_SHIFT; - /************************************************************************** - * compressor - **************************************************************************/ - if ((drcComp->profile[0] != DRC_NONE) || (drcComp->profile[1] != DRC_NONE)) { - /* Calc loudness level */ - FIXP_DBL level_b = FL2FXCONST_DBL(0.f); - int level_e = DFRACT_BITS-1; + /* y = b0 * (x - x2) - a1 * y1 - a2 * y2; */ + y = fMult(b0, x - x2) - fMult(a1, y1) - fMult(a2, y2); - /* Increase energy time resolution with shorter processing blocks. 32 is an empiric value. */ - const int granuleLength = fixMin(32, drcComp->blockLength); - - if (drcComp->useWeighting) { - FIXP_DBL x1, x2, y, y1, y2; - /* sum of filter coefficients about 2.5 -> squared value is 6.25 - WEIGHTING_FILTER_SHIFT is 2 -> scaling about 16, therefore reduce granuleShift by 1. - */ - const int granuleShift = getShiftFactor(granuleLength)-1; - - for (c = 0; c < (int)drcComp->channels; c++) { - const INT_PCM* pSamples = &inSamples[c]; - - if (c == drcComp->channelIdx[LFE]) { - continue; /* skip LFE */ - } - - /* get filter states */ - x1 = drcComp->filter[c].x1; - x2 = drcComp->filter[c].x2; - y1 = drcComp->filter[c].y1; - y2 = drcComp->filter[c].y2; - - i = 0; - - do { - - int offset = i; - FIXP_DBL accu = FL2FXCONST_DBL(0.f); - - for (i=offset; i < fixMin(offset+granuleLength,drcComp->blockLength); i++) { - /* apply weighting filter */ - FIXP_DBL x = FX_PCM2FX_DBL((FIXP_PCM)pSamples[i*drcComp->channels]) >> WEIGHTING_FILTER_SHIFT; - - /* y = b0 * (x - x2) - a1 * y1 - a2 * y2; */ - y = fMult(b0,x-x2) - fMult(a1,y1) - fMult(a2,y2); - - x2 = x1; - x1 = x; - y2 = y1; - y1 = y; - - accu += fPow2Div2(y)>>(granuleShift-1); /* partial energy */ - } /* i */ - - fixpAdd(accu, granuleShift+2*WEIGHTING_FILTER_SHIFT, &level_b, &level_e); /* sup up partial energies */ - - } while ( i < drcComp->blockLength ); - - - /* save filter states */ - drcComp->filter[c].x1 = x1; - drcComp->filter[c].x2 = x2; - drcComp->filter[c].y1 = y1; - drcComp->filter[c].y2 = y2; - } /* c */ - } /* weighting */ - else { - const int granuleShift = getShiftFactor(granuleLength); - - for (c = 0; c < (int)drcComp->channels; c++) { - const INT_PCM* pSamples = &inSamples[c]; - - if ((int)c == drcComp->channelIdx[LFE]) { - continue; /* skip LFE */ - } - - i = 0; - - do { - int offset = i; - FIXP_DBL accu = FL2FXCONST_DBL(0.f); - - for (i=offset; i < fixMin(offset+granuleLength,drcComp->blockLength); i++) { - /* partial energy */ - accu += fPow2Div2((FIXP_PCM)pSamples[i*drcComp->channels])>>(granuleShift-1); - } /* i */ - - fixpAdd(accu, granuleShift, &level_b, &level_e); /* sup up partial energies */ - - } while ( i < drcComp->blockLength ); - } - } /* weighting */ - - /* - * Convert to dBFS, apply dialnorm - */ - /* level scaling */ - - /* descaled level in ld64 representation */ - FIXP_DBL ldLevel = CalcLdData(level_b) + (FIXP_DBL)((level_e-12)<<(DFRACT_BITS-1-LD_DATA_SHIFT)) - CalcLdData((FIXP_DBL)(drcComp->blockLength<<(DFRACT_BITS-1-12))); - - /* if (level < 1e-10) level = 1e-10f; */ - ldLevel = FDKmax(ldLevel, FL2FXCONST_DBL(-0.51905126482615036685473741085772f)); - - /* level = 10 * log(level)/log(10) + 3; - * = 10*log(2)/log(10) * ld(level) + 3; - * = 10 * 0.30102999566398119521373889472449 * ld(level) + 3 - * = 10 * (0.30102999566398119521373889472449 * ld(level) + 0.3) - * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 64 - * - * additional scaling with METADATA_FRACT_BITS: - * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 64 * 2^(METADATA_FRACT_BITS) - * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) - * = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * ( 0.30102999566398119521373889472449 * ld64(level) + 0.3/64 ) - * */ - FIXP_DBL level = fMult((FIXP_DBL)(10<<(METADATA_FRACT_BITS+LD_DATA_SHIFT)), fMult( FL2FXCONST_DBL(0.30102999566398119521373889472449f), ldLevel) + (FIXP_DBL)(FL2FXCONST_DBL(0.3f)>>LD_DATA_SHIFT) ); - - /* level -= dialnorm + 31 */ /* this is fixed to Dolby-ReferenceLevel as compressor profiles are defined relative to this */ - level -= ((FIXP_DBL)(dialnorm<<(METADATA_FRACT_BITS-16)) + (FIXP_DBL)(31<profile[i] == DRC_NONE) { - /* no compression */ - drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f); - } - else { - FIXP_DBL gain, alpha, lvl2smthlvl; - - /* calc static gain */ - if (level <= drcComp->maxBoostThr[i]) { - /* max boost */ - gain = drcComp->maxBoost[i]; - } - else if (level < drcComp->boostThr[i]) { - /* boost range */ - gain = fMult((level - drcComp->boostThr[i]),drcComp->boostFac[i]); - } - else if (level <= drcComp->earlyCutThr[i]) { - /* null band */ - gain = FL2FXCONST_DBL(0.f); - } - else if (level <= drcComp->cutThr[i]) { - /* early cut range */ - gain = fMult((level - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]); - } - else if (level < drcComp->maxCutThr[i]) { - /* cut range */ - gain = fMult((level - drcComp->cutThr[i]), drcComp->cutFac[i]) - drcComp->maxEarlyCut[i]; - } - else { - /* max cut */ - gain = -drcComp->maxCut[i]; - } - - /* choose time constant */ - lvl2smthlvl = level - drcComp->smoothLevel[i]; - if (gain < drcComp->smoothGain[i]) { - /* attack */ - if (lvl2smthlvl > drcComp->attackThr[i]) { - /* fast attack */ - alpha = drcComp->fastAttack[i]; - } - else { - /* slow attack */ - alpha = drcComp->slowAttack[i]; - } - } - else { - /* release */ - if (lvl2smthlvl < -drcComp->decayThr[i]) { - /* fast release */ - alpha = drcComp->fastDecay[i]; - } - else { - /* slow release */ - alpha = drcComp->slowDecay[i]; - } - } - - /* smooth gain & level */ - if ((gain < drcComp->smoothGain[i]) || (drcComp->holdCnt[i] == 0)) { /* hold gain unless we have an attack or hold period is over */ - FIXP_DBL accu; - - /* drcComp->smoothLevel[i] = (1-alpha) * drcComp->smoothLevel[i] + alpha * level; */ - accu = fMult(((FIXP_DBL)MAXVAL_DBL-alpha), drcComp->smoothLevel[i]); - accu += fMult(alpha,level); - drcComp->smoothLevel[i] = accu; - - /* drcComp->smoothGain[i] = (1-alpha) * drcComp->smoothGain[i] + alpha * gain; */ - accu = fMult(((FIXP_DBL)MAXVAL_DBL-alpha), drcComp->smoothGain[i]); - accu += fMult(alpha,gain); - drcComp->smoothGain[i] = accu; - } - - /* hold counter */ - if (drcComp->holdCnt[i]) { - drcComp->holdCnt[i]--; - } - if (gain < drcComp->smoothGain[i]) { - drcComp->holdCnt[i] = drcComp->holdOff[i]; - } - } /* profile != DRC_NONE */ - } /* for i=1..2 */ - } else { - /* no compression */ - drcComp->smoothGain[0] = FL2FXCONST_DBL(0.f); - drcComp->smoothGain[1] = FL2FXCONST_DBL(0.f); - } + x2 = x1; + x1 = x; + y2 = y1; + y1 = y; - /************************************************************************** - * limiter - **************************************************************************/ + accu += fPow2Div2(y) >> (granuleShift - 1); /* partial energy */ + } /* i */ - /* find peak level */ - peak[0] = peak[1] = FL2FXCONST_DBL(0.f); - for (i = 0; i < drcComp->blockLength; i++) { - FIXP_DBL tmp; - const INT_PCM* pSamples = &inSamples[i*drcComp->channels]; - INT_PCM maxSample = 0; + fixpAdd(accu, granuleShift + 2 * WEIGHTING_FILTER_SHIFT, &level_b, + &level_e); /* sup up partial energies */ + + } while (i < drcComp->blockLength); + + /* save filter states */ + drcComp->filter[c].x1 = x1; + drcComp->filter[c].x2 = x2; + drcComp->filter[c].y1 = y1; + drcComp->filter[c].y2 = y2; + } /* c */ + } /* weighting */ + else { + const int granuleShift = getShiftFactor(granuleLength); - /* single channels */ - for (c = 0; c < (int)drcComp->channels; c++) { - maxSample = FDKmax(maxSample, fAbs(pSamples[c])); + for (c = 0; c < (int)drcComp->channels; c++) { + const INT_PCM* pSamples = inSamples + c * inSamplesBufSize; + + if ((int)c == drcComp->channelIdx[LFE]) { + continue; /* skip LFE */ } - peak[0] = fixMax(peak[0], FX_PCM2FX_DBL(maxSample)>>DOWNMIX_SHIFT); - - /* Lt/Rt downmix */ - if (drcComp->fullChannels > 2) { - /* Lt */ - tmp = FL2FXCONST_DBL(0.f); - - if (drcComp->channelIdx[LS] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1); /* Ls */ - if (drcComp->channelIdx[LS2] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1); /* Ls2 */ - if (drcComp->channelIdx[RS] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1); /* Rs */ - if (drcComp->channelIdx[RS2] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1); /* Rs2 */ - if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ - if (drcComp->channelIdx[S] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]])>>(DOWNMIX_SHIFT-1); /* S */ - if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C */ - tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT); /* L */ - - peak[0] = fixMax(peak[0], fixp_abs(tmp)); - - /* Rt */ - tmp = FL2FXCONST_DBL(0.f); - if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1); /* Ls */ - if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1); /* Ls2 */ - if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1); /* Rs */ - if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1); /* Rs2 */ - if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ - if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]])>>(DOWNMIX_SHIFT-1); /* S */ - if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C */ - tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]])>>DOWNMIX_SHIFT); /* R */ - - peak[0] = fixMax(peak[0], fixp_abs(tmp)); + + i = 0; + + do { + int offset = i; + FIXP_DBL accu = FL2FXCONST_DBL(0.f); + + for (i = offset; + i < fixMin(offset + granuleLength, drcComp->blockLength); i++) { + /* partial energy */ + accu += fPow2Div2((FIXP_PCM)pSamples[i]) >> (granuleShift - 1); + } /* i */ + + fixpAdd(accu, granuleShift, &level_b, + &level_e); /* sup up partial energies */ + + } while (i < drcComp->blockLength); + } + } /* weighting */ + + /* + * Convert to dBFS, apply dialnorm + */ + /* level scaling */ + + /* descaled level in ld64 representation */ + FIXP_DBL ldLevel = + CalcLdData(level_b) + + (FIXP_DBL)((level_e - 12) << (DFRACT_BITS - 1 - LD_DATA_SHIFT)) - + CalcLdData((FIXP_DBL)(drcComp->blockLength << (DFRACT_BITS - 1 - 12))); + + /* if (level < 1e-10) level = 1e-10f; */ + ldLevel = + fMax(ldLevel, FL2FXCONST_DBL(-0.51905126482615036685473741085772f)); + + /* level = 10 * log(level)/log(10) + 3; + * = 10*log(2)/log(10) * ld(level) + 3; + * = 10 * 0.30102999566398119521373889472449 * ld(level) + 3 + * = 10 * (0.30102999566398119521373889472449 * ld(level) + 0.3) + * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) + * * 64 + * + * additional scaling with METADATA_FRACT_BITS: + * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) + * * 64 * 2^(METADATA_FRACT_BITS) = 10 * (0.30102999566398119521373889472449 + * * ld64(level) + 0.3/64) * 2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) = + * 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * ( + * 0.30102999566398119521373889472449 * ld64(level) + 0.3/64 ) + * */ + FIXP_DBL level = fMult( + (FIXP_DBL)(10 << (METADATA_FRACT_BITS + LD_DATA_SHIFT)), + fMult(FL2FXCONST_DBL(0.30102999566398119521373889472449f), ldLevel) + + (FIXP_DBL)(FL2FXCONST_DBL(0.3f) >> LD_DATA_SHIFT)); + + /* level -= dialnorm + 31 */ /* this is fixed to Dolby-ReferenceLevel as + compressor profiles are defined relative to + this */ + level -= ((FIXP_DBL)(dialnorm << (METADATA_FRACT_BITS - 16)) + + (FIXP_DBL)(31 << METADATA_FRACT_BITS)); + + for (i = 0; i < 2; i++) { + if (drcComp->profile[i] == DRC_NONE) { + /* no compression */ + drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f); + } else { + FIXP_DBL gain, alpha, lvl2smthlvl; + + /* calc static gain */ + if (level <= drcComp->maxBoostThr[i]) { + /* max boost */ + gain = drcComp->maxBoost[i]; + } else if (level < drcComp->boostThr[i]) { + /* boost range */ + gain = fMult((level - drcComp->boostThr[i]), drcComp->boostFac[i]); + } else if (level <= drcComp->earlyCutThr[i]) { + /* null band */ + gain = FL2FXCONST_DBL(0.f); + } else if (level <= drcComp->cutThr[i]) { + /* early cut range */ + gain = + fMult((level - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]); + } else if (level < drcComp->maxCutThr[i]) { + /* cut range */ + gain = fMult((level - drcComp->cutThr[i]), drcComp->cutFac[i]) - + drcComp->maxEarlyCut[i]; + } else { + /* max cut */ + gain = -drcComp->maxCut[i]; } - /* Lo/Ro downmix */ - if (drcComp->fullChannels > 2) { - /* Lo */ - tmp = FL2FXCONST_DBL(0.f); - if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1); /* Ls */ - if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1); /* Ls2 */ - if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ - if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(slev, fMult(FL2FXCONST_DBL(0.7f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]]))>>(DOWNMIX_SHIFT-1); /* S */ - if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C */ - tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT); /* L */ - - peak[0] = fixMax(peak[0], fixp_abs(tmp)); - - /* Ro */ - tmp = FL2FXCONST_DBL(0.f); - if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1); /* Rs */ - if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1); /* Rs2 */ - if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ - if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(slev, fMult(FL2FXCONST_DBL(0.7f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]]))>>(DOWNMIX_SHIFT-1); /* S */ - if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C */ - tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]])>>DOWNMIX_SHIFT); /* R */ - - peak[0] = fixMax(peak[0], fixp_abs(tmp)); + /* choose time constant */ + lvl2smthlvl = level - drcComp->smoothLevel[i]; + if (gain < drcComp->smoothGain[i]) { + /* attack */ + if (lvl2smthlvl > drcComp->attackThr[i]) { + /* fast attack */ + alpha = drcComp->fastAttack[i]; + } else { + /* slow attack */ + alpha = drcComp->slowAttack[i]; + } + } else { + /* release */ + if (lvl2smthlvl < -drcComp->decayThr[i]) { + /* fast release */ + alpha = drcComp->fastDecay[i]; + } else { + /* slow release */ + alpha = drcComp->slowDecay[i]; + } } - peak[1] = fixMax(peak[0], peak[1]); - - /* Mono Downmix - for comp_val only */ - if (drcComp->fullChannels > 1) { - tmp = FL2FXCONST_DBL(0.f); - if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1); /* Ls */ - if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1); /* Ls2 */ - if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1); /* Rs */ - if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1); /* Rs2 */ - if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ - /*if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp *=0.707f;*/ /* 7.1ch */ - if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(slev, fMult(FL2FXCONST_DBL(0.7f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]]))>>(DOWNMIX_SHIFT-1); /* S */ - if (drcComp->channelIdx[C] >= 0) tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C (2*clev) */ - tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT); /* L */ - tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]])>>DOWNMIX_SHIFT); /* R */ - - peak[1] = fixMax(peak[1], fixp_abs(tmp)); + /* smooth gain & level */ + if ((gain < drcComp->smoothGain[i]) || + (drcComp->holdCnt[i] == + 0)) { /* hold gain unless we have an attack or hold + period is over */ + FIXP_DBL accu; + + /* drcComp->smoothLevel[i] = (1-alpha) * drcComp->smoothLevel[i] + + * alpha * level; */ + accu = fMult(((FIXP_DBL)MAXVAL_DBL - alpha), drcComp->smoothLevel[i]); + accu += fMult(alpha, level); + drcComp->smoothLevel[i] = accu; + + /* drcComp->smoothGain[i] = (1-alpha) * drcComp->smoothGain[i] + + * alpha * gain; */ + accu = fMult(((FIXP_DBL)MAXVAL_DBL - alpha), drcComp->smoothGain[i]); + accu += fMult(alpha, gain); + drcComp->smoothGain[i] = accu; } - } - for (i=0; i<2; i++) { - FIXP_DBL tmp = drcComp->prevPeak[i]; - drcComp->prevPeak[i] = peak[i]; - peak[i] = fixMax(peak[i], tmp); + /* hold counter */ + if (drcComp->holdCnt[i]) { + drcComp->holdCnt[i]--; + } + if (gain < drcComp->smoothGain[i]) { + drcComp->holdCnt[i] = drcComp->holdOff[i]; + } + } /* profile != DRC_NONE */ + } /* for i=1..2 */ + } else { + /* no compression */ + drcComp->smoothGain[0] = FL2FXCONST_DBL(0.f); + drcComp->smoothGain[1] = FL2FXCONST_DBL(0.f); + } - /* - * Convert to dBFS, apply dialnorm - */ - /* descaled peak in ld64 representation */ - FIXP_DBL ld_peak = CalcLdData(peak[i]) + (FIXP_DBL)((LONG)DOWNMIX_SHIFT<<(DFRACT_BITS-1-LD_DATA_SHIFT)); - - /* if (peak < 1e-6) level = 1e-6f; */ - ld_peak = FDKmax(ld_peak, FL2FXCONST_DBL(-0.31143075889569022011284244651463f)); - - /* peak[i] = 20 * log(peak[i])/log(10) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) - * peak[i] = 20 * log(2)/log(10) * ld(peak[i]) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) - * peak[i] = 10 * 2*0.30102999566398119521373889472449 * ld(peak[i]) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) - * - * additional scaling with METADATA_FRACT_BITS: - * peak[i] = (10 * 2*0.30102999566398119521373889472449 * ld64(peak[i]) * 64 + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS))*2^(-METADATA_FRACT_BITS) - * peak[i] = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * 2*0.30102999566398119521373889472449 * ld64(peak[i]) - * + 0.2f*2^(-METADATA_FRACT_BITS) + drcComp->smoothGain[i] - */ - peak[i] = fMult((FIXP_DBL)(10<<(METADATA_FRACT_BITS+LD_DATA_SHIFT)), fMult( FL2FX_DBL(2*0.30102999566398119521373889472449f), ld_peak)); - peak[i] += (FL2FX_DBL(0.5f)>>METADATA_INT_BITS); /* add a little bit headroom */ - peak[i] += drcComp->smoothGain[i]; - } + /************************************************************************** + * limiter + **************************************************************************/ + + findPeakLevels(drcComp, inSamples, clev, slev, ext_leva, ext_levb, lfe_lev, + (FIXP_DBL)((LONG)(dmxGain5) << (METADATA_FRACT_BITS - 16)), + (FIXP_DBL)((LONG)(dmxGain2) << (METADATA_FRACT_BITS - 16)), + peak); + + for (i = 0; i < 2; i++) { + FIXP_DBL tmp = drcComp->prevPeak[i]; + drcComp->prevPeak[i] = peak[i]; + peak[i] = fixMax(peak[i], tmp); + + /* + * Convert to dBFS, apply dialnorm + */ + /* descaled peak in ld64 representation */ + FIXP_DBL ld_peak = + CalcLdData(peak[i]) + + (FIXP_DBL)((LONG)DOWNMIX_SHIFT << (DFRACT_BITS - 1 - LD_DATA_SHIFT)); + + /* if (peak < 1e-6) level = 1e-6f; */ + ld_peak = + fMax(ld_peak, FL2FXCONST_DBL(-0.31143075889569022011284244651463f)); + + /* peak[i] = 20 * log(peak[i])/log(10) + 0.2f + + * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) peak[i] = 20 * + * log(2)/log(10) * ld(peak[i]) + 0.2f + + * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) peak[i] = 10 * + * 2*0.30102999566398119521373889472449 * ld(peak[i]) + 0.2f + + * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) + * + * additional scaling with METADATA_FRACT_BITS: + * peak[i] = (10 * 2*0.30102999566398119521373889472449 * ld64(peak[i]) * 64 + * + 0.2f + + * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS))*2^(-METADATA_FRACT_BITS) + * peak[i] = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * + * 2*0.30102999566398119521373889472449 * ld64(peak[i]) + * + 0.2f*2^(-METADATA_FRACT_BITS) + drcComp->smoothGain[i] + */ + peak[i] = fMult( + (FIXP_DBL)(10 << (METADATA_FRACT_BITS + LD_DATA_SHIFT)), + fMult(FL2FX_DBL(2 * 0.30102999566398119521373889472449f), ld_peak)); + peak[i] += + (FL2FX_DBL(0.5f) >> METADATA_INT_BITS); /* add a little bit headroom */ + peak[i] += drcComp->smoothGain[i]; + } - /* peak -= dialnorm + 31; */ /* this is Dolby style only */ - peak[0] -= (FIXP_DBL)((dialnorm-drc_TargetRefLevel)<<(METADATA_FRACT_BITS-16)); /* peak[0] -= dialnorm - drc_TargetRefLevel */ + /* peak -= dialnorm + 31; */ /* this is Dolby style only */ + peak[0] -= (FIXP_DBL)((dialnorm - drc_TargetRefLevel) + << (METADATA_FRACT_BITS - + 16)); /* peak[0] -= dialnorm - drc_TargetRefLevel */ - /* peak += 11; */ /* this is Dolby style only */ /* RF mode output is 11dB higher */ - /*peak += comp_TargetRefLevel - drc_TargetRefLevel;*/ - peak[1] -= (FIXP_DBL)((dialnorm-comp_TargetRefLevel)<<(METADATA_FRACT_BITS-16)); /* peak[1] -= dialnorm - comp_TargetRefLevel */ + /* peak += 11; */ + /* this is Dolby style only */ /* RF mode output is 11dB higher */ + /*peak += comp_TargetRefLevel - drc_TargetRefLevel;*/ + peak[1] -= + (FIXP_DBL)((dialnorm - comp_TargetRefLevel) + << (METADATA_FRACT_BITS - + 16)); /* peak[1] -= dialnorm - comp_TargetRefLevel */ - /* limiter gain */ - drcComp->limGain[0] += drcComp->limDecay; /* linear limiter release */ - drcComp->limGain[0] = fixMin(drcComp->limGain[0], -peak[0]); + /* limiter gain */ + drcComp->limGain[0] += drcComp->limDecay; /* linear limiter release */ + drcComp->limGain[0] = fixMin(drcComp->limGain[0], -peak[0]); - drcComp->limGain[1] += 2*drcComp->limDecay; /* linear limiter release */ - drcComp->limGain[1] = fixMin(drcComp->limGain[1], -peak[1]); + drcComp->limGain[1] += 2 * drcComp->limDecay; /* linear limiter release */ + drcComp->limGain[1] = fixMin(drcComp->limGain[1], -peak[1]); - /*************************************************************************/ + /*************************************************************************/ - /* apply limiting, return DRC gains*/ - { - FIXP_DBL tmp; + /* apply limiting, return DRC gains*/ + { + FIXP_DBL tmp; - tmp = drcComp->smoothGain[0]; - if (drcComp->limGain[0] < FL2FXCONST_DBL(0.f)) { - tmp += drcComp->limGain[0]; - } - *pDynrng = (LONG) scaleValue(tmp, -(METADATA_FRACT_BITS-16)); + tmp = drcComp->smoothGain[0]; + if (drcComp->limGain[0] < FL2FXCONST_DBL(0.f)) { + tmp += drcComp->limGain[0]; + } + *pDynrng = (LONG)scaleValue(tmp, -(METADATA_FRACT_BITS - 16)); - tmp = drcComp->smoothGain[1]; - if (drcComp->limGain[1] < FL2FXCONST_DBL(0.f)) { - tmp += drcComp->limGain[1]; - } - *pCompr = (LONG) scaleValue(tmp, -(METADATA_FRACT_BITS-16)); + tmp = drcComp->smoothGain[1]; + if (drcComp->limGain[1] < FL2FXCONST_DBL(0.f)) { + tmp += drcComp->limGain[1]; } + *pCompr = (LONG)scaleValue(tmp, -(METADATA_FRACT_BITS - 16)); + } - return 0; + return 0; } - -DRC_PROFILE FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp) -{ - return drcComp->profile[0]; +DRC_PROFILE FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp) { + return drcComp->profile[0]; } -DRC_PROFILE FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp) -{ - return drcComp->profile[1]; +DRC_PROFILE FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp) { + return drcComp->profile[1]; } - - diff --git a/libAACenc/src/metadata_compressor.h b/libAACenc/src/metadata_compressor.h index ff639b5..1d0aa42 100644 --- a/libAACenc/src/metadata_compressor.h +++ b/libAACenc/src/metadata_compressor.h @@ -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,75 +90,73 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/********************** Fraunhofer IIS FDK AAC Encoder lib ****************** +/**************************** AAC encoder library ****************************** - Author(s): M. Neusinger - Description: Compressor for AAC Metadata Generator + Author(s): M. Neusinger -******************************************************************************/ + Description: Compressor for AAC Metadata Generator -#ifndef _METADATA_COMPRESSOR_H -#define _METADATA_COMPRESSOR_H +*******************************************************************************/ +#ifndef METADATA_COMPRESSOR_H +#define METADATA_COMPRESSOR_H #include "FDK_audio.h" #include "common_fix.h" #include "aacenc.h" +#define LFE_LEV_SCALE 2 /** * DRC compression profiles. */ typedef enum DRC_PROFILE { - DRC_NONE = 0, - DRC_FILMSTANDARD = 1, - DRC_FILMLIGHT = 2, + DRC_NONE = 0, + DRC_FILMSTANDARD = 1, + DRC_FILMLIGHT = 2, DRC_MUSICSTANDARD = 3, - DRC_MUSICLIGHT = 4, - DRC_SPEECH = 5, - DRC_DELAY_TEST = 6 + DRC_MUSICLIGHT = 4, + DRC_SPEECH = 5, + DRC_DELAY_TEST = 6, + DRC_NOT_PRESENT = -2 } DRC_PROFILE; - /** * DRC Compressor handle. */ -typedef struct DRC_COMP DRC_COMP, *HDRC_COMP; +typedef struct DRC_COMP DRC_COMP, *HDRC_COMP; /** * \brief Open a DRC Compressor instance. * * Allocate memory for a compressor instance. * - * \param phDrcComp A pointer to a compressor handle. Initialized on return. + * \param phDrcComp A pointer to a compressor handle. Initialized on + * return. * * \return * - 0, on succes. * - unequal 0, on failure. */ -INT FDK_DRC_Generator_Open( - HDRC_COMP *phDrcComp - ); - +INT FDK_DRC_Generator_Open(HDRC_COMP *phDrcComp); /** * \brief Close the DRC Compressor instance. * * Deallocate instance and free whole memory. * - * \param phDrcComp Pointer to the compressor handle to be deallocated. + * \param phDrcComp Pointer to the compressor handle to be + * deallocated. * * \return * - 0, on succes. * - unequal 0, on failure. */ -INT FDK_DRC_Generator_Close( - HDRC_COMP *phDrcComp - ); +INT FDK_DRC_Generator_Close(HDRC_COMP *phDrcComp); /** * \brief Configure DRC Compressor. @@ -155,7 +164,8 @@ INT FDK_DRC_Generator_Close( * \param drcComp Compressor handle. * \param profileLine DRC profile for line mode. * \param profileRF DRC profile for RF mode. - * \param blockLength Length of processing block in samples per channel. + * \param blockLength Length of processing block in samples per + * channel. * \param sampleRate Sampling rate in Hz. * \param channelMode Channel configuration. * \param channelOrder Channel order, MPEG or WAV. @@ -165,46 +175,49 @@ INT FDK_DRC_Generator_Close( * - 0, on success, * - unequal 0, on failure */ -INT FDK_DRC_Generator_Initialize( - HDRC_COMP drcComp, - const DRC_PROFILE profileLine, - const DRC_PROFILE profileRF, - const INT blockLength, - const UINT sampleRate, - const CHANNEL_MODE channelMode, - const CHANNEL_ORDER channelOrder, - const UCHAR useWeighting - ); +INT FDK_DRC_Generator_Initialize(HDRC_COMP drcComp, + const DRC_PROFILE profileLine, + const DRC_PROFILE profileRF, + const INT blockLength, const UINT sampleRate, + const CHANNEL_MODE channelMode, + const CHANNEL_ORDER channelOrder, + const UCHAR useWeighting); /** * \brief Calculate DRC Compressor Gain. * * \param drcComp Compressor handle. * \param inSamples Pointer to interleaved input audio samples. + * \param inSamplesBufSize Size of inSamples for one channel. * \param dialnorm Dialog Level in dB (typically -31...-1). * \param drc_TargetRefLevel * \param comp_TargetRefLevel - * \param clev Downmix center mix factor (typically 0.707, 0.595 or 0.5) - * \param slev Downmix surround mix factor (typically 0.707, 0.5, or 0) - * \param dynrng Pointer to variable receiving line mode DRC gain in dB - * \param compr Pointer to variable receiving RF mode DRC gain in dB + * \param clev Downmix center mix factor (typically 0.707, + * 0.595 or 0.5) + * \param slev Downmix surround mix factor (typically 0.707, + * 0.5, or 0) + * \param ext_leva Downmix gain factor A + * \param ext_levb Downmix gain factor B + * \param lfe_lev LFE gain factor + * \param dmxGain5 Gain factor for downmix to 5 channels + * \param dmxGain2 Gain factor for downmix to 2 channels + * \param dynrng Pointer to variable receiving line mode DRC gain + * in dB + * \param compr Pointer to variable receiving RF mode DRC gain + * in dB * * \return * - 0, on success, * - unequal 0, on failure */ -INT FDK_DRC_Generator_Calc( - HDRC_COMP drcComp, - const INT_PCM * const inSamples, - const INT dialnorm, - const INT drc_TargetRefLevel, - const INT comp_TargetRefLevel, - FIXP_DBL clev, - FIXP_DBL slev, - INT * const dynrng, - INT * const compr - ); - +INT FDK_DRC_Generator_Calc(HDRC_COMP drcComp, const INT_PCM *const inSamples, + const UINT inSamplesBufSize, const INT dialnorm, + const INT drc_TargetRefLevel, + const INT comp_TargetRefLevel, const FIXP_DBL clev, + const FIXP_DBL slev, const FIXP_DBL ext_leva, + const FIXP_DBL ext_levb, const FIXP_DBL lfe_lev, + const INT dmxGain5, const INT dmxGain2, + INT *const dynrng, INT *const compr); /** * \brief Configure DRC Compressor Profile. @@ -217,12 +230,9 @@ INT FDK_DRC_Generator_Calc( * - 0, on success, * - unequal 0, on failure */ -INT FDK_DRC_Generator_setDrcProfile( - HDRC_COMP drcComp, - const DRC_PROFILE profileLine, - const DRC_PROFILE profileRF - ); - +INT FDK_DRC_Generator_setDrcProfile(HDRC_COMP drcComp, + const DRC_PROFILE profileLine, + const DRC_PROFILE profileRF); /** * \brief Get DRC profile for line mode. @@ -231,10 +241,7 @@ INT FDK_DRC_Generator_setDrcProfile( * * \return Current Profile. */ -DRC_PROFILE FDK_DRC_Generator_getDrcProfile( - const HDRC_COMP drcComp - ); - +DRC_PROFILE FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp); /** * \brief Get DRC profile for RF mode. @@ -243,10 +250,6 @@ DRC_PROFILE FDK_DRC_Generator_getDrcProfile( * * \return Current Profile. */ -DRC_PROFILE FDK_DRC_Generator_getCompProfile( - const HDRC_COMP drcComp - ); - - -#endif /* _METADATA_COMPRESSOR_H */ +DRC_PROFILE FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp); +#endif /* METADATA_COMPRESSOR_H */ diff --git a/libAACenc/src/metadata_main.cpp b/libAACenc/src/metadata_main.cpp index 90f8f4e..edd3831 100644 --- a/libAACenc/src/metadata_main.cpp +++ b/libAACenc/src/metadata_main.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,15 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/********************** Fraunhofer IIS FDK AAC Encoder lib ****************** +/**************************** AAC encoder library ****************************** - Author(s): V. Bacigalupo - Description: Metadata Encoder library interface functions + Author(s): V. Bacigalupo -******************************************************************************/ + Description: Metadata Encoder library interface functions +*******************************************************************************/ #include "metadata_main.h" #include "metadata_compressor.h" @@ -96,551 +107,697 @@ amm-info@iis.fraunhofer.de #include "genericStds.h" /*----------------- defines ----------------------*/ -#define MAX_DRC_BANDS (1<<4) -#define MAX_DRC_CHANNELS (8) -#define MAX_DRC_FRAMELEN (2*1024) +#define MAX_DRC_BANDS (1 << 4) +#define MAX_DRC_FRAMELEN (2 * 1024) +#define MAX_DELAY_FRAMES (3) /*--------------- structure definitions --------------------*/ -typedef struct AAC_METADATA -{ +typedef struct AAC_METADATA { /* MPEG: Dynamic Range Control */ struct { - UCHAR prog_ref_level_present; - SCHAR prog_ref_level; + UCHAR prog_ref_level_present; + SCHAR prog_ref_level; - UCHAR dyn_rng_sgn[MAX_DRC_BANDS]; - UCHAR dyn_rng_ctl[MAX_DRC_BANDS]; + UCHAR dyn_rng_sgn[MAX_DRC_BANDS]; + UCHAR dyn_rng_ctl[MAX_DRC_BANDS]; - UCHAR drc_bands_present; - UCHAR drc_band_incr; - UCHAR drc_band_top[MAX_DRC_BANDS]; - UCHAR drc_interpolation_scheme; - AACENC_METADATA_DRC_PROFILE drc_profile; - INT drc_TargetRefLevel; /* used for Limiter */ + UCHAR drc_bands_present; + UCHAR drc_band_incr; + UCHAR drc_band_top[MAX_DRC_BANDS]; + UCHAR drc_interpolation_scheme; + AACENC_METADATA_DRC_PROFILE drc_profile; + INT drc_TargetRefLevel; /* used for Limiter */ /* excluded channels */ - UCHAR excluded_chns_present; - UCHAR exclude_mask[2]; /* MAX_NUMBER_CHANNELS/8 */ + UCHAR excluded_chns_present; + UCHAR exclude_mask[2]; /* MAX_NUMBER_CHANNELS/8 */ } mpegDrc; /* ETSI: addtl ancillary data */ struct { /* Heavy Compression */ - UCHAR compression_on; /* flag, if compression value should be written */ - UCHAR compression_value; /* compression value */ - AACENC_METADATA_DRC_PROFILE comp_profile; - INT comp_TargetRefLevel; /* used for Limiter */ - INT timecode_coarse_status; - INT timecode_fine_status; + UCHAR compression_on; /* flag, if compression value should be written */ + UCHAR compression_value; /* compression value */ + AACENC_METADATA_DRC_PROFILE comp_profile; + INT comp_TargetRefLevel; /* used for Limiter */ + INT timecode_coarse_status; + INT timecode_fine_status; + + UCHAR extAncDataStatus; + + struct { + UCHAR ext_downmix_lvl_status; + UCHAR ext_downmix_gain_status; + UCHAR ext_lfe_downmix_status; + UCHAR + ext_dmix_a_idx; /* extended downmix level (0..7, according to table) + */ + UCHAR + ext_dmix_b_idx; /* extended downmix level (0..7, according to table) + */ + UCHAR dmx_gain_5_sgn; + UCHAR dmx_gain_5_idx; + UCHAR dmx_gain_2_sgn; + UCHAR dmx_gain_2_idx; + UCHAR ext_dmix_lfe_idx; /* extended downmix level for lfe (0..15, + according to table) */ + + } extAncData; + } etsiAncData; - SCHAR centerMixLevel; /* center downmix level (0...7, according to table) */ - SCHAR surroundMixLevel; /* surround downmix level (0...7, according to table) */ - UCHAR WritePCEMixDwnIdx; /* flag */ - UCHAR DmxLvl_On; /* flag */ + SCHAR centerMixLevel; /* center downmix level (0...7, according to table) */ + SCHAR + surroundMixLevel; /* surround downmix level (0...7, according to table) */ + UCHAR WritePCEMixDwnIdx; /* flag */ + UCHAR DmxLvl_On; /* flag */ - UCHAR dolbySurroundMode; + UCHAR dolbySurroundMode; + UCHAR drcPresentationMode; - UCHAR metadataMode; /* indicate meta data mode in current frame (delay line) */ + UCHAR + metadataMode; /* indicate meta data mode in current frame (delay line) */ } AAC_METADATA; -struct FDK_METADATA_ENCODER -{ - INT metadataMode; - HDRC_COMP hDrcComp; - AACENC_MetaData submittedMetaData; +typedef struct FDK_METADATA_ENCODER { + INT metadataMode; + HDRC_COMP hDrcComp; + AACENC_MetaData submittedMetaData; - INT nAudioDataDelay; - INT nMetaDataDelay; - INT nChannels; + INT nAudioDataDelay; /* Additional delay to round up to next frame border (in + samples) */ + INT nMetaDataDelay; /* Meta data delay (in frames) */ + INT nChannels; + CHANNEL_MODE channelMode; - INT_PCM audioDelayBuffer[MAX_DRC_CHANNELS*MAX_DRC_FRAMELEN]; - int audioDelayIdx; + INT_PCM* pAudioDelayBuffer; - AAC_METADATA metaDataBuffer[3]; - int metaDataDelayIdx; + AAC_METADATA metaDataBuffer[MAX_DELAY_FRAMES]; + INT metaDataDelayIdx; - UCHAR drcInfoPayload[12]; - UCHAR drcDsePayload[8]; + UCHAR drcInfoPayload[12]; + UCHAR drcDsePayload[8]; + + INT matrix_mixdown_idx; - INT matrix_mixdown_idx; AACENC_EXT_PAYLOAD exPayload[2]; - INT nExtensions; + INT nExtensions; - INT finalizeMetaData; /* Delay switch off by one frame and write default configuration to - finalize the metadata setup. */ -}; + UINT maxChannels; /* Maximum number of audio channels to be supported. */ + INT finalizeMetaData; /* Delay switch off by one frame and write default + configuration to finalize the metadata setup. */ + INT initializeMetaData; /* Fill up delay line with first meta data info. This + is required to have meta data already in first + frame. */ +} FDK_METADATA_ENCODER; /*---------------- constants -----------------------*/ static const AACENC_MetaData defaultMetaDataSetup = { - AACENC_METADATA_DRC_NONE, - AACENC_METADATA_DRC_NONE, - -(31<<16), - -(31<<16), - 0, - -(31<<16), - 0, - 0, - 0, - 0, - 0 + AACENC_METADATA_DRC_NONE, /* drc_profile */ + AACENC_METADATA_DRC_NOT_PRESENT, /* comp_profile */ + -(31 << 16), /* drc_TargetRefLevel */ + -(23 << 16), /* comp_TargetRefLevel */ + 0, /* prog_ref_level_present */ + -(23 << 16), /* prog_ref_level */ + 0, /* PCE_mixdown_idx_present */ + 0, /* ETSI_DmxLvl_present */ + 0, /* centerMixLevel */ + 0, /* surroundMixLevel */ + 0, /* dolbySurroundMode */ + 0, /* drcPresentationMode */ + {0, 0, 0, 0, 0, 0, 0, 0, 0} /* ExtMetaData */ }; static const FIXP_DBL dmxTable[8] = { - ((FIXP_DBL)MAXVAL_DBL), FL2FXCONST_DBL(0.841f), FL2FXCONST_DBL(0.707f), FL2FXCONST_DBL(0.596f), - FL2FXCONST_DBL(0.500f), FL2FXCONST_DBL(0.422f), FL2FXCONST_DBL(0.355f), FL2FXCONST_DBL(0.000f) -}; + ((FIXP_DBL)MAXVAL_DBL), FL2FXCONST_DBL(0.841f), FL2FXCONST_DBL(0.707f), + FL2FXCONST_DBL(0.596f), FL2FXCONST_DBL(0.500f), FL2FXCONST_DBL(0.422f), + FL2FXCONST_DBL(0.355f), FL2FXCONST_DBL(0.000f)}; -static const UCHAR surmix2matrix_mixdown_idx[8] = { - 0, 0, 0, 1, 1, 2, 2, 3 -}; +#define FL2DMXLFE(a) FL2FXCONST_DBL((a) / (1 << LFE_LEV_SCALE)) +static const FIXP_DBL dmxLfeTable[16] = { + FL2DMXLFE(3.162f), FL2DMXLFE(2.000f), FL2DMXLFE(1.679f), FL2DMXLFE(1.413f), + FL2DMXLFE(1.189f), FL2DMXLFE(1.000f), FL2DMXLFE(0.841f), FL2DMXLFE(0.707f), + FL2DMXLFE(0.596f), FL2DMXLFE(0.500f), FL2DMXLFE(0.316f), FL2DMXLFE(0.178f), + FL2DMXLFE(0.100f), FL2DMXLFE(0.032f), FL2DMXLFE(0.010f), FL2DMXLFE(0.000f)}; +static const UCHAR surmix2matrix_mixdown_idx[8] = {0, 0, 0, 1, 1, 2, 2, 3}; /*--------------- function declarations --------------------*/ static FDK_METADATA_ERROR WriteMetadataPayload( - const HANDLE_FDK_METADATA_ENCODER hMetaData, - const AAC_METADATA * const pMetadata - ); + const HANDLE_FDK_METADATA_ENCODER hMetaData, + const AAC_METADATA* const pMetadata); -static INT WriteDynamicRangeInfoPayload( - const AAC_METADATA* const pMetadata, - UCHAR* const pExtensionPayload - ); +static INT WriteDynamicRangeInfoPayload(const AAC_METADATA* const pMetadata, + UCHAR* const pExtensionPayload); -static INT WriteEtsiAncillaryDataPayload( - const AAC_METADATA* const pMetadata, - UCHAR* const pExtensionPayload - ); +static INT WriteEtsiAncillaryDataPayload(const AAC_METADATA* const pMetadata, + UCHAR* const pExtensionPayload); static FDK_METADATA_ERROR CompensateAudioDelay( - HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, - INT_PCM * const pAudioSamples, - const INT nAudioSamples - ); + HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples, + const UINT audioSamplesBufSize, const INT nAudioSamples); static FDK_METADATA_ERROR LoadSubmittedMetadata( - const AACENC_MetaData * const hMetadata, - const INT nChannels, - const INT metadataMode, - AAC_METADATA * const pAacMetaData - ); - -static FDK_METADATA_ERROR ProcessCompressor( - AAC_METADATA *pMetadata, - HDRC_COMP hDrcComp, - const INT_PCM * const pSamples, - const INT nSamples - ); + const AACENC_MetaData* const hMetadata, const INT nChannels, + const INT metadataMode, AAC_METADATA* const pAacMetaData); + +static FDK_METADATA_ERROR ProcessCompressor(AAC_METADATA* pMetadata, + HDRC_COMP hDrcComp, + const INT_PCM* const pSamples, + const UINT samplesBufSize, + const INT nSamples); /*------------- function definitions ----------------*/ -static DRC_PROFILE convertProfile(AACENC_METADATA_DRC_PROFILE aacProfile) -{ - DRC_PROFILE drcProfile = DRC_NONE; - - switch(aacProfile) { - case AACENC_METADATA_DRC_NONE: drcProfile = DRC_NONE; break; - case AACENC_METADATA_DRC_FILMSTANDARD: drcProfile = DRC_FILMSTANDARD; break; - case AACENC_METADATA_DRC_FILMLIGHT: drcProfile = DRC_FILMLIGHT; break; - case AACENC_METADATA_DRC_MUSICSTANDARD: drcProfile = DRC_MUSICSTANDARD; break; - case AACENC_METADATA_DRC_MUSICLIGHT: drcProfile = DRC_MUSICLIGHT; break; - case AACENC_METADATA_DRC_SPEECH: drcProfile = DRC_SPEECH; break; - default: drcProfile = DRC_NONE; break; - } - return drcProfile; +static DRC_PROFILE convertProfile(AACENC_METADATA_DRC_PROFILE aacProfile) { + DRC_PROFILE drcProfile = DRC_NONE; + + switch (aacProfile) { + case AACENC_METADATA_DRC_NONE: + drcProfile = DRC_NONE; + break; + case AACENC_METADATA_DRC_FILMSTANDARD: + drcProfile = DRC_FILMSTANDARD; + break; + case AACENC_METADATA_DRC_FILMLIGHT: + drcProfile = DRC_FILMLIGHT; + break; + case AACENC_METADATA_DRC_MUSICSTANDARD: + drcProfile = DRC_MUSICSTANDARD; + break; + case AACENC_METADATA_DRC_MUSICLIGHT: + drcProfile = DRC_MUSICLIGHT; + break; + case AACENC_METADATA_DRC_SPEECH: + drcProfile = DRC_SPEECH; + break; + case AACENC_METADATA_DRC_NOT_PRESENT: + drcProfile = DRC_NOT_PRESENT; + break; + default: + drcProfile = DRC_NONE; + break; + } + return drcProfile; } - /* convert dialog normalization to program reference level */ -/* NOTE: this only is correct, if the decoder target level is set to -31dB for line mode / -20dB for RF mode */ -static UCHAR dialnorm2progreflvl(const INT d) -{ - return ((UCHAR)FDKmax(0, FDKmin((-d + (1<<13)) >> 14, 127))); +/* NOTE: this only is correct, if the decoder target level is set to -31dB for + * line mode / -20dB for RF mode */ +static UCHAR dialnorm2progreflvl(const INT d) { + return ((UCHAR)fMax(0, fMin((-d + (1 << 13)) >> 14, 127))); } /* convert program reference level to dialog normalization */ -static INT progreflvl2dialnorm(const UCHAR p) -{ - return -((INT)(p<<(16-2))); +static INT progreflvl2dialnorm(const UCHAR p) { + return -((INT)(p << (16 - 2))); } /* encode downmix levels to Downmixing_levels_MPEG4 */ -static SCHAR encodeDmxLvls(const SCHAR cmixlev, const SCHAR surmixlev) -{ - SCHAR dmxLvls = 0; - dmxLvls |= 0x80 | (cmixlev << 4); /* center_mix_level_on */ - dmxLvls |= 0x08 | surmixlev; /* surround_mix_level_on */ +static SCHAR encodeDmxLvls(const SCHAR cmixlev, const SCHAR surmixlev) { + SCHAR dmxLvls = 0; + dmxLvls |= 0x80 | (cmixlev << 4); /* center_mix_level_on */ + dmxLvls |= 0x08 | surmixlev; /* surround_mix_level_on */ - return dmxLvls; + return dmxLvls; } /* encode AAC DRC gain (ISO/IEC 14496-3:2005 4.5.2.7) */ -static void encodeDynrng(INT gain, UCHAR* const dyn_rng_ctl, UCHAR* const dyn_rng_sgn ) -{ - if(gain < 0) - { - *dyn_rng_sgn = 1; - gain = -gain; - } - else - { - *dyn_rng_sgn = 0; - } - gain = FDKmin(gain,(127<<14)); - - *dyn_rng_ctl = (UCHAR)((gain + (1<<13)) >> 14); +static void encodeDynrng(INT gain, UCHAR* const dyn_rng_ctl, + UCHAR* const dyn_rng_sgn) { + if (gain < 0) { + *dyn_rng_sgn = 1; + gain = -gain; + } else { + *dyn_rng_sgn = 0; + } + gain = fMin(gain, (127 << 14)); + + *dyn_rng_ctl = (UCHAR)((gain + (1 << 13)) >> 14); } /* decode AAC DRC gain (ISO/IEC 14496-3:2005 4.5.2.7) */ -static INT decodeDynrng(const UCHAR dyn_rng_ctl, const UCHAR dyn_rng_sgn) -{ - INT tmp = ((INT)dyn_rng_ctl << (16-2)); - if (dyn_rng_sgn) tmp = -tmp; +static INT decodeDynrng(const UCHAR dyn_rng_ctl, const UCHAR dyn_rng_sgn) { + INT tmp = ((INT)dyn_rng_ctl << (16 - 2)); + if (dyn_rng_sgn) tmp = -tmp; - return tmp; + return tmp; } /* encode AAC compression value (ETSI TS 101 154 page 99) */ -static UCHAR encodeCompr(INT gain) -{ - UCHAR x, y; - INT tmp; - - /* tmp = (int)((48.164f - gain) / 6.0206f * 15 + 0.5f); */ - tmp = ((3156476 - gain) * 15 + 197283) / 394566; - - if (tmp >= 240) { - return 0xFF; - } - else if (tmp < 0) { - return 0; - } - else { - x = tmp / 15; - y = tmp % 15; - } - - return (x << 4) | y; +static UCHAR encodeCompr(INT gain) { + UCHAR x, y; + INT tmp; + + /* tmp = (int)((48.164f - gain) / 6.0206f * 15 + 0.5f); */ + tmp = ((3156476 - gain) * 15 + 197283) / 394566; + + if (tmp >= 240) { + return 0xFF; + } else if (tmp < 0) { + return 0; + } else { + x = tmp / 15; + y = tmp % 15; + } + + return (x << 4) | y; } /* decode AAC compression value (ETSI TS 101 154 page 99) */ -static INT decodeCompr(const UCHAR compr) -{ - INT gain; - SCHAR x = compr >> 4; /* 4 MSB of compr */ - UCHAR y = (compr & 0x0F); /* 4 LSB of compr */ - - /* gain = (INT)((48.164f - 6.0206f * x - 0.4014f * y) ); */ - gain = (INT)( scaleValue(((LONG)FL2FXCONST_DBL(6.0206f/128.f)*(8-x) - (LONG)FL2FXCONST_DBL(0.4014f/128.f)*y), -(DFRACT_BITS-1-7-16)) ); - - return gain; +static INT decodeCompr(const UCHAR compr) { + INT gain; + SCHAR x = compr >> 4; /* 4 MSB of compr */ + UCHAR y = (compr & 0x0F); /* 4 LSB of compr */ + + /* gain = (INT)((48.164f - 6.0206f * x - 0.4014f * y) ); */ + gain = (INT)( + scaleValue((FIXP_DBL)(((LONG)FL2FXCONST_DBL(6.0206f / 128.f) * (8 - x) - + (LONG)FL2FXCONST_DBL(0.4014f / 128.f) * y)), + -(DFRACT_BITS - 1 - 7 - 16))); + + return gain; } - -FDK_METADATA_ERROR FDK_MetadataEnc_Open( - HANDLE_FDK_METADATA_ENCODER *phMetaData - ) -{ - FDK_METADATA_ERROR err = METADATA_OK; - HANDLE_FDK_METADATA_ENCODER hMetaData = NULL; - - if (phMetaData == NULL) { - err = METADATA_INVALID_HANDLE; - goto bail; - } - - /* allocate memory */ - hMetaData = (HANDLE_FDK_METADATA_ENCODER) FDKcalloc(1, sizeof(FDK_METADATA_ENCODER) ); - - if (hMetaData == NULL) { - err = METADATA_MEMORY_ERROR; - goto bail; - } - - FDKmemclear(hMetaData, sizeof(FDK_METADATA_ENCODER)); - - /* Allocate DRC Compressor. */ - if (FDK_DRC_Generator_Open(&hMetaData->hDrcComp)!=0) { - err = METADATA_MEMORY_ERROR; - goto bail; - } - - /* Return metadata instance */ - *phMetaData = hMetaData; - - return err; +FDK_METADATA_ERROR FDK_MetadataEnc_Open(HANDLE_FDK_METADATA_ENCODER* phMetaData, + const UINT maxChannels) { + FDK_METADATA_ERROR err = METADATA_OK; + HANDLE_FDK_METADATA_ENCODER hMetaData = NULL; + + if (phMetaData == NULL) { + err = METADATA_INVALID_HANDLE; + goto bail; + } + + /* allocate memory */ + if (NULL == (hMetaData = (HANDLE_FDK_METADATA_ENCODER)FDKcalloc( + 1, sizeof(FDK_METADATA_ENCODER)))) { + err = METADATA_MEMORY_ERROR; + goto bail; + } + FDKmemclear(hMetaData, sizeof(FDK_METADATA_ENCODER)); + + if (NULL == (hMetaData->pAudioDelayBuffer = (INT_PCM*)FDKcalloc( + maxChannels * MAX_DRC_FRAMELEN, sizeof(INT_PCM)))) { + err = METADATA_MEMORY_ERROR; + goto bail; + } + FDKmemclear(hMetaData->pAudioDelayBuffer, + maxChannels * MAX_DRC_FRAMELEN * sizeof(INT_PCM)); + hMetaData->maxChannels = maxChannels; + + /* Allocate DRC Compressor. */ + if (FDK_DRC_Generator_Open(&hMetaData->hDrcComp) != 0) { + err = METADATA_MEMORY_ERROR; + goto bail; + } + hMetaData->channelMode = MODE_UNKNOWN; + + /* Return metadata instance */ + *phMetaData = hMetaData; + + return err; bail: - FDK_MetadataEnc_Close(&hMetaData); - return err; + FDK_MetadataEnc_Close(&hMetaData); + return err; } FDK_METADATA_ERROR FDK_MetadataEnc_Close( - HANDLE_FDK_METADATA_ENCODER *phMetaData - ) -{ - FDK_METADATA_ERROR err = METADATA_OK; - - if (phMetaData == NULL) { - err = METADATA_INVALID_HANDLE; - goto bail; - } - - if (*phMetaData != NULL) { - FDK_DRC_Generator_Close(&(*phMetaData)->hDrcComp); - FDKfree(*phMetaData); - *phMetaData = NULL; - } + HANDLE_FDK_METADATA_ENCODER* phMetaData) { + FDK_METADATA_ERROR err = METADATA_OK; + + if (phMetaData == NULL) { + err = METADATA_INVALID_HANDLE; + goto bail; + } + + if (*phMetaData != NULL) { + FDK_DRC_Generator_Close(&(*phMetaData)->hDrcComp); + FDKfree((*phMetaData)->pAudioDelayBuffer); + FDKfree(*phMetaData); + *phMetaData = NULL; + } bail: - return err; + return err; } FDK_METADATA_ERROR FDK_MetadataEnc_Init( - HANDLE_FDK_METADATA_ENCODER hMetaData, - const INT resetStates, - const INT metadataMode, - const INT audioDelay, - const UINT frameLength, - const UINT sampleRate, - const UINT nChannels, - const CHANNEL_MODE channelMode, - const CHANNEL_ORDER channelOrder - ) -{ - FDK_METADATA_ERROR err = METADATA_OK; - int i, nFrames, delay; - - if (hMetaData==NULL) { - err = METADATA_INVALID_HANDLE; - goto bail; - } - - /* Determine values for delay compensation. */ - for (nFrames=0, delay=audioDelay-frameLength; delay>0; delay-=frameLength, nFrames++); - - if ( (hMetaData->nChannels>MAX_DRC_CHANNELS) || ((-delay)>MAX_DRC_FRAMELEN) ) { - err = METADATA_INIT_ERROR; - goto bail; - } - - /* Initialize with default setup. */ - FDKmemcpy(&hMetaData->submittedMetaData, &defaultMetaDataSetup, sizeof(AACENC_MetaData)); - - hMetaData->finalizeMetaData = 0; /* finalize meta data only while on/off switching, else disabled */ - - /* Reset delay lines. */ - if ( resetStates || (hMetaData->nAudioDataDelay!=-delay) || (hMetaData->nChannels!=(INT)nChannels) ) - { - FDKmemclear(hMetaData->audioDelayBuffer, sizeof(hMetaData->audioDelayBuffer)); - FDKmemclear(hMetaData->metaDataBuffer, sizeof(hMetaData->metaDataBuffer)); - hMetaData->audioDelayIdx = 0; - hMetaData->metaDataDelayIdx = 0; - } - else { - /* Enable meta data. */ - if ( (hMetaData->metadataMode==0) && (metadataMode!=0) ) { - /* disable meta data in all delay lines */ - for (i=0; i<(int)(sizeof(hMetaData->metaDataBuffer)/sizeof(AAC_METADATA)); i++) { - LoadSubmittedMetadata(&hMetaData->submittedMetaData, nChannels, 0, &hMetaData->metaDataBuffer[i]); - } + HANDLE_FDK_METADATA_ENCODER hMetaData, const INT resetStates, + const INT metadataMode, const INT audioDelay, const UINT frameLength, + const UINT sampleRate, const UINT nChannels, const CHANNEL_MODE channelMode, + const CHANNEL_ORDER channelOrder) { + FDK_METADATA_ERROR err = METADATA_OK; + int i, nFrames, delay; + + if (hMetaData == NULL) { + err = METADATA_INVALID_HANDLE; + goto bail; + } + + /* Determine values for delay compensation. */ + for (nFrames = 0, delay = audioDelay - (INT)frameLength; delay > 0; + delay -= (INT)frameLength, nFrames++) + ; + + if ((nChannels > (8)) || (nChannels > hMetaData->maxChannels) || + ((-delay) > MAX_DRC_FRAMELEN) || nFrames >= MAX_DELAY_FRAMES) { + err = METADATA_INIT_ERROR; + goto bail; + } + + /* Initialize with default setup. */ + FDKmemcpy(&hMetaData->submittedMetaData, &defaultMetaDataSetup, + sizeof(AACENC_MetaData)); + + hMetaData->finalizeMetaData = + 0; /* finalize meta data only while on/off switching, else disabled */ + hMetaData->initializeMetaData = + 0; /* fill up meta data delay line only at a reset otherwise disabled */ + + /* Reset delay lines. */ + if (resetStates || (hMetaData->nAudioDataDelay != -delay) || + (hMetaData->channelMode != channelMode)) { + if (resetStates || (hMetaData->channelMode == MODE_UNKNOWN)) { + /* clear delay buffer */ + FDKmemclear(hMetaData->pAudioDelayBuffer, + hMetaData->maxChannels * MAX_DRC_FRAMELEN * sizeof(INT_PCM)); + } else { + /* if possible, keep static audio channels for seamless channel + * reconfiguration */ + FDK_channelMapDescr mapDescrPrev, mapDescr; + int c, src[2] = {-1, -1}, dst[2] = {-1, -1}; + + FDK_chMapDescr_init(&mapDescrPrev, NULL, 0, + (channelOrder == CH_ORDER_MPEG) ? 1 : 0); + FDK_chMapDescr_init(&mapDescr, NULL, 0, + (channelOrder == CH_ORDER_MPEG) ? 1 : 0); + + switch (channelMode) { + case MODE_1: + if ((INT)nChannels != 2) { + /* preserve center channel */ + src[0] = FDK_chMapDescr_getMapValue(&mapDescrPrev, 0, + hMetaData->channelMode); + dst[0] = FDK_chMapDescr_getMapValue(&mapDescr, 0, channelMode); + } + break; + case MODE_2: + case MODE_1_2: + case MODE_1_2_1: + case MODE_1_2_2: + case MODE_1_2_2_1: + if (hMetaData->nChannels >= 2) { + /* preserve left/right channel */ + src[0] = FDK_chMapDescr_getMapValue( + &mapDescrPrev, ((hMetaData->channelMode == 2) ? 0 : 1), + hMetaData->channelMode); + src[1] = FDK_chMapDescr_getMapValue( + &mapDescrPrev, ((hMetaData->channelMode == 2) ? 1 : 2), + hMetaData->channelMode); + dst[0] = FDK_chMapDescr_getMapValue( + &mapDescr, ((channelMode == 2) ? 0 : 1), channelMode); + dst[1] = FDK_chMapDescr_getMapValue( + &mapDescr, ((channelMode == 2) ? 1 : 2), channelMode); + } + break; + default:; } + C_ALLOC_SCRATCH_START(scratch_audioDelayBuffer, INT_PCM, (8)); + FDKmemclear(scratch_audioDelayBuffer, (8) * sizeof(INT_PCM)); + + i = (hMetaData->nChannels > (INT)nChannels) + ? 0 + : hMetaData->nAudioDataDelay - 1; + do { + for (c = 0; c < 2; c++) { + if (src[c] != -1 && dst[c] != -1) { + scratch_audioDelayBuffer[dst[c]] = + hMetaData->pAudioDelayBuffer[i * hMetaData->nChannels + src[c]]; + } + } + FDKmemcpy(&hMetaData->pAudioDelayBuffer[i * nChannels], + scratch_audioDelayBuffer, nChannels * sizeof(INT_PCM)); + i += (hMetaData->nChannels > (INT)nChannels) ? 1 : -1; + } while ((i < hMetaData->nAudioDataDelay) && (i >= 0)); - /* Disable meta data.*/ - if ( (hMetaData->metadataMode!=0) && (metadataMode==0) ) { - hMetaData->finalizeMetaData = hMetaData->metadataMode; + C_ALLOC_SCRATCH_END(scratch_audioDelayBuffer, INT_PCM, (8)); + } + FDKmemclear(hMetaData->metaDataBuffer, sizeof(hMetaData->metaDataBuffer)); + hMetaData->metaDataDelayIdx = 0; + hMetaData->initializeMetaData = + 1; /* fill up delay line with first meta data info */ + } else { + /* Enable meta data. */ + if ((hMetaData->metadataMode == 0) && (metadataMode != 0)) { + /* disable meta data in all delay lines */ + for (i = 0; + i < (int)(sizeof(hMetaData->metaDataBuffer) / sizeof(AAC_METADATA)); + i++) { + LoadSubmittedMetadata(&hMetaData->submittedMetaData, nChannels, 0, + &hMetaData->metaDataBuffer[i]); } } - /* Initialize delay. */ - hMetaData->nAudioDataDelay = -delay; - hMetaData->nMetaDataDelay = nFrames; - hMetaData->nChannels = nChannels; - hMetaData->metadataMode = metadataMode; - - /* Initialize compressor. */ - if (metadataMode != 0) { - if ( FDK_DRC_Generator_Initialize( - hMetaData->hDrcComp, - DRC_NONE, - DRC_NONE, - frameLength, - sampleRate, - channelMode, - channelOrder, - 1) != 0) - { - err = METADATA_INIT_ERROR; - } + /* Disable meta data.*/ + if ((hMetaData->metadataMode != 0) && (metadataMode == 0)) { + hMetaData->finalizeMetaData = hMetaData->metadataMode; + } + } + + /* Initialize delay. */ + hMetaData->nAudioDataDelay = -delay; + hMetaData->nMetaDataDelay = nFrames; + hMetaData->nChannels = nChannels; + hMetaData->channelMode = channelMode; + hMetaData->metadataMode = metadataMode; + + /* Initialize compressor. */ + if ((metadataMode == 1) || (metadataMode == 2)) { + if (FDK_DRC_Generator_Initialize(hMetaData->hDrcComp, DRC_NONE, DRC_NONE, + frameLength, sampleRate, channelMode, + channelOrder, 1) != 0) { + err = METADATA_INIT_ERROR; } + } bail: - return err; + return err; } -static FDK_METADATA_ERROR ProcessCompressor( - AAC_METADATA *pMetadata, - HDRC_COMP hDrcComp, - const INT_PCM * const pSamples, - const INT nSamples - ) -{ - FDK_METADATA_ERROR err = METADATA_OK; - - if ( (pMetadata==NULL) || (hDrcComp==NULL) ) { - err = METADATA_INVALID_HANDLE; - return err; - } - DRC_PROFILE profileDrc = convertProfile(pMetadata->mpegDrc.drc_profile); - DRC_PROFILE profileComp = convertProfile(pMetadata->etsiAncData.comp_profile); +static FDK_METADATA_ERROR ProcessCompressor(AAC_METADATA* pMetadata, + HDRC_COMP hDrcComp, + const INT_PCM* const pSamples, + const UINT samplesBufSize, + const INT nSamples) { + FDK_METADATA_ERROR err = METADATA_OK; - /* first, check if profile is same as last frame - * otherwise, update setup */ - if ( (profileDrc != FDK_DRC_Generator_getDrcProfile(hDrcComp)) - || (profileComp != FDK_DRC_Generator_getCompProfile(hDrcComp)) ) - { - FDK_DRC_Generator_setDrcProfile(hDrcComp, profileDrc, profileComp); - } + INT dynrng, compr; + INT dmxGain5, dmxGain2; + DRC_PROFILE profileDrc; + DRC_PROFILE profileComp; - /* Sanity check */ - if (profileComp == DRC_NONE) { - pMetadata->etsiAncData.compression_value = 0x80; /* to ensure no external values will be written if not configured */ - } - - /* in case of embedding external values, copy this now (limiter may overwrite them) */ - INT dynrng = decodeDynrng(pMetadata->mpegDrc.dyn_rng_ctl[0], pMetadata->mpegDrc.dyn_rng_sgn[0]); - INT compr = decodeCompr(pMetadata->etsiAncData.compression_value); - - /* Call compressor */ - if (FDK_DRC_Generator_Calc(hDrcComp, - pSamples, - progreflvl2dialnorm(pMetadata->mpegDrc.prog_ref_level), - pMetadata->mpegDrc.drc_TargetRefLevel, - pMetadata->etsiAncData.comp_TargetRefLevel, - dmxTable[pMetadata->centerMixLevel], - dmxTable[pMetadata->surroundMixLevel], - &dynrng, - &compr) != 0) - { - err = METADATA_ENCODE_ERROR; - goto bail; - } - - /* Write DRC values */ - pMetadata->mpegDrc.drc_band_incr = 0; - encodeDynrng(dynrng, pMetadata->mpegDrc.dyn_rng_ctl, pMetadata->mpegDrc.dyn_rng_sgn); - pMetadata->etsiAncData.compression_value = encodeCompr(compr); + if ((pMetadata == NULL) || (hDrcComp == NULL)) { + err = METADATA_INVALID_HANDLE; + return err; + } + + profileDrc = convertProfile(pMetadata->mpegDrc.drc_profile); + profileComp = convertProfile(pMetadata->etsiAncData.comp_profile); + + /* first, check if profile is same as last frame + * otherwise, update setup */ + if ((profileDrc != FDK_DRC_Generator_getDrcProfile(hDrcComp)) || + (profileComp != FDK_DRC_Generator_getCompProfile(hDrcComp))) { + FDK_DRC_Generator_setDrcProfile(hDrcComp, profileDrc, profileComp); + } + + /* Sanity check */ + if (profileComp == DRC_NONE) { + pMetadata->etsiAncData.compression_value = 0x80; /* to ensure no external + values will be written + if not configured */ + } + + /* in case of embedding external values, copy this now (limiter may overwrite + * them) */ + dynrng = decodeDynrng(pMetadata->mpegDrc.dyn_rng_ctl[0], + pMetadata->mpegDrc.dyn_rng_sgn[0]); + compr = decodeCompr(pMetadata->etsiAncData.compression_value); + + dmxGain5 = decodeDynrng(pMetadata->etsiAncData.extAncData.dmx_gain_5_idx, + pMetadata->etsiAncData.extAncData.dmx_gain_5_sgn); + dmxGain2 = decodeDynrng(pMetadata->etsiAncData.extAncData.dmx_gain_2_idx, + pMetadata->etsiAncData.extAncData.dmx_gain_2_sgn); + + /* Call compressor */ + if (FDK_DRC_Generator_Calc( + hDrcComp, pSamples, samplesBufSize, + progreflvl2dialnorm(pMetadata->mpegDrc.prog_ref_level), + pMetadata->mpegDrc.drc_TargetRefLevel, + pMetadata->etsiAncData.comp_TargetRefLevel, + dmxTable[pMetadata->centerMixLevel], + dmxTable[pMetadata->surroundMixLevel], + dmxTable[pMetadata->etsiAncData.extAncData.ext_dmix_a_idx], + dmxTable[pMetadata->etsiAncData.extAncData.ext_dmix_b_idx], + pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status + ? dmxLfeTable[pMetadata->etsiAncData.extAncData.ext_dmix_lfe_idx] + : (FIXP_DBL)0, + dmxGain5, dmxGain2, &dynrng, &compr) != 0) { + err = METADATA_ENCODE_ERROR; + goto bail; + } + + /* Write DRC values */ + pMetadata->mpegDrc.drc_band_incr = 0; + encodeDynrng(dynrng, pMetadata->mpegDrc.dyn_rng_ctl, + pMetadata->mpegDrc.dyn_rng_sgn); + pMetadata->etsiAncData.compression_value = encodeCompr(compr); bail: - return err; + return err; } FDK_METADATA_ERROR FDK_MetadataEnc_Process( - HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, - INT_PCM * const pAudioSamples, - const INT nAudioSamples, - const AACENC_MetaData * const pMetadata, - AACENC_EXT_PAYLOAD ** ppMetaDataExtPayload, - UINT * nMetaDataExtensions, - INT * matrix_mixdown_idx - ) -{ - FDK_METADATA_ERROR err = METADATA_OK; - int metaDataDelayWriteIdx, metaDataDelayReadIdx, metadataMode; - - /* Where to write new meta data info */ - metaDataDelayWriteIdx = hMetaDataEnc->metaDataDelayIdx; - - /* How to write the data */ - metadataMode = hMetaDataEnc->metadataMode; - - /* Compensate meta data delay. */ - hMetaDataEnc->metaDataDelayIdx++; - if (hMetaDataEnc->metaDataDelayIdx > hMetaDataEnc->nMetaDataDelay) hMetaDataEnc->metaDataDelayIdx = 0; - - /* Where to read pending meta data info from. */ - metaDataDelayReadIdx = hMetaDataEnc->metaDataDelayIdx; - - /* Submit new data if available. */ - if (pMetadata!=NULL) { - FDKmemcpy(&hMetaDataEnc->submittedMetaData, pMetadata, sizeof(AACENC_MetaData)); + HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples, + const UINT audioSamplesBufSize, const INT nAudioSamples, + const AACENC_MetaData* const pMetadata, + AACENC_EXT_PAYLOAD** ppMetaDataExtPayload, UINT* nMetaDataExtensions, + INT* matrix_mixdown_idx) { + FDK_METADATA_ERROR err = METADATA_OK; + int metaDataDelayWriteIdx, metaDataDelayReadIdx, metadataMode; + + /* Where to write new meta data info */ + metaDataDelayWriteIdx = hMetaDataEnc->metaDataDelayIdx; + + /* How to write the data */ + metadataMode = hMetaDataEnc->metadataMode; + + /* Compensate meta data delay. */ + hMetaDataEnc->metaDataDelayIdx++; + if (hMetaDataEnc->metaDataDelayIdx > hMetaDataEnc->nMetaDataDelay) + hMetaDataEnc->metaDataDelayIdx = 0; + + /* Where to read pending meta data info from. */ + metaDataDelayReadIdx = hMetaDataEnc->metaDataDelayIdx; + + /* Submit new data if available. */ + if (pMetadata != NULL) { + FDKmemcpy(&hMetaDataEnc->submittedMetaData, pMetadata, + sizeof(AACENC_MetaData)); + } + + /* Write one additional frame with default configuration of meta data. Ensure + * defined behaviour on decoder side. */ + if ((hMetaDataEnc->finalizeMetaData != 0) && + (hMetaDataEnc->metadataMode == 0)) { + FDKmemcpy(&hMetaDataEnc->submittedMetaData, &defaultMetaDataSetup, + sizeof(AACENC_MetaData)); + metadataMode = hMetaDataEnc->finalizeMetaData; + hMetaDataEnc->finalizeMetaData = 0; + } + + /* Get last submitted data. */ + if ((err = LoadSubmittedMetadata( + &hMetaDataEnc->submittedMetaData, hMetaDataEnc->nChannels, + metadataMode, + &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx])) != + METADATA_OK) { + goto bail; + } + + /* Calculate compressor if necessary and updata meta data info */ + if ((hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode == 1) || + (hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode == 2)) { + if ((err = ProcessCompressor( + &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx], + hMetaDataEnc->hDrcComp, pAudioSamples, audioSamplesBufSize, + nAudioSamples)) != METADATA_OK) { + /* Get last submitted data again. */ + LoadSubmittedMetadata( + &hMetaDataEnc->submittedMetaData, hMetaDataEnc->nChannels, + metadataMode, &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]); } - - /* Write one additional frame with default configuration of meta data. Ensure defined behaviour on decoder side. */ - if ( (hMetaDataEnc->finalizeMetaData!=0) && (hMetaDataEnc->metadataMode==0)) { - FDKmemcpy(&hMetaDataEnc->submittedMetaData, &defaultMetaDataSetup, sizeof(AACENC_MetaData)); - metadataMode = hMetaDataEnc->finalizeMetaData; - hMetaDataEnc->finalizeMetaData = 0; - } - - /* Get last submitted data. */ - if ( (err = LoadSubmittedMetadata( - &hMetaDataEnc->submittedMetaData, - hMetaDataEnc->nChannels, - metadataMode, - &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx])) != METADATA_OK ) - { - goto bail; - } - - /* Calculate compressor if necessary and updata meta data info */ - if (hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode != 0) { - if ( (err = ProcessCompressor( - &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx], - hMetaDataEnc->hDrcComp, - pAudioSamples, - nAudioSamples)) != METADATA_OK) - { - /* Get last submitted data again. */ - LoadSubmittedMetadata( - &hMetaDataEnc->submittedMetaData, - hMetaDataEnc->nChannels, - metadataMode, - &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]); + } + + /* Fill up delay line with initial meta data info.*/ + if ((hMetaDataEnc->initializeMetaData != 0) && + (hMetaDataEnc->metadataMode != 0)) { + int i; + for (i = 0; + i < (int)(sizeof(hMetaDataEnc->metaDataBuffer) / sizeof(AAC_METADATA)); + i++) { + if (i != metaDataDelayWriteIdx) { + FDKmemcpy(&hMetaDataEnc->metaDataBuffer[i], + &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx], + sizeof(hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx])); } } - - /* Convert Meta Data side info to bitstream data. */ - if ( (err = WriteMetadataPayload(hMetaDataEnc, &hMetaDataEnc->metaDataBuffer[metaDataDelayReadIdx])) != METADATA_OK ) { - goto bail; - } - - /* Assign meta data to output */ - *ppMetaDataExtPayload = hMetaDataEnc->exPayload; - *nMetaDataExtensions = hMetaDataEnc->nExtensions; - *matrix_mixdown_idx = hMetaDataEnc->matrix_mixdown_idx; + hMetaDataEnc->initializeMetaData = 0; + } + + /* Convert Meta Data side info to bitstream data. */ + FDK_ASSERT(metaDataDelayReadIdx < MAX_DELAY_FRAMES); + if ((err = WriteMetadataPayload( + hMetaDataEnc, + &hMetaDataEnc->metaDataBuffer[metaDataDelayReadIdx])) != + METADATA_OK) { + goto bail; + } + + /* Assign meta data to output */ + *ppMetaDataExtPayload = hMetaDataEnc->exPayload; + *nMetaDataExtensions = hMetaDataEnc->nExtensions; + *matrix_mixdown_idx = hMetaDataEnc->matrix_mixdown_idx; bail: - /* Compensate audio delay, reset err status. */ - err = CompensateAudioDelay(hMetaDataEnc, pAudioSamples, nAudioSamples); + /* Compensate audio delay, reset err status. */ + err = CompensateAudioDelay(hMetaDataEnc, pAudioSamples, audioSamplesBufSize, + nAudioSamples / hMetaDataEnc->nChannels); - return err; + return err; } - static FDK_METADATA_ERROR CompensateAudioDelay( - HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, - INT_PCM * const pAudioSamples, - const INT nAudioSamples - ) -{ - FDK_METADATA_ERROR err = METADATA_OK; - - if (hMetaDataEnc->nAudioDataDelay) { - int i, delaySamples = hMetaDataEnc->nAudioDataDelay*hMetaDataEnc->nChannels; - - for (i = 0; i < nAudioSamples; i++) { - INT_PCM tmp = pAudioSamples[i]; - pAudioSamples[i] = hMetaDataEnc->audioDelayBuffer[hMetaDataEnc->audioDelayIdx]; - hMetaDataEnc->audioDelayBuffer[hMetaDataEnc->audioDelayIdx] = tmp; - - hMetaDataEnc->audioDelayIdx++; - if (hMetaDataEnc->audioDelayIdx >= delaySamples) hMetaDataEnc->audioDelayIdx = 0; - } + HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples, + const UINT audioSamplesBufSize, const INT nAudioSamples) { + FDK_METADATA_ERROR err = METADATA_OK; + + if (hMetaDataEnc->nAudioDataDelay) { + C_ALLOC_SCRATCH_START(scratch_audioDelayBuffer, INT_PCM, 1024); + + for (int c = 0; c < hMetaDataEnc->nChannels; c++) { + int M = 1024; + INT_PCM* pAudioSamples2 = pAudioSamples + c * audioSamplesBufSize; + int delayIdx = hMetaDataEnc->nAudioDataDelay; + + do { + M = fMin(M, delayIdx); + delayIdx -= M; + + FDKmemcpy(&scratch_audioDelayBuffer[0], + &pAudioSamples2[(nAudioSamples - M)], sizeof(INT_PCM) * M); + FDKmemmove(&pAudioSamples2[M], &pAudioSamples2[0], + sizeof(INT_PCM) * (nAudioSamples - M)); + FDKmemcpy( + &pAudioSamples2[0], + &hMetaDataEnc->pAudioDelayBuffer[delayIdx + + c * hMetaDataEnc->nAudioDataDelay], + sizeof(INT_PCM) * M); + FDKmemcpy( + &hMetaDataEnc->pAudioDelayBuffer[delayIdx + + c * hMetaDataEnc->nAudioDataDelay], + &scratch_audioDelayBuffer[0], sizeof(INT_PCM) * M); + + } while (delayIdx > 0); } - return err; + C_ALLOC_SCRATCH_END(scratch_audioDelayBuffer, INT_PCM, 1024); + } + + return err; } /*----------------------------------------------------------------------------- @@ -651,219 +808,377 @@ static FDK_METADATA_ERROR CompensateAudioDelay( ------------------------------------------------------------------------------*/ static FDK_METADATA_ERROR WriteMetadataPayload( - const HANDLE_FDK_METADATA_ENCODER hMetaData, - const AAC_METADATA * const pMetadata - ) -{ - FDK_METADATA_ERROR err = METADATA_OK; - - if ( (hMetaData==NULL) || (pMetadata==NULL) ) { - err = METADATA_INVALID_HANDLE; - goto bail; - } + const HANDLE_FDK_METADATA_ENCODER hMetaData, + const AAC_METADATA* const pMetadata) { + FDK_METADATA_ERROR err = METADATA_OK; - hMetaData->nExtensions = 0; - hMetaData->matrix_mixdown_idx = -1; + if ((hMetaData == NULL) || (pMetadata == NULL)) { + err = METADATA_INVALID_HANDLE; + goto bail; + } - /* AAC-DRC */ - if (pMetadata->metadataMode != 0) - { - hMetaData->exPayload[hMetaData->nExtensions].pData = hMetaData->drcInfoPayload; - hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DYNAMIC_RANGE; - hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1; - - hMetaData->exPayload[hMetaData->nExtensions].dataSize = - WriteDynamicRangeInfoPayload(pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData); + hMetaData->nExtensions = 0; + hMetaData->matrix_mixdown_idx = -1; - hMetaData->nExtensions++; - - /* Matrix Mixdown Coefficient in PCE */ - if (pMetadata->WritePCEMixDwnIdx) { - hMetaData->matrix_mixdown_idx = surmix2matrix_mixdown_idx[pMetadata->surroundMixLevel]; - } + if (pMetadata->metadataMode != 0) { + /* AAC-DRC */ + if ((pMetadata->metadataMode == 1) || (pMetadata->metadataMode == 2)) { + hMetaData->exPayload[hMetaData->nExtensions].pData = + hMetaData->drcInfoPayload; + hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DYNAMIC_RANGE; + hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1; + + hMetaData->exPayload[hMetaData->nExtensions].dataSize = + WriteDynamicRangeInfoPayload( + pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData); + + hMetaData->nExtensions++; + } /* pMetadata->metadataMode==1 || pMetadata->metadataMode==2 */ + + /* Matrix Mixdown Coefficient in PCE */ + if (pMetadata->WritePCEMixDwnIdx) { + hMetaData->matrix_mixdown_idx = + surmix2matrix_mixdown_idx[pMetadata->surroundMixLevel]; + } - /* ETSI TS 101 154 (DVB) - MPEG4 ancillary_data() */ - if (pMetadata->metadataMode == 2) /* MP4_METADATA_MPEG_ETSI */ - { - hMetaData->exPayload[hMetaData->nExtensions].pData = hMetaData->drcDsePayload; - hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DATA_ELEMENT; - hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1; + /* ETSI TS 101 154 (DVB) - MPEG4 ancillary_data() */ + if ((pMetadata->metadataMode == 2) || + (pMetadata->metadataMode == 3)) /* MP4_METADATA_MPEG_ETSI */ + { + hMetaData->exPayload[hMetaData->nExtensions].pData = + hMetaData->drcDsePayload; + hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DATA_ELEMENT; + hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1; - hMetaData->exPayload[hMetaData->nExtensions].dataSize = - WriteEtsiAncillaryDataPayload(pMetadata,hMetaData->exPayload[hMetaData->nExtensions].pData); + hMetaData->exPayload[hMetaData->nExtensions].dataSize = + WriteEtsiAncillaryDataPayload( + pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData); - hMetaData->nExtensions++; - } /* metadataMode == 2 */ + hMetaData->nExtensions++; + } /* metadataMode==2 || metadataMode==3 */ - } /* metadataMode != 0 */ + } /* metadataMode != 0 */ bail: - return err; + return err; } -static INT WriteDynamicRangeInfoPayload( - const AAC_METADATA* const pMetadata, - UCHAR* const pExtensionPayload - ) -{ - const INT pce_tag_present = 0; /* yet fixed setting! */ - const INT prog_ref_lev_res_bits = 0; - INT i, drc_num_bands = 1; - - FDK_BITSTREAM bsWriter; - FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER); - - /* dynamic_range_info() */ - FDKwriteBits(&bsWriter, pce_tag_present, 1); /* pce_tag_present */ - if (pce_tag_present) { - FDKwriteBits(&bsWriter, 0x0, 4); /* pce_instance_tag */ - FDKwriteBits(&bsWriter, 0x0, 4); /* drc_tag_reserved_bits */ - } - - /* Exclude channels */ - FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.excluded_chns_present) ? 1 : 0, 1); /* excluded_chns_present*/ - - /* Multiband DRC */ - FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.drc_bands_present) ? 1 : 0, 1); /* drc_bands_present */ - if (pMetadata->mpegDrc.drc_bands_present) - { - FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_incr, 4); /* drc_band_incr */ - FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_interpolation_scheme, 4); /* drc_interpolation_scheme */ - drc_num_bands += pMetadata->mpegDrc.drc_band_incr; - for (i=0; impegDrc.drc_band_top[i], 8); /* drc_band_top */ - } - } - - /* Program Reference Level */ - FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level_present, 1); /* prog_ref_level_present */ - if (pMetadata->mpegDrc.prog_ref_level_present) - { - FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level, 7); /* prog_ref_level */ - FDKwriteBits(&bsWriter, prog_ref_lev_res_bits, 1); /* prog_ref_level_reserved_bits */ - } - - /* DRC Values */ - for (i=0; impegDrc.dyn_rng_sgn[i]) ? 1 : 0, 1); /* dyn_rng_sgn[ */ - FDKwriteBits(&bsWriter, pMetadata->mpegDrc.dyn_rng_ctl[i], 7); /* dyn_rng_ctl */ +static INT WriteDynamicRangeInfoPayload(const AAC_METADATA* const pMetadata, + UCHAR* const pExtensionPayload) { + const INT pce_tag_present = 0; /* yet fixed setting! */ + const INT prog_ref_lev_res_bits = 0; + INT i, drc_num_bands = 1; + + FDK_BITSTREAM bsWriter; + FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER); + + /* dynamic_range_info() */ + FDKwriteBits(&bsWriter, pce_tag_present, 1); /* pce_tag_present */ + if (pce_tag_present) { + FDKwriteBits(&bsWriter, 0x0, 4); /* pce_instance_tag */ + FDKwriteBits(&bsWriter, 0x0, 4); /* drc_tag_reserved_bits */ + } + + /* Exclude channels */ + FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.excluded_chns_present) ? 1 : 0, + 1); /* excluded_chns_present*/ + + /* Multiband DRC */ + FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.drc_bands_present) ? 1 : 0, + 1); /* drc_bands_present */ + if (pMetadata->mpegDrc.drc_bands_present) { + FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_incr, + 4); /* drc_band_incr */ + FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_interpolation_scheme, + 4); /* drc_interpolation_scheme */ + drc_num_bands += pMetadata->mpegDrc.drc_band_incr; + for (i = 0; i < drc_num_bands; i++) { + FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_top[i], + 8); /* drc_band_top */ } - - /* return number of valid bits in extension payload. */ - return FDKgetValidBits(&bsWriter); + } + + /* Program Reference Level */ + FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level_present, + 1); /* prog_ref_level_present */ + if (pMetadata->mpegDrc.prog_ref_level_present) { + FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level, + 7); /* prog_ref_level */ + FDKwriteBits(&bsWriter, prog_ref_lev_res_bits, + 1); /* prog_ref_level_reserved_bits */ + } + + /* DRC Values */ + for (i = 0; i < drc_num_bands; i++) { + FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.dyn_rng_sgn[i]) ? 1 : 0, + 1); /* dyn_rng_sgn[ */ + FDKwriteBits(&bsWriter, pMetadata->mpegDrc.dyn_rng_ctl[i], + 7); /* dyn_rng_ctl */ + } + + /* return number of valid bits in extension payload. */ + return FDKgetValidBits(&bsWriter); } -static INT WriteEtsiAncillaryDataPayload( - const AAC_METADATA* const pMetadata, - UCHAR* const pExtensionPayload - ) -{ - FDK_BITSTREAM bsWriter; - FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER); - - /* ancillary_data_sync */ - FDKwriteBits(&bsWriter, 0xBC, 8); - - /* bs_info */ - FDKwriteBits(&bsWriter, 0x3, 2); /* mpeg_audio_type */ - FDKwriteBits(&bsWriter, pMetadata->dolbySurroundMode, 2); /* dolby_surround_mode */ - FDKwriteBits(&bsWriter, 0x0, 4); /* reserved */ - - /* ancillary_data_status */ - FDKwriteBits(&bsWriter, 0, 3); /* 3 bit Reserved, set to "0" */ - FDKwriteBits(&bsWriter, (pMetadata->DmxLvl_On) ? 1 : 0, 1); /* downmixing_levels_MPEG4_status */ - FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */ - FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.compression_on) ? 1 : 0, 1); /* audio_coding_mode_and_compression status */ - FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_coarse_status) ? 1 : 0, 1); /* coarse_grain_timecode_status */ - FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_fine_status) ? 1 : 0, 1); /* fine_grain_timecode_status */ - - /* downmixing_levels_MPEG4_status */ - if (pMetadata->DmxLvl_On) { - FDKwriteBits(&bsWriter, encodeDmxLvls(pMetadata->centerMixLevel, pMetadata->surroundMixLevel), 8); - } - - /* audio_coding_mode_and_compression_status */ - if (pMetadata->etsiAncData.compression_on) { - FDKwriteBits(&bsWriter, 0x01, 8); /* audio coding mode */ - FDKwriteBits(&bsWriter, pMetadata->etsiAncData.compression_value, 8); /* compression value */ +static INT WriteEtsiAncillaryDataPayload(const AAC_METADATA* const pMetadata, + UCHAR* const pExtensionPayload) { + FDK_BITSTREAM bsWriter; + FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER); + + /* ancillary_data_sync */ + FDKwriteBits(&bsWriter, 0xBC, 8); + + /* bs_info */ + FDKwriteBits(&bsWriter, 0x3, 2); /* mpeg_audio_type */ + FDKwriteBits(&bsWriter, pMetadata->dolbySurroundMode, + 2); /* dolby_surround_mode */ + FDKwriteBits(&bsWriter, pMetadata->drcPresentationMode, + 2); /* DRC presentation mode */ + FDKwriteBits(&bsWriter, 0x0, 1); /* stereo_downmix_mode */ + FDKwriteBits(&bsWriter, 0x0, 1); /* reserved */ + + /* ancillary_data_status */ + FDKwriteBits(&bsWriter, 0, 3); /* 3 bit Reserved, set to "0" */ + FDKwriteBits(&bsWriter, (pMetadata->DmxLvl_On) ? 1 : 0, + 1); /* downmixing_levels_MPEG4_status */ + FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncDataStatus, + 1); /* ext_anc_data_status */ + FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.compression_on) ? 1 : 0, + 1); /* audio_coding_mode_and_compression status */ + FDKwriteBits(&bsWriter, + (pMetadata->etsiAncData.timecode_coarse_status) ? 1 : 0, + 1); /* coarse_grain_timecode_status */ + FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_fine_status) ? 1 : 0, + 1); /* fine_grain_timecode_status */ + + /* downmixing_levels_MPEG4_status */ + if (pMetadata->DmxLvl_On) { + FDKwriteBits( + &bsWriter, + encodeDmxLvls(pMetadata->centerMixLevel, pMetadata->surroundMixLevel), + 8); + } + + /* audio_coding_mode_and_compression_status */ + if (pMetadata->etsiAncData.compression_on) { + FDKwriteBits(&bsWriter, 0x01, 8); /* audio coding mode */ + FDKwriteBits(&bsWriter, pMetadata->etsiAncData.compression_value, + 8); /* compression value */ + } + + /* grain-timecode coarse/fine */ + if (pMetadata->etsiAncData.timecode_coarse_status) { + FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */ + } + + if (pMetadata->etsiAncData.timecode_fine_status) { + FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */ + } + + /* extended ancillary data structure */ + if (pMetadata->etsiAncData.extAncDataStatus) { + /* ext_ancillary_data_status */ + FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */ + FDKwriteBits(&bsWriter, + pMetadata->etsiAncData.extAncData.ext_downmix_lvl_status, + 1); /* ext_downmixing_levels_status */ + FDKwriteBits(&bsWriter, + pMetadata->etsiAncData.extAncData.ext_downmix_gain_status, + 1); /* ext_downmixing_global_gains_status */ + FDKwriteBits(&bsWriter, + pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status, + 1); /* ext_downmixing_lfe_level_status" */ + FDKwriteBits(&bsWriter, 0, 4); /* Reserved, set to "0" */ + + /* ext_downmixing_levels */ + if (pMetadata->etsiAncData.extAncData.ext_downmix_lvl_status) { + FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.ext_dmix_a_idx, + 3); /* dmix_a_idx */ + FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.ext_dmix_b_idx, + 3); /* dmix_b_idx */ + FDKwriteBits(&bsWriter, 0, 2); /* Reserved, set to "0" */ } - /* grain-timecode coarse/fine */ - if (pMetadata->etsiAncData.timecode_coarse_status) { - FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */ + /* ext_downmixing_gains */ + if (pMetadata->etsiAncData.extAncData.ext_downmix_gain_status) { + FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_5_sgn, + 1); /* dmx_gain_5_sign */ + FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_5_idx, + 6); /* dmx_gain_5_idx */ + FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */ + FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_2_sgn, + 1); /* dmx_gain_2_sign */ + FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_2_idx, + 6); /* dmx_gain_2_idx */ + FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */ } - if (pMetadata->etsiAncData.timecode_fine_status) { - FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */ + if (pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status) { + FDKwriteBits(&bsWriter, + pMetadata->etsiAncData.extAncData.ext_dmix_lfe_idx, + 4); /* dmix_lfe_idx */ + FDKwriteBits(&bsWriter, 0, 4); /* Reserved, set to "0" */ } + } - return FDKgetValidBits(&bsWriter); + return FDKgetValidBits(&bsWriter); } - static FDK_METADATA_ERROR LoadSubmittedMetadata( - const AACENC_MetaData * const hMetadata, - const INT nChannels, - const INT metadataMode, - AAC_METADATA * const pAacMetaData - ) -{ - FDK_METADATA_ERROR err = METADATA_OK; - - if (pAacMetaData==NULL) { - err = METADATA_INVALID_HANDLE; - } - else { - /* init struct */ - FDKmemclear(pAacMetaData, sizeof(AAC_METADATA)); - - if (hMetadata!=NULL) { - /* convert data */ - pAacMetaData->mpegDrc.drc_profile = hMetadata->drc_profile; - pAacMetaData->etsiAncData.comp_profile = hMetadata->comp_profile; - pAacMetaData->mpegDrc.drc_TargetRefLevel = hMetadata->drc_TargetRefLevel; - pAacMetaData->etsiAncData.comp_TargetRefLevel= hMetadata->comp_TargetRefLevel; - pAacMetaData->mpegDrc.prog_ref_level_present = hMetadata->prog_ref_level_present; - pAacMetaData->mpegDrc.prog_ref_level = dialnorm2progreflvl(hMetadata->prog_ref_level); - - pAacMetaData->centerMixLevel = hMetadata->centerMixLevel; - pAacMetaData->surroundMixLevel = hMetadata->surroundMixLevel; - pAacMetaData->WritePCEMixDwnIdx = hMetadata->PCE_mixdown_idx_present; - pAacMetaData->DmxLvl_On = hMetadata->ETSI_DmxLvl_present; + const AACENC_MetaData* const hMetadata, const INT nChannels, + const INT metadataMode, AAC_METADATA* const pAacMetaData) { + FDK_METADATA_ERROR err = METADATA_OK; + + if (pAacMetaData == NULL) { + err = METADATA_INVALID_HANDLE; + } else { + /* init struct */ + FDKmemclear(pAacMetaData, sizeof(AAC_METADATA)); + + if (hMetadata != NULL) { + /* convert data */ + pAacMetaData->mpegDrc.drc_profile = hMetadata->drc_profile; + pAacMetaData->etsiAncData.comp_profile = hMetadata->comp_profile; + pAacMetaData->mpegDrc.drc_TargetRefLevel = hMetadata->drc_TargetRefLevel; + pAacMetaData->etsiAncData.comp_TargetRefLevel = + hMetadata->comp_TargetRefLevel; + pAacMetaData->mpegDrc.prog_ref_level_present = + hMetadata->prog_ref_level_present; + pAacMetaData->mpegDrc.prog_ref_level = + dialnorm2progreflvl(hMetadata->prog_ref_level); + + pAacMetaData->centerMixLevel = hMetadata->centerMixLevel; + pAacMetaData->surroundMixLevel = hMetadata->surroundMixLevel; + pAacMetaData->WritePCEMixDwnIdx = hMetadata->PCE_mixdown_idx_present; + pAacMetaData->DmxLvl_On = hMetadata->ETSI_DmxLvl_present; + + pAacMetaData->etsiAncData.compression_on = + (hMetadata->comp_profile == AACENC_METADATA_DRC_NOT_PRESENT ? 0 : 1); + + if (pAacMetaData->mpegDrc.drc_profile == + AACENC_METADATA_DRC_NOT_PRESENT) { + pAacMetaData->mpegDrc.drc_profile = + AACENC_METADATA_DRC_NONE; /* MPEG DRC gains are + always present in BS + syntax */ + /* we should give a warning, but ErrorHandler does not support this */ + } - pAacMetaData->etsiAncData.compression_on = 1; + if (nChannels == 2) { + pAacMetaData->dolbySurroundMode = + hMetadata->dolbySurroundMode; /* dolby_surround_mode */ + } else { + pAacMetaData->dolbySurroundMode = 0; + } + pAacMetaData->drcPresentationMode = hMetadata->drcPresentationMode; + /* override external values if DVB DRC presentation mode is given */ + if (pAacMetaData->drcPresentationMode == 1) { + pAacMetaData->mpegDrc.drc_TargetRefLevel = + fMax(-(31 << 16), pAacMetaData->mpegDrc.drc_TargetRefLevel); + pAacMetaData->etsiAncData.comp_TargetRefLevel = fMax( + -(20 << 16), + pAacMetaData->etsiAncData.comp_TargetRefLevel); /* implies -23dB */ + } + if (pAacMetaData->drcPresentationMode == 2) { + pAacMetaData->mpegDrc.drc_TargetRefLevel = + fMax(-(23 << 16), pAacMetaData->mpegDrc.drc_TargetRefLevel); + pAacMetaData->etsiAncData.comp_TargetRefLevel = + fMax(-(23 << 16), pAacMetaData->etsiAncData.comp_TargetRefLevel); + } + if (pAacMetaData->etsiAncData.comp_profile == + AACENC_METADATA_DRC_NOT_PRESENT) { + /* DVB defines to revert to Light DRC if heavy is not present */ + if (pAacMetaData->drcPresentationMode != 0) { + /* we exclude the "not indicated" mode as this requires the user to + * define desired levels anyway */ + pAacMetaData->mpegDrc.drc_TargetRefLevel = + fMax(pAacMetaData->etsiAncData.comp_TargetRefLevel, + pAacMetaData->mpegDrc.drc_TargetRefLevel); + } + } - if (nChannels == 2) { - pAacMetaData->dolbySurroundMode = hMetadata->dolbySurroundMode; /* dolby_surround_mode */ + pAacMetaData->etsiAncData.timecode_coarse_status = + 0; /* not yet supported - attention: Update + GetEstMetadataBytesPerFrame() if enable this! */ + pAacMetaData->etsiAncData.timecode_fine_status = + 0; /* not yet supported - attention: Update + GetEstMetadataBytesPerFrame() if enable this! */ + + /* extended ancillary data */ + pAacMetaData->etsiAncData.extAncDataStatus = + ((hMetadata->ExtMetaData.extAncDataEnable == 1) ? 1 : 0); + + if (pAacMetaData->etsiAncData.extAncDataStatus) { + pAacMetaData->etsiAncData.extAncData.ext_downmix_lvl_status = + (hMetadata->ExtMetaData.extDownmixLevelEnable ? 1 : 0); + pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status = + (hMetadata->ExtMetaData.dmxGainEnable ? 1 : 0); + pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status = + (hMetadata->ExtMetaData.lfeDmxEnable ? 1 : 0); + + pAacMetaData->etsiAncData.extAncData.ext_dmix_a_idx = + hMetadata->ExtMetaData.extDownmixLevel_A; + pAacMetaData->etsiAncData.extAncData.ext_dmix_b_idx = + hMetadata->ExtMetaData.extDownmixLevel_B; + + if (pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status) { + encodeDynrng(hMetadata->ExtMetaData.dmxGain5, + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx), + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn)); + encodeDynrng(hMetadata->ExtMetaData.dmxGain2, + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx), + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn)); } else { - pAacMetaData->dolbySurroundMode = 0; + encodeDynrng(1 << 16, + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx), + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn)); + encodeDynrng(1 << 16, + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx), + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn)); } - pAacMetaData->etsiAncData.timecode_coarse_status = 0; /* not yet supported - attention: Update GetEstMetadataBytesPerFrame() if enable this! */ - pAacMetaData->etsiAncData.timecode_fine_status = 0; /* not yet supported - attention: Update GetEstMetadataBytesPerFrame() if enable this! */ - - pAacMetaData->metadataMode = metadataMode; - } - else { - pAacMetaData->metadataMode = 0; /* there is no configuration available */ + if (pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status) { + pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx = + hMetadata->ExtMetaData.lfeDmxLevel; + } else { + pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx = + 15; /* -inf dB */ + } + } else { + pAacMetaData->etsiAncData.extAncData.ext_downmix_lvl_status = 0; + pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status = 0; + pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status = 0; + + pAacMetaData->etsiAncData.extAncData.ext_dmix_a_idx = 7; /* -inf dB */ + pAacMetaData->etsiAncData.extAncData.ext_dmix_b_idx = 7; /* -inf dB */ + + encodeDynrng(1 << 16, + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx), + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn)); + encodeDynrng(1 << 16, + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx), + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn)); + + pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx = + 15; /* -inf dB */ } + + pAacMetaData->metadataMode = metadataMode; + } else { + pAacMetaData->metadataMode = 0; /* there is no configuration available */ } + } - return err; + return err; } -INT FDK_MetadataEnc_GetDelay( - HANDLE_FDK_METADATA_ENCODER hMetadataEnc - ) -{ - INT delay = 0; +INT FDK_MetadataEnc_GetDelay(HANDLE_FDK_METADATA_ENCODER hMetadataEnc) { + INT delay = 0; - if (hMetadataEnc!=NULL) { - delay = hMetadataEnc->nAudioDataDelay; - } + if (hMetadataEnc != NULL) { + delay = hMetadataEnc->nAudioDataDelay; + } - return delay; + return delay; } - - diff --git a/libAACenc/src/metadata_main.h b/libAACenc/src/metadata_main.h index bfc8ae1..d872c77 100644 --- a/libAACenc/src/metadata_main.h +++ b/libAACenc/src/metadata_main.h @@ -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,34 +90,36 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/********************** Fraunhofer IIS FDK AAC Encoder lib ****************** +/**************************** AAC encoder library ****************************** - Author(s): V. Bacigalupo - Description: Metadata Encoder library interface functions + Author(s): V. Bacigalupo -******************************************************************************/ + Description: Metadata Encoder library interface functions -#ifndef _METADATA_MAIN_H -#define _METADATA_MAIN_H +*******************************************************************************/ +#ifndef METADATA_MAIN_H +#define METADATA_MAIN_H /* Includes ******************************************************************/ #include "aacenc_lib.h" #include "aacenc.h" - /* Defines *******************************************************************/ /* Data Types ****************************************************************/ typedef enum { - METADATA_OK = 0x0000, /*!< No error happened. All fine. */ - METADATA_INVALID_HANDLE = 0x0020, /*!< Handle passed to function call was invalid. */ - METADATA_MEMORY_ERROR = 0x0021, /*!< Memory allocation failed. */ - METADATA_INIT_ERROR = 0x0040, /*!< General initialization error. */ - METADATA_ENCODE_ERROR = 0x0060 /*!< The encoding process was interrupted by an unexpected error. */ + METADATA_OK = 0x0000, /*!< No error happened. All fine. */ + METADATA_INVALID_HANDLE = + 0x0020, /*!< Handle passed to function call was invalid. */ + METADATA_MEMORY_ERROR = 0x0021, /*!< Memory allocation failed. */ + METADATA_INIT_ERROR = 0x0040, /*!< General initialization error. */ + METADATA_ENCODE_ERROR = + 0x0060 /*!< The encoding process was interrupted by an unexpected error. + */ } FDK_METADATA_ERROR; @@ -115,32 +128,33 @@ typedef enum { */ typedef struct FDK_METADATA_ENCODER *HANDLE_FDK_METADATA_ENCODER; - /** * \brief Open a Meta Data instance. * - * \param phMetadataEnc A pointer to a Meta Data handle to be allocated. Initialized on return. + * \param phMetadataEnc A pointer to a Meta Data handle to be allocated. + * Initialized on return. + * \param maxChannels Maximum number of supported audio channels. * * \return * - METADATA_OK, on succes. * - METADATA_INVALID_HANDLE, METADATA_MEMORY_ERROR, on failure. */ FDK_METADATA_ERROR FDK_MetadataEnc_Open( - HANDLE_FDK_METADATA_ENCODER *phMetadataEnc - ); - + HANDLE_FDK_METADATA_ENCODER *phMetadataEnc, const UINT maxChannels); /** * \brief Initialize a Meta Data instance. * * \param hMetadataEnc Meta Data handle. * \param resetStates Indication for full reset of all states. - * \param metadataMode Configures metat data output format (0,1,2). + * \param metadataMode Configures meta data output format (0,1,2,3). * \param audioDelay Delay cause by the audio encoder. - * \param frameLength Number of samples to be processes within one frame. + * \param frameLength Number of samples to be processes within one + * frame. * \param sampleRate Sampling rat in Hz of audio input signal. * \param nChannels Number of audio input channels. - * \param channelMode Channel configuration which is used by the encoder. + * \param channelMode Channel configuration which is used by the + * encoder. * \param channelOrder Channel order of the input data. (WAV, MPEG) * * \return @@ -148,17 +162,10 @@ FDK_METADATA_ERROR FDK_MetadataEnc_Open( * - METADATA_INVALID_HANDLE, METADATA_INIT_ERROR, on failure. */ FDK_METADATA_ERROR FDK_MetadataEnc_Init( - HANDLE_FDK_METADATA_ENCODER hMetadataEnc, - const INT resetStates, - const INT metadataMode, - const INT audioDelay, - const UINT frameLength, - const UINT sampleRate, - const UINT nChannels, - const CHANNEL_MODE channelMode, - const CHANNEL_ORDER channelOrder - ); - + HANDLE_FDK_METADATA_ENCODER hMetadataEnc, const INT resetStates, + const INT metadataMode, const INT audioDelay, const UINT frameLength, + const UINT sampleRate, const UINT nChannels, const CHANNEL_MODE channelMode, + const CHANNEL_ORDER channelOrder); /** * \brief Calculate Meta Data processing. @@ -170,43 +177,42 @@ FDK_METADATA_ERROR FDK_MetadataEnc_Init( * - Apply audio data and meta data delay compensation. * * \param hMetadataEnc Meta Data handle. - * \param pAudioSamples Pointer to audio input data. Existing function overwrites audio data with delayed audio samples. + * \param pAudioSamples Pointer to audio input data. Existing function + * overwrites audio data with delayed audio samples. * \param nAudioSamples Number of input audio samples to be prcessed. * \param pMetadata Pointer to Metat Data input. - * \param ppMetaDataExtPayload Pointer to extension payload array. Filled on return. - * \param nMetaDataExtensions Pointer to variable to describe number of available extension payloads. Filled on return. - * \param matrix_mixdown_idx Pointer to variable for matrix mixdown coefficient. Filled on return. + * \param ppMetaDataExtPayload Pointer to extension payload array. Filled on + * return. + * \param nMetaDataExtensions Pointer to variable to describe number of + * available extension payloads. Filled on return. + * \param matrix_mixdown_idx Pointer to variable for matrix mixdown + * coefficient. Filled on return. * * \return * - METADATA_OK, on succes. * - METADATA_INVALID_HANDLE, METADATA_ENCODE_ERROR, on failure. */ FDK_METADATA_ERROR FDK_MetadataEnc_Process( - HANDLE_FDK_METADATA_ENCODER hMetadataEnc, - INT_PCM * const pAudioSamples, - const INT nAudioSamples, - const AACENC_MetaData * const pMetadata, - AACENC_EXT_PAYLOAD ** ppMetaDataExtPayload, - UINT * nMetaDataExtensions, - INT * matrix_mixdown_idx - ); - + HANDLE_FDK_METADATA_ENCODER hMetadataEnc, INT_PCM *const pAudioSamples, + const UINT audioSamplesBufSize, const INT nAudioSamples, + const AACENC_MetaData *const pMetadata, + AACENC_EXT_PAYLOAD **ppMetaDataExtPayload, UINT *nMetaDataExtensions, + INT *matrix_mixdown_idx); /** * \brief Close the Meta Data instance. * * Deallocate instance and free whole memory. * - * \param phMetaData Pointer to the Meta Data handle to be deallocated. + * \param phMetaData Pointer to the Meta Data handle to be + * deallocated. * * \return * - METADATA_OK, on succes. * - METADATA_INVALID_HANDLE, on failure. */ FDK_METADATA_ERROR FDK_MetadataEnc_Close( - HANDLE_FDK_METADATA_ENCODER *phMetaData - ); - + HANDLE_FDK_METADATA_ENCODER *phMetaData); /** * \brief Get Meta Data Encoder delay. @@ -215,10 +221,6 @@ FDK_METADATA_ERROR FDK_MetadataEnc_Close( * * \return Delay caused by Meta Data module. */ -INT FDK_MetadataEnc_GetDelay( - HANDLE_FDK_METADATA_ENCODER hMetadataEnc - ); - - -#endif /* _METADATA_MAIN_H */ +INT FDK_MetadataEnc_GetDelay(HANDLE_FDK_METADATA_ENCODER hMetadataEnc); +#endif /* METADATA_MAIN_H */ diff --git a/libAACenc/src/mps_main.cpp b/libAACenc/src/mps_main.cpp new file mode 100644 index 0000000..1048228 --- /dev/null +++ b/libAACenc/src/mps_main.cpp @@ -0,0 +1,529 @@ +/* ----------------------------------------------------------------------------- +Software License for The Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. + + 1. INTRODUCTION +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. + +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** + + Author(s): Markus Lohwasser + + Description: Mpeg Surround library interface functions + +*******************************************************************************/ + +/* Includes ******************************************************************/ +#include "mps_main.h" +#include "sacenc_lib.h" + +/* Data Types ****************************************************************/ +struct MPS_ENCODER { + HANDLE_MP4SPACE_ENCODER hSacEncoder; + + AUDIO_OBJECT_TYPE audioObjectType; + + FDK_bufDescr inBufDesc; + FDK_bufDescr outBufDesc; + SACENC_InArgs inargs; + SACENC_OutArgs outargs; + + void *pInBuffer[1]; + UINT pInBufferSize[1]; + UINT pInBufferElSize[1]; + UINT pInBufferType[1]; + + void *pOutBuffer[2]; + UINT pOutBufferSize[2]; + UINT pOutBufferElSize[2]; + UINT pOutBufferType[2]; + + UCHAR sacOutBuffer[1024]; /* Worst case memory consumption for ELDv2: 768 + bytes => 6144 bits (Core + SBR + MPS) */ +}; + +struct MPS_CONFIG_TAB { + AUDIO_OBJECT_TYPE audio_object_type; + CHANNEL_MODE channel_mode; + ULONG sbr_ratio; + ULONG sampling_rate; + ULONG bitrate_min; + ULONG bitrate_max; +}; + +/* Constants *****************************************************************/ +static const MPS_CONFIG_TAB mpsConfigTab[] = { + {AOT_ER_AAC_ELD, MODE_212, 0, 16000, 16000, 39999}, + {AOT_ER_AAC_ELD, MODE_212, 0, 22050, 16000, 49999}, + {AOT_ER_AAC_ELD, MODE_212, 0, 24000, 16000, 61999}, + {AOT_ER_AAC_ELD, MODE_212, 0, 32000, 20000, 84999}, + {AOT_ER_AAC_ELD, MODE_212, 0, 44100, 50000, 192000}, + {AOT_ER_AAC_ELD, MODE_212, 0, 48000, 62000, 192000}, + + {AOT_ER_AAC_ELD, MODE_212, 1, 16000, 18000, 31999}, + {AOT_ER_AAC_ELD, MODE_212, 1, 22050, 18000, 31999}, + {AOT_ER_AAC_ELD, MODE_212, 1, 24000, 20000, 64000}, + + {AOT_ER_AAC_ELD, MODE_212, 2, 32000, 18000, 64000}, + {AOT_ER_AAC_ELD, MODE_212, 2, 44100, 21000, 64000}, + {AOT_ER_AAC_ELD, MODE_212, 2, 48000, 26000, 64000} + +}; + +/* Function / Class Declarations *********************************************/ + +/* Function / Class Definition ***********************************************/ +static INT FDK_MpegsEnc_WriteFrameHeader(HANDLE_MPS_ENCODER hMpsEnc, + UCHAR *const pOutputBuffer, + const int outputBufferSize); + +MPS_ENCODER_ERROR FDK_MpegsEnc_Open(HANDLE_MPS_ENCODER *phMpsEnc) { + MPS_ENCODER_ERROR error = MPS_ENCODER_OK; + HANDLE_MPS_ENCODER hMpsEnc = NULL; + + if (phMpsEnc == NULL) { + error = MPS_ENCODER_INVALID_HANDLE; + goto bail; + } + + if (NULL == + (hMpsEnc = (HANDLE_MPS_ENCODER)FDKcalloc(1, sizeof(MPS_ENCODER)))) { + error = MPS_ENCODER_MEMORY_ERROR; + goto bail; + } + FDKmemclear(hMpsEnc, sizeof(MPS_ENCODER)); + + if (SACENC_OK != FDK_sacenc_open(&hMpsEnc->hSacEncoder)) { + error = MPS_ENCODER_MEMORY_ERROR; + goto bail; + } + + /* Return mps encoder instance */ + *phMpsEnc = hMpsEnc; + +bail: + if (error != MPS_ENCODER_OK) { + FDK_MpegsEnc_Close(&hMpsEnc); + } + return error; +} + +MPS_ENCODER_ERROR FDK_MpegsEnc_Close(HANDLE_MPS_ENCODER *phMpsEnc) { + MPS_ENCODER_ERROR error = MPS_ENCODER_OK; + + if (phMpsEnc == NULL) { + error = MPS_ENCODER_INVALID_HANDLE; + goto bail; + } + + if (*phMpsEnc != NULL) { + FDK_sacenc_close(&(*phMpsEnc)->hSacEncoder); + FDKfree(*phMpsEnc); + *phMpsEnc = NULL; + } +bail: + return error; +} + +MPS_ENCODER_ERROR FDK_MpegsEnc_Init(HANDLE_MPS_ENCODER hMpsEnc, + const AUDIO_OBJECT_TYPE audioObjectType, + const UINT samplingrate, const UINT bitrate, + const UINT sbrRatio, const UINT framelength, + const UINT inputBufferSizePerChannel, + const UINT coreCoderDelay) { + MPS_ENCODER_ERROR error = MPS_ENCODER_OK; + const UINT fs_low = 27713; /* low MPS sampling frequencies */ + const UINT fs_high = 55426; /* high MPS sampling frequencies */ + UINT nTimeSlots = 0, nQmfBandsLd = 0; + + if (hMpsEnc == NULL) { + error = MPS_ENCODER_INVALID_HANDLE; + goto bail; + } + + /* Combine MPS with SBR only if the number of QMF band fits together.*/ + switch (sbrRatio) { + case 1: /* downsampled sbr - 32 QMF bands required */ + if (!(samplingrate < fs_low)) { + error = MPS_ENCODER_INIT_ERROR; + goto bail; + } + break; + case 2: /* dualrate - 64 QMF bands required */ + if (!((samplingrate >= fs_low) && (samplingrate < fs_high))) { + error = MPS_ENCODER_INIT_ERROR; + goto bail; + } + break; + case 0: + default:; /* time interface - no samplingrate restriction */ + } + + /* 32 QMF-Bands ( fs < 27713 ) + * 64 QMF-Bands ( 27713 >= fs <= 55426 ) + * 128 QMF-Bands ( fs > 55426 ) + */ + nQmfBandsLd = + (samplingrate < fs_low) ? 5 : ((samplingrate > fs_high) ? 7 : 6); + nTimeSlots = framelength >> nQmfBandsLd; + + /* check if number of qmf bands is usable for given framelength */ + if (framelength != (nTimeSlots << nQmfBandsLd)) { + error = MPS_ENCODER_INIT_ERROR; + goto bail; + } + + /* is given bitrate intended to be supported */ + if ((INT)bitrate != FDK_MpegsEnc_GetClosestBitRate(audioObjectType, MODE_212, + samplingrate, sbrRatio, + bitrate)) { + error = MPS_ENCODER_INIT_ERROR; + goto bail; + } + + /* init SAC library */ + switch (audioObjectType) { + case AOT_ER_AAC_ELD: { + const UINT noInterFrameCoding = 0; + + if ((SACENC_OK != + FDK_sacenc_setParam(hMpsEnc->hSacEncoder, SACENC_LOWDELAY, + (noInterFrameCoding == 1) ? 1 : 2)) || + (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder, + SACENC_ENC_MODE, SACENC_212)) || + (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder, + SACENC_SAMPLERATE, samplingrate)) || + (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder, + SACENC_FRAME_TIME_SLOTS, + nTimeSlots)) || + (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder, + SACENC_PARAM_BANDS, + SACENC_BANDS_15)) || + (SACENC_OK != + FDK_sacenc_setParam(hMpsEnc->hSacEncoder, SACENC_TIME_DOM_DMX, 2)) || + (SACENC_OK != + FDK_sacenc_setParam(hMpsEnc->hSacEncoder, SACENC_COARSE_QUANT, 0)) || + (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder, + SACENC_QUANT_MODE, + SACENC_QUANTMODE_FINE)) || + (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder, + SACENC_TIME_ALIGNMENT, 0)) || + (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder, + SACENC_INDEPENDENCY_FACTOR, 20))) { + error = MPS_ENCODER_INIT_ERROR; + goto bail; + } + break; + } + default: + error = MPS_ENCODER_INIT_ERROR; + goto bail; + } + + if (SACENC_OK != FDK_sacenc_init(hMpsEnc->hSacEncoder, coreCoderDelay)) { + error = MPS_ENCODER_INIT_ERROR; + } + + hMpsEnc->audioObjectType = audioObjectType; + + hMpsEnc->inBufDesc.ppBase = (void **)&hMpsEnc->pInBuffer; + hMpsEnc->inBufDesc.pBufSize = hMpsEnc->pInBufferSize; + hMpsEnc->inBufDesc.pEleSize = hMpsEnc->pInBufferElSize; + hMpsEnc->inBufDesc.pBufType = hMpsEnc->pInBufferType; + hMpsEnc->inBufDesc.numBufs = 1; + + hMpsEnc->outBufDesc.ppBase = (void **)&hMpsEnc->pOutBuffer; + hMpsEnc->outBufDesc.pBufSize = hMpsEnc->pOutBufferSize; + hMpsEnc->outBufDesc.pEleSize = hMpsEnc->pOutBufferElSize; + hMpsEnc->outBufDesc.pBufType = hMpsEnc->pOutBufferType; + hMpsEnc->outBufDesc.numBufs = 2; + + hMpsEnc->pInBuffer[0] = NULL; + hMpsEnc->pInBufferSize[0] = 0; + hMpsEnc->pInBufferElSize[0] = sizeof(INT_PCM); + hMpsEnc->pInBufferType[0] = (FDK_BUF_TYPE_INPUT | FDK_BUF_TYPE_PCM_DATA); + + hMpsEnc->pOutBuffer[0] = NULL; + hMpsEnc->pOutBufferSize[0] = 0; + hMpsEnc->pOutBufferElSize[0] = sizeof(INT_PCM); + hMpsEnc->pOutBufferType[0] = (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_PCM_DATA); + + hMpsEnc->pOutBuffer[1] = NULL; + hMpsEnc->pOutBufferSize[1] = 0; + hMpsEnc->pOutBufferElSize[1] = sizeof(UCHAR); + hMpsEnc->pOutBufferType[1] = (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_BS_DATA); + + hMpsEnc->inargs.isInputInterleaved = 0; + hMpsEnc->inargs.inputBufferSizePerChannel = inputBufferSizePerChannel; + +bail: + return error; +} + +MPS_ENCODER_ERROR FDK_MpegsEnc_Process(HANDLE_MPS_ENCODER hMpsEnc, + INT_PCM *const pAudioSamples, + const INT nAudioSamples, + AACENC_EXT_PAYLOAD *pMpsExtPayload) { + MPS_ENCODER_ERROR error = MPS_ENCODER_OK; + + if (hMpsEnc == NULL) { + error = MPS_ENCODER_INVALID_HANDLE; + } else { + int sacHeaderFlag = 1; + int sacOutBufferOffset = 0; + + /* In case of eld the ssc is explicit and doesn't need to be inband */ + if (hMpsEnc->audioObjectType == AOT_ER_AAC_ELD) { + sacHeaderFlag = 0; + } + + /* 4 bits nibble after extension type */ + hMpsEnc->sacOutBuffer[0] = (sacHeaderFlag == 0) ? 0x3 : 0x7; + sacOutBufferOffset += 1; + + if (sacHeaderFlag) { + sacOutBufferOffset += FDK_MpegsEnc_WriteFrameHeader( + hMpsEnc, &hMpsEnc->sacOutBuffer[sacOutBufferOffset], + sizeof(hMpsEnc->sacOutBuffer) - sacOutBufferOffset); + } + + /* Register input and output buffer. */ + hMpsEnc->pInBuffer[0] = (void *)pAudioSamples; + hMpsEnc->inargs.nInputSamples = nAudioSamples; + + hMpsEnc->pOutBuffer[0] = (void *)pAudioSamples; + hMpsEnc->pOutBufferSize[0] = sizeof(INT_PCM) * nAudioSamples / 2; + + hMpsEnc->pOutBuffer[1] = (void *)&hMpsEnc->sacOutBuffer[sacOutBufferOffset]; + hMpsEnc->pOutBufferSize[1] = + sizeof(hMpsEnc->sacOutBuffer) - sacOutBufferOffset; + + /* encode SAC frame */ + if (SACENC_OK != FDK_sacenc_encode(hMpsEnc->hSacEncoder, + &hMpsEnc->inBufDesc, + &hMpsEnc->outBufDesc, &hMpsEnc->inargs, + &hMpsEnc->outargs)) { + error = MPS_ENCODER_ENCODE_ERROR; + goto bail; + } + + /* export MPS payload */ + pMpsExtPayload->pData = (UCHAR *)hMpsEnc->sacOutBuffer; + pMpsExtPayload->dataSize = + hMpsEnc->outargs.nOutputBits + 8 * (sacOutBufferOffset - 1); + pMpsExtPayload->dataType = EXT_LDSAC_DATA; + pMpsExtPayload->associatedChElement = -1; + } + +bail: + return error; +} + +INT FDK_MpegsEnc_WriteSpatialSpecificConfig(HANDLE_MPS_ENCODER hMpsEnc, + HANDLE_FDK_BITSTREAM hBs) { + INT sscBits = 0; + + if (NULL != hMpsEnc) { + MP4SPACEENC_INFO mp4SpaceEncoderInfo; + FDK_sacenc_getInfo(hMpsEnc->hSacEncoder, &mp4SpaceEncoderInfo); + + if (hBs != NULL) { + int i; + int writtenBits = 0; + for (i = 0; inSscSizeBits>> 3; i++) { + FDKwriteBits(hBs, mp4SpaceEncoderInfo.pSscBuf->pSsc[i], 8); + writtenBits += 8; + } + FDKwriteBits(hBs, mp4SpaceEncoderInfo.pSscBuf->pSsc[i], + mp4SpaceEncoderInfo.pSscBuf->nSscSizeBits - writtenBits); + } /* hBS */ + + sscBits = mp4SpaceEncoderInfo.pSscBuf->nSscSizeBits; + + } /* valid hMpsEnc */ + + return sscBits; +} + +static INT FDK_MpegsEnc_WriteFrameHeader(HANDLE_MPS_ENCODER hMpsEnc, + UCHAR *const pOutputBuffer, + const int outputBufferSize) { + const int sacTimeAlignFlag = 0; + + /* Initialize variables */ + int numBits = 0; + + if ((NULL != hMpsEnc) && (NULL != pOutputBuffer)) { + UINT alignAnchor, cnt; + FDK_BITSTREAM Bs; + FDKinitBitStream(&Bs, pOutputBuffer, outputBufferSize, 0, BS_WRITER); + + /* Calculate SSC length information */ + cnt = (FDK_MpegsEnc_WriteSpatialSpecificConfig(hMpsEnc, NULL) + 7) >> 3; + + /* Write SSC */ + FDKwriteBits(&Bs, sacTimeAlignFlag, 1); + + if (cnt < 127) { + FDKwriteBits(&Bs, cnt, 7); + } else { + FDKwriteBits(&Bs, 127, 7); + FDKwriteBits(&Bs, cnt - 127, 16); + } + + alignAnchor = FDKgetValidBits(&Bs); + FDK_MpegsEnc_WriteSpatialSpecificConfig(hMpsEnc, &Bs); + FDKbyteAlign(&Bs, alignAnchor); /* bsFillBits */ + + if (sacTimeAlignFlag) { + FDK_ASSERT(1); /* time alignment not supported */ + } + + numBits = FDKgetValidBits(&Bs); + } /* valid handle */ + + return ((numBits + 7) >> 3); +} + +INT FDK_MpegsEnc_GetClosestBitRate(const AUDIO_OBJECT_TYPE audioObjectType, + const CHANNEL_MODE channelMode, + const UINT samplingrate, const UINT sbrRatio, + const UINT bitrate) { + unsigned int i; + int targetBitrate = -1; + + for (i = 0; i < sizeof(mpsConfigTab) / sizeof(MPS_CONFIG_TAB); i++) { + if ((mpsConfigTab[i].audio_object_type == audioObjectType) && + (mpsConfigTab[i].channel_mode == channelMode) && + (mpsConfigTab[i].sbr_ratio == sbrRatio) && + (mpsConfigTab[i].sampling_rate == samplingrate)) { + targetBitrate = fMin(fMax(bitrate, mpsConfigTab[i].bitrate_min), + mpsConfigTab[i].bitrate_max); + } + } + + return targetBitrate; +} + +INT FDK_MpegsEnc_GetDelay(HANDLE_MPS_ENCODER hMpsEnc) { + INT delay = 0; + + if (NULL != hMpsEnc) { + MP4SPACEENC_INFO mp4SpaceEncoderInfo; + FDK_sacenc_getInfo(hMpsEnc->hSacEncoder, &mp4SpaceEncoderInfo); + delay = mp4SpaceEncoderInfo.nCodecDelay; + } + + return delay; +} + +INT FDK_MpegsEnc_GetDecDelay(HANDLE_MPS_ENCODER hMpsEnc) { + INT delay = 0; + + if (NULL != hMpsEnc) { + MP4SPACEENC_INFO mp4SpaceEncoderInfo; + FDK_sacenc_getInfo(hMpsEnc->hSacEncoder, &mp4SpaceEncoderInfo); + delay = mp4SpaceEncoderInfo.nDecoderDelay; + } + + return delay; +} + +MPS_ENCODER_ERROR FDK_MpegsEnc_GetLibInfo(LIB_INFO *info) { + MPS_ENCODER_ERROR error = MPS_ENCODER_OK; + + if (NULL == info) { + error = MPS_ENCODER_INVALID_HANDLE; + } else if (SACENC_OK != FDK_sacenc_getLibInfo(info)) { + error = MPS_ENCODER_INIT_ERROR; + } + + return error; +} diff --git a/libAACenc/src/mps_main.h b/libAACenc/src/mps_main.h new file mode 100644 index 0000000..f56678a --- /dev/null +++ b/libAACenc/src/mps_main.h @@ -0,0 +1,270 @@ +/* ----------------------------------------------------------------------------- +Software License for The Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. + + 1. INTRODUCTION +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. + +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** + + Author(s): Markus Lohwasser + + Description: Mpeg Surround library interface functions + +*******************************************************************************/ + +#ifndef MPS_MAIN_H +#define MPS_MAIN_H + +/* Includes ******************************************************************/ +#include "aacenc.h" +#include "FDK_audio.h" +#include "machine_type.h" + +/* Defines *******************************************************************/ +typedef enum { + MPS_ENCODER_OK = 0x0000, /*!< No error happened. All fine. */ + MPS_ENCODER_INVALID_HANDLE = + 0x0020, /*!< Handle passed to function call was invalid. */ + MPS_ENCODER_MEMORY_ERROR = 0x0021, /*!< Memory allocation failed. */ + MPS_ENCODER_INIT_ERROR = 0x0040, /*!< General initialization error. */ + MPS_ENCODER_ENCODE_ERROR = + 0x0060 /*!< The encoding process was interrupted by an unexpected error. + */ + +} MPS_ENCODER_ERROR; + +/* Data Types ****************************************************************/ + +/** + * MPEG Surround Encoder interface handle. + */ +typedef struct MPS_ENCODER MPS_ENCODER, *HANDLE_MPS_ENCODER; + +/* Function / Class Declarations *********************************************/ + +/** + * \brief Open a Mpeg Surround Encoder instance. + * + * \phMpsEnc A pointer to a MPS handle to be allocated. + * Initialized on return. + * + * \return + * - MPS_ENCODER_OK, on succes. + * - MPS_ENCODER_INVALID_HANDLE, MPS_ENCODER_MEMORY_ERROR, on failure. + */ +MPS_ENCODER_ERROR FDK_MpegsEnc_Open(HANDLE_MPS_ENCODER *phMpsEnc); + +/** + * \brief Close the Mpeg Surround Encoder instance. + * + * Deallocate instance and free whole memory. + * + * \param phMpsEnc Pointer to the MPS handle to be deallocated. + * + * \return + * - MPS_ENCODER_OK, on succes. + * - MPS_ENCODER_INVALID_HANDLE, on failure. + */ +MPS_ENCODER_ERROR FDK_MpegsEnc_Close(HANDLE_MPS_ENCODER *phMpsEnc); + +/** + * \brief Initialize a Mpeg Surround Encoder instance. + * + * \param hMpsEnc MPS Encoder handle. + * \param audioObjectType Audio object type. + * \param samplingrate Sampling rate in Hz of audio input signal. + * \param bitrate Encder target bitrate. + * \param sbrRatio SBR sampling rate ratio. + * \param framelength Number of samples to be processes within one + * frame. + * \param inputBufferSizePerChannel Size of input buffer per channel. + * \param coreCoderDelay Core coder delay. + * + * \return + * - MPS_ENCODER_OK, on succes. + * - MPS_ENCODER_INVALID_HANDLE, MPS_ENCODER_ENCODE_ERROR, on failure. + */ +MPS_ENCODER_ERROR FDK_MpegsEnc_Init(HANDLE_MPS_ENCODER hMpsEnc, + const AUDIO_OBJECT_TYPE audioObjectType, + const UINT samplingrate, const UINT bitrate, + const UINT sbrRatio, const UINT framelength, + const UINT inputBufferSizePerChannel, + const UINT coreCoderDelay); + +/** + * \brief Calculate Mpeg Surround processing. + * + * This fuction applies the MPS processing. The MPS side info will be written to + * extension payload. The input audio data will be overwritten by the calculated + * downmix. + * + * \param hMpsEnc MPS Encoder handle. + * \param pAudioSamples Pointer to audio input/output data. + * \param nAudioSamples Number of input audio samples to be prcessed. + * \param pMpsExtPayload Pointer to extension payload to be filled on + * return. + * + * \return + * - MPS_ENCODER_OK, on succes. + * - MPS_ENCODER_INVALID_HANDLE, MPS_ENCODER_ENCODE_ERROR, on failure. + */ +MPS_ENCODER_ERROR FDK_MpegsEnc_Process(HANDLE_MPS_ENCODER hMpsEnc, + INT_PCM *const pAudioSamples, + const INT nAudioSamples, + AACENC_EXT_PAYLOAD *pMpsExtPayload); + +/** + * \brief Write Spatial Specific Config. + * + * This function can be called via call back from the transport library to write + * the Spatial Specific Config to given bitstream buffer. + * + * \param hMpsEnc MPS Encoder handle. + * \param hBs Bitstream buffer handle. + * + * \return Number of written bits. + */ +INT FDK_MpegsEnc_WriteSpatialSpecificConfig(HANDLE_MPS_ENCODER hMpsEnc, + HANDLE_FDK_BITSTREAM hBs); + +/** + * \brief Get closest valid bitrate supported by given config. + * + * \param audioObjectType Audio object type. + * \param channelMode Encoder channel mode. + * \param samplingrate Sampling rate in Hz of audio input signal. + * \param sbrRatio SBR sampling rate ratio. + * \param bitrate The desired target bitrate. + * + * \return Closest valid bitrate to given bitrate.. + */ +INT FDK_MpegsEnc_GetClosestBitRate(const AUDIO_OBJECT_TYPE audioObjectType, + const CHANNEL_MODE channelMode, + const UINT samplingrate, const UINT sbrRatio, + const UINT bitrate); + +/** + * \brief Get codec delay. + * + * This function returns delay of the whole en-/decoded signal, including + * corecoder delay. + * + * \param hMpsEnc MPS Encoder handle. + * + * \return Codec delay in samples. + */ +INT FDK_MpegsEnc_GetDelay(HANDLE_MPS_ENCODER hMpsEnc); + +/** + * \brief Get Mpeg Surround Decoder delay. + * + * This function returns delay of the Mpeg Surround decoder. + * + * \param hMpsEnc MPS Encoder handle. + * + * \return Mpeg Surround Decoder delay in samples. + */ +INT FDK_MpegsEnc_GetDecDelay(HANDLE_MPS_ENCODER hMpsEnc); + +/** + * \brief Get information about encoder library build. + * + * Fill a given LIB_INFO structure with library version information. + * + * \param info Pointer to an allocated LIB_INFO struct. + * + * \return + * - MPS_ENCODER_OK, on succes. + * - MPS_ENCODER_INVALID_HANDLE, MPS_ENCODER_INIT_ERROR, on failure. + */ +MPS_ENCODER_ERROR FDK_MpegsEnc_GetLibInfo(LIB_INFO *info); + +#endif /* MPS_MAIN_H */ diff --git a/libAACenc/src/ms_stereo.cpp b/libAACenc/src/ms_stereo.cpp index 306d490..6a121b2 100644 --- a/libAACenc/src/ms_stereo.cpp +++ b/libAACenc/src/ms_stereo.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,173 +90,206 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** + + Author(s): M.Werner -/******************************** MPEG Audio Encoder ************************** + Description: MS stereo processing - Initial author: M.Werner - contents/description: MS stereo processing +*******************************************************************************/ -******************************************************************************/ #include "ms_stereo.h" #include "psy_const.h" /* static const float scaleMinThres = 1.0f; */ /* 0.75f for 3db boost */ -void FDKaacEnc_MsStereoProcessing(PSY_DATA *RESTRICT psyData[(2)], - PSY_OUT_CHANNEL* psyOutChannel[2], - const INT *isBook, - INT *msDigest, /* output */ - INT *msMask, /* output */ - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup, - const INT *sfbOffset) -{ - FIXP_DBL *sfbEnergyLeft = psyData[0]->sfbEnergy.Long; /* modified where msMask==1 */ - FIXP_DBL *sfbEnergyRight = psyData[1]->sfbEnergy.Long; /* modified where msMask==1 */ - const FIXP_DBL *sfbEnergyMid = psyData[0]->sfbEnergyMS.Long; - const FIXP_DBL *sfbEnergySide = psyData[1]->sfbEnergyMS.Long; - FIXP_DBL *sfbThresholdLeft = psyData[0]->sfbThreshold.Long; /* modified where msMask==1 */ - FIXP_DBL *sfbThresholdRight = psyData[1]->sfbThreshold.Long; /* modified where msMask==1 */ - - FIXP_DBL *sfbSpreadEnLeft = psyData[0]->sfbSpreadEnergy.Long; - FIXP_DBL *sfbSpreadEnRight = psyData[1]->sfbSpreadEnergy.Long; - - FIXP_DBL *sfbEnergyLeftLdData = psyOutChannel[0]->sfbEnergyLdData; /* modified where msMask==1 */ - FIXP_DBL *sfbEnergyRightLdData = psyOutChannel[1]->sfbEnergyLdData; /* modified where msMask==1 */ - FIXP_DBL *sfbEnergyMidLdData = psyData[0]->sfbEnergyMSLdData; - FIXP_DBL *sfbEnergySideLdData = psyData[1]->sfbEnergyMSLdData; - FIXP_DBL *sfbThresholdLeftLdData = psyOutChannel[0]->sfbThresholdLdData; /* modified where msMask==1 */ - FIXP_DBL *sfbThresholdRightLdData = psyOutChannel[1]->sfbThresholdLdData; /* modified where msMask==1 */ - - FIXP_DBL *mdctSpectrumLeft = psyData[0]->mdctSpectrum; /* modified where msMask==1 */ - FIXP_DBL *mdctSpectrumRight = psyData[1]->mdctSpectrum; /* modified where msMask==1 */ - - INT sfb,sfboffs, j; /* loop counters */ - FIXP_DBL pnlrLdData, pnmsLdData; - FIXP_DBL minThresholdLdData; - FIXP_DBL minThreshold; - INT useMS; - - INT msMaskTrueSomewhere = 0; /* to determine msDigest */ - INT numMsMaskFalse = 0; /* number of non-intensity bands where L/R coding is used */ - - for(sfb=0; sfb pnlr); -*/ - - /* we assume that scaleMinThres == 1.0f and we can drop it */ - minThresholdLdData = fixMin(sfbThresholdLeftLdData[sfb+sfboffs], sfbThresholdRightLdData[sfb+sfboffs]); - - /* pnlrLdData = sfbThresholdLeftLdData[sfb+sfboffs] - - max(sfbEnergyLeftLdData[sfb+sfboffs], sfbThresholdLeftLdData[sfb+sfboffs]) + - sfbThresholdRightLdData[sfb+sfboffs] - - max(sfbEnergyRightLdData[sfb+sfboffs], sfbThresholdRightLdData[sfb+sfboffs]); */ - tmp = fixMax(sfbEnergyLeftLdData[sfb+sfboffs], sfbThresholdLeftLdData[sfb+sfboffs]); - pnlrLdData = (sfbThresholdLeftLdData[sfb+sfboffs]>>1) - (tmp>>1); - pnlrLdData = pnlrLdData + (sfbThresholdRightLdData[sfb+sfboffs]>>1); - tmp = fixMax(sfbEnergyRightLdData[sfb+sfboffs], sfbThresholdRightLdData[sfb+sfboffs]); - pnlrLdData = pnlrLdData - (tmp>>1); - - /* pnmsLdData = minThresholdLdData - max(sfbEnergyMidLdData[sfb+sfboffs], minThresholdLdData) + - minThresholdLdData - max(sfbEnergySideLdData[sfb+sfboffs], minThresholdLdData); */ - tmp = fixMax(sfbEnergyMidLdData[sfb+sfboffs], minThresholdLdData); - pnmsLdData = minThresholdLdData - (tmp>>1); - tmp = fixMax(sfbEnergySideLdData[sfb+sfboffs], minThresholdLdData); - pnmsLdData = pnmsLdData - (tmp>>1); - useMS = (pnmsLdData > (pnlrLdData)); - - - if (useMS) { - msMask[sfb+sfboffs] = 1; - msMaskTrueSomewhere = 1; - for(j=sfbOffset[sfb+sfboffs]; jsfbEnergy.Long; /* modified where msMask==1 */ + FIXP_DBL *sfbEnergyRight = + psyData[1]->sfbEnergy.Long; /* modified where msMask==1 */ + const FIXP_DBL *sfbEnergyMid = psyData[0]->sfbEnergyMS.Long; + const FIXP_DBL *sfbEnergySide = psyData[1]->sfbEnergyMS.Long; + FIXP_DBL *sfbThresholdLeft = + psyData[0]->sfbThreshold.Long; /* modified where msMask==1 */ + FIXP_DBL *sfbThresholdRight = + psyData[1]->sfbThreshold.Long; /* modified where msMask==1 */ + + FIXP_DBL *sfbSpreadEnLeft = psyData[0]->sfbSpreadEnergy.Long; + FIXP_DBL *sfbSpreadEnRight = psyData[1]->sfbSpreadEnergy.Long; + + FIXP_DBL *sfbEnergyLeftLdData = + psyOutChannel[0]->sfbEnergyLdData; /* modified where msMask==1 */ + FIXP_DBL *sfbEnergyRightLdData = + psyOutChannel[1]->sfbEnergyLdData; /* modified where msMask==1 */ + FIXP_DBL *sfbEnergyMidLdData = psyData[0]->sfbEnergyMSLdData; + FIXP_DBL *sfbEnergySideLdData = psyData[1]->sfbEnergyMSLdData; + FIXP_DBL *sfbThresholdLeftLdData = + psyOutChannel[0]->sfbThresholdLdData; /* modified where msMask==1 */ + FIXP_DBL *sfbThresholdRightLdData = + psyOutChannel[1]->sfbThresholdLdData; /* modified where msMask==1 */ + + FIXP_DBL *mdctSpectrumLeft = + psyData[0]->mdctSpectrum; /* modified where msMask==1 */ + FIXP_DBL *mdctSpectrumRight = + psyData[1]->mdctSpectrum; /* modified where msMask==1 */ + + INT sfb, sfboffs, j; /* loop counters */ + FIXP_DBL pnlrLdData, pnmsLdData; + FIXP_DBL minThresholdLdData; + FIXP_DBL minThreshold; + INT useMS; + + INT msMaskTrueSomewhere = 0; /* to determine msDigest */ + INT numMsMaskFalse = + 0; /* number of non-intensity bands where L/R coding is used */ + + for (sfb = 0; sfb < sfbCnt; sfb += sfbPerGroup) { + for (sfboffs = 0; sfboffs < maxSfbPerGroup; sfboffs++) { + if ((isBook == NULL) ? 1 : (isBook[sfb + sfboffs] == 0)) { + FIXP_DBL tmp; + + /* + minThreshold=min(sfbThresholdLeft[sfb+sfboffs], + sfbThresholdRight[sfb+sfboffs])*scaleMinThres; pnlr = + (sfbThresholdLeft[sfb+sfboffs]/ + max(sfbEnergyLeft[sfb+sfboffs],sfbThresholdLeft[sfb+sfboffs]))* + (sfbThresholdRight[sfb+sfboffs]/ + max(sfbEnergyRight[sfb+sfboffs],sfbThresholdRight[sfb+sfboffs])); + pnms = + (minThreshold/max(sfbEnergyMid[sfb+sfboffs],minThreshold))* + (minThreshold/max(sfbEnergySide[sfb+sfboffs],minThreshold)); + useMS = (pnms > pnlr); + */ + + /* we assume that scaleMinThres == 1.0f and we can drop it */ + minThresholdLdData = fixMin(sfbThresholdLeftLdData[sfb + sfboffs], + sfbThresholdRightLdData[sfb + sfboffs]); + + /* pnlrLdData = sfbThresholdLeftLdData[sfb+sfboffs] - + max(sfbEnergyLeftLdData[sfb+sfboffs], + sfbThresholdLeftLdData[sfb+sfboffs]) + + sfbThresholdRightLdData[sfb+sfboffs] - + max(sfbEnergyRightLdData[sfb+sfboffs], + sfbThresholdRightLdData[sfb+sfboffs]); */ + tmp = fixMax(sfbEnergyLeftLdData[sfb + sfboffs], + sfbThresholdLeftLdData[sfb + sfboffs]); + pnlrLdData = (sfbThresholdLeftLdData[sfb + sfboffs] >> 1) - (tmp >> 1); + pnlrLdData = pnlrLdData + (sfbThresholdRightLdData[sfb + sfboffs] >> 1); + tmp = fixMax(sfbEnergyRightLdData[sfb + sfboffs], + sfbThresholdRightLdData[sfb + sfboffs]); + pnlrLdData = pnlrLdData - (tmp >> 1); + + /* pnmsLdData = minThresholdLdData - + max(sfbEnergyMidLdData[sfb+sfboffs], minThresholdLdData) + + minThresholdLdData - max(sfbEnergySideLdData[sfb+sfboffs], + minThresholdLdData); */ + tmp = fixMax(sfbEnergyMidLdData[sfb + sfboffs], minThresholdLdData); + pnmsLdData = minThresholdLdData - (tmp >> 1); + tmp = fixMax(sfbEnergySideLdData[sfb + sfboffs], minThresholdLdData); + pnmsLdData = pnmsLdData - (tmp >> 1); + useMS = ((allowMS != 0) && (pnmsLdData > pnlrLdData)) ? 1 : 0; + + if (useMS) { + msMask[sfb + sfboffs] = 1; + msMaskTrueSomewhere = 1; + for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; + j++) { + FIXP_DBL specL, specR; + specL = mdctSpectrumLeft[j] >> 1; + specR = mdctSpectrumRight[j] >> 1; + mdctSpectrumLeft[j] = specL + specR; + mdctSpectrumRight[j] = specL - specR; + } + minThreshold = fixMin(sfbThresholdLeft[sfb + sfboffs], + sfbThresholdRight[sfb + sfboffs]); + sfbThresholdLeft[sfb + sfboffs] = sfbThresholdRight[sfb + sfboffs] = + minThreshold; + sfbThresholdLeftLdData[sfb + sfboffs] = + sfbThresholdRightLdData[sfb + sfboffs] = minThresholdLdData; + sfbEnergyLeft[sfb + sfboffs] = sfbEnergyMid[sfb + sfboffs]; + sfbEnergyRight[sfb + sfboffs] = sfbEnergySide[sfb + sfboffs]; + sfbEnergyLeftLdData[sfb + sfboffs] = + sfbEnergyMidLdData[sfb + sfboffs]; + sfbEnergyRightLdData[sfb + sfboffs] = + sfbEnergySideLdData[sfb + sfboffs]; + + sfbSpreadEnLeft[sfb + sfboffs] = sfbSpreadEnRight[sfb + sfboffs] = + fixMin(sfbSpreadEnLeft[sfb + sfboffs], + sfbSpreadEnRight[sfb + sfboffs]) >> + 1; + + } else { + msMask[sfb + sfboffs] = 0; + numMsMaskFalse++; + } /* useMS */ + } /* isBook */ + else { + /* keep mDigest from IS module */ + if (msMask[sfb + sfboffs]) { + msMaskTrueSomewhere = 1; + } + /* prohibit MS_MASK_ALL in combination with IS */ + numMsMaskFalse = 9; + } /* isBook */ + } /* sfboffs */ + } /* sfb */ + + if (msMaskTrueSomewhere == 1) { + if ((numMsMaskFalse == 0) || + ((numMsMaskFalse < maxSfbPerGroup) && (numMsMaskFalse < 9))) { + *msDigest = SI_MS_MASK_ALL; + /* loop through M/S bands; if msMask==0, set it to 1 and apply M/S */ + for (sfb = 0; sfb < sfbCnt; sfb += sfbPerGroup) { + for (sfboffs = 0; sfboffs < maxSfbPerGroup; sfboffs++) { + if (((isBook == NULL) ? 1 : (isBook[sfb + sfboffs] == 0)) && + (msMask[sfb + sfboffs] == 0)) { + msMask[sfb + sfboffs] = 1; + /* apply M/S coding */ + for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; + j++) { FIXP_DBL specL, specR; - specL = mdctSpectrumLeft[j]>>1; - specR = mdctSpectrumRight[j]>>1; + specL = mdctSpectrumLeft[j] >> 1; + specR = mdctSpectrumRight[j] >> 1; mdctSpectrumLeft[j] = specL + specR; mdctSpectrumRight[j] = specL - specR; } - minThreshold = fixMin(sfbThresholdLeft[sfb+sfboffs], sfbThresholdRight[sfb+sfboffs]); - sfbThresholdLeft[sfb+sfboffs] = sfbThresholdRight[sfb+sfboffs] = minThreshold; - sfbThresholdLeftLdData[sfb+sfboffs] = sfbThresholdRightLdData[sfb+sfboffs] = minThresholdLdData; - sfbEnergyLeft[sfb+sfboffs] = sfbEnergyMid[sfb+sfboffs]; - sfbEnergyRight[sfb+sfboffs] = sfbEnergySide[sfb+sfboffs]; - sfbEnergyLeftLdData[sfb+sfboffs] = sfbEnergyMidLdData[sfb+sfboffs]; - sfbEnergyRightLdData[sfb+sfboffs] = sfbEnergySideLdData[sfb+sfboffs]; - - sfbSpreadEnLeft[sfb+sfboffs] = sfbSpreadEnRight[sfb+sfboffs] = - fixMin( sfbSpreadEnLeft[sfb+sfboffs], - sfbSpreadEnRight[sfb+sfboffs] ) >> 1; - - } - else { - msMask[sfb+sfboffs] = 0; - numMsMaskFalse++; - } /* useMS */ - } /* isBook */ - else { - /* keep mDigest from IS module */ - if (msMask[sfb+sfboffs]) { - msMaskTrueSomewhere = 1; - } - /* prohibit MS_MASK_ALL in combination with IS */ - numMsMaskFalse = 9; - } /* isBook */ - } /* sfboffs */ - } /* sfb */ - - - if(msMaskTrueSomewhere == 1) { - if ((numMsMaskFalse == 0) || ((numMsMaskFalse < maxSfbPerGroup) && (numMsMaskFalse < 9))) { - *msDigest = SI_MS_MASK_ALL; - /* loop through M/S bands; if msMask==0, set it to 1 and apply M/S */ - for (sfb = 0; sfb < sfbCnt; sfb += sfbPerGroup) { - for (sfboffs = 0; sfboffs < maxSfbPerGroup; sfboffs++) { - if (( (isBook == NULL) ? 1 : (isBook[sfb+sfboffs] == 0) ) && (msMask[sfb+sfboffs] == 0)) { - msMask[sfb+sfboffs] = 1; - /* apply M/S coding */ - for(j=sfbOffset[sfb+sfboffs]; j>1; - specR = mdctSpectrumRight[j]>>1; - mdctSpectrumLeft[j] = specL + specR; - mdctSpectrumRight[j] = specL - specR; - } - minThreshold = fixMin(sfbThresholdLeft[sfb+sfboffs], sfbThresholdRight[sfb+sfboffs]); - sfbThresholdLeft[sfb+sfboffs] = sfbThresholdRight[sfb+sfboffs] = minThreshold; - minThresholdLdData = fixMin(sfbThresholdLeftLdData[sfb+sfboffs], sfbThresholdRightLdData[sfb+sfboffs]); - sfbThresholdLeftLdData[sfb+sfboffs] = sfbThresholdRightLdData[sfb+sfboffs] = minThresholdLdData; - sfbEnergyLeft[sfb+sfboffs] = sfbEnergyMid[sfb+sfboffs]; - sfbEnergyRight[sfb+sfboffs] = sfbEnergySide[sfb+sfboffs]; - sfbEnergyLeftLdData[sfb+sfboffs] = sfbEnergyMidLdData[sfb+sfboffs]; - sfbEnergyRightLdData[sfb+sfboffs] = sfbEnergySideLdData[sfb+sfboffs]; - - sfbSpreadEnLeft[sfb+sfboffs] = sfbSpreadEnRight[sfb+sfboffs] = - fixMin( sfbSpreadEnLeft[sfb+sfboffs], - sfbSpreadEnRight[sfb+sfboffs] ) >> 1; - } + minThreshold = fixMin(sfbThresholdLeft[sfb + sfboffs], + sfbThresholdRight[sfb + sfboffs]); + sfbThresholdLeft[sfb + sfboffs] = sfbThresholdRight[sfb + sfboffs] = + minThreshold; + minThresholdLdData = fixMin(sfbThresholdLeftLdData[sfb + sfboffs], + sfbThresholdRightLdData[sfb + sfboffs]); + sfbThresholdLeftLdData[sfb + sfboffs] = + sfbThresholdRightLdData[sfb + sfboffs] = minThresholdLdData; + sfbEnergyLeft[sfb + sfboffs] = sfbEnergyMid[sfb + sfboffs]; + sfbEnergyRight[sfb + sfboffs] = sfbEnergySide[sfb + sfboffs]; + sfbEnergyLeftLdData[sfb + sfboffs] = + sfbEnergyMidLdData[sfb + sfboffs]; + sfbEnergyRightLdData[sfb + sfboffs] = + sfbEnergySideLdData[sfb + sfboffs]; + + sfbSpreadEnLeft[sfb + sfboffs] = sfbSpreadEnRight[sfb + sfboffs] = + fixMin(sfbSpreadEnLeft[sfb + sfboffs], + sfbSpreadEnRight[sfb + sfboffs]) >> + 1; } } - } else { - *msDigest = SI_MS_MASK_SOME; } } else { - *msDigest = SI_MS_MASK_NONE; + *msDigest = SI_MS_MASK_SOME; } + } else { + *msDigest = SI_MS_MASK_NONE; + } } diff --git a/libAACenc/src/ms_stereo.h b/libAACenc/src/ms_stereo.h index 2f3addb..a202307 100644 --- a/libAACenc/src/ms_stereo.h +++ b/libAACenc/src/ms_stereo.h @@ -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,29 +90,28 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M.Werner - contents/description: MS stereo processing + Author(s): M.Werner -******************************************************************************/ + Description: MS stereo processing -#ifndef __MS_STEREO_H__ -#define __MS_STEREO_H__ +*******************************************************************************/ +#ifndef MS_STEREO_H +#define MS_STEREO_H #include "interface.h" -void FDKaacEnc_MsStereoProcessing(PSY_DATA *RESTRICT psyData[(2)], - PSY_OUT_CHANNEL* psyOutChannel[2], - const INT *isBook, - INT *msDigest, /* output */ - INT *msMask, /* output */ - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup, - const INT *sfbOffset); - -#endif +void FDKaacEnc_MsStereoProcessing(PSY_DATA *RESTRICT psyData[(2)], + PSY_OUT_CHANNEL *psyOutChannel[2], + const INT *isBook, INT *msDigest, /* output */ + INT *msMask, /* output */ + const INT allowMS, const INT sfbCnt, + const INT sfbPerGroup, + const INT maxSfbPerGroup, + const INT *sfbOffset); + +#endif /* MS_STEREO_H */ diff --git a/libAACenc/src/noisedet.cpp b/libAACenc/src/noisedet.cpp index f3c51de..c984304 100644 --- a/libAACenc/src/noisedet.cpp +++ b/libAACenc/src/noisedet.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,22 +90,22 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Lohwasser - Initial author: M. Lohwasser - contents/description: noisedet.c - Routines for Noise Detection + Description: noisedet.c + Routines for Noise Detection -******************************************************************************/ +*******************************************************************************/ #include "noisedet.h" #include "aacenc_pns.h" #include "pnsparam.h" - /***************************************************************************** functionname: FDKaacEnc_fuzzyIsSmaller @@ -105,20 +116,16 @@ amm-info@iis.fraunhofer.de output: return fuzzy value *****************************************************************************/ -static FIXP_SGL FDKaacEnc_fuzzyIsSmaller( FIXP_DBL testVal, - FIXP_DBL refVal, - FIXP_DBL loLim, - FIXP_DBL hiLim ) -{ +static FIXP_SGL FDKaacEnc_fuzzyIsSmaller(FIXP_DBL testVal, FIXP_DBL refVal, + FIXP_DBL loLim, FIXP_DBL hiLim) { if (refVal <= FL2FXCONST_DBL(0.0)) - return( FL2FXCONST_SGL(0.0f) ); - else if (testVal >= fMult((hiLim>>1)+(loLim>>1), refVal)) - return( FL2FXCONST_SGL(0.0f) ); - else return( (FIXP_SGL)MAXVAL_SGL ); + return (FL2FXCONST_SGL(0.0f)); + else if (testVal >= fMult((hiLim >> 1) + (loLim >> 1), refVal)) + return (FL2FXCONST_SGL(0.0f)); + else + return ((FIXP_SGL)MAXVAL_SGL); } - - /***************************************************************************** functionname: FDKaacEnc_noiseDetect @@ -140,45 +147,45 @@ static FIXP_SGL FDKaacEnc_fuzzyIsSmaller( FIXP_DBL testVal, *****************************************************************************/ -void FDKaacEnc_noiseDetect(FIXP_DBL *RESTRICT mdctSpectrum, - INT *RESTRICT sfbMaxScaleSpec, - INT sfbActive, - const INT *RESTRICT sfbOffset, - FIXP_SGL *RESTRICT noiseFuzzyMeasure, - NOISEPARAMS *np, - FIXP_SGL *RESTRICT sfbtonality ) +void FDKaacEnc_noiseDetect(FIXP_DBL *RESTRICT mdctSpectrum, + INT *RESTRICT sfbMaxScaleSpec, INT sfbActive, + const INT *RESTRICT sfbOffset, + FIXP_SGL *RESTRICT noiseFuzzyMeasure, + NOISEPARAMS *np, FIXP_SGL *RESTRICT sfbtonality) { - int i, k, sfb, sfbWidth; + int i, k, sfb, sfbWidth; FIXP_SGL fuzzy, fuzzyTotal; FIXP_DBL refVal, testVal; /***** Start detection phase *****/ /* Start noise detection for each band based on a number of checks */ - for (sfb=0; sfbstartSfb || sfbWidth < np->minSfbWidth) { + if (sfb < np->startSfb || sfbWidth < np->minSfbWidth) { noiseFuzzyMeasure[sfb] = FL2FXCONST_SGL(0.0f); continue; } - if ( (np->detectionAlgorithmFlags & USE_POWER_DISTRIBUTION) && (fuzzyTotal > FL2FXCONST_SGL(0.5f)) ) { + if ((np->detectionAlgorithmFlags & USE_POWER_DISTRIBUTION) && + (fuzzyTotal > FL2FXCONST_SGL(0.5f))) { FIXP_DBL fhelp1, fhelp2, fhelp3, fhelp4, maxVal, minVal; - INT leadingBits = fixMax(0,(sfbMaxScaleSpec[sfb] - 3)); /* max sfbWidth = 96/4 ; 2^5=32 => 5/2 = 3 (spc*spc) */ + INT leadingBits = fixMax( + 0, (sfbMaxScaleSpec[sfb] - + 3)); /* max sfbWidth = 96/4 ; 2^5=32 => 5/2 = 3 (spc*spc) */ /* check power distribution in four regions */ fhelp1 = fhelp2 = fhelp3 = fhelp4 = FL2FXCONST_DBL(0.0f); - k = sfbWidth >>2; /* Width of a quarter band */ + k = sfbWidth >> 2; /* Width of a quarter band */ - for (i=sfbOffset[sfb]; ipowDistPSDcurve[sfb]); - fuzzy = FDKaacEnc_fuzzyIsSmaller(testVal, /* 1/2 * maxValue * PSDcurve */ - refVal, /* 1 * minValue */ - FL2FXCONST_DBL(0.495), /* 1/2 * loLim (0.99f/2) */ - FL2FXCONST_DBL(0.505)); /* 1/2 * hiLim (1.01f/2) */ + fuzzy = FDKaacEnc_fuzzyIsSmaller( + testVal, /* 1/2 * maxValue * PSDcurve */ + refVal, /* 1 * minValue */ + FL2FXCONST_DBL(0.495), /* 1/2 * loLim (0.99f/2) */ + FL2FXCONST_DBL(0.505)); /* 1/2 * hiLim (1.01f/2) */ fuzzyTotal = fixMin(fuzzyTotal, fuzzy); } - if ( (np->detectionAlgorithmFlags & USE_PSYCH_TONALITY) && (fuzzyTotal > FL2FXCONST_SGL(0.5f)) ) { + if ((np->detectionAlgorithmFlags & USE_PSYCH_TONALITY) && + (fuzzyTotal > FL2FXCONST_SGL(0.5f))) { /* Detection with tonality-value of psych. acoustic (here: 1 is tonal!)*/ - testVal = FX_SGL2FX_DBL(sfbtonality[sfb])>>1; /* 1/2 * sfbTonality */ - refVal = np->refTonality; + testVal = FX_SGL2FX_DBL(sfbtonality[sfb]) >> 1; /* 1/2 * sfbTonality */ + refVal = np->refTonality; - fuzzy = FDKaacEnc_fuzzyIsSmaller(testVal, - refVal, - FL2FXCONST_DBL(0.45f), /* 1/2 * loLim (0.9f/2) */ - FL2FXCONST_DBL(0.55f)); /* 1/2 * hiLim (1.1f/2) */ + fuzzy = FDKaacEnc_fuzzyIsSmaller( + testVal, refVal, FL2FXCONST_DBL(0.45f), /* 1/2 * loLim (0.9f/2) */ + FL2FXCONST_DBL(0.55f)); /* 1/2 * hiLim (1.1f/2) */ fuzzyTotal = fixMin(fuzzyTotal, fuzzy); } - /* Output of final result */ noiseFuzzyMeasure[sfb] = fuzzyTotal; } diff --git a/libAACenc/src/noisedet.h b/libAACenc/src/noisedet.h index 8d5e365..478701f 100644 --- a/libAACenc/src/noisedet.h +++ b/libAACenc/src/noisedet.h @@ -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,30 +90,27 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Lohwasser - Initial author: M. Lohwasser - contents/description: noisedet.h + Description: noisedet.h -******************************************************************************/ +*******************************************************************************/ -#ifndef __NOISEDET_H -#define __NOISEDET_H +#ifndef NOISEDET_H +#define NOISEDET_H #include "common_fix.h" #include "pnsparam.h" #include "psy_data.h" +void FDKaacEnc_noiseDetect(FIXP_DBL *mdctSpectrum, INT *sfbMaxScaleSpec, + INT sfbActive, const INT *sfbOffset, + FIXP_SGL noiseFuzzyMeasure[], NOISEPARAMS *np, + FIXP_SGL *sfbtonality); -void FDKaacEnc_noiseDetect( FIXP_DBL *mdctSpectrum, - INT *sfbMaxScaleSpec, - INT sfbActive, - const INT *sfbOffset, - FIXP_SGL noiseFuzzyMeasure[], - NOISEPARAMS *np, - FIXP_SGL *sfbtonality ); - -#endif +#endif /* NOISEDET_H */ diff --git a/libAACenc/src/pns_func.h b/libAACenc/src/pns_func.h index efa44ef..88f4586 100644 --- a/libAACenc/src/pns_func.h +++ b/libAACenc/src/pns_func.h @@ -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,72 +90,49 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M. Lohwasser - contents/description: pns_func.h + Author(s): M. Lohwasser -******************************************************************************/ + Description: pns_func.h -#ifndef _PNS_FUNC_H -#define _PNS_FUNC_H +*******************************************************************************/ -#include "common_fix.h" +#ifndef PNS_FUNC_H +#define PNS_FUNC_H +#include "common_fix.h" #include "aacenc_pns.h" #include "psy_data.h" - - -AAC_ENCODER_ERROR FDKaacEnc_InitPnsConfiguration(PNS_CONFIG *pnsConf, - INT bitRate, - INT sampleRate, - INT usePns, - INT sfbCnt, - const INT *sfbOffset, - const INT numChan, - const INT isLC ); - -void FDKaacEnc_PnsDetect( PNS_CONFIG *pnsConf, - PNS_DATA *pnsData, - const INT lastWindowSequence, - const INT sfbActive, - const INT maxSfbPerGroup, - FIXP_DBL *sfbThresholdLdData, - const INT *sfbOffset, - FIXP_DBL *mdctSpectrum, - INT *sfbMaxScaleSpec, - FIXP_SGL *sfbtonality, - int tnsOrder, - INT tnsPredictionGain, - INT tnsActive, - FIXP_DBL *sfbEnergyLdData, - INT *noiseNrg ); - -void FDKaacEnc_CodePnsChannel( const INT sfbActive, - PNS_CONFIG *pnsConf, - INT *pnsFlag, - FIXP_DBL *sfbEnergy, - INT *noiseNrg, - FIXP_DBL *sfbThreshold ); - -void FDKaacEnc_PreProcessPnsChannelPair( const INT sfbActive, - FIXP_DBL *sfbEnergyLeft, - FIXP_DBL *sfbEnergyRight, - FIXP_DBL *sfbEnergyLeftLD, - FIXP_DBL *sfbEnergyRightLD, - FIXP_DBL *sfbEnergyMid, - PNS_CONFIG *pnsConfLeft, - PNS_DATA *pnsDataLeft, - PNS_DATA *pnsDataRight ); - -void FDKaacEnc_PostProcessPnsChannelPair( const INT sfbActive, - PNS_CONFIG *pnsConf, - PNS_DATA *pnsDataLeft, - PNS_DATA *pnsDataRight, - INT *msMask, - INT *msDigest ); - -#endif /* _PNS_FUNC_H */ +AAC_ENCODER_ERROR FDKaacEnc_InitPnsConfiguration( + PNS_CONFIG *pnsConf, INT bitRate, INT sampleRate, INT usePns, INT sfbCnt, + const INT *sfbOffset, const INT numChan, const INT isLC); + +void FDKaacEnc_PnsDetect(PNS_CONFIG *pnsConf, PNS_DATA *pnsData, + const INT lastWindowSequence, const INT sfbActive, + const INT maxSfbPerGroup, FIXP_DBL *sfbThresholdLdData, + const INT *sfbOffset, FIXP_DBL *mdctSpectrum, + INT *sfbMaxScaleSpec, FIXP_SGL *sfbtonality, + int tnsOrder, INT tnsPredictionGain, INT tnsActive, + FIXP_DBL *sfbEnergyLdData, INT *noiseNrg); + +void FDKaacEnc_CodePnsChannel(const INT sfbActive, PNS_CONFIG *pnsConf, + INT *pnsFlag, FIXP_DBL *sfbEnergy, INT *noiseNrg, + FIXP_DBL *sfbThreshold); + +void FDKaacEnc_PreProcessPnsChannelPair( + const INT sfbActive, FIXP_DBL *sfbEnergyLeft, FIXP_DBL *sfbEnergyRight, + FIXP_DBL *sfbEnergyLeftLD, FIXP_DBL *sfbEnergyRightLD, + FIXP_DBL *sfbEnergyMid, PNS_CONFIG *pnsConfLeft, PNS_DATA *pnsDataLeft, + PNS_DATA *pnsDataRight); + +void FDKaacEnc_PostProcessPnsChannelPair(const INT sfbActive, + PNS_CONFIG *pnsConf, + PNS_DATA *pnsDataLeft, + PNS_DATA *pnsDataRight, INT *msMask, + INT *msDigest); + +#endif /* PNS_FUNC_H */ diff --git a/libAACenc/src/pnsparam.cpp b/libAACenc/src/pnsparam.cpp index 9d59ddc..a6aab06 100644 --- a/libAACenc/src/pnsparam.cpp +++ b/libAACenc/src/pnsparam.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,31 +90,32 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Lohwasser - Initial author: M.Lohwasser - contents/description: PNS parameters depending on bitrate and bandwidth + Description: PNS parameters depending on bitrate and bandwidth -******************************************************************************/ +*******************************************************************************/ #include "pnsparam.h" + #include "psy_configuration.h" typedef struct { - SHORT startFreq; + SHORT startFreq; /* Parameters for detection */ - FIXP_SGL refPower; - FIXP_SGL refTonality; - SHORT tnsGainThreshold; /* scaled by TNS_PREDGAIN_SCALE (=1000) */ - SHORT tnsPNSGainThreshold; /* scaled by TNS_PREDGAIN_SCALE (=1000) */ - FIXP_SGL gapFillThr; - SHORT minSfbWidth; - USHORT detectionAlgorithmFlags; + FIXP_SGL refPower; + FIXP_SGL refTonality; + SHORT tnsGainThreshold; /* scaled by TNS_PREDGAIN_SCALE (=1000) */ + SHORT tnsPNSGainThreshold; /* scaled by TNS_PREDGAIN_SCALE (=1000) */ + FIXP_SGL gapFillThr; + SHORT minSfbWidth; + USHORT detectionAlgorithmFlags; } PNS_INFO_TAB; - typedef struct { ULONG brFrom; ULONG brTo; @@ -115,197 +127,448 @@ typedef struct { UCHAR S48000; } AUTO_PNS_TAB; -static const AUTO_PNS_TAB levelTable_mono[]= { - {0, 11999, 0, 1, 1, 1, 1, 1,}, - {12000, 19999, 0, 1, 1, 1, 1, 1,}, - {20000, 28999, 0, 2, 1, 1, 1, 1,}, - {29000, 40999, 0, 4, 4, 4, 2, 2,}, - {41000, 55999, 0, 9, 9, 7, 7, 7,}, - {56000, 61999, 0, 0, 0, 0, 9, 9,}, - {62000, 75999, 0, 0, 0, 0, 0, 0,}, - {76000, 92999, 0, 0, 0, 0, 0, 0,}, - {93000, 999999, 0, 0, 0, 0, 0, 0,}, +static const AUTO_PNS_TAB levelTable_mono[] = { + { + 0, + 11999, + 0, + 1, + 1, + 1, + 1, + 1, + }, + { + 12000, + 19999, + 0, + 1, + 1, + 1, + 1, + 1, + }, + { + 20000, + 28999, + 0, + 2, + 1, + 1, + 1, + 1, + }, + { + 29000, + 40999, + 0, + 4, + 4, + 4, + 2, + 2, + }, + { + 41000, + 55999, + 0, + 9, + 9, + 7, + 7, + 7, + }, + { + 56000, + 61999, + 0, + 0, + 0, + 0, + 9, + 9, + }, + { + 62000, + 75999, + 0, + 0, + 0, + 0, + 0, + 0, + }, + { + 76000, + 92999, + 0, + 0, + 0, + 0, + 0, + 0, + }, + { + 93000, + 999999, + 0, + 0, + 0, + 0, + 0, + 0, + }, }; -static const AUTO_PNS_TAB levelTable_stereo[]= { - {0, 11999, 0, 1, 1, 1, 1, 1,}, - {12000, 19999, 0, 3, 1, 1, 1, 1,}, - {20000, 28999, 0, 3, 3, 3, 2, 2,}, - {29000, 40999, 0, 7, 6, 6, 5, 5,}, - {41000, 55999, 0, 9, 9, 7, 7, 7,}, - {56000, 79999, 0, 0, 0, 0, 0, 0,}, - {80000, 99999, 0, 0, 0, 0, 0, 0,}, - {100000,999999, 0, 0, 0, 0, 0, 0,}, +static const AUTO_PNS_TAB levelTable_stereo[] = { + { + 0, + 11999, + 0, + 1, + 1, + 1, + 1, + 1, + }, + { + 12000, + 19999, + 0, + 3, + 1, + 1, + 1, + 1, + }, + { + 20000, + 28999, + 0, + 3, + 3, + 3, + 2, + 2, + }, + { + 29000, + 40999, + 0, + 7, + 6, + 6, + 5, + 5, + }, + { + 41000, + 55999, + 0, + 9, + 9, + 7, + 7, + 7, + }, + { + 56000, + 79999, + 0, + 0, + 0, + 0, + 0, + 0, + }, + { + 80000, + 99999, + 0, + 0, + 0, + 0, + 0, + 0, + }, + { + 100000, + 999999, + 0, + 0, + 0, + 0, + 0, + 0, + }, }; - static const PNS_INFO_TAB pnsInfoTab[] = { -/*0 pns off */ -/*1*/ { 4000, FL2FXCONST_SGL(0.04), FL2FXCONST_SGL(0.06), 1150, 1200, FL2FXCONST_SGL(0.02), 8, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS /*| JUST_LONG_WINDOW*/ }, -/*2*/ { 4000, FL2FXCONST_SGL(0.04), FL2FXCONST_SGL(0.07), 1130, 1300, FL2FXCONST_SGL(0.05), 8, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS /*| JUST_LONG_WINDOW*/ }, -/*3*/ { 4100, FL2FXCONST_SGL(0.04), FL2FXCONST_SGL(0.07), 1100, 1400, FL2FXCONST_SGL(0.10), 8, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS /*| JUST_LONG_WINDOW*/ }, -/*4*/ { 4100, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.10), 1100, 1400, FL2FXCONST_SGL(0.15), 8, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS /*| JUST_LONG_WINDOW*/ }, -/*5*/ { 4300, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.10), 1100, 1400, FL2FXCONST_SGL(0.15), 8, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS | JUST_LONG_WINDOW }, -/*6*/ { 5000, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.10), 1100, 1400, FL2FXCONST_SGL(0.25), 8, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS | JUST_LONG_WINDOW }, -/*7*/ { 5500, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.12), 1100, 1400, FL2FXCONST_SGL(0.35), 8, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS | JUST_LONG_WINDOW }, -/*8*/ { 6000, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.12), 1080, 1400, FL2FXCONST_SGL(0.40), 8, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS | JUST_LONG_WINDOW }, -/*9*/ { 6000, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.14), 1070, 1400, FL2FXCONST_SGL(0.45), 8, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS | JUST_LONG_WINDOW }, + /*0 pns off */ + /*1*/ {4000, FL2FXCONST_SGL(0.04), FL2FXCONST_SGL(0.06), 1150, 1200, + FL2FXCONST_SGL(0.02), 8, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS /*| JUST_LONG_WINDOW*/}, + /*2*/ + {4000, FL2FXCONST_SGL(0.04), FL2FXCONST_SGL(0.07), 1130, 1300, + FL2FXCONST_SGL(0.05), 8, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS /*| JUST_LONG_WINDOW*/}, + /*3*/ + {4100, FL2FXCONST_SGL(0.04), FL2FXCONST_SGL(0.07), 1100, 1400, + FL2FXCONST_SGL(0.10), 8, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS /*| JUST_LONG_WINDOW*/}, + /*4*/ + {4100, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.10), 1100, 1400, + FL2FXCONST_SGL(0.15), 8, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS /*| JUST_LONG_WINDOW*/}, + /*5*/ + {4300, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.10), 1100, 1400, + FL2FXCONST_SGL(0.15), 8, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS | JUST_LONG_WINDOW}, + /*6*/ + {5000, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.10), 1100, 1400, + FL2FXCONST_SGL(0.25), 8, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS | JUST_LONG_WINDOW}, + /*7*/ + {5500, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.12), 1100, 1400, + FL2FXCONST_SGL(0.35), 8, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS | JUST_LONG_WINDOW}, + /*8*/ + {6000, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.12), 1080, 1400, + FL2FXCONST_SGL(0.40), 8, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS | JUST_LONG_WINDOW}, + /*9*/ + {6000, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.14), 1070, 1400, + FL2FXCONST_SGL(0.45), 8, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS | JUST_LONG_WINDOW}, }; -static const AUTO_PNS_TAB levelTable_lowComplexity[]= { - {0, 27999, 0, 0, 0, 0, 0, 0,}, - {28000, 31999, 0, 2, 2, 2, 2, 2,}, - {32000, 47999, 0, 3, 3, 3, 3, 3,}, - {48000, 48000, 0, 4, 4, 4, 4, 4,}, - {48001, 999999, 0, 0, 0, 0, 0, 0,}, +static const AUTO_PNS_TAB levelTable_lowComplexity[] = { + { + 0, + 27999, + 0, + 0, + 0, + 0, + 0, + 0, + }, + { + 28000, + 31999, + 0, + 2, + 2, + 2, + 2, + 2, + }, + { + 32000, + 47999, + 0, + 3, + 3, + 3, + 3, + 3, + }, + { + 48000, + 48000, + 0, + 4, + 4, + 4, + 4, + 4, + }, + { + 48001, + 999999, + 0, + 0, + 0, + 0, + 0, + 0, + }, }; - -/* conversion of old LC tuning tables to new (LD enc) structure (only entries which are actually used were converted) */ +/* conversion of old LC tuning tables to new (LD enc) structure (only entries + * which are actually used were converted) */ static const PNS_INFO_TAB pnsInfoTab_lowComplexity[] = { -/*0 pns off */ - /* DEFAULT parameter set */ -/*1*/ { 4100, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.16), 1100, 1400, FL2FXCONST_SGL(0.5), 16, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS | JUST_LONG_WINDOW }, -/*2*/ { 4100, FL2FXCONST_SGL(0.05), FL2FXCONST_SGL(0.10), 1410, 1400, FL2FXCONST_SGL(0.5), 16, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS | JUST_LONG_WINDOW }, -/*3*/ { 4100, FL2FXCONST_SGL(0.05), FL2FXCONST_SGL(0.10), 1100, 1400, FL2FXCONST_SGL(0.5), 16, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS | JUST_LONG_WINDOW }, - /* LOWSUBST -> PNS is used less often than with DEFAULT parameter set (for br: 48000 - 79999) */ -/*4*/ { 4100, FL2FXCONST_SGL(0.20), FL2FXCONST_SGL(0.10), 1410, 1400, FL2FXCONST_SGL(0.5), 16, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS | JUST_LONG_WINDOW }, + /*0 pns off */ + /* DEFAULT parameter set */ + /*1*/ {4100, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.16), 1100, 1400, + FL2FXCONST_SGL(0.5), 16, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS | JUST_LONG_WINDOW}, + /*2*/ + {4100, FL2FXCONST_SGL(0.05), FL2FXCONST_SGL(0.10), 1410, 1400, + FL2FXCONST_SGL(0.5), 16, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS | JUST_LONG_WINDOW}, + /*3*/ + {4100, FL2FXCONST_SGL(0.05), FL2FXCONST_SGL(0.10), 1100, 1400, + FL2FXCONST_SGL(0.5), 16, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS | JUST_LONG_WINDOW}, + /* LOWSUBST -> PNS is used less often than with DEFAULT parameter set (for + br: 48000 - 79999) */ + /*4*/ + {4100, FL2FXCONST_SGL(0.20), FL2FXCONST_SGL(0.10), 1410, 1400, + FL2FXCONST_SGL(0.5), 16, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS | JUST_LONG_WINDOW}, }; /**************************************************************************** function to look up used pns level ****************************************************************************/ -int FDKaacEnc_lookUpPnsUse (int bitRate, int sampleRate, int numChan, const int isLC) { - - int hUsePns=0, size, i; +int FDKaacEnc_lookUpPnsUse(int bitRate, int sampleRate, int numChan, + const int isLC) { + int hUsePns = 0, size, i; const AUTO_PNS_TAB *levelTable; if (isLC) { levelTable = &levelTable_lowComplexity[0]; size = sizeof(levelTable_lowComplexity); - } else - { /* (E)LD */ + } else { /* (E)LD */ levelTable = (numChan > 1) ? &levelTable_stereo[0] : &levelTable_mono[0]; size = (numChan > 1) ? sizeof(levelTable_stereo) : sizeof(levelTable_mono); } - for(i = 0; i < (int) (size/sizeof(AUTO_PNS_TAB)); i++) { - if(((ULONG)bitRate >= levelTable[i].brFrom) && - ((ULONG)bitRate <= levelTable[i].brTo) ) + for (i = 0; i < (int)(size / sizeof(AUTO_PNS_TAB)); i++) { + if (((ULONG)bitRate >= levelTable[i].brFrom) && + ((ULONG)bitRate <= levelTable[i].brTo)) break; } /* sanity check */ - if ((int)(sizeof(pnsInfoTab)/sizeof(PNS_INFO_TAB)) < i ) { + if ((int)(sizeof(pnsInfoTab) / sizeof(PNS_INFO_TAB)) < i) { return (PNS_TABLE_ERROR); } switch (sampleRate) { - case 16000: hUsePns = levelTable[i].S16000; break; - case 22050: hUsePns = levelTable[i].S22050; break; - case 24000: hUsePns = levelTable[i].S24000; break; - case 32000: hUsePns = levelTable[i].S32000; break; - case 44100: hUsePns = levelTable[i].S44100; break; - case 48000: hUsePns = levelTable[i].S48000; break; - default: - if (isLC) { + case 16000: + hUsePns = levelTable[i].S16000; + break; + case 22050: + hUsePns = levelTable[i].S22050; + break; + case 24000: + hUsePns = levelTable[i].S24000; + break; + case 32000: + hUsePns = levelTable[i].S32000; + break; + case 44100: + hUsePns = levelTable[i].S44100; + break; + case 48000: hUsePns = levelTable[i].S48000; - } - break; + break; + default: + if (isLC) { + hUsePns = levelTable[i].S48000; + } + break; } return (hUsePns); } - /***************************************************************************** functionname: FDKaacEnc_GetPnsParam - description: Gets PNS parameters depending on bitrate and bandwidth + description: Gets PNS parameters depending on bitrate and bandwidth or + bitsPerLine returns: error status input: Noiseparams struct, bitrate, sampling rate, number of sfb's, pointer to sfb offset output: PNS parameters *****************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_GetPnsParam(NOISEPARAMS *np, - INT bitRate, - INT sampleRate, - INT sfbCnt, - const INT *sfbOffset, - INT *usePns, - INT numChan, - const int isLC) - -{ - int i, hUsePns; - const PNS_INFO_TAB *pnsInfo; - - if (isLC) { - np->detectionAlgorithmFlags = IS_LOW_COMLEXITY; - pnsInfo = pnsInfoTab_lowComplexity; +AAC_ENCODER_ERROR FDKaacEnc_GetPnsParam(NOISEPARAMS *np, INT bitRate, + INT sampleRate, INT sfbCnt, + const INT *sfbOffset, INT *usePns, + INT numChan, const INT isLC) { + int i, hUsePns; + const PNS_INFO_TAB *pnsInfo; + + if (*usePns <= 0) return AAC_ENC_OK; + + if (isLC) { + np->detectionAlgorithmFlags = IS_LOW_COMPLEXITY; + + pnsInfo = pnsInfoTab_lowComplexity; + + /* new pns params */ + hUsePns = FDKaacEnc_lookUpPnsUse(bitRate, sampleRate, numChan, isLC); + if (hUsePns == 0) { + *usePns = 0; + return AAC_ENC_OK; } - else - { - np->detectionAlgorithmFlags = 0; - pnsInfo = pnsInfoTab; + + if (hUsePns == PNS_TABLE_ERROR) { + return AAC_ENC_PNS_TABLE_ERROR; } - if (*usePns<=0) - return AAC_ENC_OK; + /* select correct row of tuning table */ + pnsInfo += hUsePns - 1; + + } else { + np->detectionAlgorithmFlags = 0; + pnsInfo = pnsInfoTab; /* new pns params */ - hUsePns = FDKaacEnc_lookUpPnsUse (bitRate, sampleRate, numChan, isLC); + hUsePns = FDKaacEnc_lookUpPnsUse(bitRate, sampleRate, numChan, isLC); if (hUsePns == 0) { *usePns = 0; - return AAC_ENC_OK; - } - if (hUsePns == PNS_TABLE_ERROR) - return AAC_ENC_PNS_TABLE_ERROR; + return AAC_ENC_OK; + } + if (hUsePns == PNS_TABLE_ERROR) return AAC_ENC_PNS_TABLE_ERROR; /* select correct row of tuning table */ - pnsInfo += hUsePns-1; + pnsInfo += hUsePns - 1; + } - np->startSfb = FDKaacEnc_FreqToBandWithRounding( pnsInfo->startFreq, - sampleRate, - sfbCnt, - sfbOffset ); + np->startSfb = FDKaacEnc_FreqToBandWidthRounding( + pnsInfo->startFreq, sampleRate, sfbCnt, sfbOffset); - np->detectionAlgorithmFlags |= pnsInfo->detectionAlgorithmFlags; + np->detectionAlgorithmFlags |= pnsInfo->detectionAlgorithmFlags; - np->refPower = FX_SGL2FX_DBL(pnsInfo->refPower); - np->refTonality = FX_SGL2FX_DBL(pnsInfo->refTonality); - np->tnsGainThreshold = pnsInfo->tnsGainThreshold; - np->tnsPNSGainThreshold = pnsInfo->tnsPNSGainThreshold; - np->minSfbWidth = pnsInfo->minSfbWidth; + np->refPower = FX_SGL2FX_DBL(pnsInfo->refPower); + np->refTonality = FX_SGL2FX_DBL(pnsInfo->refTonality); + np->tnsGainThreshold = pnsInfo->tnsGainThreshold; + np->tnsPNSGainThreshold = pnsInfo->tnsPNSGainThreshold; + np->minSfbWidth = pnsInfo->minSfbWidth; - np->gapFillThr = (FIXP_SGL)pnsInfo->gapFillThr; + np->gapFillThr = + pnsInfo->gapFillThr; /* for LC it is always FL2FXCONST_SGL(0.5) */ - /* assuming a constant dB/Hz slope in the signal's PSD curve, + /* assuming a constant dB/Hz slope in the signal's PSD curve, the detection threshold needs to be corrected for the width of the band */ - for ( i = 0; i < (sfbCnt-1); i++) - { - INT qtmp, sfbWidth; - FIXP_DBL tmp; - sfbWidth = sfbOffset[i+1]-sfbOffset[i]; + for (i = 0; i < (sfbCnt - 1); i++) { + INT qtmp, sfbWidth; + FIXP_DBL tmp; - tmp = fPow(np->refPower, 0, sfbWidth, DFRACT_BITS-1-5, &qtmp); - np->powDistPSDcurve[i] = (FIXP_SGL)((LONG)(scaleValue(tmp, qtmp) >> 16)); - } - np->powDistPSDcurve[sfbCnt] = np->powDistPSDcurve[sfbCnt-1]; + sfbWidth = sfbOffset[i + 1] - sfbOffset[i]; + + tmp = fPow(np->refPower, 0, sfbWidth, DFRACT_BITS - 1 - 5, &qtmp); + np->powDistPSDcurve[i] = (FIXP_SGL)((LONG)(scaleValue(tmp, qtmp) >> 16)); + } + np->powDistPSDcurve[sfbCnt] = np->powDistPSDcurve[sfbCnt - 1]; return AAC_ENC_OK; } diff --git a/libAACenc/src/pnsparam.h b/libAACenc/src/pnsparam.h index 08bb83e..c37738a 100644 --- a/libAACenc/src/pnsparam.h +++ b/libAACenc/src/pnsparam.h @@ -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,36 +90,36 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Lohwasser - Initial author: M. Lohwasser - contents/description: PNS parameters depending on bitrate and bandwidth + Description: PNS parameters depending on bitrate and bandwidth -******************************************************************************/ +*******************************************************************************/ -#ifndef __PNSPARAM_H -#define __PNSPARAM_H +#ifndef PNSPARAM_H +#define PNSPARAM_H #include "aacenc.h" #include "common_fix.h" #include "psy_const.h" -#define NUM_PNSINFOTAB 4 -#define PNS_TABLE_ERROR -1 +#define NUM_PNSINFOTAB 4 +#define PNS_TABLE_ERROR -1 /* detection algorithm flags */ -#define USE_POWER_DISTRIBUTION (1<<0) -#define USE_PSYCH_TONALITY (1<<1) -#define USE_TNS_GAIN_THR (1<<2) -#define USE_TNS_PNS (1<<3) -#define JUST_LONG_WINDOW (1<<4) +#define USE_POWER_DISTRIBUTION (1 << 0) +#define USE_PSYCH_TONALITY (1 << 1) +#define USE_TNS_GAIN_THR (1 << 2) +#define USE_TNS_PNS (1 << 3) +#define JUST_LONG_WINDOW (1 << 4) /* additional algorithm flags */ -#define IS_LOW_COMLEXITY (1<<5) +#define IS_LOW_COMPLEXITY (1 << 5) -typedef struct -{ +typedef struct { /* PNS start band */ short startSfb; @@ -116,26 +127,23 @@ typedef struct USHORT detectionAlgorithmFlags; /* Parameters for detection */ - FIXP_DBL refPower; - FIXP_DBL refTonality; - INT tnsGainThreshold; - INT tnsPNSGainThreshold; - INT minSfbWidth; - FIXP_SGL powDistPSDcurve[MAX_GROUPED_SFB]; - FIXP_SGL gapFillThr; + FIXP_DBL refPower; + FIXP_DBL refTonality; + INT tnsGainThreshold; + INT tnsPNSGainThreshold; + INT minSfbWidth; + FIXP_SGL powDistPSDcurve[MAX_GROUPED_SFB]; + FIXP_SGL gapFillThr; } NOISEPARAMS; -int FDKaacEnc_lookUpPnsUse (int bitRate, int sampleRate, int numChan, const int isLC); +int FDKaacEnc_lookUpPnsUse(int bitRate, int sampleRate, int numChan, + const int isLC); /****** Definition of prototypes ******/ -AAC_ENCODER_ERROR FDKaacEnc_GetPnsParam(NOISEPARAMS *np, - INT bitRate, - INT sampleRate, - INT sfbCnt, - const INT *sfbOffset, - INT *usePns, - INT numChan, - const INT isLC); +AAC_ENCODER_ERROR FDKaacEnc_GetPnsParam(NOISEPARAMS *np, INT bitRate, + INT sampleRate, INT sfbCnt, + const INT *sfbOffset, INT *usePns, + INT numChan, const INT isLC); -#endif +#endif /* PNSPARAM_H */ diff --git a/libAACenc/src/pre_echo_control.cpp b/libAACenc/src/pre_echo_control.cpp index 3dfd8ed..3d5d153 100644 --- a/libAACenc/src/pre_echo_control.cpp +++ b/libAACenc/src/pre_echo_control.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,92 +90,87 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Pre echo control + Description: Pre echo control -******************************************************************************/ +*******************************************************************************/ #include "pre_echo_control.h" #include "psy_configuration.h" -void FDKaacEnc_InitPreEchoControl(FIXP_DBL *RESTRICT pbThresholdNm1, - INT *calcPreEcho, - INT numPb, - FIXP_DBL *RESTRICT sfbPcmQuantThreshold, - INT *mdctScalenm1) -{ - *mdctScalenm1 = PCM_QUANT_THR_SCALE>>1; +void FDKaacEnc_InitPreEchoControl(FIXP_DBL *RESTRICT pbThresholdNm1, + INT *calcPreEcho, INT numPb, + FIXP_DBL *RESTRICT sfbPcmQuantThreshold, + INT *mdctScalenm1) { + *mdctScalenm1 = PCM_QUANT_THR_SCALE >> 1; - FDKmemcpy(pbThresholdNm1, sfbPcmQuantThreshold, numPb*sizeof(FIXP_DBL)); + FDKmemcpy(pbThresholdNm1, sfbPcmQuantThreshold, numPb * sizeof(FIXP_DBL)); *calcPreEcho = 1; } +void FDKaacEnc_PreEchoControl(FIXP_DBL *RESTRICT pbThresholdNm1, + INT calcPreEcho, INT numPb, + INT maxAllowedIncreaseFactor, + FIXP_SGL minRemainingThresholdFactor, + FIXP_DBL *RESTRICT pbThreshold, INT mdctScale, + INT *mdctScalenm1) { + int i; + FIXP_DBL tmpThreshold1, tmpThreshold2; + int scaling; + + /* If lastWindowSequence in previous frame was start- or stop-window, + skip preechocontrol calculation */ + if (calcPreEcho == 0) { + /* copy thresholds to internal memory */ + FDKmemcpy(pbThresholdNm1, pbThreshold, numPb * sizeof(FIXP_DBL)); + *mdctScalenm1 = mdctScale; + return; + } + + if (mdctScale > *mdctScalenm1) { + /* if current thresholds are downscaled more than the ones from the last + * block */ + scaling = 2 * (mdctScale - *mdctScalenm1); + for (i = 0; i < numPb; i++) { + /* multiplication with return data type fract ist equivalent to int + * multiplication */ + FDK_ASSERT(scaling >= 0); + tmpThreshold1 = maxAllowedIncreaseFactor * (pbThresholdNm1[i] >> scaling); + tmpThreshold2 = fMult(minRemainingThresholdFactor, pbThreshold[i]); + + FIXP_DBL tmp = pbThreshold[i]; -void FDKaacEnc_PreEchoControl(FIXP_DBL *RESTRICT pbThresholdNm1, - INT calcPreEcho, - INT numPb, - INT maxAllowedIncreaseFactor, - FIXP_SGL minRemainingThresholdFactor, - FIXP_DBL *RESTRICT pbThreshold, - INT mdctScale, - INT *mdctScalenm1) -{ - int i; - FIXP_DBL tmpThreshold1, tmpThreshold2; - int scaling; - - /* If lastWindowSequence in previous frame was start- or stop-window, - skip preechocontrol calculation */ - if (calcPreEcho==0) { /* copy thresholds to internal memory */ - FDKmemcpy(pbThresholdNm1, pbThreshold, numPb*sizeof(FIXP_DBL)); - *mdctScalenm1 = mdctScale; - return; - } - - if ( mdctScale > *mdctScalenm1 ) { - /* if current thresholds are downscaled more than the ones from the last block */ - scaling = 2*(mdctScale-*mdctScalenm1); - for(i = 0; i < numPb; i++) { + pbThresholdNm1[i] = tmp; - /* multiplication with return data type fract ist equivalent to int multiplication */ - FDK_ASSERT(scaling>=0); - tmpThreshold1 = maxAllowedIncreaseFactor * (pbThresholdNm1[i]>>scaling); - tmpThreshold2 = fMult(minRemainingThresholdFactor, pbThreshold[i]); - - FIXP_DBL tmp = pbThreshold[i]; + tmp = fixMin(tmp, tmpThreshold1); + pbThreshold[i] = fixMax(tmp, tmpThreshold2); + } + } else { + /* if thresholds of last block are more downscaled than the current ones */ + scaling = 2 * (*mdctScalenm1 - mdctScale); + for (i = 0; i < numPb; i++) { + /* multiplication with return data type fract ist equivalent to int + * multiplication */ + tmpThreshold1 = (maxAllowedIncreaseFactor >> 1) * pbThresholdNm1[i]; + tmpThreshold2 = fMult(minRemainingThresholdFactor, pbThreshold[i]); - /* copy thresholds to internal memory */ - pbThresholdNm1[i] = tmp; + /* copy thresholds to internal memory */ + pbThresholdNm1[i] = pbThreshold[i]; - tmp = fixMin(tmp, tmpThreshold1); - pbThreshold[i] = fixMax(tmp, tmpThreshold2); - } - } - else { - /* if thresholds of last block are more downscaled than the current ones */ - scaling = 2*(*mdctScalenm1-mdctScale); - for(i = 0; i < numPb; i++) { - - /* multiplication with return data type fract ist equivalent to int multiplication */ - tmpThreshold1 = (maxAllowedIncreaseFactor>>1) * pbThresholdNm1[i]; - tmpThreshold2 = fMult(minRemainingThresholdFactor, pbThreshold[i]); - - /* copy thresholds to internal memory */ - pbThresholdNm1[i] = pbThreshold[i]; - - FDK_ASSERT(scaling>=0); - if((pbThreshold[i]>>(scaling+1)) > tmpThreshold1) { - pbThreshold[i] = tmpThreshold1<<(scaling+1); - } - pbThreshold[i] = fixMax(pbThreshold[i], tmpThreshold2); - } + FDK_ASSERT(scaling >= 0); + if ((pbThreshold[i] >> (scaling + 1)) > tmpThreshold1) { + pbThreshold[i] = tmpThreshold1 << (scaling + 1); + } + pbThreshold[i] = fixMax(pbThreshold[i], tmpThreshold2); } + } - *mdctScalenm1 = mdctScale; + *mdctScalenm1 = mdctScale; } diff --git a/libAACenc/src/pre_echo_control.h b/libAACenc/src/pre_echo_control.h index 9224db0..688efdb 100644 --- a/libAACenc/src/pre_echo_control.h +++ b/libAACenc/src/pre_echo_control.h @@ -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,36 +90,29 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ - -/******************************** MPEG Audio Encoder ************************** +----------------------------------------------------------------------------- */ - Initial author: M.Werner - contents/description: Pre echo control +/**************************** AAC encoder library ****************************** -******************************************************************************/ + Author(s): M.Werner -#ifndef __PRE_ECHO_CONTROL_H -#define __PRE_ECHO_CONTROL_H + Description: Pre echo control -#include "common_fix.h" +*******************************************************************************/ +#ifndef PRE_ECHO_CONTROL_H +#define PRE_ECHO_CONTROL_H -void FDKaacEnc_InitPreEchoControl(FIXP_DBL *pbThresholdnm1, - INT *calcPreEcho, - INT numPb, - FIXP_DBL *sfbPcmQuantThreshold, - INT *mdctScalenm1); +#include "common_fix.h" +void FDKaacEnc_InitPreEchoControl(FIXP_DBL *pbThresholdnm1, INT *calcPreEcho, + INT numPb, FIXP_DBL *sfbPcmQuantThreshold, + INT *mdctScalenm1); -void FDKaacEnc_PreEchoControl(FIXP_DBL *pbThresholdNm1, - INT calcPreEcho, - INT numPb, - INT maxAllowedIncreaseFactor, - FIXP_SGL minRemainingThresholdFactor, - FIXP_DBL *pbThreshold, - INT mdctScale, - INT *mdctScalenm1); +void FDKaacEnc_PreEchoControl(FIXP_DBL *pbThresholdNm1, INT calcPreEcho, + INT numPb, INT maxAllowedIncreaseFactor, + FIXP_SGL minRemainingThresholdFactor, + FIXP_DBL *pbThreshold, INT mdctScale, + INT *mdctScalenm1); #endif - diff --git a/libAACenc/src/psy_configuration.cpp b/libAACenc/src/psy_configuration.cpp index 9a72c68..eef90bc 100644 --- a/libAACenc/src/psy_configuration.cpp +++ b/libAACenc/src/psy_configuration.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Psychoaccoustic configuration + Description: Psychoaccoustic configuration -******************************************************************************/ +*******************************************************************************/ #include "psy_configuration.h" #include "adj_thr.h" @@ -96,15 +108,14 @@ amm-info@iis.fraunhofer.de #include "FDK_trigFcts.h" -typedef struct{ - LONG sampleRate; - const SFB_PARAM_LONG *paramLong; - const SFB_PARAM_SHORT *paramShort; -}SFB_INFO_TAB; - +typedef struct { + LONG sampleRate; + const SFB_PARAM_LONG *paramLong; + const SFB_PARAM_SHORT *paramShort; +} SFB_INFO_TAB; static const SFB_INFO_TAB sfbInfoTab[] = { - {8000, &p_FDKaacEnc_8000_long_1024, &p_FDKaacEnc_8000_short_128}, + {8000, &p_FDKaacEnc_8000_long_1024, &p_FDKaacEnc_8000_short_128}, {11025, &p_FDKaacEnc_11025_long_1024, &p_FDKaacEnc_11025_short_128}, {12000, &p_FDKaacEnc_12000_long_1024, &p_FDKaacEnc_12000_short_128}, {16000, &p_FDKaacEnc_16000_long_1024, &p_FDKaacEnc_16000_short_128}, @@ -121,108 +132,81 @@ static const SFB_INFO_TAB sfbInfoTab[] = { /* 22050 and 24000 Hz */ static const SFB_PARAM_LONG p_22050_long_512 = { - 31, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 8, 8, 8, 12, 12, 12, 16, 20, 24, - 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32} -}; + 31, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, + 12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}}; /* 32000 Hz */ static const SFB_PARAM_LONG p_32000_long_512 = { 37, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 8, 8, 8, 8, 8, 12, - 12, 12, 12, 16, 16, 16, 20, 24, 24, 28, - 32, 32, 32, 32, 32, 32, 32} -}; + {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, + 12, 12, 12, 12, 16, 16, 16, 20, 24, 24, 28, 32, 32, 32, 32, 32, 32, 32}}; /* 44100 Hz */ static const SFB_PARAM_LONG p_44100_long_512 = { - 36, - {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, - 12, 12, 12, 12, 16, 20, 24, 28, 32, 32, - 32, 32, 32, 32, 32, 52} -}; + 36, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, + 8, 8, 12, 12, 12, 12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32, 32, 52}}; static const SFB_INFO_TAB sfbInfoTabLD512[] = { - { 8000, &p_22050_long_512, NULL}, - {11025, &p_22050_long_512, NULL}, - {12000, &p_22050_long_512, NULL}, - {16000, &p_22050_long_512, NULL}, - {22050, &p_22050_long_512, NULL}, - {24000, &p_22050_long_512, NULL}, - {32000, &p_32000_long_512, NULL}, - {44100, &p_44100_long_512, NULL}, - {48000, &p_44100_long_512, NULL}, - {64000, &p_44100_long_512, NULL}, - {88200, &p_44100_long_512, NULL}, - {96000, &p_44100_long_512, NULL}, - + {8000, &p_22050_long_512, NULL}, {11025, &p_22050_long_512, NULL}, + {12000, &p_22050_long_512, NULL}, {16000, &p_22050_long_512, NULL}, + {22050, &p_22050_long_512, NULL}, {24000, &p_22050_long_512, NULL}, + {32000, &p_32000_long_512, NULL}, {44100, &p_44100_long_512, NULL}, + {48000, &p_44100_long_512, NULL}, {64000, &p_44100_long_512, NULL}, + {88200, &p_44100_long_512, NULL}, {96000, &p_44100_long_512, NULL}, + {128000, &p_44100_long_512, NULL}, {176400, &p_44100_long_512, NULL}, + {192000, &p_44100_long_512, NULL}, {256000, &p_44100_long_512, NULL}, + {352800, &p_44100_long_512, NULL}, {384000, &p_44100_long_512, NULL}, }; - /* 22050 and 24000 Hz */ static const SFB_PARAM_LONG p_22050_long_480 = { - 30, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 8, 8, 8, 12, 12, 12, 16, 20, 24, - 28, 32, 32, 32, 32, 32, 32, 32, 32, 32} -}; + 30, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, + 12, 12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32}}; /* 32000 Hz */ static const SFB_PARAM_LONG p_32000_long_480 = { - 37, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, - 8, 8, 12, 12, 12, 16, 16, 20, 24, 32, - 32, 32, 32, 32, 32, 32, 32} -}; + 37, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, + 8, 8, 8, 12, 12, 12, 16, 16, 20, 24, 32, 32, 32, 32, 32, 32, 32, 32}}; /* 44100 Hz */ static const SFB_PARAM_LONG p_44100_long_480 = { - 35, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 8, 8, 8, 8, 8, 12, - 12, 12, 12, 12, 16, 16, 24, 28, 32, 32, - 32, 32, 32, 32, 48} -}; + 35, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, + 8, 12, 12, 12, 12, 12, 16, 16, 24, 28, 32, 32, 32, 32, 32, 32, 48}}; static const SFB_INFO_TAB sfbInfoTabLD480[] = { - { 8000, &p_22050_long_480, NULL}, - {11025, &p_22050_long_480, NULL}, - {12000, &p_22050_long_480, NULL}, - {16000, &p_22050_long_480, NULL}, - {22050, &p_22050_long_480, NULL}, - {24000, &p_22050_long_480, NULL}, - {32000, &p_32000_long_480, NULL}, - {44100, &p_44100_long_480, NULL}, - {48000, &p_44100_long_480, NULL}, - {64000, &p_44100_long_480, NULL}, - {88200, &p_44100_long_480, NULL}, - {96000, &p_44100_long_480, NULL}, - + {8000, &p_22050_long_480, NULL}, {11025, &p_22050_long_480, NULL}, + {12000, &p_22050_long_480, NULL}, {16000, &p_22050_long_480, NULL}, + {22050, &p_22050_long_480, NULL}, {24000, &p_22050_long_480, NULL}, + {32000, &p_32000_long_480, NULL}, {44100, &p_44100_long_480, NULL}, + {48000, &p_44100_long_480, NULL}, {64000, &p_44100_long_480, NULL}, + {88200, &p_44100_long_480, NULL}, {96000, &p_44100_long_480, NULL}, + {128000, &p_44100_long_480, NULL}, {176400, &p_44100_long_480, NULL}, + {192000, &p_44100_long_480, NULL}, {256000, &p_44100_long_480, NULL}, + {352800, &p_44100_long_480, NULL}, {384000, &p_44100_long_480, NULL}, }; /* Fixed point precision definitions */ -#define Q_BARCVAL (25) - -static AAC_ENCODER_ERROR FDKaacEnc_initSfbTable(LONG sampleRate, INT blockType, INT granuleLength, INT *sfbOffset, INT *sfbCnt) -{ - INT i, specStartOffset = 0; - const UCHAR* sfbWidth = NULL; +#define Q_BARCVAL (25) + +AAC_ENCODER_ERROR FDKaacEnc_initSfbTable(const LONG sampleRate, + const INT blockType, + const INT granuleLength, + INT *const sfbOffset, + INT *const sfbCnt) { + INT i, specStartOffset = 0; + INT granuleLengthWindow = granuleLength; + const UCHAR *sfbWidth = NULL; const SFB_INFO_TAB *sfbInfo = NULL; int size; /* select table */ - switch(granuleLength) { + switch (granuleLength) { case 1024: - case 960: + case 960: sfbInfo = sfbInfoTab; - size = (INT)(sizeof(sfbInfoTab)/sizeof(SFB_INFO_TAB)); + size = (INT)(sizeof(sfbInfoTab) / sizeof(SFB_INFO_TAB)); break; case 512: sfbInfo = sfbInfoTabLD512; @@ -236,20 +220,20 @@ static AAC_ENCODER_ERROR FDKaacEnc_initSfbTable(LONG sampleRate, INT blockType, return AAC_ENC_INVALID_FRAME_LENGTH; } - for(i = 0; i < size; i++){ - if(sfbInfo[i].sampleRate == sampleRate){ - switch(blockType){ - case LONG_WINDOW: - case START_WINDOW: - case STOP_WINDOW: - sfbWidth = sfbInfo[i].paramLong->sfbWidth; - *sfbCnt = sfbInfo[i].paramLong->sfbCnt; - break; - case SHORT_WINDOW: - sfbWidth = sfbInfo[i].paramShort->sfbWidth; - *sfbCnt = sfbInfo[i].paramShort->sfbCnt; - granuleLength /= TRANS_FAC; - break; + for (i = 0; i < size; i++) { + if (sfbInfo[i].sampleRate == sampleRate) { + switch (blockType) { + case LONG_WINDOW: + case START_WINDOW: + case STOP_WINDOW: + sfbWidth = sfbInfo[i].paramLong->sfbWidth; + *sfbCnt = sfbInfo[i].paramLong->sfbCnt; + break; + case SHORT_WINDOW: + sfbWidth = sfbInfo[i].paramShort->sfbWidth; + *sfbCnt = sfbInfo[i].paramShort->sfbCnt; + granuleLengthWindow /= TRANS_FAC; + break; } break; } @@ -261,21 +245,19 @@ static AAC_ENCODER_ERROR FDKaacEnc_initSfbTable(LONG sampleRate, INT blockType, /* calc sfb offsets */ - for(i = 0; i < *sfbCnt; i++){ - sfbOffset[i] = specStartOffset; - specStartOffset += sfbWidth[i]; - if (specStartOffset >= granuleLength) { - i++; - break; - } + for (i = 0; i < *sfbCnt; i++) { + sfbOffset[i] = specStartOffset; + specStartOffset += sfbWidth[i]; + if (specStartOffset >= granuleLengthWindow) { + i++; + break; + } } - *sfbCnt = fixMin(i,*sfbCnt); - sfbOffset[*sfbCnt] = fixMin(specStartOffset,granuleLength); - + *sfbCnt = fixMin(i, *sfbCnt); + sfbOffset[*sfbCnt] = fixMin(specStartOffset, granuleLengthWindow); return AAC_ENC_OK; } - /***************************************************************************** functionname: FDKaacEnc_BarcLineValue @@ -285,51 +267,53 @@ static AAC_ENCODER_ERROR FDKaacEnc_initSfbTable(LONG sampleRate, INT blockType, output: *****************************************************************************/ -static FIXP_DBL FDKaacEnc_BarcLineValue(INT noOfLines, INT fftLine, LONG samplingFreq) -{ - - FIXP_DBL FOURBY3EM4 = (FIXP_DBL)0x45e7b273; /* 4.0/3 * 0.0001 in q43 */ - FIXP_DBL PZZZ76 = (FIXP_DBL)0x639d5e4a; /* 0.00076 in q41 */ - FIXP_DBL ONE3P3 = (FIXP_DBL)0x35333333; /* 13.3 in q26 */ - FIXP_DBL THREEP5 = (FIXP_DBL)0x1c000000; /* 3.5 in q27 */ - FIXP_DBL INV480 = (FIXP_DBL)0x44444444; // 1/480 in q39 - - FIXP_DBL center_freq, x1, x2; - FIXP_DBL bvalFFTLine, atan1, atan2; - - /* Theoritical maximum of center_freq (samp_freq*0.5) is 96khz * 0.5 = 48000 */ - /* Theoritical maximum of x1 is 1.3333333e-4f * center_freq = 6.4, can keep in q28 */ - /* Theoritical maximum of x2 is 0.00076f * center_freq = 36.48, can keep in q25 */ - - center_freq = fftLine * samplingFreq; /* q11 or q8 */ - - switch (noOfLines) { - case 1024: - center_freq = center_freq << 2; /* q13 */ - break; - case 128: - center_freq = center_freq << 5; /* q13 */ - break; - case 512: - center_freq = (fftLine * samplingFreq) << 3; // q13 - break; - case 480: - center_freq = fMult(center_freq, INV480) << 4; // q13 - break; - default: - center_freq = (FIXP_DBL)0; - } - - x1 = fMult(center_freq, FOURBY3EM4); /* q13 * q43 - (DFRACT_BITS-1) = q25 */ - x2 = fMult(center_freq, PZZZ76) << 2; /* q13 * q41 - (DFRACT_BITS-1) + 2 = q25 */ +static FIXP_DBL FDKaacEnc_BarcLineValue(INT noOfLines, INT fftLine, + LONG samplingFreq) { + FIXP_DBL FOURBY3EM4 = (FIXP_DBL)0x45e7b273; /* 4.0/3 * 0.0001 in q43 */ + FIXP_DBL PZZZ76 = (FIXP_DBL)0x639d5e4a; /* 0.00076 in q41 */ + FIXP_DBL ONE3P3 = (FIXP_DBL)0x35333333; /* 13.3 in q26 */ + FIXP_DBL THREEP5 = (FIXP_DBL)0x1c000000; /* 3.5 in q27 */ + FIXP_DBL INV480 = (FIXP_DBL)0x44444444; // 1/480 in q39 + + FIXP_DBL center_freq, x1, x2; + FIXP_DBL bvalFFTLine, atan1, atan2; + + /* Theoritical maximum of center_freq (samp_freq*0.5) is 96khz * 0.5 = 48000 + */ + /* Theoritical maximum of x1 is 1.3333333e-4f * center_freq = 6.4, can keep in + * q28 */ + /* Theoritical maximum of x2 is 0.00076f * center_freq = 36.48, can keep in + * q25 */ + + center_freq = fftLine * samplingFreq; /* q11 or q8 */ + + switch (noOfLines) { + case 1024: + center_freq = center_freq << 2; /* q13 */ + break; + case 128: + center_freq = center_freq << 5; /* q13 */ + break; + case 512: + center_freq = (fftLine * samplingFreq) << 3; // q13 + break; + case 480: + center_freq = fMult(center_freq, INV480) << 4; // q13 + break; + default: + center_freq = (FIXP_DBL)0; + } - atan1 = fixp_atan(x1); - atan2 = fixp_atan(x2); + x1 = fMult(center_freq, FOURBY3EM4); /* q13 * q43 - (DFRACT_BITS-1) = q25 */ + x2 = fMult(center_freq, PZZZ76) + << 2; /* q13 * q41 - (DFRACT_BITS-1) + 2 = q25 */ - /* q25 (q26 * q30 - (DFRACT_BITS-1)) + q25 (q27 * q30 * q30) */ - bvalFFTLine = fMult(ONE3P3, atan2) + fMult(THREEP5, fMult(atan1, atan1)); - return(bvalFFTLine); + atan1 = fixp_atan(x1); + atan2 = fixp_atan(x2); + /* q25 (q26 * q30 - (DFRACT_BITS-1)) + q25 (q27 * q30 * q30) */ + bvalFFTLine = fMult(ONE3P3, atan2) + fMult(THREEP5, fMult(atan1, atan1)); + return (bvalFFTLine); } /* @@ -338,320 +322,306 @@ static FIXP_DBL FDKaacEnc_BarcLineValue(INT noOfLines, INT fftLine, LONG samplin might need to be configurable to e.g. 24 bit PCM Input or a lower resolution for low bit rates */ -static void FDKaacEnc_InitMinPCMResolution(int numPb, - int *pbOffset, - FIXP_DBL *sfbPCMquantThreshold) -{ - /* PCM_QUANT_NOISE = FDKpow(10.0f, - 20.f / 10.0f) * ABS_LOW * NORM_PCM_ENERGY * FDKpow(2,PCM_QUANT_THR_SCALE) */ - #define PCM_QUANT_NOISE ((FIXP_DBL)0x00547062) - - for( int i = 0; i < numPb; i++ ) { - sfbPCMquantThreshold[i] = (pbOffset[i+1] - pbOffset[i]) * PCM_QUANT_NOISE; +static void FDKaacEnc_InitMinPCMResolution(int numPb, int *pbOffset, + FIXP_DBL *sfbPCMquantThreshold) { +/* PCM_QUANT_NOISE = FDKpow(10.0f, - 20.f / 10.0f) * ABS_LOW * NORM_PCM_ENERGY * + * FDKpow(2,PCM_QUANT_THR_SCALE) */ +#define PCM_QUANT_NOISE ((FIXP_DBL)0x00547062) + + for (int i = 0; i < numPb; i++) { + sfbPCMquantThreshold[i] = (pbOffset[i + 1] - pbOffset[i]) * PCM_QUANT_NOISE; } } -static FIXP_DBL getMaskFactor( - const FIXP_DBL dbVal_fix, - const INT dbVal_e, - const FIXP_DBL ten_fix, - const INT ten_e - ) -{ - INT q_msk; - FIXP_DBL mask_factor; +static FIXP_DBL getMaskFactor(const FIXP_DBL dbVal_fix, const INT dbVal_e, + const FIXP_DBL ten_fix, const INT ten_e) { + INT q_msk; + FIXP_DBL mask_factor; - mask_factor = fPow(ten_fix, DFRACT_BITS-1-ten_e, -dbVal_fix, DFRACT_BITS-1-dbVal_e, &q_msk); - q_msk = fixMin(DFRACT_BITS-1,fixMax(-(DFRACT_BITS-1),q_msk)); + mask_factor = fPow(ten_fix, DFRACT_BITS - 1 - ten_e, -dbVal_fix, + DFRACT_BITS - 1 - dbVal_e, &q_msk); + q_msk = fixMin(DFRACT_BITS - 1, fixMax(-(DFRACT_BITS - 1), q_msk)); - if ( (q_msk>0) && (mask_factor>(FIXP_DBL)MAXVAL_DBL>>q_msk) ) { - mask_factor = (FIXP_DBL)MAXVAL_DBL; - } - else { - mask_factor = scaleValue(mask_factor, q_msk); - } + if ((q_msk > 0) && (mask_factor > (FIXP_DBL)MAXVAL_DBL >> q_msk)) { + mask_factor = (FIXP_DBL)MAXVAL_DBL; + } else { + mask_factor = scaleValue(mask_factor, q_msk); + } - return (mask_factor); + return (mask_factor); } -static void FDKaacEnc_initSpreading(INT numPb, - FIXP_DBL *pbBarcValue, - FIXP_DBL *pbMaskLoFactor, - FIXP_DBL *pbMaskHiFactor, - FIXP_DBL *pbMaskLoFactorSprEn, - FIXP_DBL *pbMaskHiFactorSprEn, - const LONG bitrate, - const INT blockType) +static void FDKaacEnc_initSpreading(INT numPb, FIXP_DBL *pbBarcValue, + FIXP_DBL *pbMaskLoFactor, + FIXP_DBL *pbMaskHiFactor, + FIXP_DBL *pbMaskLoFactorSprEn, + FIXP_DBL *pbMaskHiFactorSprEn, + const LONG bitrate, const INT blockType) { - INT i; - FIXP_DBL MASKLOWSPREN, MASKHIGHSPREN; - - FIXP_DBL MASKHIGH = (FIXP_DBL)0x30000000; /* 1.5 in q29 */ - FIXP_DBL MASKLOW = (FIXP_DBL)0x60000000; /* 3.0 in q29 */ - FIXP_DBL MASKLOWSPRENLONG = (FIXP_DBL)0x60000000; /* 3.0 in q29 */ - FIXP_DBL MASKHIGHSPRENLONG = (FIXP_DBL)0x40000000; /* 2.0 in q29 */ - FIXP_DBL MASKHIGHSPRENLONGLOWBR = (FIXP_DBL)0x30000000; /* 1.5 in q29 */ - FIXP_DBL MASKLOWSPRENSHORT = (FIXP_DBL)0x40000000; /* 2.0 in q29 */ - FIXP_DBL MASKHIGHSPRENSHORT = (FIXP_DBL)0x30000000; /* 1.5 in q29 */ - FIXP_DBL TEN = (FIXP_DBL)0x50000000; /* 10.0 in q27 */ - - if (blockType != SHORT_WINDOW) - { - MASKLOWSPREN = MASKLOWSPRENLONG; - MASKHIGHSPREN = (bitrate>20000)?MASKHIGHSPRENLONG:MASKHIGHSPRENLONGLOWBR; - } - else - { - MASKLOWSPREN = MASKLOWSPRENSHORT; - MASKHIGHSPREN = MASKHIGHSPRENSHORT; - } + INT i; + FIXP_DBL MASKLOWSPREN, MASKHIGHSPREN; + + FIXP_DBL MASKHIGH = (FIXP_DBL)0x30000000; /* 1.5 in q29 */ + FIXP_DBL MASKLOW = (FIXP_DBL)0x60000000; /* 3.0 in q29 */ + FIXP_DBL MASKLOWSPRENLONG = (FIXP_DBL)0x60000000; /* 3.0 in q29 */ + FIXP_DBL MASKHIGHSPRENLONG = (FIXP_DBL)0x40000000; /* 2.0 in q29 */ + FIXP_DBL MASKHIGHSPRENLONGLOWBR = (FIXP_DBL)0x30000000; /* 1.5 in q29 */ + FIXP_DBL MASKLOWSPRENSHORT = (FIXP_DBL)0x40000000; /* 2.0 in q29 */ + FIXP_DBL MASKHIGHSPRENSHORT = (FIXP_DBL)0x30000000; /* 1.5 in q29 */ + FIXP_DBL TEN = (FIXP_DBL)0x50000000; /* 10.0 in q27 */ + + if (blockType != SHORT_WINDOW) { + MASKLOWSPREN = MASKLOWSPRENLONG; + MASKHIGHSPREN = + (bitrate > 20000) ? MASKHIGHSPRENLONG : MASKHIGHSPRENLONGLOWBR; + } else { + MASKLOWSPREN = MASKLOWSPRENSHORT; + MASKHIGHSPREN = MASKHIGHSPRENSHORT; + } - for(i=0; i 0) - { - pbMaskHiFactor[i] = getMaskFactor( - fMult(MASKHIGH, (pbBarcValue[i] - pbBarcValue[i-1])), 23, - TEN, 27); - - pbMaskLoFactor[i-1] = getMaskFactor( - fMult(MASKLOW, (pbBarcValue[i] - pbBarcValue[i-1])), 23, - TEN, 27); - - pbMaskHiFactorSprEn[i] = getMaskFactor( - fMult(MASKHIGHSPREN, (pbBarcValue[i] - pbBarcValue[i-1])), 23, - TEN, 27); - - pbMaskLoFactorSprEn[i-1] = getMaskFactor( - fMult(MASKLOWSPREN, (pbBarcValue[i] - pbBarcValue[i-1])), 23, - TEN, 27); - } - else - { - pbMaskHiFactor[i] = (FIXP_DBL)0; - pbMaskLoFactor[numPb-1] = (FIXP_DBL)0; - pbMaskHiFactorSprEn[i] = (FIXP_DBL)0; - pbMaskLoFactorSprEn[numPb-1] = (FIXP_DBL)0; - } + for (i = 0; i < numPb; i++) { + if (i > 0) { + pbMaskHiFactor[i] = getMaskFactor( + fMult(MASKHIGH, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, 27); + + pbMaskLoFactor[i - 1] = getMaskFactor( + fMult(MASKLOW, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, 27); + + pbMaskHiFactorSprEn[i] = getMaskFactor( + fMult(MASKHIGHSPREN, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, + 27); + + pbMaskLoFactorSprEn[i - 1] = getMaskFactor( + fMult(MASKLOWSPREN, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, + 27); + } else { + pbMaskHiFactor[i] = (FIXP_DBL)0; + pbMaskLoFactor[numPb - 1] = (FIXP_DBL)0; + pbMaskHiFactorSprEn[i] = (FIXP_DBL)0; + pbMaskLoFactorSprEn[numPb - 1] = (FIXP_DBL)0; } + } } -static void FDKaacEnc_initBarcValues(INT numPb, - INT *pbOffset, - INT numLines, - INT samplingFrequency, - FIXP_DBL *pbBval) -{ - INT i; - FIXP_DBL MAX_BARC = (FIXP_DBL)0x30000000; /* 24.0 in q25 */ - - for(i=0; i> 1) + (v2 >> 1); - pbBval[i] = fixMin(cur_bark, MAX_BARC); - } +static void FDKaacEnc_initBarcValues(INT numPb, INT *pbOffset, INT numLines, + INT samplingFrequency, FIXP_DBL *pbBval) { + INT i; + FIXP_DBL MAX_BARC = (FIXP_DBL)0x30000000; /* 24.0 in q25 */ + + for (i = 0; i < numPb; i++) { + FIXP_DBL v1, v2, cur_bark; + v1 = FDKaacEnc_BarcLineValue(numLines, pbOffset[i], samplingFrequency); + v2 = FDKaacEnc_BarcLineValue(numLines, pbOffset[i + 1], samplingFrequency); + cur_bark = (v1 >> 1) + (v2 >> 1); + pbBval[i] = fixMin(cur_bark, MAX_BARC); + } } -static void FDKaacEnc_initMinSnr(const LONG bitrate, - const LONG samplerate, - const INT numLines, - const INT *sfbOffset, - const INT sfbActive, - const INT blockType, - FIXP_DBL *sfbMinSnrLdData) -{ - INT sfb; - - /* Fix conversion variables */ - INT qbfac, qperwin, qdiv, qpeprt_const, qpeprt; - INT qtmp, qsnr, sfbWidth; - - FIXP_DBL MAX_BARC = (FIXP_DBL)0x30000000; /* 24.0 in q25 */ - FIXP_DBL MAX_BARCP1 = (FIXP_DBL)0x32000000; /* 25.0 in q25 */ - FIXP_DBL BITS2PEFAC = (FIXP_DBL)0x4b851eb8; /* 1.18 in q30 */ - FIXP_DBL PERS2P4 = (FIXP_DBL)0x624dd2f2; /* 0.024 in q36 */ - FIXP_DBL ONEP5 = (FIXP_DBL)0x60000000; /* 1.5 in q30 */ - FIXP_DBL MAX_SNR = (FIXP_DBL)0x33333333; /* 0.8 in q30 */ - FIXP_DBL MIN_SNR = (FIXP_DBL)0x003126e9; /* 0.003 in q30 */ - - FIXP_DBL barcFactor, pePerWindow, pePart, barcWidth; - FIXP_DBL pePart_const, tmp, snr, one_qsnr, one_point5; - - /* relative number of active barks */ - barcFactor = fDivNorm(fixMin(FDKaacEnc_BarcLineValue(numLines, sfbOffset[sfbActive], samplerate), MAX_BARC), - MAX_BARCP1, &qbfac); - - qbfac = DFRACT_BITS-1-qbfac; - - pePerWindow = fDivNorm(bitrate, samplerate, &qperwin); - qperwin = DFRACT_BITS-1-qperwin; - pePerWindow = fMult(pePerWindow, BITS2PEFAC); qperwin = qperwin + 30 - (DFRACT_BITS-1); - pePerWindow = fMult(pePerWindow, PERS2P4); qperwin = qperwin + 36 - (DFRACT_BITS-1); - - switch (numLines) { - case 1024: - qperwin = qperwin - 10; - break; - case 128: - qperwin = qperwin - 7; - break; - case 512: - qperwin = qperwin - 9; - break; - case 480: - qperwin = qperwin - 9; - pePerWindow = fMult(pePerWindow, FL2FXCONST_DBL(480.f/512.f)); - break; - } +static void FDKaacEnc_initMinSnr(const LONG bitrate, const LONG samplerate, + const INT numLines, const INT *sfbOffset, + const INT sfbActive, const INT blockType, + FIXP_DBL *sfbMinSnrLdData) { + INT sfb; + + /* Fix conversion variables */ + INT qbfac, qperwin, qdiv, qpeprt_const, qpeprt; + INT qtmp, qsnr, sfbWidth; + + FIXP_DBL MAX_BARC = (FIXP_DBL)0x30000000; /* 24.0 in q25 */ + FIXP_DBL MAX_BARCP1 = (FIXP_DBL)0x32000000; /* 25.0 in q25 */ + FIXP_DBL BITS2PEFAC = (FIXP_DBL)0x4b851eb8; /* 1.18 in q30 */ + FIXP_DBL PERS2P4 = (FIXP_DBL)0x624dd2f2; /* 0.024 in q36 */ + FIXP_DBL ONEP5 = (FIXP_DBL)0x60000000; /* 1.5 in q30 */ + FIXP_DBL MAX_SNR = (FIXP_DBL)0x33333333; /* 0.8 in q30 */ + FIXP_DBL MIN_SNR = (FIXP_DBL)0x003126e9; /* 0.003 in q30 */ + + FIXP_DBL barcFactor, pePerWindow, pePart, barcWidth; + FIXP_DBL pePart_const, tmp, snr, one_qsnr, one_point5; + + /* relative number of active barks */ + barcFactor = fDivNorm(fixMin(FDKaacEnc_BarcLineValue( + numLines, sfbOffset[sfbActive], samplerate), + MAX_BARC), + MAX_BARCP1, &qbfac); + + qbfac = DFRACT_BITS - 1 - qbfac; + + pePerWindow = fDivNorm(bitrate, samplerate, &qperwin); + qperwin = DFRACT_BITS - 1 - qperwin; + pePerWindow = fMult(pePerWindow, BITS2PEFAC); + qperwin = qperwin + 30 - (DFRACT_BITS - 1); + pePerWindow = fMult(pePerWindow, PERS2P4); + qperwin = qperwin + 36 - (DFRACT_BITS - 1); + + switch (numLines) { + case 1024: + qperwin = qperwin - 10; + break; + case 128: + qperwin = qperwin - 7; + break; + case 512: + qperwin = qperwin - 9; + break; + case 480: + qperwin = qperwin - 9; + pePerWindow = fMult(pePerWindow, FL2FXCONST_DBL(480.f / 512.f)); + break; + } - /* for short blocks it is assumed that more bits are available */ - if (blockType == SHORT_WINDOW) - { - pePerWindow = fMult(pePerWindow, ONEP5); - qperwin = qperwin + 30 - (DFRACT_BITS-1); - } - pePart_const = fDivNorm(pePerWindow, barcFactor, &qdiv); qpeprt_const = qperwin - qbfac + DFRACT_BITS-1-qdiv; + /* for short blocks it is assumed that more bits are available */ + if (blockType == SHORT_WINDOW) { + pePerWindow = fMult(pePerWindow, ONEP5); + qperwin = qperwin + 30 - (DFRACT_BITS - 1); + } + pePart_const = fDivNorm(pePerWindow, barcFactor, &qdiv); + qpeprt_const = qperwin - qbfac + DFRACT_BITS - 1 - qdiv; - for (sfb = 0; sfb < sfbActive; sfb++) - { - barcWidth = FDKaacEnc_BarcLineValue(numLines, sfbOffset[sfb+1], samplerate) - - FDKaacEnc_BarcLineValue(numLines, sfbOffset[sfb], samplerate); + for (sfb = 0; sfb < sfbActive; sfb++) { + barcWidth = + FDKaacEnc_BarcLineValue(numLines, sfbOffset[sfb + 1], samplerate) - + FDKaacEnc_BarcLineValue(numLines, sfbOffset[sfb], samplerate); - /* adapt to sfb bands */ - pePart = fMult(pePart_const, barcWidth); qpeprt = qpeprt_const + 25 - (DFRACT_BITS-1); + /* adapt to sfb bands */ + pePart = fMult(pePart_const, barcWidth); + qpeprt = qpeprt_const + 25 - (DFRACT_BITS - 1); - /* pe -> snr calculation */ - sfbWidth = (sfbOffset[sfb+1] - sfbOffset[sfb]); - pePart = fDivNorm(pePart, sfbWidth, &qdiv); qpeprt += DFRACT_BITS-1-qdiv; + /* pe -> snr calculation */ + sfbWidth = (sfbOffset[sfb + 1] - sfbOffset[sfb]); + pePart = fDivNorm(pePart, sfbWidth, &qdiv); + qpeprt += DFRACT_BITS - 1 - qdiv; - tmp = f2Pow(pePart, DFRACT_BITS-1-qpeprt, &qtmp); - qtmp = DFRACT_BITS-1-qtmp; + tmp = f2Pow(pePart, DFRACT_BITS - 1 - qpeprt, &qtmp); + qtmp = DFRACT_BITS - 1 - qtmp; - /* Subtract 1.5 */ - qsnr = fixMin(qtmp, 30); - tmp = tmp >> (qtmp - qsnr); + /* Subtract 1.5 */ + qsnr = fixMin(qtmp, 30); + tmp = tmp >> (qtmp - qsnr); - if((30+1-qsnr) > (DFRACT_BITS-1)) - one_point5 = (FIXP_DBL)0; - else - one_point5 = (FIXP_DBL)(ONEP5 >> (30+1-qsnr)); + if ((30 + 1 - qsnr) > (DFRACT_BITS - 1)) + one_point5 = (FIXP_DBL)0; + else + one_point5 = (FIXP_DBL)(ONEP5 >> (30 + 1 - qsnr)); - snr = (tmp>>1) - (one_point5); qsnr -= 1; + snr = (tmp >> 1) - (one_point5); + qsnr -= 1; - /* max(snr, 1.0) */ - if(qsnr > 0) - one_qsnr = (FIXP_DBL)(1 << qsnr); - else - one_qsnr = (FIXP_DBL)0; + /* max(snr, 1.0) */ + if (qsnr > 0) + one_qsnr = (FIXP_DBL)(1 << qsnr); + else + one_qsnr = (FIXP_DBL)0; - snr = fixMax(one_qsnr, snr); + snr = fixMax(one_qsnr, snr); - /* 1/snr */ - snr = fDivNorm(one_qsnr, snr, &qsnr); - qsnr = DFRACT_BITS-1-qsnr; - snr = (qsnr > 30)? (snr>>(qsnr-30)):snr; + /* 1/snr */ + snr = fDivNorm(one_qsnr, snr, &qsnr); + qsnr = DFRACT_BITS - 1 - qsnr; + snr = (qsnr > 30) ? (snr >> (qsnr - 30)) : snr; - /* upper limit is -1 dB */ - snr = (snr > MAX_SNR) ? MAX_SNR : snr; + /* upper limit is -1 dB */ + snr = (snr > MAX_SNR) ? MAX_SNR : snr; - /* lower limit is -25 dB */ - snr = (snr < MIN_SNR) ? MIN_SNR : snr; - snr = snr << 1; + /* lower limit is -25 dB */ + snr = (snr < MIN_SNR) ? MIN_SNR : snr; + snr = snr << 1; - sfbMinSnrLdData[sfb] = CalcLdData(snr); - } + sfbMinSnrLdData[sfb] = CalcLdData(snr); + } } -AAC_ENCODER_ERROR FDKaacEnc_InitPsyConfiguration(INT bitrate, - INT samplerate, - INT bandwidth, - INT blocktype, - INT granuleLength, - INT useIS, +AAC_ENCODER_ERROR FDKaacEnc_InitPsyConfiguration(INT bitrate, INT samplerate, + INT bandwidth, INT blocktype, + INT granuleLength, INT useIS, + INT useMS, PSY_CONFIGURATION *psyConf, - FB_TYPE filterbank) -{ - AAC_ENCODER_ERROR ErrorStatus; - INT sfb; - FIXP_DBL sfbBarcVal[MAX_SFB]; - const INT frameLengthLong = granuleLength; - const INT frameLengthShort = granuleLength/TRANS_FAC; - - FDKmemclear(psyConf, sizeof(PSY_CONFIGURATION)); - psyConf->granuleLength = granuleLength; - psyConf->filterbank = filterbank; - - psyConf->allowIS = (useIS) && ( (bitrate/bandwidth) < 5 ); - - /* init sfb table */ - ErrorStatus = FDKaacEnc_initSfbTable(samplerate,blocktype,granuleLength,psyConf->sfbOffset,&psyConf->sfbCnt); - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; - - /* calculate barc values for each pb */ - FDKaacEnc_initBarcValues(psyConf->sfbCnt, - psyConf->sfbOffset, - psyConf->sfbOffset[psyConf->sfbCnt], - samplerate, - sfbBarcVal); - - FDKaacEnc_InitMinPCMResolution(psyConf->sfbCnt, - psyConf->sfbOffset, - psyConf->sfbPcmQuantThreshold); - - /* calculate spreading function */ - FDKaacEnc_initSpreading(psyConf->sfbCnt, - sfbBarcVal, - psyConf->sfbMaskLowFactor, - psyConf->sfbMaskHighFactor, - psyConf->sfbMaskLowFactorSprEn, - psyConf->sfbMaskHighFactorSprEn, - bitrate, - blocktype); - - /* init ratio */ - - psyConf->maxAllowedIncreaseFactor = 2; /* integer */ - psyConf->minRemainingThresholdFactor = (FIXP_SGL)0x0148; /* FL2FXCONST_SGL(0.01f); */ /* fract */ - - psyConf->clipEnergy = (FIXP_DBL)0x773593ff; /* FL2FXCONST_DBL(1.0e9*NORM_PCM_ENERGY); */ - - if (blocktype!=SHORT_WINDOW) { - psyConf->lowpassLine = (INT)((2*bandwidth*frameLengthLong)/samplerate); - psyConf->lowpassLineLFE = LFE_LOWPASS_LINE; - } - else { - psyConf->lowpassLine = (INT)((2*bandwidth*frameLengthShort)/samplerate); - psyConf->lowpassLineLFE = 0; /* LFE only in lonf blocks */ - /* psyConf->clipEnergy /= (TRANS_FAC * TRANS_FAC); */ - psyConf->clipEnergy >>= 6; - } + FB_TYPE filterbank) { + AAC_ENCODER_ERROR ErrorStatus; + INT sfb; + FIXP_DBL sfbBarcVal[MAX_SFB]; + const INT frameLengthLong = granuleLength; + const INT frameLengthShort = granuleLength / TRANS_FAC; + INT downscaleFactor = 1; + + switch (granuleLength) { + case 256: + case 240: + downscaleFactor = 2; + break; + case 128: + case 120: + downscaleFactor = 4; + break; + default: + downscaleFactor = 1; + break; + } - for (sfb = 0; sfb < psyConf->sfbCnt; sfb++){ - if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLine) - break; - } - psyConf->sfbActive = FDKmax(sfb, 1); + FDKmemclear(psyConf, sizeof(PSY_CONFIGURATION)); + psyConf->granuleLength = granuleLength; + psyConf->filterbank = filterbank; + + psyConf->allowIS = (useIS) && ((bitrate / bandwidth) < 5); + psyConf->allowMS = useMS; + + /* init sfb table */ + ErrorStatus = FDKaacEnc_initSfbTable(samplerate * downscaleFactor, blocktype, + granuleLength * downscaleFactor, + psyConf->sfbOffset, &psyConf->sfbCnt); + + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; + + /* calculate barc values for each pb */ + FDKaacEnc_initBarcValues(psyConf->sfbCnt, psyConf->sfbOffset, + psyConf->sfbOffset[psyConf->sfbCnt], samplerate, + sfbBarcVal); + + FDKaacEnc_InitMinPCMResolution(psyConf->sfbCnt, psyConf->sfbOffset, + psyConf->sfbPcmQuantThreshold); + + /* calculate spreading function */ + FDKaacEnc_initSpreading(psyConf->sfbCnt, sfbBarcVal, + psyConf->sfbMaskLowFactor, psyConf->sfbMaskHighFactor, + psyConf->sfbMaskLowFactorSprEn, + psyConf->sfbMaskHighFactorSprEn, bitrate, blocktype); + + /* init ratio */ + + psyConf->maxAllowedIncreaseFactor = 2; /* integer */ + psyConf->minRemainingThresholdFactor = (FIXP_SGL)0x0148; + /* FL2FXCONST_SGL(0.01f); */ /* fract */ + + psyConf->clipEnergy = + (FIXP_DBL)0x773593ff; /* FL2FXCONST_DBL(1.0e9*NORM_PCM_ENERGY); */ + + if (blocktype != SHORT_WINDOW) { + psyConf->lowpassLine = + (INT)((2 * bandwidth * frameLengthLong) / samplerate); + psyConf->lowpassLineLFE = LFE_LOWPASS_LINE; + } else { + psyConf->lowpassLine = + (INT)((2 * bandwidth * frameLengthShort) / samplerate); + psyConf->lowpassLineLFE = 0; /* LFE only in lonf blocks */ + /* psyConf->clipEnergy /= (TRANS_FAC * TRANS_FAC); */ + psyConf->clipEnergy >>= 6; + } - for (sfb = 0; sfb < psyConf->sfbCnt; sfb++){ - if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLineLFE) - break; - } - psyConf->sfbActiveLFE = sfb; - psyConf->sfbActive = FDKmax(psyConf->sfbActive, psyConf->sfbActiveLFE); - - /* calculate minSnr */ - FDKaacEnc_initMinSnr(bitrate, - samplerate, - psyConf->sfbOffset[psyConf->sfbCnt], - psyConf->sfbOffset, - psyConf->sfbActive, - blocktype, - psyConf->sfbMinSnrLdData); - - return AAC_ENC_OK; -} + for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) { + if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLine) break; + } + psyConf->sfbActive = fMax(sfb, 1); + for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) { + if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLineLFE) break; + } + psyConf->sfbActiveLFE = sfb; + psyConf->sfbActive = fMax(psyConf->sfbActive, psyConf->sfbActiveLFE); + + /* calculate minSnr */ + FDKaacEnc_initMinSnr(bitrate, samplerate * downscaleFactor, + psyConf->sfbOffset[psyConf->sfbCnt], psyConf->sfbOffset, + psyConf->sfbActive, blocktype, psyConf->sfbMinSnrLdData); + + return AAC_ENC_OK; +} diff --git a/libAACenc/src/psy_configuration.h b/libAACenc/src/psy_configuration.h index 3629246..52b2887 100644 --- a/libAACenc/src/psy_configuration.h +++ b/libAACenc/src/psy_configuration.h @@ -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,18 +90,18 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M.Werner - contents/description: Psychoaccoustic configuration + Author(s): M.Werner -******************************************************************************/ + Description: Psychoaccoustic configuration -#ifndef _PSY_CONFIGURATION_H -#define _PSY_CONFIGURATION_H +*******************************************************************************/ +#ifndef PSY_CONFIGURATION_H +#define PSY_CONFIGURATION_H #include "aacenc.h" #include "common_fix.h" @@ -99,67 +110,62 @@ amm-info@iis.fraunhofer.de #include "aacenc_tns.h" #include "aacenc_pns.h" -#define THR_SHIFTBITS 4 -#define PCM_QUANT_THR_SCALE 16 - -#define C_RATIO (FIXP_DBL)0x02940a10 /* FL2FXCONST_DBL(0.001258925f) << THR_SHIFTBITS; */ /* pow(10.0f, -(29.0f/10.0f)) */ +#define THR_SHIFTBITS 4 +#define PCM_QUANT_THR_SCALE 16 +#define BITS_PER_LINE_SHIFT 3 -typedef struct{ +#define C_RATIO \ + (FIXP_DBL)0x02940a10 /* FL2FXCONST_DBL(0.001258925f) << THR_SHIFTBITS; */ /* pow(10.0f, -(29.0f/10.0f)) */ - INT sfbCnt; /* number of existing sf bands */ - INT sfbActive; /* number of sf bands containing energy after lowpass */ +typedef struct { + INT sfbCnt; /* number of existing sf bands */ + INT sfbActive; /* number of sf bands containing energy after lowpass */ INT sfbActiveLFE; - INT sfbOffset[MAX_SFB+1]; + INT sfbOffset[MAX_SFB + 1]; - INT filterbank; /* LC, LD or ELD */ + INT filterbank; /* LC, LD or ELD */ - FIXP_DBL sfbPcmQuantThreshold[MAX_SFB]; + FIXP_DBL sfbPcmQuantThreshold[MAX_SFB]; - INT maxAllowedIncreaseFactor; /* preecho control */ - FIXP_SGL minRemainingThresholdFactor; + INT maxAllowedIncreaseFactor; /* preecho control */ + FIXP_SGL minRemainingThresholdFactor; - INT lowpassLine; - INT lowpassLineLFE; - FIXP_DBL clipEnergy; /* for level dependend tmn */ + INT lowpassLine; + INT lowpassLineLFE; + FIXP_DBL clipEnergy; /* for level dependend tmn */ - FIXP_DBL sfbMaskLowFactor[MAX_SFB]; - FIXP_DBL sfbMaskHighFactor[MAX_SFB]; + FIXP_DBL sfbMaskLowFactor[MAX_SFB]; + FIXP_DBL sfbMaskHighFactor[MAX_SFB]; - FIXP_DBL sfbMaskLowFactorSprEn[MAX_SFB]; - FIXP_DBL sfbMaskHighFactorSprEn[MAX_SFB]; + FIXP_DBL sfbMaskLowFactorSprEn[MAX_SFB]; + FIXP_DBL sfbMaskHighFactorSprEn[MAX_SFB]; - FIXP_DBL sfbMinSnrLdData[MAX_SFB]; /* minimum snr (formerly known as bmax) */ + FIXP_DBL sfbMinSnrLdData[MAX_SFB]; /* minimum snr (formerly known as bmax) */ TNS_CONFIG tnsConf; PNS_CONFIG pnsConf; - INT granuleLength; - INT allowIS; - -}PSY_CONFIGURATION; - - -typedef struct{ - UCHAR sfbCnt; /* Number of scalefactor bands */ - UCHAR sfbWidth[MAX_SFB_LONG]; /* Width of scalefactor bands for long blocks */ -}SFB_PARAM_LONG; - -typedef struct{ - UCHAR sfbCnt; /* Number of scalefactor bands */ - UCHAR sfbWidth[MAX_SFB_SHORT]; /* Width of scalefactor bands for short blocks */ -}SFB_PARAM_SHORT; - - -AAC_ENCODER_ERROR FDKaacEnc_InitPsyConfiguration(INT bitrate, - INT samplerate, - INT bandwidth, - INT blocktype, - INT granuleLength, - INT useIS, + INT granuleLength; + INT allowIS; + INT allowMS; +} PSY_CONFIGURATION; + +typedef struct { + UCHAR sfbCnt; /* Number of scalefactor bands */ + UCHAR sfbWidth[MAX_SFB_LONG]; /* Width of scalefactor bands for long blocks */ +} SFB_PARAM_LONG; + +typedef struct { + UCHAR sfbCnt; /* Number of scalefactor bands */ + UCHAR + sfbWidth[MAX_SFB_SHORT]; /* Width of scalefactor bands for short blocks */ +} SFB_PARAM_SHORT; + +AAC_ENCODER_ERROR FDKaacEnc_InitPsyConfiguration(INT bitrate, INT samplerate, + INT bandwidth, INT blocktype, + INT granuleLength, INT useIS, + INT useMS, PSY_CONFIGURATION *psyConf, FB_TYPE filterbank); -#endif /* _PSY_CONFIGURATION_H */ - - - +#endif /* PSY_CONFIGURATION_H */ diff --git a/libAACenc/src/psy_const.h b/libAACenc/src/psy_const.h index d9c9f43..c2d5304 100644 --- a/libAACenc/src/psy_const.h +++ b/libAACenc/src/psy_const.h @@ -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,37 +90,34 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Global psychoaccoustic constants + Description: Global psychoaccoustic constants -******************************************************************************/ -#ifndef _PSYCONST_H -#define _PSYCONST_H +*******************************************************************************/ +#ifndef PSY_CONST_H +#define PSY_CONST_H -#define TRUE 1 +#define TRUE 1 #define FALSE 0 - #define TRANS_FAC 8 /* encoder short long ratio */ +#define TRANS_FAC 8 /* encoder short long ratio */ -#define FRAME_MAXLEN_SHORT ((1024)/TRANS_FAC) -#define FRAME_LEN_SHORT_128 ((1024)/TRANS_FAC) +#define FRAME_MAXLEN_SHORT ((1024) / TRANS_FAC) +#define FRAME_LEN_SHORT_128 ((1024) / TRANS_FAC) +#define FRAME_LEN_SHORT_120 (FRAME_LEN_LONG_960 / TRANS_FAC) /* Filterbank type*/ -enum FB_TYPE { - FB_LC = 0, - FB_LD = 1, - FB_ELD = 2 -}; +enum FB_TYPE { FB_LC = 0, FB_LD = 1, FB_ELD = 2 }; /* Block types */ #define N_BLOCKTYPES 6 -enum -{ +enum { LONG_WINDOW = 0, START_WINDOW, SHORT_WINDOW, @@ -119,42 +127,42 @@ enum }; /* Window shapes */ -enum -{ +enum { SINE_WINDOW = 0, - KBD_WINDOW = 1, + KBD_WINDOW = 1, LOL_WINDOW = 2 /* Low OverLap window shape for AAC-LD */ }; /* MS stuff */ -enum -{ - SI_MS_MASK_NONE = 0, - SI_MS_MASK_SOME = 1, - SI_MS_MASK_ALL = 2 -}; - - - #define MAX_NO_OF_GROUPS 4 - #define MAX_SFB_LONG 51 /* 51 for a memory optimized implementation, maybe 64 for convenient debugging */ - #define MAX_SFB_SHORT 15 /* 15 for a memory optimized implementation, maybe 16 for convenient debugging */ +enum { SI_MS_MASK_NONE = 0, SI_MS_MASK_SOME = 1, SI_MS_MASK_ALL = 2 }; -#define MAX_SFB (MAX_SFB_SHORT > MAX_SFB_LONG ? MAX_SFB_SHORT : MAX_SFB_LONG) /* = 51 */ -#define MAX_GROUPED_SFB (MAX_NO_OF_GROUPS*MAX_SFB_SHORT > MAX_SFB_LONG ? \ - MAX_NO_OF_GROUPS*MAX_SFB_SHORT : MAX_SFB_LONG) /* = 60 */ +#define MAX_NO_OF_GROUPS 4 +#define MAX_SFB_LONG \ + 51 /* 51 for a memory optimized implementation, maybe 64 for convenient \ + debugging */ +#define MAX_SFB_SHORT \ + 15 /* 15 for a memory optimized implementation, maybe 16 for convenient \ + debugging */ -#define MAX_INPUT_BUFFER_SIZE (2*(1024)) /* 2048 */ +#define MAX_SFB \ + (MAX_SFB_SHORT > MAX_SFB_LONG ? MAX_SFB_SHORT : MAX_SFB_LONG) /* = 51 */ +#define MAX_GROUPED_SFB \ + (MAX_NO_OF_GROUPS * MAX_SFB_SHORT > MAX_SFB_LONG \ + ? MAX_NO_OF_GROUPS * MAX_SFB_SHORT \ + : MAX_SFB_LONG) /* = 60 */ +#define MAX_INPUT_BUFFER_SIZE (2 * (1024)) /* 2048 */ -#define PCM_LEVEL 1.0f -#define NORM_PCM (PCM_LEVEL/32768.0f) -#define NORM_PCM_ENERGY (NORM_PCM*NORM_PCM) -#define LOG_NORM_PCM -15 +#define PCM_LEVEL 1.0f +#define NORM_PCM (PCM_LEVEL / 32768.0f) +#define NORM_PCM_ENERGY (NORM_PCM * NORM_PCM) +#define LOG_NORM_PCM -15 -#define TNS_PREDGAIN_SCALE (1000) +#define TNS_PREDGAIN_SCALE (1000) -#define LFE_LOWPASS_LINE 12 +#define LFE_LOWPASS_LINE 12 +#define LFE_LOWPASS_LINE_MIN 4 -#endif /* _PSYCONST_H */ +#endif /* PSY_CONST_H */ diff --git a/libAACenc/src/psy_data.h b/libAACenc/src/psy_data.h index 7183955..fc04734 100644 --- a/libAACenc/src/psy_data.h +++ b/libAACenc/src/psy_data.h @@ -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,74 +90,80 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M.Werner - contents/description: Psychoaccoustic data + Author(s): M.Werner -******************************************************************************/ + Description: Psychoaccoustic data -#ifndef _PSY_DATA_H -#define _PSY_DATA_H +*******************************************************************************/ +#ifndef PSY_DATA_H +#define PSY_DATA_H #include "block_switch.h" +#include "mdct.h" /* Be careful with MAX_SFB_LONG as length of the .Long arrays. - * sfbEnergy.Long and sfbEnergyMS.Long and sfbThreshold.Long are used as a temporary storage for the regrouped - * short energies and thresholds between FDKaacEnc_groupShortData() and BuildInterface() in FDKaacEnc_psyMain(). - * The space required for this is MAX_GROUPED_SFB ( = MAX_NO_OF_GROUPS*MAX_SFB_SHORT ). - * However, this is not important if unions are used (which is not possible with pfloat). */ - -typedef shouldBeUnion{ - FIXP_DBL Long[MAX_GROUPED_SFB]; - FIXP_DBL Short[TRANS_FAC][MAX_SFB_SHORT]; -}SFB_THRESHOLD; - -typedef shouldBeUnion{ - FIXP_DBL Long[MAX_GROUPED_SFB]; - FIXP_DBL Short[TRANS_FAC][MAX_SFB_SHORT]; -}SFB_ENERGY; - -typedef shouldBeUnion{ - FIXP_DBL Long[MAX_GROUPED_SFB]; - FIXP_DBL Short[TRANS_FAC][MAX_SFB_SHORT]; -}SFB_LD_ENERGY; - -typedef shouldBeUnion{ - INT Long[MAX_GROUPED_SFB]; - INT Short[TRANS_FAC][MAX_SFB_SHORT]; -}SFB_MAX_SCALE; - - -typedef struct{ - INT_PCM* psyInputBuffer; - FIXP_DBL overlapAddBuffer[1024]; - - BLOCK_SWITCHING_CONTROL blockSwitchingControl; /* block switching */ - FIXP_DBL sfbThresholdnm1[MAX_SFB]; /* FDKaacEnc_PreEchoControl */ - INT mdctScalenm1; /* scale of last block's mdct (FDKaacEnc_PreEchoControl) */ - INT calcPreEcho; - INT isLFE; -}PSY_STATIC; - - -typedef struct{ - FIXP_DBL *mdctSpectrum; - SFB_THRESHOLD sfbThreshold; /* adapt */ - SFB_ENERGY sfbEnergy; /* sfb energies */ - SFB_LD_ENERGY sfbEnergyLdData; /* sfb energies in ldData format */ - SFB_MAX_SCALE sfbMaxScaleSpec; - SFB_ENERGY sfbEnergyMS; /* mid/side sfb energies */ - FIXP_DBL sfbEnergyMSLdData[MAX_GROUPED_SFB]; /* mid/side sfb energies in ldData format */ - SFB_ENERGY sfbSpreadEnergy; - INT mdctScale; /* exponent of data in mdctSpectrum */ - INT groupedSfbOffset[MAX_GROUPED_SFB+1]; - INT sfbActive; - INT lowpassLine; -}PSY_DATA; - - -#endif /* _PSY_DATA_H */ + * sfbEnergy.Long and sfbEnergyMS.Long and sfbThreshold.Long are used as a + * temporary storage for the regrouped short energies and thresholds between + * FDKaacEnc_groupShortData() and BuildInterface() in FDKaacEnc_psyMain(). The + * space required for this is MAX_GROUPED_SFB ( = MAX_NO_OF_GROUPS*MAX_SFB_SHORT + * ). However, this is not important if unions are used (which is not possible + * with pfloat). */ + +typedef shouldBeUnion { + FIXP_DBL Long[MAX_GROUPED_SFB]; + FIXP_DBL Short[TRANS_FAC][MAX_SFB_SHORT]; +} +SFB_THRESHOLD; + +typedef shouldBeUnion { + FIXP_DBL Long[MAX_GROUPED_SFB]; + FIXP_DBL Short[TRANS_FAC][MAX_SFB_SHORT]; +} +SFB_ENERGY; + +typedef shouldBeUnion { + FIXP_DBL Long[MAX_GROUPED_SFB]; + FIXP_DBL Short[TRANS_FAC][MAX_SFB_SHORT]; +} +SFB_LD_ENERGY; + +typedef shouldBeUnion { + INT Long[MAX_GROUPED_SFB]; + INT Short[TRANS_FAC][MAX_SFB_SHORT]; +} +SFB_MAX_SCALE; + +typedef struct { + INT_PCM* psyInputBuffer; + FIXP_DBL overlapAddBuffer[3 * 512 / 2]; + + mdct_t mdctPers; /* MDCT persistent data */ + BLOCK_SWITCHING_CONTROL blockSwitchingControl; /* block switching */ + FIXP_DBL sfbThresholdnm1[MAX_SFB]; /* FDKaacEnc_PreEchoControl */ + INT mdctScalenm1; /* scale of last block's mdct (FDKaacEnc_PreEchoControl) */ + INT calcPreEcho; + INT isLFE; +} PSY_STATIC; + +typedef struct { + FIXP_DBL* mdctSpectrum; + SFB_THRESHOLD sfbThreshold; /* adapt */ + SFB_ENERGY sfbEnergy; /* sfb energies */ + SFB_LD_ENERGY sfbEnergyLdData; /* sfb energies in ldData format */ + SFB_MAX_SCALE sfbMaxScaleSpec; + SFB_ENERGY sfbEnergyMS; /* mid/side sfb energies */ + FIXP_DBL sfbEnergyMSLdData[MAX_GROUPED_SFB]; /* mid/side sfb energies in + ldData format */ + SFB_ENERGY sfbSpreadEnergy; + INT mdctScale; /* exponent of data in mdctSpectrum */ + INT groupedSfbOffset[MAX_GROUPED_SFB + 1]; + INT sfbActive; + INT lowpassLine; +} PSY_DATA; + +#endif /* PSY_DATA_H */ diff --git a/libAACenc/src/psy_main.cpp b/libAACenc/src/psy_main.cpp index 446c894..f6345e4 100644 --- a/libAACenc/src/psy_main.cpp +++ b/libAACenc/src/psy_main.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Psychoaccoustic major function block + Description: Psychoaccoustic major function block -******************************************************************************/ +*******************************************************************************/ #include "psy_const.h" @@ -107,15 +119,13 @@ amm-info@iis.fraunhofer.de #include "aacEnc_ram.h" #include "intensity.h" - - /* blending to reduce gibbs artifacts */ #define FADE_OUT_LEN 6 -static const FIXP_DBL fadeOutFactor[FADE_OUT_LEN] = {1840644096, 1533870080, 1227096064, 920322048, 613548032, 306774016}; +static const FIXP_DBL fadeOutFactor[FADE_OUT_LEN] = { + 1840644096, 1533870080, 1227096064, 920322048, 613548032, 306774016}; /* forward definitions */ - /***************************************************************************** functionname: FDKaacEnc_PsyNew @@ -124,56 +134,52 @@ static const FIXP_DBL fadeOutFactor[FADE_OUT_LEN] = {1840644096, 1533870080, 122 input: pointer to a psych handle *****************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_PsyNew(PSY_INTERNAL **phpsy, - const INT nElements, - const INT nChannels - ,UCHAR *dynamic_RAM - ) -{ - AAC_ENCODER_ERROR ErrorStatus; - PSY_INTERNAL *hPsy; - INT i; - - hPsy = GetRam_aacEnc_PsyInternal(); - *phpsy = hPsy; - if (hPsy == NULL) { +AAC_ENCODER_ERROR FDKaacEnc_PsyNew(PSY_INTERNAL **phpsy, const INT nElements, + const INT nChannels, UCHAR *dynamic_RAM) { + AAC_ENCODER_ERROR ErrorStatus; + PSY_INTERNAL *hPsy; + INT i; + + hPsy = GetRam_aacEnc_PsyInternal(); + *phpsy = hPsy; + if (hPsy == NULL) { + ErrorStatus = AAC_ENC_NO_MEMORY; + goto bail; + } + + for (i = 0; i < nElements; i++) { + /* PSY_ELEMENT */ + hPsy->psyElement[i] = GetRam_aacEnc_PsyElement(i); + if (hPsy->psyElement[i] == NULL) { ErrorStatus = AAC_ENC_NO_MEMORY; goto bail; } + } - for (i=0; ipsyElement[i] = GetRam_aacEnc_PsyElement(i); - if (hPsy->psyElement[i] == NULL) { - ErrorStatus = AAC_ENC_NO_MEMORY; - goto bail; - } + for (i = 0; i < nChannels; i++) { + /* PSY_STATIC */ + hPsy->pStaticChannels[i] = GetRam_aacEnc_PsyStatic(i); + if (hPsy->pStaticChannels[i] == NULL) { + ErrorStatus = AAC_ENC_NO_MEMORY; + goto bail; } - - for (i=0; ipStaticChannels[i] = GetRam_aacEnc_PsyStatic(i); - if (hPsy->pStaticChannels[i]==NULL) { - ErrorStatus = AAC_ENC_NO_MEMORY; - goto bail; - } - /* AUDIO INPUT BUFFER */ - hPsy->pStaticChannels[i]->psyInputBuffer = GetRam_aacEnc_PsyInputBuffer(i); - if (hPsy->pStaticChannels[i]->psyInputBuffer==NULL) { - ErrorStatus = AAC_ENC_NO_MEMORY; - goto bail; - } + /* AUDIO INPUT BUFFER */ + hPsy->pStaticChannels[i]->psyInputBuffer = GetRam_aacEnc_PsyInputBuffer(i); + if (hPsy->pStaticChannels[i]->psyInputBuffer == NULL) { + ErrorStatus = AAC_ENC_NO_MEMORY; + goto bail; } + } - /* reusable psych memory */ - hPsy->psyDynamic = GetRam_aacEnc_PsyDynamic(0, dynamic_RAM); + /* reusable psych memory */ + hPsy->psyDynamic = GetRam_aacEnc_PsyDynamic(0, dynamic_RAM); - return AAC_ENC_OK; + return AAC_ENC_OK; bail: - FDKaacEnc_PsyClose(phpsy, NULL); + FDKaacEnc_PsyClose(phpsy, NULL); - return ErrorStatus; + return ErrorStatus; } /***************************************************************************** @@ -184,18 +190,14 @@ bail: input: pointer to a psych handle *****************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_PsyOutNew(PSY_OUT **phpsyOut, - const INT nElements, - const INT nChannels, - const INT nSubFrames - ,UCHAR *dynamic_RAM - ) -{ +AAC_ENCODER_ERROR FDKaacEnc_PsyOutNew(PSY_OUT **phpsyOut, const INT nElements, + const INT nChannels, const INT nSubFrames, + UCHAR *dynamic_RAM) { AAC_ENCODER_ERROR ErrorStatus; int n, i; int elInc = 0, chInc = 0; - for (n=0; npPsyOutChannels[i] = GetRam_aacEnc_PsyOutChannel(chInc++); + if (NULL == phpsyOut[n]->pPsyOutChannels[i]) { + ErrorStatus = AAC_ENC_NO_MEMORY; + goto bail; + } } - for (i=0; ipsyOutElement[i] = GetRam_aacEnc_PsyOutElements(elInc++); if (phpsyOut[n]->psyOutElement[i] == NULL) { ErrorStatus = AAC_ENC_NO_MEMORY; @@ -223,63 +229,59 @@ bail: return ErrorStatus; } - -AAC_ENCODER_ERROR FDKaacEnc_psyInitStates(PSY_INTERNAL *hPsy, - PSY_STATIC* psyStatic, - AUDIO_OBJECT_TYPE audioObjectType) -{ +AAC_ENCODER_ERROR FDKaacEnc_psyInitStates(PSY_INTERNAL *hPsy, + PSY_STATIC *psyStatic, + AUDIO_OBJECT_TYPE audioObjectType) { /* init input buffer */ - FDKmemclear(psyStatic->psyInputBuffer, MAX_INPUT_BUFFER_SIZE*sizeof(INT_PCM)); + FDKmemclear(psyStatic->psyInputBuffer, + MAX_INPUT_BUFFER_SIZE * sizeof(INT_PCM)); FDKaacEnc_InitBlockSwitching(&psyStatic->blockSwitchingControl, - isLowDelay(audioObjectType) - ); + isLowDelay(audioObjectType)); return AAC_ENC_OK; } - -AAC_ENCODER_ERROR FDKaacEnc_psyInit(PSY_INTERNAL *hPsy, - PSY_OUT **phpsyOut, - const INT nSubFrames, - const INT nMaxChannels, +AAC_ENCODER_ERROR FDKaacEnc_psyInit(PSY_INTERNAL *hPsy, PSY_OUT **phpsyOut, + const INT nSubFrames, + const INT nMaxChannels, const AUDIO_OBJECT_TYPE audioObjectType, - CHANNEL_MAPPING *cm) -{ + CHANNEL_MAPPING *cm) { AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK; int i, ch, n, chInc = 0, resetChannels = 3; - if ( (nMaxChannels>2) && (cm->nChannels==2) ) { + if ((nMaxChannels > 2) && (cm->nChannels == 2)) { chInc = 1; FDKaacEnc_psyInitStates(hPsy, hPsy->pStaticChannels[0], audioObjectType); } - if ( (nMaxChannels==2) ) { + if ((nMaxChannels == 2)) { resetChannels = 0; } - for (i=0; inElements; i++) { - for (ch=0; chelInfo[i].nChannelsInEl; ch++) { - if (cm->elInfo[i].elType!=ID_LFE) { - hPsy->psyElement[i]->psyStatic[ch] = hPsy->pStaticChannels[chInc]; - if (chInc>=resetChannels) { - FDKaacEnc_psyInitStates(hPsy, hPsy->psyElement[i]->psyStatic[ch], audioObjectType); + for (i = 0; i < cm->nElements; i++) { + for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) { + hPsy->psyElement[i]->psyStatic[ch] = hPsy->pStaticChannels[chInc]; + if (cm->elInfo[i].elType != ID_LFE) { + if (chInc >= resetChannels) { + FDKaacEnc_psyInitStates(hPsy, hPsy->psyElement[i]->psyStatic[ch], + audioObjectType); } + mdct_init(&(hPsy->psyElement[i]->psyStatic[ch]->mdctPers), NULL, 0); hPsy->psyElement[i]->psyStatic[ch]->isLFE = 0; - } - else { - hPsy->psyElement[i]->psyStatic[ch] = hPsy->pStaticChannels[nMaxChannels-1]; + } else { hPsy->psyElement[i]->psyStatic[ch]->isLFE = 1; } chInc++; } } - for (n=0; nnElements; i++) { - for (ch=0; chelInfo[i].nChannelsInEl; ch++) { - phpsyOut[n]->psyOutElement[i]->psyOutChannel[ch] = phpsyOut[n]->pPsyOutChannels[chInc++]; + for (i = 0; i < cm->nElements; i++) { + for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) { + phpsyOut[n]->psyOutElement[i]->psyOutChannel[ch] = + phpsyOut[n]->pPsyOutChannels[chInc++]; } } } @@ -287,7 +289,6 @@ AAC_ENCODER_ERROR FDKaacEnc_psyInit(PSY_INTERNAL *hPsy, return ErrorStatus; } - /***************************************************************************** functionname: FDKaacEnc_psyMainInit @@ -296,139 +297,104 @@ AAC_ENCODER_ERROR FDKaacEnc_psyInit(PSY_INTERNAL *hPsy, *****************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_psyMainInit(PSY_INTERNAL *hPsy, - AUDIO_OBJECT_TYPE audioObjectType, - CHANNEL_MAPPING *cm, - INT sampleRate, - INT granuleLength, - INT bitRate, - INT tnsMask, - INT bandwidth, - INT usePns, - INT useIS, - UINT syntaxFlags, - ULONG initFlags) -{ +AAC_ENCODER_ERROR FDKaacEnc_psyMainInit( + PSY_INTERNAL *hPsy, AUDIO_OBJECT_TYPE audioObjectType, CHANNEL_MAPPING *cm, + INT sampleRate, INT granuleLength, INT bitRate, INT tnsMask, INT bandwidth, + INT usePns, INT useIS, INT useMS, UINT syntaxFlags, ULONG initFlags) { AAC_ENCODER_ERROR ErrorStatus; int i, ch; int channelsEff = cm->nChannelsEff; int tnsChannels = 0; FB_TYPE filterBank; - - switch(FDKaacEnc_GetMonoStereoMode(cm->encMode)) { + switch (FDKaacEnc_GetMonoStereoMode(cm->encMode)) { /* ... and map to tnsChannels */ - case EL_MODE_MONO: tnsChannels = 1; break; - case EL_MODE_STEREO: tnsChannels = 2; break; - default: tnsChannels = 0; + case EL_MODE_MONO: + tnsChannels = 1; + break; + case EL_MODE_STEREO: + tnsChannels = 2; + break; + default: + tnsChannels = 0; } - switch (audioObjectType) - { - default: filterBank = FB_LC; break; - case AOT_ER_AAC_LD: filterBank = FB_LD; break; - case AOT_ER_AAC_ELD: filterBank = FB_ELD; break; + switch (audioObjectType) { + default: + filterBank = FB_LC; + break; + case AOT_ER_AAC_LD: + filterBank = FB_LD; + break; + case AOT_ER_AAC_ELD: + filterBank = FB_ELD; + break; } hPsy->granuleLength = granuleLength; - ErrorStatus = FDKaacEnc_InitPsyConfiguration(bitRate/channelsEff, sampleRate, bandwidth, LONG_WINDOW, hPsy->granuleLength, useIS, &(hPsy->psyConf[0]), filterBank); - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; + ErrorStatus = FDKaacEnc_InitPsyConfiguration( + bitRate / channelsEff, sampleRate, bandwidth, LONG_WINDOW, + hPsy->granuleLength, useIS, useMS, &(hPsy->psyConf[0]), filterBank); + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; ErrorStatus = FDKaacEnc_InitTnsConfiguration( - (bitRate*tnsChannels)/channelsEff, - sampleRate, - tnsChannels, - LONG_WINDOW, - hPsy->granuleLength, - isLowDelay(audioObjectType), - (syntaxFlags&AC_SBR_PRESENT)?1:0, - &(hPsy->psyConf[0].tnsConf), - &hPsy->psyConf[0], - (INT)(tnsMask&2), - (INT)(tnsMask&8) ); - - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; + (bitRate * tnsChannels) / channelsEff, sampleRate, tnsChannels, + LONG_WINDOW, hPsy->granuleLength, isLowDelay(audioObjectType), + (syntaxFlags & AC_SBR_PRESENT) ? 1 : 0, &(hPsy->psyConf[0].tnsConf), + &hPsy->psyConf[0], (INT)(tnsMask & 2), (INT)(tnsMask & 8)); + + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; if (granuleLength > 512) { - ErrorStatus = FDKaacEnc_InitPsyConfiguration(bitRate/channelsEff, sampleRate, bandwidth, SHORT_WINDOW, hPsy->granuleLength, useIS, &hPsy->psyConf[1], filterBank); - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; + ErrorStatus = FDKaacEnc_InitPsyConfiguration( + bitRate / channelsEff, sampleRate, bandwidth, SHORT_WINDOW, + hPsy->granuleLength, useIS, useMS, &hPsy->psyConf[1], filterBank); + + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; ErrorStatus = FDKaacEnc_InitTnsConfiguration( - (bitRate*tnsChannels)/channelsEff, - sampleRate, - tnsChannels, - SHORT_WINDOW, - hPsy->granuleLength, - isLowDelay(audioObjectType), - (syntaxFlags&AC_SBR_PRESENT)?1:0, - &hPsy->psyConf[1].tnsConf, - &hPsy->psyConf[1], - (INT)(tnsMask&1), - (INT)(tnsMask&4) ); - - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; + (bitRate * tnsChannels) / channelsEff, sampleRate, tnsChannels, + SHORT_WINDOW, hPsy->granuleLength, isLowDelay(audioObjectType), + (syntaxFlags & AC_SBR_PRESENT) ? 1 : 0, &hPsy->psyConf[1].tnsConf, + &hPsy->psyConf[1], (INT)(tnsMask & 1), (INT)(tnsMask & 4)); + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; } - - for (i=0; inElements; i++) { - for (ch=0; chelInfo[i].nChannelsInEl; ch++) { + for (i = 0; i < cm->nElements; i++) { + for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) { if (initFlags) { /* reset states */ - FDKaacEnc_psyInitStates(hPsy, hPsy->psyElement[i]->psyStatic[ch], audioObjectType); + FDKaacEnc_psyInitStates(hPsy, hPsy->psyElement[i]->psyStatic[ch], + audioObjectType); } - FDKaacEnc_InitPreEchoControl(hPsy->psyElement[i]->psyStatic[ch]->sfbThresholdnm1, - &hPsy->psyElement[i]->psyStatic[ch]->calcPreEcho, - hPsy->psyConf[0].sfbCnt, - hPsy->psyConf[0].sfbPcmQuantThreshold, - &hPsy->psyElement[i]->psyStatic[ch]->mdctScalenm1); + FDKaacEnc_InitPreEchoControl( + hPsy->psyElement[i]->psyStatic[ch]->sfbThresholdnm1, + &hPsy->psyElement[i]->psyStatic[ch]->calcPreEcho, + hPsy->psyConf[0].sfbCnt, hPsy->psyConf[0].sfbPcmQuantThreshold, + &hPsy->psyElement[i]->psyStatic[ch]->mdctScalenm1); } } - ErrorStatus = FDKaacEnc_InitPnsConfiguration(&hPsy->psyConf[0].pnsConf, - bitRate/channelsEff, - sampleRate, - usePns, - hPsy->psyConf[0].sfbCnt, - hPsy->psyConf[0].sfbOffset, - cm->elInfo[0].nChannelsInEl, - (hPsy->psyConf[0].filterbank == FB_LC)); - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; - - ErrorStatus = FDKaacEnc_InitPnsConfiguration(&hPsy->psyConf[1].pnsConf, - bitRate/channelsEff, - sampleRate, - usePns, - hPsy->psyConf[1].sfbCnt, - hPsy->psyConf[1].sfbOffset, - cm->elInfo[1].nChannelsInEl, - (hPsy->psyConf[1].filterbank == FB_LC)); - return ErrorStatus; -} + ErrorStatus = FDKaacEnc_InitPnsConfiguration( + &hPsy->psyConf[0].pnsConf, bitRate / channelsEff, sampleRate, usePns, + hPsy->psyConf[0].sfbCnt, hPsy->psyConf[0].sfbOffset, + cm->elInfo[0].nChannelsInEl, (hPsy->psyConf[0].filterbank == FB_LC)); + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; + if (granuleLength > 512) { + ErrorStatus = FDKaacEnc_InitPnsConfiguration( + &hPsy->psyConf[1].pnsConf, bitRate / channelsEff, sampleRate, usePns, + hPsy->psyConf[1].sfbCnt, hPsy->psyConf[1].sfbOffset, + cm->elInfo[1].nChannelsInEl, (hPsy->psyConf[1].filterbank == FB_LC)); + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; + } -static -void FDKaacEnc_deinterleaveInputBuffer(INT_PCM *pOutputSamples, - INT_PCM *pInputSamples, - INT nSamples, - INT nChannels) -{ - INT k; - /* deinterlave input samples and write to output buffer */ - for (k=0; kpsyOutChannel; + FIXP_SGL sfbTonality[(2)][MAX_SFB_LONG]; + + PSY_STATIC **RESTRICT psyStatic = psyElement->psyStatic; + + PSY_DATA *RESTRICT psyData[(2)]; + TNS_DATA *RESTRICT tnsData[(2)]; + PNS_DATA *RESTRICT pnsData[(2)]; + + INT zeroSpec = TRUE; /* means all spectral lines are zero */ + + INT blockSwitchingOffset; + + PSY_CONFIGURATION *RESTRICT hThisPsyConf[(2)]; + INT windowLength[(2)]; + INT nWindows[(2)]; + INT wOffset; + + INT maxSfb[(2)]; + INT *pSfbMaxScaleSpec[(2)]; + FIXP_DBL *pSfbEnergy[(2)]; + FIXP_DBL *pSfbSpreadEnergy[(2)]; + FIXP_DBL *pSfbEnergyLdData[(2)]; + FIXP_DBL *pSfbEnergyMS[(2)]; + FIXP_DBL *pSfbThreshold[(2)]; + + INT isShortWindow[(2)]; + + /* number of incoming time samples to be processed */ + const INT nTimeSamples = psyConf->granuleLength; + + switch (hPsyConfLong->filterbank) { + case FB_LC: + blockSwitchingOffset = + nTimeSamples + (9 * nTimeSamples / (2 * TRANS_FAC)); + break; + case FB_LD: + case FB_ELD: + blockSwitchingOffset = nTimeSamples; + break; + default: + return AAC_ENC_UNSUPPORTED_FILTERBANK; + } -AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels, - PSY_ELEMENT *psyElement, - PSY_DYNAMIC *psyDynamic, - PSY_CONFIGURATION *psyConf, - PSY_OUT_ELEMENT *RESTRICT psyOutElement, - INT_PCM *pInput, - INT *chIdx, - INT totalChannels - ) -{ - const INT commonWindow = 1; - INT maxSfbPerGroup[(2)]; - INT mdctSpectrum_e; - INT ch; /* counts through channels */ - INT w; /* counts through windows */ - INT sfb; /* counts through scalefactor bands */ - INT line; /* counts through lines */ - - PSY_CONFIGURATION *RESTRICT hPsyConfLong = &psyConf[0]; - PSY_CONFIGURATION *RESTRICT hPsyConfShort = &psyConf[1]; - PSY_OUT_CHANNEL **RESTRICT psyOutChannel = psyOutElement->psyOutChannel; - FIXP_SGL sfbTonality[(2)][MAX_SFB_LONG]; - - PSY_STATIC **RESTRICT psyStatic = psyElement->psyStatic; - - PSY_DATA *RESTRICT psyData[(2)]; - TNS_DATA *RESTRICT tnsData[(2)]; - PNS_DATA *RESTRICT pnsData[(2)]; - - INT zeroSpec = TRUE; /* means all spectral lines are zero */ - - INT blockSwitchingOffset; - - PSY_CONFIGURATION *RESTRICT hThisPsyConf[(2)]; - INT windowLength[(2)]; - INT nWindows[(2)]; - INT wOffset; - - INT maxSfb[(2)]; - INT *pSfbMaxScaleSpec[(2)]; - FIXP_DBL *pSfbEnergy[(2)]; - FIXP_DBL *pSfbSpreadEnergy[(2)]; - FIXP_DBL *pSfbEnergyLdData[(2)]; - FIXP_DBL *pSfbEnergyMS[(2)]; - FIXP_DBL *pSfbThreshold[(2)]; - - INT isShortWindow[(2)]; - - - if (hPsyConfLong->filterbank == FB_LC) { - blockSwitchingOffset = psyConf->granuleLength + (9*psyConf->granuleLength/(2*TRANS_FAC)); - } else { - blockSwitchingOffset = psyConf->granuleLength; - } + for (ch = 0; ch < channels; ch++) { + psyData[ch] = &psyDynamic->psyData[ch]; + tnsData[ch] = &psyDynamic->tnsData[ch]; + pnsData[ch] = &psyDynamic->pnsData[ch]; - for(ch = 0; ch < channels; ch++) - { - psyData[ch] = &psyDynamic->psyData[ch]; - tnsData[ch] = &psyDynamic->tnsData[ch]; - pnsData[ch] = &psyDynamic->pnsData[ch]; + psyData[ch]->mdctSpectrum = psyOutChannel[ch]->mdctSpectrum; + } - psyData[ch]->mdctSpectrum = psyOutChannel[ch]->mdctSpectrum; - } + /* block switching */ + if (hPsyConfLong->filterbank != FB_ELD) { + int err; - /* block switching */ - if (hPsyConfLong->filterbank != FB_ELD) - { - int err; + for (ch = 0; ch < channels; ch++) { + C_ALLOC_SCRATCH_START(pTimeSignal, INT_PCM, (1024)) - for(ch = 0; ch < channels; ch++) - { - C_ALLOC_SCRATCH_START(pTimeSignal, INT_PCM, (1024)) + /* copy input data and use for block switching */ + FDKmemcpy(pTimeSignal, pInput + chIdx[ch] * inputBufSize, + nTimeSamples * sizeof(INT_PCM)); - /* deinterleave input data and use for block switching */ - FDKaacEnc_deinterleaveInputBuffer( pTimeSignal, - &pInput[chIdx[ch]], - psyConf->granuleLength, - totalChannels); + FDKaacEnc_BlockSwitching(&psyStatic[ch]->blockSwitchingControl, + nTimeSamples, psyStatic[ch]->isLFE, pTimeSignal); + /* fill up internal input buffer, to 2xframelength samples */ + FDKmemcpy(psyStatic[ch]->psyInputBuffer + blockSwitchingOffset, + pTimeSignal, + (2 * nTimeSamples - blockSwitchingOffset) * sizeof(INT_PCM)); - FDKaacEnc_BlockSwitching (&psyStatic[ch]->blockSwitchingControl, - psyConf->granuleLength, - psyStatic[ch]->isLFE, - pTimeSignal - ); + C_ALLOC_SCRATCH_END(pTimeSignal, INT_PCM, (1024)) + } + /* synch left and right block type */ + err = FDKaacEnc_SyncBlockSwitching( + &psyStatic[0]->blockSwitchingControl, + (channels > 1) ? &psyStatic[1]->blockSwitchingControl : NULL, channels, + commonWindow); - /* fill up internal input buffer, to 2xframelength samples */ - FDKmemcpy(psyStatic[ch]->psyInputBuffer+blockSwitchingOffset, - pTimeSignal, - (2*psyConf->granuleLength-blockSwitchingOffset)*sizeof(INT_PCM)); + if (err) { + return AAC_ENC_UNSUPPORTED_AOT; /* mixed up LC and LD */ + } - C_ALLOC_SCRATCH_END(pTimeSignal, INT_PCM, (1024)) - } + } else { + for (ch = 0; ch < channels; ch++) { + /* copy input data and use for block switching */ + FDKmemcpy(psyStatic[ch]->psyInputBuffer + blockSwitchingOffset, + pInput + chIdx[ch] * inputBufSize, + nTimeSamples * sizeof(INT_PCM)); + } + } - /* synch left and right block type */ - err = FDKaacEnc_SyncBlockSwitching(&psyStatic[0]->blockSwitchingControl, - &psyStatic[1]->blockSwitchingControl, - channels, - commonWindow); + for (ch = 0; ch < channels; ch++) + isShortWindow[ch] = + (psyStatic[ch]->blockSwitchingControl.lastWindowSequence == + SHORT_WINDOW); + + /* set parameters according to window length */ + for (ch = 0; ch < channels; ch++) { + if (isShortWindow[ch]) { + hThisPsyConf[ch] = hPsyConfShort; + windowLength[ch] = psyConf->granuleLength / TRANS_FAC; + nWindows[ch] = TRANS_FAC; + maxSfb[ch] = MAX_SFB_SHORT; + + pSfbMaxScaleSpec[ch] = psyData[ch]->sfbMaxScaleSpec.Short[0]; + pSfbEnergy[ch] = psyData[ch]->sfbEnergy.Short[0]; + pSfbSpreadEnergy[ch] = psyData[ch]->sfbSpreadEnergy.Short[0]; + pSfbEnergyLdData[ch] = psyData[ch]->sfbEnergyLdData.Short[0]; + pSfbEnergyMS[ch] = psyData[ch]->sfbEnergyMS.Short[0]; + pSfbThreshold[ch] = psyData[ch]->sfbThreshold.Short[0]; - if (err) { - return AAC_ENC_UNSUPPORTED_AOT; /* mixed up LC and LD */ - } + } else { + hThisPsyConf[ch] = hPsyConfLong; + windowLength[ch] = psyConf->granuleLength; + nWindows[ch] = 1; + maxSfb[ch] = MAX_GROUPED_SFB; + + pSfbMaxScaleSpec[ch] = psyData[ch]->sfbMaxScaleSpec.Long; + pSfbEnergy[ch] = psyData[ch]->sfbEnergy.Long; + pSfbSpreadEnergy[ch] = psyData[ch]->sfbSpreadEnergy.Long; + pSfbEnergyLdData[ch] = psyData[ch]->sfbEnergyLdData.Long; + pSfbEnergyMS[ch] = psyData[ch]->sfbEnergyMS.Long; + pSfbThreshold[ch] = psyData[ch]->sfbThreshold.Long; + } + } + /* Transform and get mdctScaling for all channels and windows. */ + for (ch = 0; ch < channels; ch++) { + /* update number of active bands */ + if (psyStatic[ch]->isLFE) { + psyData[ch]->sfbActive = hThisPsyConf[ch]->sfbActiveLFE; + psyData[ch]->lowpassLine = hThisPsyConf[ch]->lowpassLineLFE; + } else { + psyData[ch]->sfbActive = hThisPsyConf[ch]->sfbActive; + psyData[ch]->lowpassLine = hThisPsyConf[ch]->lowpassLine; } - else { - for(ch = 0; ch < channels; ch++) - { - /* deinterleave input data and use for block switching */ - FDKaacEnc_deinterleaveInputBuffer( psyStatic[ch]->psyInputBuffer + blockSwitchingOffset, - &pInput[chIdx[ch]], - psyConf->granuleLength, - totalChannels); + + if (hThisPsyConf[ch]->filterbank == FB_ELD) { + if (FDKaacEnc_Transform_Real_Eld( + psyStatic[ch]->psyInputBuffer, psyData[ch]->mdctSpectrum, + psyStatic[ch]->blockSwitchingControl.lastWindowSequence, + psyStatic[ch]->blockSwitchingControl.windowShape, + &psyStatic[ch]->blockSwitchingControl.lastWindowShape, + nTimeSamples, &mdctSpectrum_e, hThisPsyConf[ch]->filterbank, + psyStatic[ch]->overlapAddBuffer) != 0) { + return AAC_ENC_UNSUPPORTED_FILTERBANK; + } + } else { + if (FDKaacEnc_Transform_Real( + psyStatic[ch]->psyInputBuffer, psyData[ch]->mdctSpectrum, + psyStatic[ch]->blockSwitchingControl.lastWindowSequence, + psyStatic[ch]->blockSwitchingControl.windowShape, + &psyStatic[ch]->blockSwitchingControl.lastWindowShape, + &psyStatic[ch]->mdctPers, nTimeSamples, &mdctSpectrum_e, + hThisPsyConf[ch]->filterbank) != 0) { + return AAC_ENC_UNSUPPORTED_FILTERBANK; } } - for(ch = 0; ch < channels; ch++) - isShortWindow[ch]=(psyStatic[ch]->blockSwitchingControl.lastWindowSequence == SHORT_WINDOW); - - /* set parameters according to window length */ - for(ch = 0; ch < channels; ch++) - { - if(isShortWindow[ch]) { - hThisPsyConf[ch] = hPsyConfShort; - windowLength[ch] = psyConf->granuleLength/TRANS_FAC; - nWindows[ch] = TRANS_FAC; - maxSfb[ch] = MAX_SFB_SHORT; - - pSfbMaxScaleSpec[ch] = psyData[ch]->sfbMaxScaleSpec.Short[0]; - pSfbEnergy[ch] = psyData[ch]->sfbEnergy.Short[0]; - pSfbSpreadEnergy[ch] = psyData[ch]->sfbSpreadEnergy.Short[0]; - pSfbEnergyLdData[ch] = psyData[ch]->sfbEnergyLdData.Short[0]; - pSfbEnergyMS[ch] = psyData[ch]->sfbEnergyMS.Short[0]; - pSfbThreshold[ch] = psyData[ch]->sfbThreshold.Short[0]; - - } else - { - hThisPsyConf[ch] = hPsyConfLong; - windowLength[ch] = psyConf->granuleLength; - nWindows[ch] = 1; - maxSfb[ch] = MAX_GROUPED_SFB; - - pSfbMaxScaleSpec[ch] = psyData[ch]->sfbMaxScaleSpec.Long; - pSfbEnergy[ch] = psyData[ch]->sfbEnergy.Long; - pSfbSpreadEnergy[ch] = psyData[ch]->sfbSpreadEnergy.Long; - pSfbEnergyLdData[ch] = psyData[ch]->sfbEnergyLdData.Long; - pSfbEnergyMS[ch] = psyData[ch]->sfbEnergyMS.Long; - pSfbThreshold[ch] = psyData[ch]->sfbThreshold.Long; + for (w = 0; w < nWindows[ch]; w++) { + wOffset = w * windowLength[ch]; + + /* Low pass / highest sfb */ + FDKmemclear( + &psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine + wOffset], + (windowLength[ch] - psyData[ch]->lowpassLine) * sizeof(FIXP_DBL)); + + if ((hPsyConfLong->filterbank != FB_LC) && + (psyData[ch]->lowpassLine >= FADE_OUT_LEN)) { + /* Do blending to reduce gibbs artifacts */ + for (int i = 0; i < FADE_OUT_LEN; i++) { + psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine + wOffset - + FADE_OUT_LEN + i] = + fMult(psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine + + wOffset - FADE_OUT_LEN + i], + fadeOutFactor[i]); } - } + } - /* Transform and get mdctScaling for all channels and windows. */ - for(ch = 0; ch < channels; ch++) - { - /* update number of active bands */ - if (psyStatic[ch]->isLFE) { - psyData[ch]->sfbActive = hThisPsyConf[ch]->sfbActiveLFE; - psyData[ch]->lowpassLine = hThisPsyConf[ch]->lowpassLineLFE; - } else - { - psyData[ch]->sfbActive = hThisPsyConf[ch]->sfbActive; - psyData[ch]->lowpassLine = hThisPsyConf[ch]->lowpassLine; + /* Check for zero spectrum. These loops will usually terminate very, very + * early. */ + for (line = 0; (line < psyData[ch]->lowpassLine) && (zeroSpec == TRUE); + line++) { + if (psyData[ch]->mdctSpectrum[line + wOffset] != (FIXP_DBL)0) { + zeroSpec = FALSE; + break; } + } - for(w = 0; w < nWindows[ch]; w++) { - - wOffset = w*windowLength[ch]; - - FDKaacEnc_Transform_Real( psyStatic[ch]->psyInputBuffer + wOffset, - psyData[ch]->mdctSpectrum+wOffset, - psyStatic[ch]->blockSwitchingControl.lastWindowSequence, - psyStatic[ch]->blockSwitchingControl.windowShape, - &psyStatic[ch]->blockSwitchingControl.lastWindowShape, - psyConf->granuleLength, - &mdctSpectrum_e, - hThisPsyConf[ch]->filterbank - ,psyStatic[ch]->overlapAddBuffer - ); - - /* Low pass / highest sfb */ - FDKmemclear(&psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset], - (windowLength[ch]-psyData[ch]->lowpassLine)*sizeof(FIXP_DBL)); - - if ( (hPsyConfLong->filterbank != FB_LC) && (psyData[ch]->lowpassLine >= FADE_OUT_LEN) ) { - /* Do blending to reduce gibbs artifacts */ - for (int i=0; imdctSpectrum[psyData[ch]->lowpassLine+wOffset - FADE_OUT_LEN + i] = fMult(psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset - FADE_OUT_LEN + i], fadeOutFactor[i]); - } - } - - - /* Check for zero spectrum. These loops will usually terminate very, very early. */ - for(line=0; (linelowpassLine) && (zeroSpec==TRUE); line++) { - if (psyData[ch]->mdctSpectrum[line+wOffset] != (FIXP_DBL)0) { - zeroSpec = FALSE; - break; - } - } - - } /* w loop */ - - psyData[ch]->mdctScale = mdctSpectrum_e; - - /* rotate internal time samples */ - FDKmemmove(psyStatic[ch]->psyInputBuffer, - psyStatic[ch]->psyInputBuffer+psyConf->granuleLength, - psyConf->granuleLength*sizeof(INT_PCM)); - - - /* ... and get remaining samples from input buffer */ - FDKaacEnc_deinterleaveInputBuffer( psyStatic[ch]->psyInputBuffer+psyConf->granuleLength, - &pInput[ (2*psyConf->granuleLength-blockSwitchingOffset)*totalChannels + chIdx[ch] ], - blockSwitchingOffset-psyConf->granuleLength, - totalChannels); - - } /* ch */ - - /* Do some rescaling to get maximum possible accuracy for energies */ - if ( zeroSpec == FALSE) { - - /* Calc possible spectrum leftshift for each sfb (1 means: 1 bit left shift is possible without overflow) */ - INT minSpecShift = MAX_SHIFT_DBL; - INT nrgShift = MAX_SHIFT_DBL; - INT finalShift = MAX_SHIFT_DBL; - FIXP_DBL currNrg = 0; - FIXP_DBL maxNrg = 0; - - for(ch = 0; ch < channels; ch++) { - for(w = 0; w < nWindows[ch]; w++) { - wOffset = w*windowLength[ch]; - FDKaacEnc_CalcSfbMaxScaleSpec(psyData[ch]->mdctSpectrum+wOffset, - hThisPsyConf[ch]->sfbOffset, - pSfbMaxScaleSpec[ch]+w*maxSfb[ch], - psyData[ch]->sfbActive); - - for (sfb = 0; sfbsfbActive; sfb++) - minSpecShift = fixMin(minSpecShift, (pSfbMaxScaleSpec[ch]+w*maxSfb[ch])[sfb]); - } - - } + } /* w loop */ + + psyData[ch]->mdctScale = mdctSpectrum_e; + + /* rotate internal time samples */ + FDKmemmove(psyStatic[ch]->psyInputBuffer, + psyStatic[ch]->psyInputBuffer + nTimeSamples, + nTimeSamples * sizeof(INT_PCM)); + + /* ... and get remaining samples from input buffer */ + FDKmemcpy(psyStatic[ch]->psyInputBuffer + nTimeSamples, + pInput + (2 * nTimeSamples - blockSwitchingOffset) + + chIdx[ch] * inputBufSize, + (blockSwitchingOffset - nTimeSamples) * sizeof(INT_PCM)); + + } /* ch */ + + /* Do some rescaling to get maximum possible accuracy for energies */ + if (zeroSpec == FALSE) { + /* Calc possible spectrum leftshift for each sfb (1 means: 1 bit left shift + * is possible without overflow) */ + INT minSpecShift = MAX_SHIFT_DBL; + INT nrgShift = MAX_SHIFT_DBL; + INT finalShift = MAX_SHIFT_DBL; + FIXP_DBL currNrg = 0; + FIXP_DBL maxNrg = 0; + + for (ch = 0; ch < channels; ch++) { + for (w = 0; w < nWindows[ch]; w++) { + wOffset = w * windowLength[ch]; + FDKaacEnc_CalcSfbMaxScaleSpec( + psyData[ch]->mdctSpectrum + wOffset, hThisPsyConf[ch]->sfbOffset, + pSfbMaxScaleSpec[ch] + w * maxSfb[ch], psyData[ch]->sfbActive); + + for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) + minSpecShift = fixMin(minSpecShift, + (pSfbMaxScaleSpec[ch] + w * maxSfb[ch])[sfb]); + } + } - /* Calc possible energy leftshift for each sfb (1 means: 1 bit left shift is possible without overflow) */ - for(ch = 0; ch < channels; ch++) { - for(w = 0; w < nWindows[ch]; w++) { - wOffset = w*windowLength[ch]; - currNrg = FDKaacEnc_CheckBandEnergyOptim(psyData[ch]->mdctSpectrum+wOffset, - pSfbMaxScaleSpec[ch]+w*maxSfb[ch], - hThisPsyConf[ch]->sfbOffset, - psyData[ch]->sfbActive, - pSfbEnergy[ch]+w*maxSfb[ch], - pSfbEnergyLdData[ch]+w*maxSfb[ch], - minSpecShift-4); - - maxNrg = fixMax(maxNrg, currNrg); - } - } + /* Calc possible energy leftshift for each sfb (1 means: 1 bit left shift is + * possible without overflow) */ + for (ch = 0; ch < channels; ch++) { + for (w = 0; w < nWindows[ch]; w++) { + wOffset = w * windowLength[ch]; + currNrg = FDKaacEnc_CheckBandEnergyOptim( + psyData[ch]->mdctSpectrum + wOffset, + pSfbMaxScaleSpec[ch] + w * maxSfb[ch], hThisPsyConf[ch]->sfbOffset, + psyData[ch]->sfbActive, pSfbEnergy[ch] + w * maxSfb[ch], + pSfbEnergyLdData[ch] + w * maxSfb[ch], minSpecShift - 4); + + maxNrg = fixMax(maxNrg, currNrg); + } + } - if ( maxNrg != (FIXP_DBL)0 ) { - nrgShift = (CountLeadingBits(maxNrg)>>1) + (minSpecShift-4); - } + if (maxNrg != (FIXP_DBL)0) { + nrgShift = (CountLeadingBits(maxNrg) >> 1) + (minSpecShift - 4); + } - /* 2check: Hasn't this decision to be made for both channels? */ - /* For short windows 1 additional bit headroom is necessary to prevent overflows when summing up energies in FDKaacEnc_groupShortData() */ - if(isShortWindow[0]) nrgShift--; - - /* both spectrum and energies mustn't overflow */ - finalShift = fixMin(minSpecShift, nrgShift); - - /* do not shift more than 3 bits more to the left than signal without blockfloating point - * would be to avoid overflow of scaled PCM quantization thresholds */ - if (finalShift > psyData[0]->mdctScale + 3 ) - finalShift = psyData[0]->mdctScale + 3; - - FDK_ASSERT(finalShift >= 0); /* right shift is not allowed */ - - /* correct sfbEnergy and sfbEnergyLdData with new finalShift */ - FIXP_DBL ldShift = finalShift * FL2FXCONST_DBL(2.0/64); - for(ch = 0; ch < channels; ch++) { - for(w = 0; w < nWindows[ch]; w++) { - for(sfb=0; sfbsfbActive; sfb++) { - INT scale = fixMax(0, (pSfbMaxScaleSpec[ch]+w*maxSfb[ch])[sfb]-4); - scale = fixMin((scale-finalShift)<<1, DFRACT_BITS-1); - if (scale >= 0) (pSfbEnergy[ch]+w*maxSfb[ch])[sfb] >>= (scale); - else (pSfbEnergy[ch]+w*maxSfb[ch])[sfb] <<= (-scale); - (pSfbThreshold[ch]+w*maxSfb[ch])[sfb] = fMult((pSfbEnergy[ch]+w*maxSfb[ch])[sfb], C_RATIO); - (pSfbEnergyLdData[ch]+w*maxSfb[ch])[sfb] += ldShift; - } - } + /* 2check: Hasn't this decision to be made for both channels? */ + /* For short windows 1 additional bit headroom is necessary to prevent + * overflows when summing up energies in FDKaacEnc_groupShortData() */ + if (isShortWindow[0]) nrgShift--; + + /* both spectrum and energies mustn't overflow */ + finalShift = fixMin(minSpecShift, nrgShift); + + /* do not shift more than 3 bits more to the left than signal without + * blockfloating point would be to avoid overflow of scaled PCM quantization + * thresholds */ + if (finalShift > psyData[0]->mdctScale + 3) + finalShift = psyData[0]->mdctScale + 3; + + FDK_ASSERT(finalShift >= 0); /* right shift is not allowed */ + + /* correct sfbEnergy and sfbEnergyLdData with new finalShift */ + FIXP_DBL ldShift = finalShift * FL2FXCONST_DBL(2.0 / 64); + for (ch = 0; ch < channels; ch++) { + INT maxSfb_ch = maxSfb[ch]; + INT w_maxSfb_ch = 0; + for (w = 0; w < nWindows[ch]; w++) { + for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) { + INT scale = fixMax(0, (pSfbMaxScaleSpec[ch] + w_maxSfb_ch)[sfb] - 4); + scale = fixMin((scale - finalShift) << 1, DFRACT_BITS - 1); + if (scale >= 0) + (pSfbEnergy[ch] + w_maxSfb_ch)[sfb] >>= (scale); + else + (pSfbEnergy[ch] + w_maxSfb_ch)[sfb] <<= (-scale); + (pSfbThreshold[ch] + w_maxSfb_ch)[sfb] = + fMult((pSfbEnergy[ch] + w_maxSfb_ch)[sfb], C_RATIO); + (pSfbEnergyLdData[ch] + w_maxSfb_ch)[sfb] += ldShift; } + w_maxSfb_ch += maxSfb_ch; + } + } - if ( finalShift != 0 ) { - for (ch = 0; ch < channels; ch++) { - for(w = 0; w < nWindows[ch]; w++) { - wOffset = w*windowLength[ch]; - for(line=0; linelowpassLine; line++) { - psyData[ch]->mdctSpectrum[line+wOffset] <<= finalShift; - } - /* update sfbMaxScaleSpec */ - for (sfb = 0; sfbsfbActive; sfb++) - (pSfbMaxScaleSpec[ch]+w*maxSfb[ch])[sfb] -= finalShift; - } - /* update mdctScale */ - psyData[ch]->mdctScale -= finalShift; - } - } + if (finalShift != 0) { + for (ch = 0; ch < channels; ch++) { + INT wLen = windowLength[ch]; + INT lowpassLine = psyData[ch]->lowpassLine; + wOffset = 0; + FIXP_DBL *mdctSpectrum = &psyData[ch]->mdctSpectrum[0]; + for (w = 0; w < nWindows[ch]; w++) { + FIXP_DBL *spectrum = &mdctSpectrum[wOffset]; + for (line = 0; line < lowpassLine; line++) { + spectrum[line] <<= finalShift; + } + wOffset += wLen; - } else { - /* all spectral lines are zero */ - for (ch = 0; ch < channels; ch++) { - psyData[ch]->mdctScale = 0; /* otherwise mdctScale would be for example 7 and PCM quantization thresholds would be shifted - * 14 bits to the right causing some of them to become 0 (which causes problems later) */ - /* clear sfbMaxScaleSpec */ - for(w = 0; w < nWindows[ch]; w++) { - for (sfb = 0; sfbsfbActive; sfb++) { - (pSfbMaxScaleSpec[ch]+w*maxSfb[ch])[sfb] = 0; - (pSfbEnergy[ch]+w*maxSfb[ch])[sfb] = (FIXP_DBL)0; - (pSfbEnergyLdData[ch]+w*maxSfb[ch])[sfb] = FL2FXCONST_DBL(-1.0f); - (pSfbThreshold[ch]+w*maxSfb[ch])[sfb] = (FIXP_DBL)0; - } - } + /* update sfbMaxScaleSpec */ + for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) + (pSfbMaxScaleSpec[ch] + w * maxSfb[ch])[sfb] -= finalShift; } + /* update mdctScale */ + psyData[ch]->mdctScale -= finalShift; + } } - /* Advance psychoacoustics: Tonality and TNS */ - if (psyStatic[0]->isLFE) { - tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] = 0; - tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT] = 0; - } - else - { - - for(ch = 0; ch < channels; ch++) { - if (!isShortWindow[ch]) { - /* tonality */ - FDKaacEnc_CalculateFullTonality( psyData[ch]->mdctSpectrum, - pSfbMaxScaleSpec[ch], - pSfbEnergyLdData[ch], - sfbTonality[ch], - psyData[ch]->sfbActive, - hThisPsyConf[ch]->sfbOffset, - hThisPsyConf[ch]->pnsConf.usePns); - } + } else { + /* all spectral lines are zero */ + for (ch = 0; ch < channels; ch++) { + psyData[ch]->mdctScale = + 0; /* otherwise mdctScale would be for example 7 and PCM quantization + * thresholds would be shifted 14 bits to the right causing some of + * them to become 0 (which causes problems later) */ + /* clear sfbMaxScaleSpec */ + for (w = 0; w < nWindows[ch]; w++) { + for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) { + (pSfbMaxScaleSpec[ch] + w * maxSfb[ch])[sfb] = 0; + (pSfbEnergy[ch] + w * maxSfb[ch])[sfb] = (FIXP_DBL)0; + (pSfbEnergyLdData[ch] + w * maxSfb[ch])[sfb] = FL2FXCONST_DBL(-1.0f); + (pSfbThreshold[ch] + w * maxSfb[ch])[sfb] = (FIXP_DBL)0; } + } + } + } - if (hPsyConfLong->tnsConf.tnsActive || hPsyConfShort->tnsConf.tnsActive) { - INT tnsActive[TRANS_FAC]; - INT nrgScaling[2] = {0,0}; - INT tnsSpecShift = 0; - - for(ch = 0; ch < channels; ch++) { - for(w = 0; w < nWindows[ch]; w++) { - - wOffset = w*windowLength[ch]; - /* TNS */ - FDKaacEnc_TnsDetect( - tnsData[ch], - &hThisPsyConf[ch]->tnsConf, - &psyOutChannel[ch]->tnsInfo, - hThisPsyConf[ch]->sfbCnt, - psyData[ch]->mdctSpectrum+wOffset, - w, - psyStatic[ch]->blockSwitchingControl.lastWindowSequence - ); - } - } - - if (channels == 2) { - FDKaacEnc_TnsSync( - tnsData[1], - tnsData[0], - &psyOutChannel[1]->tnsInfo, - &psyOutChannel[0]->tnsInfo, + /* Advance psychoacoustics: Tonality and TNS */ + if ((channels >= 1) && (psyStatic[0]->isLFE)) { + tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] = 0; + tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT] = 0; + } else { + for (ch = 0; ch < channels; ch++) { + if (!isShortWindow[ch]) { + /* tonality */ + FDKaacEnc_CalculateFullTonality( + psyData[ch]->mdctSpectrum, pSfbMaxScaleSpec[ch], + pSfbEnergyLdData[ch], sfbTonality[ch], psyData[ch]->sfbActive, + hThisPsyConf[ch]->sfbOffset, hThisPsyConf[ch]->pnsConf.usePns); + } + } /* ch */ - psyStatic[1]->blockSwitchingControl.lastWindowSequence, - psyStatic[0]->blockSwitchingControl.lastWindowSequence, - &hThisPsyConf[1]->tnsConf); - } + if (hPsyConfLong->tnsConf.tnsActive || hPsyConfShort->tnsConf.tnsActive) { + INT tnsActive[TRANS_FAC] = {0}; + INT nrgScaling[2] = {0, 0}; + INT tnsSpecShift = 0; + + for (ch = 0; ch < channels; ch++) { + for (w = 0; w < nWindows[ch]; w++) { + wOffset = w * windowLength[ch]; + /* TNS */ + FDKaacEnc_TnsDetect( + tnsData[ch], &hThisPsyConf[ch]->tnsConf, + &psyOutChannel[ch]->tnsInfo, hThisPsyConf[ch]->sfbCnt, + psyData[ch]->mdctSpectrum + wOffset, w, + psyStatic[ch]->blockSwitchingControl.lastWindowSequence); + } + } - FDK_ASSERT(1==commonWindow); /* all checks for TNS do only work for common windows (which is always set)*/ - for(w = 0; w < nWindows[0]; w++) - { - if (isShortWindow[0]) - tnsActive[w] = tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive[HIFILT] || - tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive[LOFILT] || - tnsData[channels-1]->dataRaw.Short.subBlockInfo[w].tnsActive[HIFILT] || - tnsData[channels-1]->dataRaw.Short.subBlockInfo[w].tnsActive[LOFILT]; - else - tnsActive[w] = tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] || - tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT] || - tnsData[channels-1]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] || - tnsData[channels-1]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT]; - } + if (channels == 2) { + FDKaacEnc_TnsSync( + tnsData[1], tnsData[0], &psyOutChannel[1]->tnsInfo, + &psyOutChannel[0]->tnsInfo, - for(ch = 0; ch < channels; ch++) { - if (tnsActive[0] && !isShortWindow[ch]) { - /* Scale down spectrum if tns is active in one of the two channels with same lastWindowSequence */ - /* first part of threshold calculation; it's not necessary to update sfbMaxScaleSpec */ - INT shift = 1; - for(sfb=0; sfblowpassLine; sfb++) { - psyData[ch]->mdctSpectrum[sfb] = psyData[ch]->mdctSpectrum[sfb] >> shift; - } + psyStatic[1]->blockSwitchingControl.lastWindowSequence, + psyStatic[0]->blockSwitchingControl.lastWindowSequence, + &hThisPsyConf[1]->tnsConf); + } - /* update thresholds */ - for (sfb=0; sfbsfbActive; sfb++) { - pSfbThreshold[ch][sfb] >>= (2*shift); - } + if (channels >= 1) { + FDK_ASSERT(1 == commonWindow); /* all checks for TNS do only work for + common windows (which is always set)*/ + for (w = 0; w < nWindows[0]; w++) { + if (isShortWindow[0]) + tnsActive[w] = + tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive[HIFILT] || + tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive[LOFILT] || + tnsData[channels - 1] + ->dataRaw.Short.subBlockInfo[w] + .tnsActive[HIFILT] || + tnsData[channels - 1] + ->dataRaw.Short.subBlockInfo[w] + .tnsActive[LOFILT]; + else + tnsActive[w] = + tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] || + tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT] || + tnsData[channels - 1] + ->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] || + tnsData[channels - 1] + ->dataRaw.Long.subBlockInfo.tnsActive[LOFILT]; + } + } - psyData[ch]->mdctScale += shift; /* update mdctScale */ + for (ch = 0; ch < channels; ch++) { + if (tnsActive[0] && !isShortWindow[ch]) { + /* Scale down spectrum if tns is active in one of the two channels + * with same lastWindowSequence */ + /* first part of threshold calculation; it's not necessary to update + * sfbMaxScaleSpec */ + INT shift = 1; + for (sfb = 0; sfb < hThisPsyConf[ch]->lowpassLine; sfb++) { + psyData[ch]->mdctSpectrum[sfb] = + psyData[ch]->mdctSpectrum[sfb] >> shift; + } - /* calc sfbEnergies after tnsEncode again ! */ + /* update thresholds */ + for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) { + pSfbThreshold[ch][sfb] >>= (2 * shift); + } - } - } + psyData[ch]->mdctScale += shift; /* update mdctScale */ - for(ch = 0; ch < channels; ch++) { - for(w = 0; w < nWindows[ch]; w++) - { - wOffset = w*windowLength[ch]; - FDKaacEnc_TnsEncode( - &psyOutChannel[ch]->tnsInfo, - tnsData[ch], - hThisPsyConf[ch]->sfbCnt, - &hThisPsyConf[ch]->tnsConf, - hThisPsyConf[ch]->sfbOffset[psyData[ch]->sfbActive],/*hThisPsyConf[ch]->lowpassLine*/ /* filter stops before that line ! */ - psyData[ch]->mdctSpectrum+wOffset, - w, - psyStatic[ch]->blockSwitchingControl.lastWindowSequence); - - if(tnsActive[w]) { - /* Calc sfb-bandwise mdct-energies for left and right channel again, */ - /* if tns active in current channel or in one channel with same lastWindowSequence left and right */ - FDKaacEnc_CalcSfbMaxScaleSpec(psyData[ch]->mdctSpectrum+wOffset, - hThisPsyConf[ch]->sfbOffset, - pSfbMaxScaleSpec[ch]+w*maxSfb[ch], - psyData[ch]->sfbActive); - } - } - } + /* calc sfbEnergies after tnsEncode again ! */ + } + } - for(ch = 0; ch < channels; ch++) { - for(w = 0; w < nWindows[ch]; w++) { - - if (tnsActive[w]) { - - if (isShortWindow[ch]) { - FDKaacEnc_CalcBandEnergyOptimShort(psyData[ch]->mdctSpectrum+w*windowLength[ch], - pSfbMaxScaleSpec[ch]+w*maxSfb[ch], - hThisPsyConf[ch]->sfbOffset, - psyData[ch]->sfbActive, - pSfbEnergy[ch]+w*maxSfb[ch]); - } - else { - nrgScaling[ch] = /* with tns, energy calculation can overflow; -> scaling */ - FDKaacEnc_CalcBandEnergyOptimLong(psyData[ch]->mdctSpectrum, - pSfbMaxScaleSpec[ch], - hThisPsyConf[ch]->sfbOffset, - psyData[ch]->sfbActive, - pSfbEnergy[ch], - pSfbEnergyLdData[ch]); - tnsSpecShift = fixMax(tnsSpecShift, nrgScaling[ch]); /* nrgScaling is set only if nrg would have an overflow */ - } - } /* if tnsActive */ - } - } /* end channel loop */ - - /* adapt scaling to prevent nrg overflow, only for long blocks */ - for(ch = 0; ch < channels; ch++) { - if ( (tnsSpecShift!=0) && !isShortWindow[ch] ) { - /* scale down spectrum, nrg's and thresholds, if there was an overflow in sfbNrg calculation after tns */ - for(line=0; linelowpassLine; line++) { - psyData[ch]->mdctSpectrum[line] >>= tnsSpecShift; - } - INT scale = (tnsSpecShift-nrgScaling[ch])<<1; - for(sfb=0; sfbsfbActive; sfb++) { - pSfbEnergyLdData[ch][sfb] -= scale*FL2FXCONST_DBL(1.0/LD_DATA_SCALING); - pSfbEnergy[ch][sfb] >>= scale; - pSfbThreshold[ch][sfb] >>= (tnsSpecShift<<1); - } - psyData[ch]->mdctScale += tnsSpecShift; /* update mdctScale; not necessary to update sfbMaxScaleSpec */ - - } - } /* end channel loop */ - - } /* TNS active */ - } /* !isLFE */ - - - - - - - /* Advance thresholds */ - for(ch = 0; ch < channels; ch++) { - INT headroom; - - FIXP_DBL clipEnergy; - INT energyShift = psyData[ch]->mdctScale*2 ; - INT clipNrgShift = energyShift - THR_SHIFTBITS ; - - if(isShortWindow[ch]) - headroom = 6; - else - headroom = 0; - - if (clipNrgShift >= 0) - clipEnergy = hThisPsyConf[ch]->clipEnergy >> clipNrgShift ; - else if (clipNrgShift>=-headroom) - clipEnergy = hThisPsyConf[ch]->clipEnergy << -clipNrgShift ; - else - clipEnergy = (FIXP_DBL)MAXVAL_DBL ; - - for(w = 0; w < nWindows[ch]; w++) - { - INT i; - /* limit threshold to avoid clipping */ - for (i=0; isfbActive; i++) { - *(pSfbThreshold[ch]+w*maxSfb[ch]+i) = fixMin(*(pSfbThreshold[ch]+w*maxSfb[ch]+i), clipEnergy); - } + for (ch = 0; ch < channels; ch++) { + for (w = 0; w < nWindows[ch]; w++) { + wOffset = w * windowLength[ch]; + FDKaacEnc_TnsEncode( + &psyOutChannel[ch]->tnsInfo, tnsData[ch], + hThisPsyConf[ch]->sfbCnt, &hThisPsyConf[ch]->tnsConf, + hThisPsyConf[ch]->sfbOffset[psyData[ch]->sfbActive], + /*hThisPsyConf[ch]->lowpassLine*/ /* filter stops + before that + line ! */ + psyData[ch]->mdctSpectrum + + wOffset, + w, psyStatic[ch]->blockSwitchingControl.lastWindowSequence); + + if (tnsActive[w]) { + /* Calc sfb-bandwise mdct-energies for left and right channel again, + */ + /* if tns active in current channel or in one channel with same + * lastWindowSequence left and right */ + FDKaacEnc_CalcSfbMaxScaleSpec(psyData[ch]->mdctSpectrum + wOffset, + hThisPsyConf[ch]->sfbOffset, + pSfbMaxScaleSpec[ch] + w * maxSfb[ch], + psyData[ch]->sfbActive); + } + } + } - /* spreading */ - FDKaacEnc_SpreadingMax(psyData[ch]->sfbActive, - hThisPsyConf[ch]->sfbMaskLowFactor, - hThisPsyConf[ch]->sfbMaskHighFactor, - pSfbThreshold[ch]+w*maxSfb[ch]); - - - /* PCM quantization threshold */ - energyShift += PCM_QUANT_THR_SCALE; - if (energyShift>=0) { - energyShift = fixMin(DFRACT_BITS-1,energyShift); - for (i=0; isfbActive;i++) { - *(pSfbThreshold[ch]+w*maxSfb[ch]+i) = fixMax(*(pSfbThreshold[ch]+w*maxSfb[ch]+i) >> THR_SHIFTBITS, - (hThisPsyConf[ch]->sfbPcmQuantThreshold[i] >> energyShift)); - } + for (ch = 0; ch < channels; ch++) { + for (w = 0; w < nWindows[ch]; w++) { + if (tnsActive[w]) { + if (isShortWindow[ch]) { + FDKaacEnc_CalcBandEnergyOptimShort( + psyData[ch]->mdctSpectrum + w * windowLength[ch], + pSfbMaxScaleSpec[ch] + w * maxSfb[ch], + hThisPsyConf[ch]->sfbOffset, psyData[ch]->sfbActive, + pSfbEnergy[ch] + w * maxSfb[ch]); } else { - energyShift = fixMin(DFRACT_BITS-1,-energyShift); - for (i=0; isfbActive;i++) { - *(pSfbThreshold[ch]+w*maxSfb[ch]+i) = fixMax(*(pSfbThreshold[ch]+w*maxSfb[ch]+i) >> THR_SHIFTBITS, - (hThisPsyConf[ch]->sfbPcmQuantThreshold[i] << energyShift)); - } + nrgScaling[ch] = /* with tns, energy calculation can overflow; -> + scaling */ + FDKaacEnc_CalcBandEnergyOptimLong( + psyData[ch]->mdctSpectrum, pSfbMaxScaleSpec[ch], + hThisPsyConf[ch]->sfbOffset, psyData[ch]->sfbActive, + pSfbEnergy[ch], pSfbEnergyLdData[ch]); + tnsSpecShift = + fixMax(tnsSpecShift, nrgScaling[ch]); /* nrgScaling is set + only if nrg would + have an overflow */ } + } /* if tnsActive */ + } + } /* end channel loop */ + + /* adapt scaling to prevent nrg overflow, only for long blocks */ + for (ch = 0; ch < channels; ch++) { + if ((tnsSpecShift != 0) && !isShortWindow[ch]) { + /* scale down spectrum, nrg's and thresholds, if there was an overflow + * in sfbNrg calculation after tns */ + for (line = 0; line < hThisPsyConf[ch]->lowpassLine; line++) { + psyData[ch]->mdctSpectrum[line] >>= tnsSpecShift; + } + INT scale = (tnsSpecShift - nrgScaling[ch]) << 1; + for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) { + pSfbEnergyLdData[ch][sfb] -= + scale * FL2FXCONST_DBL(1.0 / LD_DATA_SCALING); + pSfbEnergy[ch][sfb] >>= scale; + pSfbThreshold[ch][sfb] >>= (tnsSpecShift << 1); + } + psyData[ch]->mdctScale += tnsSpecShift; /* update mdctScale; not + necessary to update + sfbMaxScaleSpec */ + } + } /* end channel loop */ - if (!psyStatic[ch]->isLFE) - { - /* preecho control */ - if(psyStatic[ch]->blockSwitchingControl.lastWindowSequence == STOP_WINDOW) { - /* prevent FDKaacEnc_PreEchoControl from comparing stop - thresholds with short thresholds */ - for (i=0; isfbActive;i++) { - psyStatic[ch]->sfbThresholdnm1[i] = (FIXP_DBL)MAXVAL_DBL; - } - - psyStatic[ch]->mdctScalenm1 = 0; - psyStatic[ch]->calcPreEcho = 0; - } - - FDKaacEnc_PreEchoControl( psyStatic[ch]->sfbThresholdnm1, - psyStatic[ch]->calcPreEcho, - psyData[ch]->sfbActive, - hThisPsyConf[ch]->maxAllowedIncreaseFactor, - hThisPsyConf[ch]->minRemainingThresholdFactor, - pSfbThreshold[ch]+w*maxSfb[ch], - psyData[ch]->mdctScale, - &psyStatic[ch]->mdctScalenm1); - - psyStatic[ch]->calcPreEcho = 1; - - if(psyStatic[ch]->blockSwitchingControl.lastWindowSequence == START_WINDOW) - { - /* prevent FDKaacEnc_PreEchoControl in next frame to compare start - thresholds with short thresholds */ - for (i=0; isfbActive;i++) { - psyStatic[ch]->sfbThresholdnm1[i] = (FIXP_DBL)MAXVAL_DBL; - } - - psyStatic[ch]->mdctScalenm1 = 0; - psyStatic[ch]->calcPreEcho = 0; - } + } /* TNS active */ + else { + /* In case of disable TNS, reset its dynamic data. Some of its elements is + * required in PNS detection below. */ + FDKmemclear(psyDynamic->tnsData, sizeof(psyDynamic->tnsData)); + } + } /* !isLFE */ - } + /* Advance thresholds */ + for (ch = 0; ch < channels; ch++) { + INT headroom; - /* spread energy to avoid hole detection */ - FDKmemcpy(pSfbSpreadEnergy[ch]+w*maxSfb[ch], pSfbEnergy[ch]+w*maxSfb[ch], psyData[ch]->sfbActive*sizeof(FIXP_DBL)); + FIXP_DBL clipEnergy; + INT energyShift = psyData[ch]->mdctScale * 2; + INT clipNrgShift = energyShift - THR_SHIFTBITS; + if (isShortWindow[ch]) + headroom = 6; + else + headroom = 0; - FDKaacEnc_SpreadingMax(psyData[ch]->sfbActive, - hThisPsyConf[ch]->sfbMaskLowFactorSprEn, - hThisPsyConf[ch]->sfbMaskHighFactorSprEn, - pSfbSpreadEnergy[ch]+w*maxSfb[ch]); - } - } + if (clipNrgShift >= 0) + clipEnergy = hThisPsyConf[ch]->clipEnergy >> clipNrgShift; + else if (clipNrgShift >= -headroom) + clipEnergy = hThisPsyConf[ch]->clipEnergy << -clipNrgShift; + else + clipEnergy = (FIXP_DBL)MAXVAL_DBL; + + for (w = 0; w < nWindows[ch]; w++) { + INT i; + /* limit threshold to avoid clipping */ + for (i = 0; i < psyData[ch]->sfbActive; i++) { + *(pSfbThreshold[ch] + w * maxSfb[ch] + i) = + fixMin(*(pSfbThreshold[ch] + w * maxSfb[ch] + i), clipEnergy); + } - /* Calc bandwise energies for mid and side channel. Do it only if 2 channels exist */ - if (channels==2) { - for(w = 0; w < nWindows[1]; w++) { - wOffset = w*windowLength[1]; - FDKaacEnc_CalcBandNrgMSOpt(psyData[0]->mdctSpectrum+wOffset, - psyData[1]->mdctSpectrum+wOffset, - pSfbMaxScaleSpec[0]+w*maxSfb[0], - pSfbMaxScaleSpec[1]+w*maxSfb[1], - hThisPsyConf[1]->sfbOffset, - psyData[0]->sfbActive, - pSfbEnergyMS[0]+w*maxSfb[0], - pSfbEnergyMS[1]+w*maxSfb[1], - (psyStatic[1]->blockSwitchingControl.lastWindowSequence != SHORT_WINDOW), - psyData[0]->sfbEnergyMSLdData, - psyData[1]->sfbEnergyMSLdData); + /* spreading */ + FDKaacEnc_SpreadingMax(psyData[ch]->sfbActive, + hThisPsyConf[ch]->sfbMaskLowFactor, + hThisPsyConf[ch]->sfbMaskHighFactor, + pSfbThreshold[ch] + w * maxSfb[ch]); + + /* PCM quantization threshold */ + energyShift += PCM_QUANT_THR_SCALE; + if (energyShift >= 0) { + energyShift = fixMin(DFRACT_BITS - 1, energyShift); + for (i = 0; i < psyData[ch]->sfbActive; i++) { + *(pSfbThreshold[ch] + w * maxSfb[ch] + i) = fixMax( + *(pSfbThreshold[ch] + w * maxSfb[ch] + i) >> THR_SHIFTBITS, + (hThisPsyConf[ch]->sfbPcmQuantThreshold[i] >> energyShift)); } - } - - /* group short data (maxSfb[ch] for short blocks is determined here) */ - for(ch=0;chblockSwitchingControl.noOfGroups * hPsyConfShort->sfbCnt; - /* At this point, energies and thresholds are copied/regrouped from the ".Short" to the ".Long" arrays */ - FDKaacEnc_groupShortData( psyData[ch]->mdctSpectrum, - &psyData[ch]->sfbThreshold, - &psyData[ch]->sfbEnergy, - &psyData[ch]->sfbEnergyMS, - &psyData[ch]->sfbSpreadEnergy, - hPsyConfShort->sfbCnt, - psyData[ch]->sfbActive, - hPsyConfShort->sfbOffset, - hPsyConfShort->sfbMinSnrLdData, - psyData[ch]->groupedSfbOffset, - &maxSfbPerGroup[ch], - psyOutChannel[ch]->sfbMinSnrLdData, - psyStatic[ch]->blockSwitchingControl.noOfGroups, - psyStatic[ch]->blockSwitchingControl.groupLen, - psyConf[1].granuleLength); - - - /* calculate ldData arrays (short values are in .Long-arrays after FDKaacEnc_groupShortData) */ - for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) { - LdDataVector(&psyData[ch]->sfbEnergy.Long[sfbGrp], &psyOutChannel[ch]->sfbEnergyLdData[sfbGrp], psyData[ch]->sfbActive); - } - - /* calc sfbThrld and set Values smaller 2^-31 to 2^-33*/ - for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) { - LdDataVector(&psyData[ch]->sfbThreshold.Long[sfbGrp], &psyOutChannel[ch]->sfbThresholdLdData[sfbGrp], psyData[ch]->sfbActive); - for (sfb=0;sfbsfbActive;sfb++) { - psyOutChannel[ch]->sfbThresholdLdData[sfbGrp+sfb] = - fixMax(psyOutChannel[ch]->sfbThresholdLdData[sfbGrp+sfb], FL2FXCONST_DBL(-0.515625f)); - } - } + } else { + energyShift = fixMin(DFRACT_BITS - 1, -energyShift); + for (i = 0; i < psyData[ch]->sfbActive; i++) { + *(pSfbThreshold[ch] + w * maxSfb[ch] + i) = fixMax( + *(pSfbThreshold[ch] + w * maxSfb[ch] + i) >> THR_SHIFTBITS, + (hThisPsyConf[ch]->sfbPcmQuantThreshold[i] << energyShift)); + } + } - if ( channels==2 ) { - for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) { - LdDataVector(&psyData[ch]->sfbEnergyMS.Long[sfbGrp], &psyData[ch]->sfbEnergyMSLdData[sfbGrp], psyData[ch]->sfbActive); - } - } + if (!psyStatic[ch]->isLFE) { + /* preecho control */ + if (psyStatic[ch]->blockSwitchingControl.lastWindowSequence == + STOP_WINDOW) { + /* prevent FDKaacEnc_PreEchoControl from comparing stop + thresholds with short thresholds */ + for (i = 0; i < psyData[ch]->sfbActive; i++) { + psyStatic[ch]->sfbThresholdnm1[i] = (FIXP_DBL)MAXVAL_DBL; + } - FDKmemcpy(psyOutChannel[ch]->sfbOffsets, psyData[ch]->groupedSfbOffset, (MAX_GROUPED_SFB+1)*sizeof(INT)); + psyStatic[ch]->mdctScalenm1 = 0; + psyStatic[ch]->calcPreEcho = 0; + } - } else { - /* maxSfb[ch] for long blocks */ - for (sfb = psyData[ch]->sfbActive-1; sfb >= 0; sfb--) { - for (line = hPsyConfLong->sfbOffset[sfb+1]-1; line >= hPsyConfLong->sfbOffset[sfb]; line--) { - if (psyData[ch]->mdctSpectrum[line] != FL2FXCONST_SGL(0.0f)) break; - } - if (line > hPsyConfLong->sfbOffset[sfb]) break; - } - maxSfbPerGroup[ch] = sfb + 1; - /* ensure at least one section in ICS; workaround for existing decoder crc implementation */ - maxSfbPerGroup[ch] = fixMax(fixMin(5,psyData[ch]->sfbActive),maxSfbPerGroup[ch]); + FDKaacEnc_PreEchoControl( + psyStatic[ch]->sfbThresholdnm1, psyStatic[ch]->calcPreEcho, + psyData[ch]->sfbActive, hThisPsyConf[ch]->maxAllowedIncreaseFactor, + hThisPsyConf[ch]->minRemainingThresholdFactor, + pSfbThreshold[ch] + w * maxSfb[ch], psyData[ch]->mdctScale, + &psyStatic[ch]->mdctScalenm1); + + psyStatic[ch]->calcPreEcho = 1; + + if (psyStatic[ch]->blockSwitchingControl.lastWindowSequence == + START_WINDOW) { + /* prevent FDKaacEnc_PreEchoControl in next frame to compare start + thresholds with short thresholds */ + for (i = 0; i < psyData[ch]->sfbActive; i++) { + psyStatic[ch]->sfbThresholdnm1[i] = (FIXP_DBL)MAXVAL_DBL; + } - /* sfbNrgLdData is calculated in FDKaacEnc_advancePsychLong, copy in psyOut structure */ - FDKmemcpy(psyOutChannel[ch]->sfbEnergyLdData, psyData[ch]->sfbEnergyLdData.Long, psyData[ch]->sfbActive*sizeof(FIXP_DBL)); + psyStatic[ch]->mdctScalenm1 = 0; + psyStatic[ch]->calcPreEcho = 0; + } + } - FDKmemcpy(psyOutChannel[ch]->sfbOffsets, hPsyConfLong->sfbOffset, (MAX_GROUPED_SFB+1)*sizeof(INT)); + /* spread energy to avoid hole detection */ + FDKmemcpy(pSfbSpreadEnergy[ch] + w * maxSfb[ch], + pSfbEnergy[ch] + w * maxSfb[ch], + psyData[ch]->sfbActive * sizeof(FIXP_DBL)); - /* sfbMinSnrLdData modified in adjust threshold, copy necessary */ - FDKmemcpy(psyOutChannel[ch]->sfbMinSnrLdData, hPsyConfLong->sfbMinSnrLdData, psyData[ch]->sfbActive*sizeof(FIXP_DBL)); + FDKaacEnc_SpreadingMax(psyData[ch]->sfbActive, + hThisPsyConf[ch]->sfbMaskLowFactorSprEn, + hThisPsyConf[ch]->sfbMaskHighFactorSprEn, + pSfbSpreadEnergy[ch] + w * maxSfb[ch]); + } + } - /* sfbEnergyMSLdData ist already calculated in FDKaacEnc_CalcBandNrgMSOpt; only in long case */ + /* Calc bandwise energies for mid and side channel. Do it only if 2 channels + * exist */ + if (channels == 2) { + for (w = 0; w < nWindows[1]; w++) { + wOffset = w * windowLength[1]; + FDKaacEnc_CalcBandNrgMSOpt( + psyData[0]->mdctSpectrum + wOffset, + psyData[1]->mdctSpectrum + wOffset, + pSfbMaxScaleSpec[0] + w * maxSfb[0], + pSfbMaxScaleSpec[1] + w * maxSfb[1], hThisPsyConf[1]->sfbOffset, + psyData[0]->sfbActive, pSfbEnergyMS[0] + w * maxSfb[0], + pSfbEnergyMS[1] + w * maxSfb[1], + (psyStatic[1]->blockSwitchingControl.lastWindowSequence != + SHORT_WINDOW), + psyData[0]->sfbEnergyMSLdData, psyData[1]->sfbEnergyMSLdData); + } + } - /* calc sfbThrld and set Values smaller 2^-31 to 2^-33*/ - LdDataVector(psyData[ch]->sfbThreshold.Long, psyOutChannel[ch]->sfbThresholdLdData, psyData[ch]->sfbActive); - for (i=0;isfbActive;i++) { - psyOutChannel[ch]->sfbThresholdLdData[i] = - fixMax(psyOutChannel[ch]->sfbThresholdLdData[i], FL2FXCONST_DBL(-0.515625f)); - } + /* group short data (maxSfb[ch] for short blocks is determined here) */ + for (ch = 0; ch < channels; ch++) { + if (isShortWindow[ch]) { + int sfbGrp; + int noSfb = psyStatic[ch]->blockSwitchingControl.noOfGroups * + hPsyConfShort->sfbCnt; + /* At this point, energies and thresholds are copied/regrouped from the + * ".Short" to the ".Long" arrays */ + FDKaacEnc_groupShortData( + psyData[ch]->mdctSpectrum, &psyData[ch]->sfbThreshold, + &psyData[ch]->sfbEnergy, &psyData[ch]->sfbEnergyMS, + &psyData[ch]->sfbSpreadEnergy, hPsyConfShort->sfbCnt, + psyData[ch]->sfbActive, hPsyConfShort->sfbOffset, + hPsyConfShort->sfbMinSnrLdData, psyData[ch]->groupedSfbOffset, + &maxSfbPerGroup[ch], psyOutChannel[ch]->sfbMinSnrLdData, + psyStatic[ch]->blockSwitchingControl.noOfGroups, + psyStatic[ch]->blockSwitchingControl.groupLen, + psyConf[1].granuleLength); + + /* calculate ldData arrays (short values are in .Long-arrays after + * FDKaacEnc_groupShortData) */ + for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) { + LdDataVector(&psyData[ch]->sfbEnergy.Long[sfbGrp], + &psyOutChannel[ch]->sfbEnergyLdData[sfbGrp], + psyData[ch]->sfbActive); + } + /* calc sfbThrld and set Values smaller 2^-31 to 2^-33*/ + for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) { + LdDataVector(&psyData[ch]->sfbThreshold.Long[sfbGrp], + &psyOutChannel[ch]->sfbThresholdLdData[sfbGrp], + psyData[ch]->sfbActive); + for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) { + psyOutChannel[ch]->sfbThresholdLdData[sfbGrp + sfb] = + fixMax(psyOutChannel[ch]->sfbThresholdLdData[sfbGrp + sfb], + FL2FXCONST_DBL(-0.515625f)); + } + } + if (channels == 2) { + for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) { + LdDataVector(&psyData[ch]->sfbEnergyMS.Long[sfbGrp], + &psyData[ch]->sfbEnergyMSLdData[sfbGrp], + psyData[ch]->sfbActive); } + } + FDKmemcpy(psyOutChannel[ch]->sfbOffsets, psyData[ch]->groupedSfbOffset, + (MAX_GROUPED_SFB + 1) * sizeof(INT)); + } else { + int i; + /* maxSfb[ch] for long blocks */ + for (sfb = psyData[ch]->sfbActive - 1; sfb >= 0; sfb--) { + for (line = hPsyConfLong->sfbOffset[sfb + 1] - 1; + line >= hPsyConfLong->sfbOffset[sfb]; line--) { + if (psyData[ch]->mdctSpectrum[line] != FL2FXCONST_SGL(0.0f)) break; + } + if (line > hPsyConfLong->sfbOffset[sfb]) break; + } + maxSfbPerGroup[ch] = sfb + 1; + maxSfbPerGroup[ch] = + fixMax(fixMin(5, psyData[ch]->sfbActive), maxSfbPerGroup[ch]); + + /* sfbNrgLdData is calculated in FDKaacEnc_advancePsychLong, copy in + * psyOut structure */ + FDKmemcpy(psyOutChannel[ch]->sfbEnergyLdData, + psyData[ch]->sfbEnergyLdData.Long, + psyData[ch]->sfbActive * sizeof(FIXP_DBL)); + + FDKmemcpy(psyOutChannel[ch]->sfbOffsets, hPsyConfLong->sfbOffset, + (MAX_GROUPED_SFB + 1) * sizeof(INT)); + + /* sfbMinSnrLdData modified in adjust threshold, copy necessary */ + FDKmemcpy(psyOutChannel[ch]->sfbMinSnrLdData, + hPsyConfLong->sfbMinSnrLdData, + psyData[ch]->sfbActive * sizeof(FIXP_DBL)); + + /* sfbEnergyMSLdData ist already calculated in FDKaacEnc_CalcBandNrgMSOpt; + * only in long case */ + + /* calc sfbThrld and set Values smaller 2^-31 to 2^-33*/ + LdDataVector(psyData[ch]->sfbThreshold.Long, + psyOutChannel[ch]->sfbThresholdLdData, + psyData[ch]->sfbActive); + for (i = 0; i < psyData[ch]->sfbActive; i++) { + psyOutChannel[ch]->sfbThresholdLdData[i] = + fixMax(psyOutChannel[ch]->sfbThresholdLdData[i], + FL2FXCONST_DBL(-0.515625f)); + } } + } + /* + Intensity parameter intialization. + */ + for (ch = 0; ch < channels; ch++) { + FDKmemclear(psyOutChannel[ch]->isBook, MAX_GROUPED_SFB * sizeof(INT)); + FDKmemclear(psyOutChannel[ch]->isScale, MAX_GROUPED_SFB * sizeof(INT)); + } - /* - Intensity parameter intialization. - */ - for(ch=0;chisBook, MAX_GROUPED_SFB*sizeof(INT)); - FDKmemclear(psyOutChannel[ch]->isScale, MAX_GROUPED_SFB*sizeof(INT)); - } + for (ch = 0; ch < channels; ch++) { + INT win = (isShortWindow[ch] ? 1 : 0); + if (!psyStatic[ch]->isLFE) { + /* PNS Decision */ + FDKaacEnc_PnsDetect( + &(psyConf[0].pnsConf), pnsData[ch], + psyStatic[ch]->blockSwitchingControl.lastWindowSequence, + psyData[ch]->sfbActive, + maxSfbPerGroup[ch], /* count of Sfb which are not zero. */ + psyOutChannel[ch]->sfbThresholdLdData, psyConf[win].sfbOffset, + psyData[ch]->mdctSpectrum, psyData[ch]->sfbMaxScaleSpec.Long, + sfbTonality[ch], psyOutChannel[ch]->tnsInfo.order[0][0], + tnsData[ch]->dataRaw.Long.subBlockInfo.predictionGain[HIFILT], + tnsData[ch]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT], + psyOutChannel[ch]->sfbEnergyLdData, psyOutChannel[ch]->noiseNrg); + } /* !isLFE */ + } /* ch */ - for(ch=0;chisLFE) - { - /* PNS Decision */ - FDKaacEnc_PnsDetect( &(psyConf[0].pnsConf), - pnsData[ch], - psyStatic[ch]->blockSwitchingControl.lastWindowSequence, - psyData[ch]->sfbActive, - maxSfbPerGroup[ch], /* count of Sfb which are not zero. */ - psyOutChannel[ch]->sfbThresholdLdData, - psyConf[win].sfbOffset, - psyData[ch]->mdctSpectrum, - psyData[ch]->sfbMaxScaleSpec.Long, - sfbTonality[ch], - psyOutChannel[ch]->tnsInfo.order[0][0], - tnsData[ch]->dataRaw.Long.subBlockInfo.predictionGain[HIFILT], - tnsData[ch]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT], - psyOutChannel[ch]->sfbEnergyLdData, - psyOutChannel[ch]->noiseNrg ); - } /* !isLFE */ - } + /* + stereo Processing + */ + if (channels == 2) { + psyOutElement->toolsInfo.msDigest = MS_NONE; + psyOutElement->commonWindow = commonWindow; + if (psyOutElement->commonWindow) + maxSfbPerGroup[0] = maxSfbPerGroup[1] = + fixMax(maxSfbPerGroup[0], maxSfbPerGroup[1]); + if (psyStatic[0]->blockSwitchingControl.lastWindowSequence != + SHORT_WINDOW) { + /* PNS preprocessing depending on ms processing: PNS not in Short Window! + */ + FDKaacEnc_PreProcessPnsChannelPair( + psyData[0]->sfbActive, (&psyData[0]->sfbEnergy)->Long, + (&psyData[1]->sfbEnergy)->Long, psyOutChannel[0]->sfbEnergyLdData, + psyOutChannel[1]->sfbEnergyLdData, psyData[0]->sfbEnergyMS.Long, + &(psyConf[0].pnsConf), pnsData[0], pnsData[1]); + + FDKaacEnc_IntensityStereoProcessing( + psyData[0]->sfbEnergy.Long, psyData[1]->sfbEnergy.Long, + psyData[0]->mdctSpectrum, psyData[1]->mdctSpectrum, + psyData[0]->sfbThreshold.Long, psyData[1]->sfbThreshold.Long, + psyOutChannel[1]->sfbThresholdLdData, + psyData[0]->sfbSpreadEnergy.Long, psyData[1]->sfbSpreadEnergy.Long, + psyOutChannel[0]->sfbEnergyLdData, psyOutChannel[1]->sfbEnergyLdData, + &psyOutElement->toolsInfo.msDigest, psyOutElement->toolsInfo.msMask, + psyConf[0].sfbCnt, psyConf[0].sfbCnt, maxSfbPerGroup[0], + psyConf[0].sfbOffset, + psyConf[0].allowIS && psyOutElement->commonWindow, + psyOutChannel[1]->isBook, psyOutChannel[1]->isScale, pnsData); + + FDKaacEnc_MsStereoProcessing( + psyData, psyOutChannel, psyOutChannel[1]->isBook, + &psyOutElement->toolsInfo.msDigest, psyOutElement->toolsInfo.msMask, + psyConf[0].allowMS, psyData[0]->sfbActive, psyData[0]->sfbActive, + maxSfbPerGroup[0], psyOutChannel[0]->sfbOffsets); + + /* PNS postprocessing */ + FDKaacEnc_PostProcessPnsChannelPair( + psyData[0]->sfbActive, &(psyConf[0].pnsConf), pnsData[0], pnsData[1], + psyOutElement->toolsInfo.msMask, &psyOutElement->toolsInfo.msDigest); - /* - stereo Processing - */ - if(channels == 2) - { - psyOutElement->toolsInfo.msDigest = MS_NONE; - psyOutElement->commonWindow = commonWindow; - if (psyOutElement->commonWindow) - maxSfbPerGroup[0] = maxSfbPerGroup[1] = - fixMax(maxSfbPerGroup[0], maxSfbPerGroup[1]); - - if(psyStatic[0]->blockSwitchingControl.lastWindowSequence != SHORT_WINDOW) - { - /* PNS preprocessing depending on ms processing: PNS not in Short Window! */ - FDKaacEnc_PreProcessPnsChannelPair( - psyData[0]->sfbActive, - (&psyData[0]->sfbEnergy)->Long, - (&psyData[1]->sfbEnergy)->Long, - psyOutChannel[0]->sfbEnergyLdData, - psyOutChannel[1]->sfbEnergyLdData, - psyData[0]->sfbEnergyMS.Long, - &(psyConf[0].pnsConf), - pnsData[0], - pnsData[1]); - - FDKaacEnc_IntensityStereoProcessing( - psyData[0]->sfbEnergy.Long, - psyData[1]->sfbEnergy.Long, - psyData[0]->mdctSpectrum, - psyData[1]->mdctSpectrum, - psyData[0]->sfbThreshold.Long, - psyData[1]->sfbThreshold.Long, - psyOutChannel[1]->sfbThresholdLdData, - psyData[0]->sfbSpreadEnergy.Long, - psyData[1]->sfbSpreadEnergy.Long, - psyOutChannel[0]->sfbEnergyLdData, - psyOutChannel[1]->sfbEnergyLdData, - &psyOutElement->toolsInfo.msDigest, - psyOutElement->toolsInfo.msMask, - psyConf[0].sfbCnt, - psyConf[0].sfbCnt, - maxSfbPerGroup[0], - psyConf[0].sfbOffset, - psyConf[0].allowIS && commonWindow, - psyOutChannel[1]->isBook, - psyOutChannel[1]->isScale, - pnsData); - - FDKaacEnc_MsStereoProcessing( - psyData, - psyOutChannel, - psyOutChannel[1]->isBook, - &psyOutElement->toolsInfo.msDigest, - psyOutElement->toolsInfo.msMask, - psyData[0]->sfbActive, - psyData[0]->sfbActive, - maxSfbPerGroup[0], - psyOutChannel[0]->sfbOffsets); - - /* PNS postprocessing */ - FDKaacEnc_PostProcessPnsChannelPair(psyData[0]->sfbActive, - &(psyConf[0].pnsConf), - pnsData[0], - pnsData[1], - psyOutElement->toolsInfo.msMask, - &psyOutElement->toolsInfo.msDigest); - - } else { - FDKaacEnc_IntensityStereoProcessing( - psyData[0]->sfbEnergy.Long, - psyData[1]->sfbEnergy.Long, - psyData[0]->mdctSpectrum, - psyData[1]->mdctSpectrum, - psyData[0]->sfbThreshold.Long, - psyData[1]->sfbThreshold.Long, - psyOutChannel[1]->sfbThresholdLdData, - psyData[0]->sfbSpreadEnergy.Long, - psyData[1]->sfbSpreadEnergy.Long, - psyOutChannel[0]->sfbEnergyLdData, - psyOutChannel[1]->sfbEnergyLdData, - &psyOutElement->toolsInfo.msDigest, - psyOutElement->toolsInfo.msMask, - psyStatic[0]->blockSwitchingControl.noOfGroups*hPsyConfShort->sfbCnt, - psyConf[1].sfbCnt, - maxSfbPerGroup[0], - psyData[0]->groupedSfbOffset, - psyConf[0].allowIS && commonWindow, - psyOutChannel[1]->isBook, - psyOutChannel[1]->isScale, - pnsData); - - /* it's OK to pass the ".Long" arrays here. They contain grouped short data since FDKaacEnc_groupShortData() */ - FDKaacEnc_MsStereoProcessing( psyData, - psyOutChannel, - psyOutChannel[1]->isBook, - &psyOutElement->toolsInfo.msDigest, - psyOutElement->toolsInfo.msMask, - psyStatic[0]->blockSwitchingControl.noOfGroups*hPsyConfShort->sfbCnt, - hPsyConfShort->sfbCnt, - maxSfbPerGroup[0], - psyOutChannel[0]->sfbOffsets); - } + } else { + FDKaacEnc_IntensityStereoProcessing( + psyData[0]->sfbEnergy.Long, psyData[1]->sfbEnergy.Long, + psyData[0]->mdctSpectrum, psyData[1]->mdctSpectrum, + psyData[0]->sfbThreshold.Long, psyData[1]->sfbThreshold.Long, + psyOutChannel[1]->sfbThresholdLdData, + psyData[0]->sfbSpreadEnergy.Long, psyData[1]->sfbSpreadEnergy.Long, + psyOutChannel[0]->sfbEnergyLdData, psyOutChannel[1]->sfbEnergyLdData, + &psyOutElement->toolsInfo.msDigest, psyOutElement->toolsInfo.msMask, + psyStatic[0]->blockSwitchingControl.noOfGroups * + hPsyConfShort->sfbCnt, + psyConf[1].sfbCnt, maxSfbPerGroup[0], psyData[0]->groupedSfbOffset, + psyConf[0].allowIS && psyOutElement->commonWindow, + psyOutChannel[1]->isBook, psyOutChannel[1]->isScale, pnsData); + + /* it's OK to pass the ".Long" arrays here. They contain grouped short + * data since FDKaacEnc_groupShortData() */ + FDKaacEnc_MsStereoProcessing( + psyData, psyOutChannel, psyOutChannel[1]->isBook, + &psyOutElement->toolsInfo.msDigest, psyOutElement->toolsInfo.msMask, + psyConf[1].allowMS, + psyStatic[0]->blockSwitchingControl.noOfGroups * + hPsyConfShort->sfbCnt, + hPsyConfShort->sfbCnt, maxSfbPerGroup[0], + psyOutChannel[0]->sfbOffsets); } + } /* (channels == 2) */ /* PNS Coding */ - for(ch=0;chisLFE) { - /* no PNS coding */ - for(sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) { - psyOutChannel[ch]->noiseNrg[sfb] = NO_NOISE_PNS; - } - } else - { - FDKaacEnc_CodePnsChannel(psyData[ch]->sfbActive, - &(psyConf[ch].pnsConf), - pnsData[ch]->pnsFlag, - psyData[ch]->sfbEnergyLdData.Long, - psyOutChannel[ch]->noiseNrg, /* this is the energy that will be written to the bitstream */ - psyOutChannel[ch]->sfbThresholdLdData); + for (ch = 0; ch < channels; ch++) { + if (psyStatic[ch]->isLFE) { + /* no PNS coding */ + for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) { + psyOutChannel[ch]->noiseNrg[sfb] = NO_NOISE_PNS; } + } else { + FDKaacEnc_CodePnsChannel( + psyData[ch]->sfbActive, &(hThisPsyConf[ch]->pnsConf), + pnsData[ch]->pnsFlag, psyData[ch]->sfbEnergyLdData.Long, + psyOutChannel[ch]->noiseNrg, /* this is the energy that will be + written to the bitstream */ + psyOutChannel[ch]->sfbThresholdLdData); + } } - /* - build output - */ - for(ch=0;chmaxSfbPerGroup = maxSfbPerGroup[ch]; - psyOutChannel[ch]->mdctScale = psyData[ch]->mdctScale; - - if(isShortWindow[ch]==0) { - - psyOutChannel[ch]->sfbCnt = hPsyConfLong->sfbActive; - psyOutChannel[ch]->sfbPerGroup = hPsyConfLong->sfbActive; - psyOutChannel[ch]->lastWindowSequence = psyStatic[ch]->blockSwitchingControl.lastWindowSequence; - psyOutChannel[ch]->windowShape = psyStatic[ch]->blockSwitchingControl.windowShape; - } - else { - INT sfbCnt = psyStatic[ch]->blockSwitchingControl.noOfGroups*hPsyConfShort->sfbCnt; - - psyOutChannel[ch]->sfbCnt = sfbCnt; - psyOutChannel[ch]->sfbPerGroup = hPsyConfShort->sfbCnt; - psyOutChannel[ch]->lastWindowSequence = SHORT_WINDOW; - psyOutChannel[ch]->windowShape = SINE_WINDOW; - } - - /* generate grouping mask */ - mask = 0; - for (grp = 0; grp < psyStatic[ch]->blockSwitchingControl.noOfGroups; grp++) - { - mask <<= 1; - for (j=1; jblockSwitchingControl.groupLen[grp]; j++) { - mask = (mask<<1) | 1 ; - } - } - psyOutChannel[ch]->groupingMask = mask; + /* + build output + */ + for (ch = 0; ch < channels; ch++) { + INT mask; + int grp; + psyOutChannel[ch]->maxSfbPerGroup = maxSfbPerGroup[ch]; + psyOutChannel[ch]->mdctScale = psyData[ch]->mdctScale; + if (isShortWindow[ch] == 0) { + psyOutChannel[ch]->sfbCnt = hPsyConfLong->sfbActive; + psyOutChannel[ch]->sfbPerGroup = hPsyConfLong->sfbActive; + psyOutChannel[ch]->lastWindowSequence = + psyStatic[ch]->blockSwitchingControl.lastWindowSequence; + psyOutChannel[ch]->windowShape = + psyStatic[ch]->blockSwitchingControl.windowShape; + } else { + INT sfbCnt = psyStatic[ch]->blockSwitchingControl.noOfGroups * + hPsyConfShort->sfbCnt; - /* build interface */ - FDKmemcpy(psyOutChannel[ch]->groupLen,psyStatic[ch]->blockSwitchingControl.groupLen,MAX_NO_OF_GROUPS*sizeof(INT)); - FDKmemcpy(psyOutChannel[ch]->sfbEnergy,(&psyData[ch]->sfbEnergy)->Long, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); - FDKmemcpy(psyOutChannel[ch]->sfbSpreadEnergy,(&psyData[ch]->sfbSpreadEnergy)->Long, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); -// FDKmemcpy(psyOutChannel[ch]->mdctSpectrum, psyData[ch]->mdctSpectrum, (1024)*sizeof(FIXP_DBL)); + psyOutChannel[ch]->sfbCnt = sfbCnt; + psyOutChannel[ch]->sfbPerGroup = hPsyConfShort->sfbCnt; + psyOutChannel[ch]->lastWindowSequence = SHORT_WINDOW; + psyOutChannel[ch]->windowShape = SINE_WINDOW; + } + /* generate grouping mask */ + mask = 0; + for (grp = 0; grp < psyStatic[ch]->blockSwitchingControl.noOfGroups; + grp++) { + int j; + mask <<= 1; + for (j = 1; j < psyStatic[ch]->blockSwitchingControl.groupLen[grp]; j++) { + mask = (mask << 1) | 1; + } } + psyOutChannel[ch]->groupingMask = mask; + + /* build interface */ + FDKmemcpy(psyOutChannel[ch]->groupLen, + psyStatic[ch]->blockSwitchingControl.groupLen, + MAX_NO_OF_GROUPS * sizeof(INT)); + FDKmemcpy(psyOutChannel[ch]->sfbEnergy, (&psyData[ch]->sfbEnergy)->Long, + MAX_GROUPED_SFB * sizeof(FIXP_DBL)); + FDKmemcpy(psyOutChannel[ch]->sfbSpreadEnergy, + (&psyData[ch]->sfbSpreadEnergy)->Long, + MAX_GROUPED_SFB * sizeof(FIXP_DBL)); + // FDKmemcpy(psyOutChannel[ch]->mdctSpectrum, + // psyData[ch]->mdctSpectrum, (1024)*sizeof(FIXP_DBL)); + } - return AAC_ENC_OK; + return AAC_ENC_OK; } +void FDKaacEnc_PsyClose(PSY_INTERNAL **phPsyInternal, PSY_OUT **phPsyOut) { + int n, i; -void FDKaacEnc_PsyClose(PSY_INTERNAL **phPsyInternal, - PSY_OUT **phPsyOut) -{ - int n, i; - - - if(phPsyInternal!=NULL) { - PSY_INTERNAL *hPsyInternal = *phPsyInternal; + if (phPsyInternal != NULL) { + PSY_INTERNAL *hPsyInternal = *phPsyInternal; - if (hPsyInternal) - { - for (i=0; i<(8); i++) { - if (hPsyInternal->pStaticChannels[i]) { - if (hPsyInternal->pStaticChannels[i]->psyInputBuffer) - FreeRam_aacEnc_PsyInputBuffer(&hPsyInternal->pStaticChannels[i]->psyInputBuffer); /* AUDIO INPUT BUFFER */ + if (hPsyInternal) { + for (i = 0; i < (8); i++) { + if (hPsyInternal->pStaticChannels[i]) { + if (hPsyInternal->pStaticChannels[i]->psyInputBuffer) + FreeRam_aacEnc_PsyInputBuffer( + &hPsyInternal->pStaticChannels[i] + ->psyInputBuffer); /* AUDIO INPUT BUFFER */ - FreeRam_aacEnc_PsyStatic(&hPsyInternal->pStaticChannels[i]); /* PSY_STATIC */ - } + FreeRam_aacEnc_PsyStatic( + &hPsyInternal->pStaticChannels[i]); /* PSY_STATIC */ } + } - for (i=0; i<(8); i++) { - if (hPsyInternal->psyElement[i]) - FreeRam_aacEnc_PsyElement(&hPsyInternal->psyElement[i]); /* PSY_ELEMENT */ - } - - - FreeRam_aacEnc_PsyInternal(phPsyInternal); + for (i = 0; i < ((8)); i++) { + if (hPsyInternal->psyElement[i]) + FreeRam_aacEnc_PsyElement( + &hPsyInternal->psyElement[i]); /* PSY_ELEMENT */ } - } - if (phPsyOut!=NULL) { - for (n=0; n<(1); n++) { - if (phPsyOut[n]) - { - for (i=0; i<(8); i++) { - if (phPsyOut[n]->pPsyOutChannels[i]) - FreeRam_aacEnc_PsyOutChannel(&phPsyOut[n]->pPsyOutChannels[i]); /* PSY_OUT_CHANNEL */ - } + FreeRam_aacEnc_PsyInternal(phPsyInternal); + } + } - for (i=0; i<(8); i++) { - if (phPsyOut[n]->psyOutElement[i]) - FreeRam_aacEnc_PsyOutElements(&phPsyOut[n]->psyOutElement[i]); /* PSY_OUT_ELEMENTS */ - } + if (phPsyOut != NULL) { + for (n = 0; n < (1); n++) { + if (phPsyOut[n]) { + for (i = 0; i < (8); i++) { + if (phPsyOut[n]->pPsyOutChannels[i]) + FreeRam_aacEnc_PsyOutChannel( + &phPsyOut[n]->pPsyOutChannels[i]); /* PSY_OUT_CHANNEL */ + } - FreeRam_aacEnc_PsyOut(&phPsyOut[n]); + for (i = 0; i < ((8)); i++) { + if (phPsyOut[n]->psyOutElement[i]) + FreeRam_aacEnc_PsyOutElements( + &phPsyOut[n]->psyOutElement[i]); /* PSY_OUT_ELEMENTS */ } + + FreeRam_aacEnc_PsyOut(&phPsyOut[n]); } } + } } diff --git a/libAACenc/src/psy_main.h b/libAACenc/src/psy_main.h index 7bdcc38..7cc01a3 100644 --- a/libAACenc/src/psy_main.h +++ b/libAACenc/src/psy_main.h @@ -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,18 +90,18 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M.Werner - contents/description: Psychoaccoustic major function block + Author(s): M.Werner -******************************************************************************/ + Description: Psychoaccoustic major function block -#ifndef _PSYMAIN_H -#define _PSYMAIN_H +*******************************************************************************/ +#ifndef PSY_MAIN_H +#define PSY_MAIN_H #include "psy_configuration.h" #include "qc_data.h" @@ -99,76 +110,52 @@ amm-info@iis.fraunhofer.de /* psych internal */ -typedef struct { - - PSY_STATIC* psyStatic[(2)]; +typedef struct { + PSY_STATIC *psyStatic[(2)]; -}PSY_ELEMENT; +} PSY_ELEMENT; -typedef struct { +typedef struct { + PSY_DATA psyData[(2)]; + TNS_DATA tnsData[(2)]; + PNS_DATA pnsData[(2)]; - PSY_DATA psyData[(2)]; - TNS_DATA tnsData[(2)]; - PNS_DATA pnsData[(2)]; +} PSY_DYNAMIC; -}PSY_DYNAMIC; +typedef struct { + PSY_CONFIGURATION psyConf[2]; /* LONG / SHORT */ + PSY_ELEMENT *psyElement[((8))]; + PSY_STATIC *pStaticChannels[(8)]; + PSY_DYNAMIC *psyDynamic; + INT granuleLength; +} PSY_INTERNAL; -typedef struct { +AAC_ENCODER_ERROR FDKaacEnc_PsyNew(PSY_INTERNAL **phpsy, const INT nElements, + const INT nChannels, UCHAR *dynamic_RAM); - PSY_CONFIGURATION psyConf[2]; /* LONG / SHORT */ - PSY_ELEMENT* psyElement[(8)]; - PSY_STATIC* pStaticChannels[(8)]; - PSY_DYNAMIC* psyDynamic; - INT granuleLength; - -}PSY_INTERNAL; +AAC_ENCODER_ERROR FDKaacEnc_PsyOutNew(PSY_OUT **phpsyOut, const INT nElements, + const INT nChannels, const INT nSubFrames, + UCHAR *dynamic_RAM); +AAC_ENCODER_ERROR FDKaacEnc_psyInit(PSY_INTERNAL *hPsy, PSY_OUT **phpsyOut, + const INT nSubFrames, + const INT nMaxChannels, + const AUDIO_OBJECT_TYPE audioObjectType, + CHANNEL_MAPPING *cm); -AAC_ENCODER_ERROR FDKaacEnc_PsyNew(PSY_INTERNAL **phpsy, - const INT nElements, - const INT nChannels - ,UCHAR *dynamic_RAM - ); +AAC_ENCODER_ERROR FDKaacEnc_psyMainInit( + PSY_INTERNAL *hPsy, AUDIO_OBJECT_TYPE audioObjectType, CHANNEL_MAPPING *cm, + INT sampleRate, INT granuleLength, INT bitRate, INT tnsMask, INT bandwidth, + INT usePns, INT useIS, INT useMS, UINT syntaxFlags, ULONG initFlags); -AAC_ENCODER_ERROR FDKaacEnc_PsyOutNew(PSY_OUT **phpsyOut, - const INT nElements, - const INT nChannels, - const INT nSubFrames - ,UCHAR *dynamic_RAM - ); +AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels, PSY_ELEMENT *psyElement, + PSY_DYNAMIC *psyDynamic, + PSY_CONFIGURATION *psyConf, + PSY_OUT_ELEMENT *psyOutElement, + INT_PCM *pInput, const UINT inputBufSize, + INT *chIdx, INT totalChannels); -AAC_ENCODER_ERROR FDKaacEnc_psyInit(PSY_INTERNAL *hPsy, - PSY_OUT **phpsyOut, - const INT nSubFrames, - const INT nMaxChannels, - const AUDIO_OBJECT_TYPE audioObjectType, - CHANNEL_MAPPING *cm); +void FDKaacEnc_PsyClose(PSY_INTERNAL **phPsyInternal, PSY_OUT **phPsyOut); -AAC_ENCODER_ERROR FDKaacEnc_psyMainInit(PSY_INTERNAL *hPsy, - AUDIO_OBJECT_TYPE audioObjectType, - CHANNEL_MAPPING *cm, - INT sampleRate, - INT granuleLength, - INT bitRate, - INT tnsMask, - INT bandwidth, - INT usePns, - INT useIS, - UINT syntaxFlags, - ULONG initFlags); - -AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels, - PSY_ELEMENT *psyElement, - PSY_DYNAMIC *psyDynamic, - PSY_CONFIGURATION *psyConf, - PSY_OUT_ELEMENT *psyOutElement, - INT_PCM *pInput, - INT *chIdx, - INT totalChannels - ); - -void FDKaacEnc_PsyClose(PSY_INTERNAL **phPsyInternal, - PSY_OUT **phPsyOut); - -#endif /* _PSYMAIN_H */ +#endif /* PSY_MAIN_H */ diff --git a/libAACenc/src/qc_data.h b/libAACenc/src/qc_data.h index 00d6090..6e671ed 100644 --- a/libAACenc/src/qc_data.h +++ b/libAACenc/src/qc_data.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,19 +90,20 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M. Werner - contents/description: Quantizing & coding data + Author(s): M. Werner -******************************************************************************/ + Description: Quantizing & coding data -#ifndef _QC_DATA_H -#define _QC_DATA_H +*******************************************************************************/ +#ifndef QC_DATA_H +#define QC_DATA_H +#include "aacenc.h" #include "psy_const.h" #include "dyn_bits.h" #include "adj_thr_data.h" @@ -99,18 +111,16 @@ amm-info@iis.fraunhofer.de #include "FDK_audio.h" #include "interface.h" - typedef enum { QCDATA_BR_MODE_INVALID = -1, - QCDATA_BR_MODE_CBR = 0, - QCDATA_BR_MODE_VBR_1 = 1, /* 32 kbps/channel */ - QCDATA_BR_MODE_VBR_2 = 2, /* 40 kbps/channel */ - QCDATA_BR_MODE_VBR_3 = 3, /* 48 kbps/channel */ - QCDATA_BR_MODE_VBR_4 = 4, /* 64 kbps/channel */ - QCDATA_BR_MODE_VBR_5 = 5, /* 96 kbps/channel */ - QCDATA_BR_MODE_FF = 6, /* Fixed frame mode. */ - QCDATA_BR_MODE_SFR = 7 /* Superframe mode. */ - + QCDATA_BR_MODE_CBR = 0, /* Constant bit rate, given average bitrate */ + QCDATA_BR_MODE_VBR_1 = 1, /* Variable bit rate, very low */ + QCDATA_BR_MODE_VBR_2 = 2, /* Variable bit rate, low */ + QCDATA_BR_MODE_VBR_3 = 3, /* Variable bit rate, medium */ + QCDATA_BR_MODE_VBR_4 = 4, /* Variable bit rate, high */ + QCDATA_BR_MODE_VBR_5 = 5, /* Variable bit rate, very high */ + QCDATA_BR_MODE_FF = 6, /* Fixed frame mode. */ + QCDATA_BR_MODE_SFR = 7 /* Superframe mode. */ } QCDATA_BR_MODE; @@ -127,137 +137,150 @@ typedef struct { INT nChannels; INT nChannelsEff; INT nElements; - ELEMENT_INFO elInfo[(8)]; + ELEMENT_INFO elInfo[((8))]; } CHANNEL_MAPPING; typedef struct { INT paddingRest; } PADDING; - /* Quantizing & coding stage */ -struct QC_INIT{ - CHANNEL_MAPPING* channelMapping; +struct QC_INIT { + CHANNEL_MAPPING *channelMapping; INT sceCpe; /* not used yet */ INT maxBits; /* maximum number of bits in reservoir */ INT averageBits; /* average number of bits we should use */ INT bitRes; - INT sampleRate; /* output sample rate */ - INT advancedBitsToPe; /* if set, calc bits2PE factor depending on samplerate */ - INT staticBits; /* Bits per frame consumed by transport layers. */ + INT sampleRate; /* output sample rate */ + INT isLowDelay; /* if set, calc bits2PE factor depending on samplerate */ + INT staticBits; /* Bits per frame consumed by transport layers. */ QCDATA_BR_MODE bitrateMode; INT meanPe; - INT chBitrate; + INT chBitrate; /* Bitrate/channel */ INT invQuant; - INT maxIterations; /* Maximum number of allowed iterations before FDKaacEnc_crashRecovery() is applied. */ + INT maxIterations; /* Maximum number of allowed iterations before + FDKaacEnc_crashRecovery() is applied. */ FIXP_DBL maxBitFac; INT bitrate; - INT nSubFrames; /* helper variable */ - INT minBits; /* minimal number of bits in one frame*/ + INT nSubFrames; /* helper variable */ + INT minBits; /* minimal number of bits in one frame*/ + AACENC_BITRES_MODE bitResMode; /* 0: full bitreservoir, 1: reduced + bitreservoir, 2: disabled bitreservoir */ + INT bitDistributionMode; /* Configure element-wise execution or execution over + all elements for the pe-dependent + threshold-adaption */ PADDING padding; }; -typedef struct -{ - FIXP_DBL mdctSpectrum[(1024)]; +typedef struct { + FIXP_DBL mdctSpectrum[(1024)]; - SHORT quantSpec[(1024)]; + SHORT quantSpec[(1024)]; - UINT maxValueInSfb[MAX_GROUPED_SFB]; - INT scf[MAX_GROUPED_SFB]; - INT globalGain; - SECTION_DATA sectionData; + UINT maxValueInSfb[MAX_GROUPED_SFB]; + INT scf[MAX_GROUPED_SFB]; + INT globalGain; + SECTION_DATA sectionData; - FIXP_DBL sfbFormFactorLdData[MAX_GROUPED_SFB]; + FIXP_DBL sfbFormFactorLdData[MAX_GROUPED_SFB]; - FIXP_DBL sfbThresholdLdData[MAX_GROUPED_SFB]; - FIXP_DBL sfbMinSnrLdData[MAX_GROUPED_SFB]; - FIXP_DBL sfbEnergyLdData[MAX_GROUPED_SFB]; - FIXP_DBL sfbEnergy[MAX_GROUPED_SFB]; - FIXP_DBL sfbWeightedEnergyLdData[MAX_GROUPED_SFB]; + FIXP_DBL sfbThresholdLdData[MAX_GROUPED_SFB]; + FIXP_DBL sfbMinSnrLdData[MAX_GROUPED_SFB]; + FIXP_DBL sfbEnergyLdData[MAX_GROUPED_SFB]; + FIXP_DBL sfbEnergy[MAX_GROUPED_SFB]; + FIXP_DBL sfbWeightedEnergyLdData[MAX_GROUPED_SFB]; - FIXP_DBL sfbEnFacLd[MAX_GROUPED_SFB]; + FIXP_DBL sfbEnFacLd[MAX_GROUPED_SFB]; - FIXP_DBL sfbSpreadEnergy[MAX_GROUPED_SFB]; + FIXP_DBL sfbSpreadEnergy[MAX_GROUPED_SFB]; } QC_OUT_CHANNEL; - -typedef struct -{ - EXT_PAYLOAD_TYPE type; /* type of the extension payload */ - INT nPayloadBits; /* size of the payload */ - UCHAR *pPayload; /* pointer to payload */ +typedef struct { + EXT_PAYLOAD_TYPE type; /* type of the extension payload */ + INT nPayloadBits; /* size of the payload */ + UCHAR *pPayload; /* pointer to payload */ } QC_OUT_EXTENSION; +typedef struct { + INT staticBitsUsed; /* for verification purposes */ + INT dynBitsUsed; /* for verification purposes */ -typedef struct -{ - INT staticBitsUsed; /* for verification purposes */ - INT dynBitsUsed; /* for verification purposes */ - - INT extBitsUsed; /* bit consumption of extended fill elements */ - INT nExtensions; /* number of extension payloads for this element */ - QC_OUT_EXTENSION extension[(1)]; /* reffering extension payload */ + INT extBitsUsed; /* bit consumption of extended fill elements */ + INT nExtensions; /* number of extension payloads for this element */ + QC_OUT_EXTENSION extension[(1)]; /* reffering extension payload */ - INT grantedDynBits; + INT grantedDynBits; - INT grantedPe; - INT grantedPeCorr; + INT grantedPe; + INT grantedPeCorr; - PE_DATA peData; + PE_DATA peData; QC_OUT_CHANNEL *qcOutChannel[(2)]; + UCHAR + *dynMem_Ah_Flag; /* pointer to dynamic buffer used by AhFlag in function + FDKaacEnc_adaptThresholdsToPe() */ + UCHAR + *dynMem_Thr_Exp; /* pointer to dynamic buffer used by ThrExp in function + FDKaacEnc_adaptThresholdsToPe() */ + UCHAR *dynMem_SfbNActiveLinesLdData; /* pointer to dynamic buffer used by + sfbNActiveLinesLdData in function + FDKaacEnc_correctThresh() */ } QC_OUT_ELEMENT; -typedef struct -{ - QC_OUT_ELEMENT *qcElement[(8)]; - QC_OUT_CHANNEL *pQcOutChannels[(8)]; - QC_OUT_EXTENSION extension[(2+2)]; /* global extension payload */ - INT nExtensions; /* number of extension payloads for this AU */ - INT maxDynBits; /* maximal allowed dynamic bits in frame */ - INT grantedDynBits; /* granted dynamic bits in frame */ - INT totFillBits; /* fill bits */ - INT elementExtBits; /* element associated extension payload bits, e.g. sbr, drc ... */ - INT globalExtBits; /* frame/au associated extension payload bits (anc data ...) */ - INT staticBits; /* aac side info bits */ - - INT totalNoRedPe; - INT totalGrantedPeCorr; - - INT usedDynBits; /* number of dynamic bits in use */ - INT alignBits; /* AU alignment bits */ - INT totalBits; /* sum of static, dyn, sbr, fill, align and dse bits */ +typedef struct { + QC_OUT_ELEMENT *qcElement[((8))]; + QC_OUT_CHANNEL *pQcOutChannels[(8)]; + QC_OUT_EXTENSION extension[(2 + 2)]; /* global extension payload */ + INT nExtensions; /* number of extension payloads for this AU */ + INT maxDynBits; /* maximal allowed dynamic bits in frame */ + INT grantedDynBits; /* granted dynamic bits in frame */ + INT totFillBits; /* fill bits */ + INT elementExtBits; /* element associated extension payload bits, e.g. sbr, + drc ... */ + INT globalExtBits; /* frame/au associated extension payload bits (anc data + ...) */ + INT staticBits; /* aac side info bits */ + + INT totalNoRedPe; + INT totalGrantedPeCorr; + + INT usedDynBits; /* number of dynamic bits in use */ + INT alignBits; /* AU alignment bits */ + INT totalBits; /* sum of static, dyn, sbr, fill, align and dse bits */ } QC_OUT; typedef struct { - INT chBitrateEl; /* channel bitrate in element (totalbitrate*el_relativeBits/el_channels) */ - INT maxBitsEl; /* used in crash recovery */ - INT bitResLevelEl; /* update bitreservoir level in each call of FDKaacEnc_QCMain */ - INT maxBitResBitsEl; /* nEffChannels*6144 - averageBitsInFrame */ - FIXP_DBL relativeBitsEl; /* Bits relative to total Bits*/ + INT chBitrateEl; /* channel bitrate in element + (totalbitrate*el_relativeBits/el_channels) */ + INT maxBitsEl; /* used in crash recovery */ + INT bitResLevelEl; /* update bitreservoir level in each call of + FDKaacEnc_QCMain */ + INT maxBitResBitsEl; /* nEffChannels*6144 - averageBitsInFrame */ + FIXP_DBL relativeBitsEl; /* Bits relative to total Bits*/ } ELEMENT_BITS; -typedef struct -{ +typedef struct { /* this is basically struct QC_INIT */ INT globHdrBits; - INT maxBitsPerFrame; /* maximal allowed bits per frame, 6144*nChannelsEff */ - INT minBitsPerFrame; /* minimal allowd bits per fram, superframing - DRM */ + INT maxBitsPerFrame; /* maximal allowed bits per frame, 6144*nChannelsEff */ + INT minBitsPerFrame; /* minimal allowd bits per fram, superframing - DRM */ INT nElements; QCDATA_BR_MODE bitrateMode; - INT bitDistributionMode; /* 0: full bitreservoir, 1: reduced bitreservoir, 2: disabled bitreservoir */ + AACENC_BITRES_MODE bitResMode; /* 0: full bitreservoir, 1: reduced + bitreservoir, 2: disabled bitreservoir */ INT bitResTot; INT bitResTotMax; - INT maxIterations; /* Maximum number of allowed iterations before FDKaacEnc_crashRecovery() is applied. */ + INT maxIterations; /* Maximum number of allowed iterations before + FDKaacEnc_crashRecovery() is applied. */ INT invQuant; FIXP_DBL vbrQualFactor; @@ -265,16 +288,12 @@ typedef struct PADDING padding; - ELEMENT_BITS *elementBits[(8)]; + ELEMENT_BITS *elementBits[((8))]; BITCNTR_STATE *hBitCounter; ADJ_THR_STATE *hAdjThr; - INT dZoneQuantEnable; /* enable dead zone quantizer */ + INT dZoneQuantEnable; /* enable dead zone quantizer */ } QC_STATE; -#endif /* _QC_DATA_H */ - - - - +#endif /* QC_DATA_H */ diff --git a/libAACenc/src/qc_main.cpp b/libAACenc/src/qc_main.cpp index 9cd73f6..ba3bc7e 100644 --- a/libAACenc/src/qc_main.cpp +++ b/libAACenc/src/qc_main.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Werner - Initial author: M. Werner - contents/description: Quantizing & coding + Description: Quantizing & coding -******************************************************************************/ +*******************************************************************************/ #include "qc_main.h" #include "quantize.h" @@ -100,6 +112,7 @@ amm-info@iis.fraunhofer.de #include "genericStds.h" +#define AACENC_DZQ_BR_THR 32000 /* Dead zone quantizer bitrate threshold */ typedef struct { QCDATA_BR_MODE bitrateMode; @@ -107,62 +120,57 @@ typedef struct { } TAB_VBR_QUAL_FACTOR; static const TAB_VBR_QUAL_FACTOR tableVbrQualFactor[] = { - {QCDATA_BR_MODE_VBR_1, FL2FXCONST_DBL(0.160f)}, /* 32 kbps mono AAC-LC + SBR + PS */ - {QCDATA_BR_MODE_VBR_2, FL2FXCONST_DBL(0.148f)}, /* 64 kbps stereo AAC-LC + SBR */ - {QCDATA_BR_MODE_VBR_3, FL2FXCONST_DBL(0.135f)}, /* 80 - 96 kbps stereo AAC-LC */ - {QCDATA_BR_MODE_VBR_4, FL2FXCONST_DBL(0.111f)}, /* 128 kbps stereo AAC-LC */ - {QCDATA_BR_MODE_VBR_5, FL2FXCONST_DBL(0.070f)} /* 192 kbps stereo AAC-LC */ + {QCDATA_BR_MODE_VBR_1, + FL2FXCONST_DBL(0.160f)}, /* Approx. 32 - 48 (AC-LC), 32 - 56 + (AAC-LD/ELD) kbps/channel */ + {QCDATA_BR_MODE_VBR_2, + FL2FXCONST_DBL(0.148f)}, /* Approx. 40 - 56 (AC-LC), 40 - 64 + (AAC-LD/ELD) kbps/channel */ + {QCDATA_BR_MODE_VBR_3, + FL2FXCONST_DBL(0.135f)}, /* Approx. 48 - 64 (AC-LC), 48 - 72 + (AAC-LD/ELD) kbps/channel */ + {QCDATA_BR_MODE_VBR_4, + FL2FXCONST_DBL(0.111f)}, /* Approx. 64 - 80 (AC-LC), 64 - 88 + (AAC-LD/ELD) kbps/channel */ + {QCDATA_BR_MODE_VBR_5, + FL2FXCONST_DBL(0.070f)} /* Approx. 96 - 120 (AC-LC), 112 - 144 + (AAC-LD/ELD) kbps/channel */ }; -static INT isConstantBitrateMode( - const QCDATA_BR_MODE bitrateMode - ) -{ - return ( ((bitrateMode==QCDATA_BR_MODE_CBR) || (bitrateMode==QCDATA_BR_MODE_SFR) || (bitrateMode==QCDATA_BR_MODE_FF)) ? 1 : 0 ); +static INT isConstantBitrateMode(const QCDATA_BR_MODE bitrateMode) { + return (((bitrateMode == QCDATA_BR_MODE_CBR) || + (bitrateMode == QCDATA_BR_MODE_SFR) || + (bitrateMode == QCDATA_BR_MODE_FF)) + ? 1 + : 0); } +typedef enum { + FRAME_LEN_BYTES_MODULO = 1, + FRAME_LEN_BYTES_INT = 2 +} FRAME_LEN_RESULT_MODE; + +/* forward declarations */ +static INT FDKaacEnc_calcMaxValueInSfb(INT sfbCnt, INT maxSfbPerGroup, + INT sfbPerGroup, INT* RESTRICT sfbOffset, + SHORT* RESTRICT quantSpectrum, + UINT* RESTRICT maxValue); -typedef enum{ - FRAME_LEN_BYTES_MODULO = 1, - FRAME_LEN_BYTES_INT = 2 -}FRAME_LEN_RESULT_MODE; +static void FDKaacEnc_crashRecovery(INT nChannels, + PSY_OUT_ELEMENT* psyOutElement, + QC_OUT* qcOut, QC_OUT_ELEMENT* qcElement, + INT bitsToSave, AUDIO_OBJECT_TYPE aot, + UINT syntaxFlags, SCHAR epConfig); -/* forward declarations */ +static AAC_ENCODER_ERROR FDKaacEnc_reduceBitConsumption( + int* iterations, const int maxIterations, int gainAdjustment, + int* chConstraintsFulfilled, int* calculateQuant, int nChannels, + PSY_OUT_ELEMENT* psyOutElement, QC_OUT* qcOut, QC_OUT_ELEMENT* qcOutElement, + ELEMENT_BITS* elBits, AUDIO_OBJECT_TYPE aot, UINT syntaxFlags, + SCHAR epConfig); -static INT FDKaacEnc_calcMaxValueInSfb(INT sfbCnt, - INT maxSfbPerGroup, - INT sfbPerGroup, - INT *RESTRICT sfbOffset, - SHORT *RESTRICT quantSpectrum, - UINT *RESTRICT maxValue); - -static void FDKaacEnc_crashRecovery(INT nChannels, - PSY_OUT_ELEMENT* psyOutElement, - QC_OUT* qcOut, - QC_OUT_ELEMENT *qcElement, - INT bitsToSave, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig); - -static -AAC_ENCODER_ERROR FDKaacEnc_reduceBitConsumption(int* iterations, - const int maxIterations, - int gainAdjustment, - int* chConstraintsFulfilled, - int* calculateQuant, - int nChannels, - PSY_OUT_ELEMENT* psyOutElement, - QC_OUT* qcOut, - QC_OUT_ELEMENT* qcOutElement, - ELEMENT_BITS* elBits, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig); - - -void FDKaacEnc_QCClose (QC_STATE **phQCstate, QC_OUT **phQC); +void FDKaacEnc_QCClose(QC_STATE** phQCstate, QC_OUT** phQC); /***************************************************************************** @@ -173,25 +181,22 @@ void FDKaacEnc_QCClose (QC_STATE **phQCstate, QC_OUT **phQC); output: *****************************************************************************/ -static INT FDKaacEnc_calcFrameLen(INT bitRate, - INT sampleRate, - INT granuleLength, - FRAME_LEN_RESULT_MODE mode) -{ - - INT result; +static INT FDKaacEnc_calcFrameLen(INT bitRate, INT sampleRate, + INT granuleLength, + FRAME_LEN_RESULT_MODE mode) { + INT result; - result = ((granuleLength)>>3)*(bitRate); + result = ((granuleLength) >> 3) * (bitRate); - switch(mode) { - case FRAME_LEN_BYTES_MODULO: - result %= sampleRate; - break; - case FRAME_LEN_BYTES_INT: - result /= sampleRate; - break; - } - return(result); + switch (mode) { + case FRAME_LEN_BYTES_MODULO: + result %= sampleRate; + break; + case FRAME_LEN_BYTES_INT: + result /= sampleRate; + break; + } + return (result); } /***************************************************************************** @@ -203,31 +208,25 @@ static INT FDKaacEnc_calcFrameLen(INT bitRate, output: *****************************************************************************/ -static INT FDKaacEnc_framePadding(INT bitRate, - INT sampleRate, - INT granuleLength, - INT *paddingRest) -{ +static INT FDKaacEnc_framePadding(INT bitRate, INT sampleRate, + INT granuleLength, INT* paddingRest) { INT paddingOn; INT difference; paddingOn = 0; - difference = FDKaacEnc_calcFrameLen( bitRate, - sampleRate, - granuleLength, - FRAME_LEN_BYTES_MODULO ); - *paddingRest-=difference; + difference = FDKaacEnc_calcFrameLen(bitRate, sampleRate, granuleLength, + FRAME_LEN_BYTES_MODULO); + *paddingRest -= difference; - if (*paddingRest <= 0 ) { + if (*paddingRest <= 0) { paddingOn = 1; *paddingRest += sampleRate; } - return( paddingOn ); + return (paddingOn); } - /********************************************************************************* functionname: FDKaacEnc_QCOutNew @@ -235,48 +234,50 @@ static INT FDKaacEnc_framePadding(INT bitRate, return: **********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_QCOutNew(QC_OUT **phQC, - const INT nElements, - const INT nChannels, - const INT nSubFrames - ,UCHAR *dynamic_RAM - ) -{ +AAC_ENCODER_ERROR FDKaacEnc_QCOutNew(QC_OUT** phQC, const INT nElements, + const INT nChannels, const INT nSubFrames, + UCHAR* dynamic_RAM) { AAC_ENCODER_ERROR ErrorStatus; int n, i; int elInc = 0, chInc = 0; - for (n=0; npQcOutChannels[i] = GetRam_aacEnc_QCchannel(chInc, dynamic_RAM); - if ( phQC[n]->pQcOutChannels[i] == NULL - ) - { - ErrorStatus = AAC_ENC_NO_MEMORY; - goto QCOutNew_bail; + if (phQC[n]->pQcOutChannels[i] == NULL) { + ErrorStatus = AAC_ENC_NO_MEMORY; + goto QCOutNew_bail; } + chInc++; } /* nChannels */ - for (i=0; iqcElement[i] = GetRam_aacEnc_QCelement(elInc); - if (phQC[n]->qcElement[i] == NULL) - { + for (i = 0; i < nElements; i++) { + phQC[n]->qcElement[i] = GetRam_aacEnc_QCelement(elInc); + if (phQC[n]->qcElement[i] == NULL) { ErrorStatus = AAC_ENC_NO_MEMORY; goto QCOutNew_bail; } elInc++; + + /* initialize pointer to dynamic buffer which are used in adjust + * thresholds */ + phQC[n]->qcElement[i]->dynMem_Ah_Flag = dynamic_RAM + (P_BUF_1); + phQC[n]->qcElement[i]->dynMem_Thr_Exp = + dynamic_RAM + (P_BUF_1) + ADJ_THR_AH_FLAG_SIZE; + phQC[n]->qcElement[i]->dynMem_SfbNActiveLinesLdData = + dynamic_RAM + (P_BUF_1) + ADJ_THR_AH_FLAG_SIZE + ADJ_THR_THR_EXP_SIZE; + } /* nElements */ } /* nSubFrames */ - return AAC_ENC_OK; QCOutNew_bail: @@ -290,21 +291,20 @@ QCOutNew_bail: return: **********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_QCOutInit(QC_OUT *phQC[(1)], - const INT nSubFrames, - const CHANNEL_MAPPING *cm) -{ - INT n,i,ch; +AAC_ENCODER_ERROR FDKaacEnc_QCOutInit(QC_OUT* phQC[(1)], const INT nSubFrames, + const CHANNEL_MAPPING* cm) { + INT n, i, ch; - for (n=0; nnElements; i++) { - for (ch=0; chelInfo[i].nChannelsInEl; ch++) { - phQC[n]->qcElement[i]->qcOutChannel[ch] = phQC[n]->pQcOutChannels[chInc]; + for (i = 0; i < cm->nElements; i++) { + for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) { + phQC[n]->qcElement[i]->qcOutChannel[ch] = + phQC[n]->pQcOutChannels[chInc]; chInc++; } /* chInEl */ - } /* nElements */ - } /* nSubFrames */ + } /* nElements */ + } /* nSubFrames */ return AAC_ENC_OK; } @@ -316,11 +316,8 @@ AAC_ENCODER_ERROR FDKaacEnc_QCOutInit(QC_OUT *phQC[(1)], return: **********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_QCNew(QC_STATE **phQC, - INT nElements - ,UCHAR* dynamic_RAM - ) -{ +AAC_ENCODER_ERROR FDKaacEnc_QCNew(QC_STATE** phQC, INT nElements, + UCHAR* dynamic_RAM) { AAC_ENCODER_ERROR ErrorStatus; int i; @@ -341,7 +338,7 @@ AAC_ENCODER_ERROR FDKaacEnc_QCNew(QC_STATE **phQC, goto QCNew_bail; } - for (i=0; ielementBits[i] = GetRam_aacEnc_ElementBits(i); if (hQC->elementBits[i] == NULL) { ErrorStatus = AAC_ENC_NO_MEMORY; @@ -363,52 +360,60 @@ QCNew_bail: return: **********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC, - struct QC_INIT *init) -{ +AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE* hQC, struct QC_INIT* init, + const ULONG initFlags) { + AAC_ENCODER_ERROR err = AAC_ENC_OK; + int i; hQC->maxBitsPerFrame = init->maxBits; hQC->minBitsPerFrame = init->minBits; - hQC->nElements = init->channelMapping->nElements; - hQC->bitResTotMax = init->bitRes; - hQC->bitResTot = init->bitRes; - hQC->maxBitFac = init->maxBitFac; - hQC->bitrateMode = init->bitrateMode; - hQC->invQuant = init->invQuant; - hQC->maxIterations = init->maxIterations; - - if ( isConstantBitrateMode(hQC->bitrateMode) ) { - INT bitresPerChannel = (hQC->bitResTotMax / init->channelMapping->nChannelsEff); - /* 0: full bitreservoir, 1: reduced bitreservoir, 2: disabled bitreservoir */ - hQC->bitDistributionMode = (bitresPerChannel>BITRES_MIN_LD) ? 0 : (bitresPerChannel>0) ? 1 : 2; + hQC->nElements = init->channelMapping->nElements; + if ((initFlags != 0) || ((init->bitrateMode != QCDATA_BR_MODE_FF) && + (hQC->bitResTotMax != init->bitRes))) { + hQC->bitResTot = init->bitRes; } - else { - hQC->bitDistributionMode = 0; /* full bitreservoir */ + hQC->bitResTotMax = init->bitRes; + hQC->maxBitFac = init->maxBitFac; + hQC->bitrateMode = init->bitrateMode; + hQC->invQuant = init->invQuant; + hQC->maxIterations = init->maxIterations; + + if (isConstantBitrateMode(hQC->bitrateMode)) { + /* 0: full bitreservoir, 1: reduced bitreservoir, 2: disabled bitreservoir + */ + hQC->bitResMode = init->bitResMode; + } else { + hQC->bitResMode = AACENC_BR_MODE_FULL; /* full bitreservoir */ } - hQC->padding.paddingRest = init->padding.paddingRest; hQC->globHdrBits = init->staticBits; /* Bit overhead due to transport */ - FDKaacEnc_InitElementBits(hQC, - init->channelMapping, - init->bitrate, - (init->averageBits/init->nSubFrames) - hQC->globHdrBits, - hQC->maxBitsPerFrame/init->channelMapping->nChannelsEff); + err = FDKaacEnc_InitElementBits( + hQC, init->channelMapping, init->bitrate, + (init->averageBits / init->nSubFrames) - hQC->globHdrBits, + hQC->maxBitsPerFrame / init->channelMapping->nChannelsEff); + if (err != AAC_ENC_OK) goto bail; hQC->vbrQualFactor = FL2FXCONST_DBL(0.f); - for (i=0; i<(int)(sizeof(tableVbrQualFactor)/sizeof(TAB_VBR_QUAL_FACTOR)); i++) { - if (hQC->bitrateMode==tableVbrQualFactor[i].bitrateMode) { + for (i = 0; + i < (int)(sizeof(tableVbrQualFactor) / sizeof(TAB_VBR_QUAL_FACTOR)); + i++) { + if (hQC->bitrateMode == tableVbrQualFactor[i].bitrateMode) { hQC->vbrQualFactor = (FIXP_DBL)tableVbrQualFactor[i].vbrQualFactor; break; } } if (init->channelMapping->nChannelsEff == 1 && - (init->bitrate / init->channelMapping->nChannelsEff) < 32000 && - init->advancedBitsToPe != 0 - ) + (init->bitrate / init->channelMapping->nChannelsEff) < + AACENC_DZQ_BR_THR && + init->isLowDelay != + 0) /* watch out here: init->bitrate is the bitrate "minus" the + standard SBR bitrate (=2500kbps) --> for the FDK the OFFSTE + tuning should start somewhere below 32000kbps-2500kbps ... so + everything is fine here */ { hQC->dZoneQuantEnable = 1; } else { @@ -416,23 +421,20 @@ AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC, } FDKaacEnc_AdjThrInit( - hQC->hAdjThr, - init->meanPe, - hQC->elementBits, /* or channelBitrates, was: channelBitrate */ - hQC->invQuant, - init->channelMapping->nElements, - init->channelMapping->nChannelsEff, - init->sampleRate, /* output sample rate */ - init->advancedBitsToPe, /* if set, calc bits2PE factor depending on samplerate */ - hQC->vbrQualFactor, - hQC->dZoneQuantEnable - ); - - return AAC_ENC_OK; + hQC->hAdjThr, init->meanPe, hQC->invQuant, init->channelMapping, + init->sampleRate, /* output sample rate */ + init->bitrate, /* total bitrate */ + init->isLowDelay, /* if set, calc bits2PE factor + depending on samplerate */ + init->bitResMode /* for a small bitreservoir, the pe + correction is calc'd differently */ + , + hQC->dZoneQuantEnable, init->bitDistributionMode, hQC->vbrQualFactor); + +bail: + return err; } - - /********************************************************************************* functionname: FDKaacEnc_QCMainPrepare @@ -440,33 +442,28 @@ AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC, return: **********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_QCMainPrepare(ELEMENT_INFO *elInfo, - ATS_ELEMENT* RESTRICT adjThrStateElement, - PSY_OUT_ELEMENT* RESTRICT psyOutElement, - QC_OUT_ELEMENT* RESTRICT qcOutElement, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig - ) -{ +AAC_ENCODER_ERROR FDKaacEnc_QCMainPrepare( + ELEMENT_INFO* elInfo, ATS_ELEMENT* RESTRICT adjThrStateElement, + PSY_OUT_ELEMENT* RESTRICT psyOutElement, + QC_OUT_ELEMENT* RESTRICT qcOutElement, AUDIO_OBJECT_TYPE aot, + UINT syntaxFlags, SCHAR epConfig) { AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK; - INT nChannels = elInfo->nChannelsInEl; + INT nChannels = elInfo->nChannelsInEl; - PSY_OUT_CHANNEL** RESTRICT psyOutChannel = psyOutElement->psyOutChannel; /* may be modified in-place */ + PSY_OUT_CHANNEL** RESTRICT psyOutChannel = + psyOutElement->psyOutChannel; /* may be modified in-place */ - FDKaacEnc_CalcFormFactor(qcOutElement->qcOutChannel, psyOutChannel, nChannels); + FDKaacEnc_CalcFormFactor(qcOutElement->qcOutChannel, psyOutChannel, + nChannels); /* prepare and calculate PE without reduction */ - FDKaacEnc_peCalculation(&qcOutElement->peData, psyOutChannel, qcOutElement->qcOutChannel, &psyOutElement->toolsInfo, adjThrStateElement, nChannels); + FDKaacEnc_peCalculation(&qcOutElement->peData, psyOutChannel, + qcOutElement->qcOutChannel, &psyOutElement->toolsInfo, + adjThrStateElement, nChannels); - ErrorStatus = FDKaacEnc_ChannelElementWrite( NULL, elInfo, NULL, - psyOutElement, - psyOutElement->psyOutChannel, - syntaxFlags, - aot, - epConfig, - &qcOutElement->staticBitsUsed, - 0 ); + ErrorStatus = FDKaacEnc_ChannelElementWrite( + NULL, elInfo, NULL, psyOutElement, psyOutElement->psyOutChannel, + syntaxFlags, aot, epConfig, &qcOutElement->staticBitsUsed, 0); return ErrorStatus; } @@ -474,57 +471,90 @@ AAC_ENCODER_ERROR FDKaacEnc_QCMainPrepare(ELEMENT_INFO *elInfo, /********************************************************************************* functionname: FDKaacEnc_AdjustBitrate - description: adjusts framelength via padding on a frame to frame basis, - to achieve a bitrate that demands a non byte aligned - framelength - return: errorcode + description: adjusts framelength via padding on a frame to frame +basis, to achieve a bitrate that demands a non byte aligned framelength return: +errorcode **********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_AdjustBitrate(QC_STATE *RESTRICT hQC, - CHANNEL_MAPPING *RESTRICT cm, - INT *avgTotalBits, - INT bitRate, /* total bitrate */ - INT sampleRate, /* output sampling rate */ - INT granuleLength) /* frame length */ +AAC_ENCODER_ERROR FDKaacEnc_AdjustBitrate( + QC_STATE* RESTRICT hQC, CHANNEL_MAPPING* RESTRICT cm, INT* avgTotalBits, + INT bitRate, /* total bitrate */ + INT sampleRate, /* output sampling rate */ + INT granuleLength) /* frame length */ { INT paddingOn; INT frameLen; /* Do we need an extra padding byte? */ - paddingOn = FDKaacEnc_framePadding(bitRate, - sampleRate, - granuleLength, - &hQC->padding.paddingRest); + paddingOn = FDKaacEnc_framePadding(bitRate, sampleRate, granuleLength, + &hQC->padding.paddingRest); - frameLen = paddingOn + FDKaacEnc_calcFrameLen(bitRate, - sampleRate, - granuleLength, - FRAME_LEN_BYTES_INT); + frameLen = + paddingOn + FDKaacEnc_calcFrameLen(bitRate, sampleRate, granuleLength, + FRAME_LEN_BYTES_INT); - *avgTotalBits = frameLen<<3; + *avgTotalBits = frameLen << 3; return AAC_ENC_OK; } -static AAC_ENCODER_ERROR FDKaacEnc_distributeElementDynBits(QC_STATE* hQC, - QC_OUT_ELEMENT* qcElement[(8)], - CHANNEL_MAPPING* cm, - INT codeBits) -{ +#define isAudioElement(elType) \ + ((elType == ID_SCE) || (elType == ID_CPE) || (elType == ID_LFE)) + +/********************************************************************************* - INT i, firstEl = cm->nElements-1; - INT totalBits = 0; + functionname: FDKaacEnc_distributeElementDynBits + description: distributes all bits over all elements. The relative bit + distibution is described in the ELEMENT_INFO of the + appropriate element. The bit distribution table is + initialized in FDKaacEnc_InitChannelMapping(). + return: errorcode - for (i=(cm->nElements-1); i>=0; i--) { - if ((cm->elInfo[i].elType == ID_SCE) || (cm->elInfo[i].elType == ID_CPE) || - (cm->elInfo[i].elType == ID_LFE)) - { - qcElement[i]->grantedDynBits = (INT)fMult(hQC->elementBits[i]->relativeBitsEl, (FIXP_DBL)codeBits); +**********************************************************************************/ +static AAC_ENCODER_ERROR FDKaacEnc_distributeElementDynBits( + QC_STATE* hQC, QC_OUT_ELEMENT* qcElement[((8))], CHANNEL_MAPPING* cm, + INT codeBits) { + INT i; /* counter variable */ + INT totalBits = 0; /* sum of bits over all elements */ + + for (i = (cm->nElements - 1); i >= 0; i--) { + if (isAudioElement(cm->elInfo[i].elType)) { + qcElement[i]->grantedDynBits = + fMax(0, fMultI(hQC->elementBits[i]->relativeBitsEl, codeBits)); totalBits += qcElement[i]->grantedDynBits; - firstEl = i; } } - qcElement[firstEl]->grantedDynBits += codeBits - totalBits; + + /* Due to inaccuracies with the multiplication, codeBits may differ from + totalBits. For that case, the difference must be added/substracted again + to/from one element, i.e: + Negative differences are substracted from the element with the most bits. + Positive differences are added to the element with the least bits. + */ + if (codeBits != totalBits) { + INT elMaxBits = cm->nElements - 1; /* element with the most bits */ + INT elMinBits = cm->nElements - 1; /* element with the least bits */ + + /* Search for biggest and smallest audio element */ + for (i = (cm->nElements - 1); i >= 0; i--) { + if (isAudioElement(cm->elInfo[i].elType)) { + if (qcElement[i]->grantedDynBits > + qcElement[elMaxBits]->grantedDynBits) { + elMaxBits = i; + } + if (qcElement[i]->grantedDynBits < + qcElement[elMinBits]->grantedDynBits) { + elMinBits = i; + } + } + } + /* Compensate for bit distibution difference */ + if (codeBits - totalBits > 0) { + qcElement[elMinBits]->grantedDynBits += codeBits - totalBits; + } else { + qcElement[elMaxBits]->grantedDynBits += codeBits - totalBits; + } + } return AAC_ENC_OK; } @@ -532,12 +562,13 @@ static AAC_ENCODER_ERROR FDKaacEnc_distributeElementDynBits(QC_STATE* hQ /** * \brief Verify whether minBitsPerFrame criterion can be satisfied. * - * This function evaluates the bit consumption only if minBitsPerFrame parameter is not 0. - * In hyperframing mode the difference between grantedDynBits and usedDynBits of all sub frames - * results the number of fillbits to be written. - * This bits can be distrubitued in superframe to reach minBitsPerFrame bit consumption in single AU's. - * The return value denotes if enough desired fill bits are available to achieve minBitsPerFrame in all frames. - * This check can only be used within superframes. + * This function evaluates the bit consumption only if minBitsPerFrame parameter + * is not 0. In hyperframing mode the difference between grantedDynBits and + * usedDynBits of all sub frames results the number of fillbits to be written. + * This bits can be distrubitued in superframe to reach minBitsPerFrame bit + * consumption in single AU's. The return value denotes if enough desired fill + * bits are available to achieve minBitsPerFrame in all frames. This check can + * only be used within superframes. * * \param qcOut Pointer to coding data struct. * \param minBitsPerFrame Minimal number of bits to be consumed in each frame. @@ -547,12 +578,8 @@ static AAC_ENCODER_ERROR FDKaacEnc_distributeElementDynBits(QC_STATE* hQ * - 1: all fine * - 0: criterion not fulfilled */ -static int checkMinFrameBitsDemand( - QC_OUT** qcOut, - const INT minBitsPerFrame, - const INT nSubFrames - ) -{ +static int checkMinFrameBitsDemand(QC_OUT** qcOut, const INT minBitsPerFrame, + const INT nSubFrames) { int result = 1; /* all fine*/ return result; } @@ -568,33 +595,26 @@ static int checkMinFrameBitsDemand( return: number of static bits **********************************************************************************/ -static int FDKaacEnc_getMinimalStaticBitdemand(CHANNEL_MAPPING* cm, - PSY_OUT** psyOut) -{ +static int FDKaacEnc_getMinimalStaticBitdemand(CHANNEL_MAPPING* cm, + PSY_OUT** psyOut) { AUDIO_OBJECT_TYPE aot = AOT_AAC_LC; - UINT syntaxFlags = 0; + UINT syntaxFlags = 0; SCHAR epConfig = -1; int i, bitcount = 0; - for (i=0; inElements; i++) { - ELEMENT_INFO elInfo = cm->elInfo[i]; + for (i = 0; i < cm->nElements; i++) { + ELEMENT_INFO elInfo = cm->elInfo[i]; - if ( (elInfo.elType == ID_SCE) - || (elInfo.elType == ID_CPE) - || (elInfo.elType == ID_LFE) ) - { - INT minElBits = 0; - - FDKaacEnc_ChannelElementWrite( NULL, &elInfo, NULL, - psyOut[0]->psyOutElement[i], - psyOut[0]->psyOutElement[i]->psyOutChannel, - syntaxFlags, - aot, - epConfig, - &minElBits, - 1 ); - bitcount += minElBits; - } + if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || + (elInfo.elType == ID_LFE)) { + INT minElBits = 0; + + FDKaacEnc_ChannelElementWrite(NULL, &elInfo, NULL, + psyOut[0]->psyOutElement[i], + psyOut[0]->psyOutElement[i]->psyOutChannel, + syntaxFlags, aot, epConfig, &minElBits, 1); + bitcount += minElBits; + } } return bitcount; @@ -602,201 +622,184 @@ static int FDKaacEnc_getMinimalStaticBitdemand(CHANNEL_MAPPING* cm, //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static AAC_ENCODER_ERROR FDKaacEnc_prepareBitDistribution(QC_STATE* hQC, - PSY_OUT** psyOut, - QC_OUT** qcOut, - CHANNEL_MAPPING* cm, - QC_OUT_ELEMENT* qcElement[(1)][(8)], - INT avgTotalBits, - INT *totalAvailableBits, - INT *avgTotalDynBits) -{ - int i; - /* get maximal allowed dynamic bits */ - qcOut[0]->grantedDynBits = (fixMin(hQC->maxBitsPerFrame, avgTotalBits) - hQC->globHdrBits)&~7; - qcOut[0]->grantedDynBits -= (qcOut[0]->globalExtBits + qcOut[0]->staticBits + qcOut[0]->elementExtBits); - qcOut[0]->maxDynBits = ((hQC->maxBitsPerFrame)&~7) - (qcOut[0]->globalExtBits + qcOut[0]->staticBits + qcOut[0]->elementExtBits); - /* assure that enough bits are available */ - if ((qcOut[0]->grantedDynBits+hQC->bitResTot) < 0) { - /* crash recovery allows to reduce static bits to a minimum */ - if ( (qcOut[0]->grantedDynBits+hQC->bitResTot) < (FDKaacEnc_getMinimalStaticBitdemand(cm, psyOut)-qcOut[0]->staticBits) ) - return AAC_ENC_BITRES_TOO_LOW; - } +static AAC_ENCODER_ERROR FDKaacEnc_prepareBitDistribution( + QC_STATE* hQC, PSY_OUT** psyOut, QC_OUT** qcOut, CHANNEL_MAPPING* cm, + QC_OUT_ELEMENT* qcElement[(1)][((8))], INT avgTotalBits, + INT* totalAvailableBits, INT* avgTotalDynBits) { + int i; + /* get maximal allowed dynamic bits */ + qcOut[0]->grantedDynBits = + (fixMin(hQC->maxBitsPerFrame, avgTotalBits) - hQC->globHdrBits) & ~7; + qcOut[0]->grantedDynBits -= (qcOut[0]->globalExtBits + qcOut[0]->staticBits + + qcOut[0]->elementExtBits); + qcOut[0]->maxDynBits = ((hQC->maxBitsPerFrame) & ~7) - + (qcOut[0]->globalExtBits + qcOut[0]->staticBits + + qcOut[0]->elementExtBits); + /* assure that enough bits are available */ + if ((qcOut[0]->grantedDynBits + hQC->bitResTot) < 0) { + /* crash recovery allows to reduce static bits to a minimum */ + if ((qcOut[0]->grantedDynBits + hQC->bitResTot) < + (FDKaacEnc_getMinimalStaticBitdemand(cm, psyOut) - + qcOut[0]->staticBits)) + return AAC_ENC_BITRES_TOO_LOW; + } - /* distribute dynamic bits to each element */ - FDKaacEnc_distributeElementDynBits(hQC, - qcElement[0], - cm, - qcOut[0]->grantedDynBits); + /* distribute dynamic bits to each element */ + FDKaacEnc_distributeElementDynBits(hQC, qcElement[0], cm, + qcOut[0]->grantedDynBits); - *avgTotalDynBits = 0; /*frameDynBits;*/ + *avgTotalDynBits = 0; /*frameDynBits;*/ - *totalAvailableBits = avgTotalBits; + *totalAvailableBits = avgTotalBits; - /* sum up corrected granted PE */ - qcOut[0]->totalGrantedPeCorr = 0; + /* sum up corrected granted PE */ + qcOut[0]->totalGrantedPeCorr = 0; - for (i=0; inElements; i++) - { - ELEMENT_INFO elInfo = cm->elInfo[i]; - int nChannels = elInfo.nChannelsInEl; + for (i = 0; i < cm->nElements; i++) { + ELEMENT_INFO elInfo = cm->elInfo[i]; + int nChannels = elInfo.nChannelsInEl; - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - /* for ( all sub frames ) ... */ - FDKaacEnc_DistributeBits(hQC->hAdjThr, - hQC->hAdjThr->adjThrStateElem[i], - psyOut[0]->psyOutElement[i]->psyOutChannel, - &qcElement[0][i]->peData, - &qcElement[0][i]->grantedPe, - &qcElement[0][i]->grantedPeCorr, - nChannels, - psyOut[0]->psyOutElement[i]->commonWindow, - qcElement[0][i]->grantedDynBits, - hQC->elementBits[i]->bitResLevelEl, - hQC->elementBits[i]->maxBitResBitsEl, - hQC->maxBitFac, - hQC->bitDistributionMode); - - *totalAvailableBits += hQC->elementBits[i]->bitResLevelEl; - /* get total corrected granted PE */ - qcOut[0]->totalGrantedPeCorr += qcElement[0][i]->grantedPeCorr; - } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ - - } /* -end- element loop */ - - *totalAvailableBits = FDKmin(hQC->maxBitsPerFrame, (*totalAvailableBits)); - - return AAC_ENC_OK; + if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || + (elInfo.elType == ID_LFE)) { + /* for ( all sub frames ) ... */ + FDKaacEnc_DistributeBits( + hQC->hAdjThr, hQC->hAdjThr->adjThrStateElem[i], + psyOut[0]->psyOutElement[i]->psyOutChannel, &qcElement[0][i]->peData, + &qcElement[0][i]->grantedPe, &qcElement[0][i]->grantedPeCorr, + nChannels, psyOut[0]->psyOutElement[i]->commonWindow, + qcElement[0][i]->grantedDynBits, hQC->elementBits[i]->bitResLevelEl, + hQC->elementBits[i]->maxBitResBitsEl, hQC->maxBitFac, + hQC->bitResMode); + + *totalAvailableBits += hQC->elementBits[i]->bitResLevelEl; + /* get total corrected granted PE */ + qcOut[0]->totalGrantedPeCorr += qcElement[0][i]->grantedPeCorr; + } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ + + } /* -end- element loop */ + + *totalAvailableBits = fMin(hQC->maxBitsPerFrame, (*totalAvailableBits)); + + return AAC_ENC_OK; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static AAC_ENCODER_ERROR FDKaacEnc_updateUsedDynBits(INT* sumDynBitsConsumed, - QC_OUT_ELEMENT* qcElement[(8)], - CHANNEL_MAPPING* cm) -{ +static AAC_ENCODER_ERROR FDKaacEnc_updateUsedDynBits( + INT* sumDynBitsConsumed, QC_OUT_ELEMENT* qcElement[((8))], + CHANNEL_MAPPING* cm) { INT i; *sumDynBitsConsumed = 0; - for (i=0; inElements; i++) - { - ELEMENT_INFO elInfo = cm->elInfo[i]; + for (i = 0; i < cm->nElements; i++) { + ELEMENT_INFO elInfo = cm->elInfo[i]; - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - /* sum up bits consumed */ - *sumDynBitsConsumed += qcElement[i]->dynBitsUsed; - } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ + if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || + (elInfo.elType == ID_LFE)) { + /* sum up bits consumed */ + *sumDynBitsConsumed += qcElement[i]->dynBitsUsed; + } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ - } /* -end- element loop */ + } /* -end- element loop */ return AAC_ENC_OK; } +static INT FDKaacEnc_getTotalConsumedDynBits(QC_OUT** qcOut, INT nSubFrames) { + INT c, totalBits = 0; -static INT FDKaacEnc_getTotalConsumedDynBits(QC_OUT** qcOut, - INT nSubFrames) -{ - INT c, totalBits=0; - - /* sum up bit consumption for all sub frames */ - for (c=0; cusedDynBits==-1) return -1; - totalBits += qcOut[c]->usedDynBits; - } - - return totalBits; + /* sum up bit consumption for all sub frames */ + for (c = 0; c < nSubFrames; c++) { + /* bit consumption not valid if dynamic bits + not available in one sub frame */ + if (qcOut[c]->usedDynBits == -1) return -1; + totalBits += qcOut[c]->usedDynBits; + } + return totalBits; } -static INT FDKaacEnc_getTotalConsumedBits(QC_OUT** qcOut, - QC_OUT_ELEMENT* qcElement[(1)][(8)], - CHANNEL_MAPPING* cm, - INT globHdrBits, - INT nSubFrames) -{ - int c, i; - int totalUsedBits = 0; - - for (c = 0 ; c < nSubFrames ; c++ ) - { - int dataBits = 0; - for (i=0; inElements; i++) - { - if ((cm->elInfo[i].elType == ID_SCE) || (cm->elInfo[i].elType == ID_CPE) || - (cm->elInfo[i].elType == ID_LFE)) - { - dataBits += qcElement[c][i]->dynBitsUsed + qcElement[c][i]->staticBitsUsed + qcElement[c][i]->extBitsUsed; - } - } - dataBits += qcOut[c]->globalExtBits; - - totalUsedBits += (8 - (dataBits) % 8) % 8; - totalUsedBits += dataBits + globHdrBits; /* header bits for every frame */ +static INT FDKaacEnc_getTotalConsumedBits(QC_OUT** qcOut, + QC_OUT_ELEMENT* qcElement[(1)][((8))], + CHANNEL_MAPPING* cm, INT globHdrBits, + INT nSubFrames) { + int c, i; + int totalUsedBits = 0; + + for (c = 0; c < nSubFrames; c++) { + int dataBits = 0; + for (i = 0; i < cm->nElements; i++) { + if ((cm->elInfo[i].elType == ID_SCE) || + (cm->elInfo[i].elType == ID_CPE) || + (cm->elInfo[i].elType == ID_LFE)) { + dataBits += qcElement[c][i]->dynBitsUsed + + qcElement[c][i]->staticBitsUsed + + qcElement[c][i]->extBitsUsed; + } } - return totalUsedBits; + dataBits += qcOut[c]->globalExtBits; + + totalUsedBits += (8 - (dataBits) % 8) % 8; + totalUsedBits += dataBits + globHdrBits; /* header bits for every frame */ + } + return totalUsedBits; } static AAC_ENCODER_ERROR FDKaacEnc_BitResRedistribution( - QC_STATE *const hQC, - const CHANNEL_MAPPING *const cm, - const INT avgTotalBits - ) -{ - /* check bitreservoir fill level */ - if (hQC->bitResTot < 0) { - return AAC_ENC_BITRES_TOO_LOW; - } - else if (hQC->bitResTot > hQC->bitResTotMax) { - return AAC_ENC_BITRES_TOO_HIGH; + QC_STATE* const hQC, const CHANNEL_MAPPING* const cm, + const INT avgTotalBits) { + /* check bitreservoir fill level */ + if (hQC->bitResTot < 0) { + return AAC_ENC_BITRES_TOO_LOW; + } else if (hQC->bitResTot > hQC->bitResTotMax) { + return AAC_ENC_BITRES_TOO_HIGH; + } else { + INT i; + INT totalBits = 0, totalBits_max = 0; + + const int totalBitreservoir = + fMin(hQC->bitResTot, (hQC->maxBitsPerFrame - avgTotalBits)); + const int totalBitreservoirMax = + fMin(hQC->bitResTotMax, (hQC->maxBitsPerFrame - avgTotalBits)); + + for (i = (cm->nElements - 1); i >= 0; i--) { + if ((cm->elInfo[i].elType == ID_SCE) || + (cm->elInfo[i].elType == ID_CPE) || + (cm->elInfo[i].elType == ID_LFE)) { + hQC->elementBits[i]->bitResLevelEl = + fMultI(hQC->elementBits[i]->relativeBitsEl, totalBitreservoir); + totalBits += hQC->elementBits[i]->bitResLevelEl; + + hQC->elementBits[i]->maxBitResBitsEl = + fMultI(hQC->elementBits[i]->relativeBitsEl, totalBitreservoirMax); + totalBits_max += hQC->elementBits[i]->maxBitResBitsEl; + } } - else { - INT i, firstEl = cm->nElements-1; - INT totalBits = 0, totalBits_max = 0; - - int totalBitreservoir = FDKmin(hQC->bitResTot, (hQC->maxBitsPerFrame-avgTotalBits)); - int totalBitreservoirMax = FDKmin(hQC->bitResTotMax, (hQC->maxBitsPerFrame-avgTotalBits)); - - int sc_bitResTot = CountLeadingBits(totalBitreservoir); - int sc_bitResTotMax = CountLeadingBits(totalBitreservoirMax); - - for (i=(cm->nElements-1); i>=0; i--) { - if ((cm->elInfo[i].elType == ID_SCE) || (cm->elInfo[i].elType == ID_CPE) || - (cm->elInfo[i].elType == ID_LFE)) - { - hQC->elementBits[i]->bitResLevelEl = (INT)fMult(hQC->elementBits[i]->relativeBitsEl, (FIXP_DBL)(totalBitreservoir<>sc_bitResTot; - totalBits += hQC->elementBits[i]->bitResLevelEl; - - hQC->elementBits[i]->maxBitResBitsEl = (INT)fMult(hQC->elementBits[i]->relativeBitsEl, (FIXP_DBL)(totalBitreservoirMax<>sc_bitResTotMax; - totalBits_max += hQC->elementBits[i]->maxBitResBitsEl; - - firstEl = i; - } + for (i = 0; i < cm->nElements; i++) { + if ((cm->elInfo[i].elType == ID_SCE) || + (cm->elInfo[i].elType == ID_CPE) || + (cm->elInfo[i].elType == ID_LFE)) { + int deltaBits = fMax(totalBitreservoir - totalBits, + -hQC->elementBits[i]->bitResLevelEl); + hQC->elementBits[i]->bitResLevelEl += deltaBits; + totalBits += deltaBits; + + deltaBits = fMax(totalBitreservoirMax - totalBits_max, + -hQC->elementBits[i]->maxBitResBitsEl); + hQC->elementBits[i]->maxBitResBitsEl += deltaBits; + totalBits_max += deltaBits; } - hQC->elementBits[firstEl]->bitResLevelEl += totalBitreservoir - totalBits; - hQC->elementBits[firstEl]->maxBitResBitsEl += totalBitreservoirMax - totalBits_max; } + } - return AAC_ENC_OK; + return AAC_ENC_OK; } - -AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC, - PSY_OUT** psyOut, - QC_OUT** qcOut, - INT avgTotalBits, - CHANNEL_MAPPING* cm - ,AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig - ) -{ +AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC, PSY_OUT** psyOut, + QC_OUT** qcOut, INT avgTotalBits, + CHANNEL_MAPPING* cm, + const AUDIO_OBJECT_TYPE aot, + UINT syntaxFlags, SCHAR epConfig) { int i, c; AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK; INT avgTotalDynBits = 0; /* maximal allowed dynamic bits for all frames */ @@ -814,363 +817,314 @@ AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC, /* fastenc needs one time threshold simulation, in case of multiple frames, one more guess has to be calculated */ - /*-------------------------------------------- */ - /* helper pointer */ - QC_OUT_ELEMENT* qcElement[(1)][(8)]; + /*-------------------------------------------- */ + /* helper pointer */ + QC_OUT_ELEMENT* qcElement[(1)][((8))]; - /* work on a copy of qcChannel and qcElement */ - for (i=0; inElements; i++) - { - ELEMENT_INFO elInfo = cm->elInfo[i]; + /* work on a copy of qcChannel and qcElement */ + for (i = 0; i < cm->nElements; i++) { + ELEMENT_INFO elInfo = cm->elInfo[i]; - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - /* for ( all sub frames ) ... */ - for (c = 0 ; c < nSubFrames ; c++ ) - { - { - qcElement[c][i] = qcOut[c]->qcElement[i]; - } - } - } + if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || + (elInfo.elType == ID_LFE)) { + /* for ( all sub frames ) ... */ + for (c = 0; c < nSubFrames; c++) { + { qcElement[c][i] = qcOut[c]->qcElement[i]; } } + } + } - /*-------------------------------------------- */ - /*-------------------------------------------- */ - if ( isConstantBitrateMode(hQC->bitrateMode) ) - { - /* calc granted dynamic bits for sub frame and - distribute it to each element */ - ErrorStatus = FDKaacEnc_prepareBitDistribution( - hQC, - psyOut, - qcOut, - cm, - qcElement, - avgTotalBits, - &totalAvailableBits, - &avgTotalDynBits); - - if (ErrorStatus != AAC_ENC_OK) { - return ErrorStatus; - } - } - else { - qcOut[0]->grantedDynBits = ((hQC->maxBitsPerFrame - (hQC->globHdrBits))&~7) - - (qcOut[0]->globalExtBits + qcOut[0]->staticBits + qcOut[0]->elementExtBits); - qcOut[0]->maxDynBits = qcOut[0]->grantedDynBits; + /*-------------------------------------------- */ + /*-------------------------------------------- */ + if (isConstantBitrateMode(hQC->bitrateMode)) { + /* calc granted dynamic bits for sub frame and + distribute it to each element */ + ErrorStatus = FDKaacEnc_prepareBitDistribution( + hQC, psyOut, qcOut, cm, qcElement, avgTotalBits, &totalAvailableBits, + &avgTotalDynBits); + + if (ErrorStatus != AAC_ENC_OK) { + return ErrorStatus; + } + } else { + qcOut[0]->grantedDynBits = + ((hQC->maxBitsPerFrame - (hQC->globHdrBits)) & ~7) - + (qcOut[0]->globalExtBits + qcOut[0]->staticBits + + qcOut[0]->elementExtBits); + qcOut[0]->maxDynBits = qcOut[0]->grantedDynBits; + + totalAvailableBits = hQC->maxBitsPerFrame; + avgTotalDynBits = 0; + } - totalAvailableBits = hQC->maxBitsPerFrame; - avgTotalDynBits = 0; - } + /* for ( all sub frames ) ... */ + for (c = 0; c < nSubFrames; c++) { + /* for CBR and VBR mode */ + FDKaacEnc_AdjustThresholds(hQC->hAdjThr, qcElement[c], qcOut[c], + psyOut[c]->psyOutElement, + isConstantBitrateMode(hQC->bitrateMode), cm); -#ifdef PNS_PRECOUNT_ENABLE - /* Calculate estimated pns bits and substract them from grantedDynBits to get a more accurate number of available bits. */ - if (syntaxFlags & (AC_LD|AC_ELD)) - { - int estimatedPnsBits = 0, ch; + } /* -end- sub frame counter */ - for (ch=0; chnChannels; ch++) { - qcOut[0]->pQcOutChannels[ch]->sectionData.noiseNrgBits = noisePreCount(psyOut[0]->pPsyOutChannels[ch]->noiseNrg, psyOut[0]->pPsyOutChannels[ch]->maxSfbPerGroup); - estimatedPnsBits += qcOut[0]->pQcOutChannels[ch]->sectionData.noiseNrgBits; + /*-------------------------------------------- */ + INT iterations[(1)][((8))]; + INT chConstraintsFulfilled[(1)][((8))][(2)]; + INT calculateQuant[(1)][((8))][(2)]; + INT constraintsFulfilled[(1)][((8))]; + /*-------------------------------------------- */ + + /* for ( all sub frames ) ... */ + for (c = 0; c < nSubFrames; c++) { + for (i = 0; i < cm->nElements; i++) { + ELEMENT_INFO elInfo = cm->elInfo[i]; + INT ch, nChannels = elInfo.nChannelsInEl; + + if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || + (elInfo.elType == ID_LFE)) { + /* Turn thresholds into scalefactors, optimize bit consumption and + * verify conformance */ + FDKaacEnc_EstimateScaleFactors( + psyOut[c]->psyOutElement[i]->psyOutChannel, + qcElement[c][i]->qcOutChannel, hQC->invQuant, hQC->dZoneQuantEnable, + cm->elInfo[i].nChannelsInEl); + + /*-------------------------------------------- */ + constraintsFulfilled[c][i] = 1; + iterations[c][i] = 0; + + for (ch = 0; ch < nChannels; ch++) { + chConstraintsFulfilled[c][i][ch] = 1; + calculateQuant[c][i][ch] = 1; } - qcOut[0]->grantedDynBits -= estimatedPnsBits; - } -#endif - /* for ( all sub frames ) ... */ - for (c = 0 ; c < nSubFrames ; c++ ) - { - /* for CBR and VBR mode */ - FDKaacEnc_AdjustThresholds(hQC->hAdjThr->adjThrStateElem, - qcElement[c], - qcOut[c], - psyOut[c]->psyOutElement, - isConstantBitrateMode(hQC->bitrateMode), - hQC->hAdjThr->maxIter2ndGuess, - cm); + /*-------------------------------------------- */ - } /* -end- sub frame counter */ + } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ - /*-------------------------------------------- */ - INT iterations[(1)][(8)]; - INT chConstraintsFulfilled[(1)][(8)][(2)]; - INT calculateQuant[(1)][(8)][(2)]; - INT constraintsFulfilled[(1)][(8)]; - /*-------------------------------------------- */ + } /* -end- element loop */ + qcOut[c]->usedDynBits = -1; - /* for ( all sub frames ) ... */ - for (c = 0 ; c < nSubFrames ; c++ ) - { - for (i=0; inElements; i++) + } /* -end- sub frame counter */ + + INT quantizationDone = 0; + INT sumDynBitsConsumedTotal = 0; + INT decreaseBitConsumption = -1; /* no direction yet! */ + + /*-------------------------------------------- */ + /* -start- Quantization loop ... */ + /*-------------------------------------------- */ + do /* until max allowed bits per frame and maxDynBits!=-1*/ + { + quantizationDone = 0; + + c = 0; /* get frame to process */ + + for (i = 0; i < cm->nElements; i++) { + ELEMENT_INFO elInfo = cm->elInfo[i]; + INT ch, nChannels = elInfo.nChannelsInEl; + + if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || + (elInfo.elType == ID_LFE)) { + do /* until element bits < nChannels*MIN_BUFSIZE_PER_EFF_CHAN */ + { + do /* until spectral values < MAX_QUANT */ { - ELEMENT_INFO elInfo = cm->elInfo[i]; - INT ch, nChannels = elInfo.nChannelsInEl; + /*-------------------------------------------- */ + if (!constraintsFulfilled[c][i]) { + if ((ErrorStatus = FDKaacEnc_reduceBitConsumption( + &iterations[c][i], hQC->maxIterations, + (decreaseBitConsumption) ? 1 : -1, + chConstraintsFulfilled[c][i], calculateQuant[c][i], + nChannels, psyOut[c]->psyOutElement[i], qcOut[c], + qcElement[c][i], hQC->elementBits[i], aot, syntaxFlags, + epConfig)) != AAC_ENC_OK) { + return ErrorStatus; + } + } - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - /* Turn thresholds into scalefactors, optimize bit consumption and verify conformance */ - FDKaacEnc_EstimateScaleFactors(psyOut[c]->psyOutElement[i]->psyOutChannel, - qcElement[c][i]->qcOutChannel, - hQC->invQuant, - hQC->dZoneQuantEnable, - cm->elInfo[i].nChannelsInEl); + /*-------------------------------------------- */ + /*-------------------------------------------- */ + constraintsFulfilled[c][i] = 1; + + /*-------------------------------------------- */ + /* quantize spectrum (per each channel) */ + for (ch = 0; ch < nChannels; ch++) { + /*-------------------------------------------- */ + chConstraintsFulfilled[c][i][ch] = 1; + + /*-------------------------------------------- */ + + if (calculateQuant[c][i][ch]) { + QC_OUT_CHANNEL* qcOutCh = qcElement[c][i]->qcOutChannel[ch]; + PSY_OUT_CHANNEL* psyOutCh = + psyOut[c]->psyOutElement[i]->psyOutChannel[ch]; + + calculateQuant[c][i][ch] = + 0; /* calculate quantization only if necessary */ + + /*-------------------------------------------- */ + FDKaacEnc_QuantizeSpectrum( + psyOutCh->sfbCnt, psyOutCh->maxSfbPerGroup, + psyOutCh->sfbPerGroup, psyOutCh->sfbOffsets, + qcOutCh->mdctSpectrum, qcOutCh->globalGain, qcOutCh->scf, + qcOutCh->quantSpec, hQC->dZoneQuantEnable); + + /*-------------------------------------------- */ + if (FDKaacEnc_calcMaxValueInSfb( + psyOutCh->sfbCnt, psyOutCh->maxSfbPerGroup, + psyOutCh->sfbPerGroup, psyOutCh->sfbOffsets, + qcOutCh->quantSpec, + qcOutCh->maxValueInSfb) > MAX_QUANT) { + chConstraintsFulfilled[c][i][ch] = 0; + constraintsFulfilled[c][i] = 0; + /* if quanizted value out of range; increase global gain! */ + decreaseBitConsumption = 1; + } + /*-------------------------------------------- */ - /*-------------------------------------------- */ - constraintsFulfilled[c][i] = 1; - iterations[c][i] = 0 ; + } /* if calculateQuant[c][i][ch] */ - for (ch = 0; ch < nChannels; ch++) - { - chConstraintsFulfilled[c][i][ch] = 1; - calculateQuant[c][i][ch] = 1; - } + } /* channel loop */ - /*-------------------------------------------- */ + /*-------------------------------------------- */ + /* quantize spectrum (per each channel) */ - } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ + /*-------------------------------------------- */ - } /* -end- element loop */ + } while (!constraintsFulfilled[c][i]); /* does not regard bit + consumption */ - qcOut[c]->usedDynBits = -1; + /*-------------------------------------------- */ + /*-------------------------------------------- */ + qcElement[c][i]->dynBitsUsed = 0; /* reset dynamic bits */ + + /* quantization valid in current channel! */ + for (ch = 0; ch < nChannels; ch++) { + QC_OUT_CHANNEL* qcOutCh = qcElement[c][i]->qcOutChannel[ch]; + PSY_OUT_CHANNEL* psyOutCh = + psyOut[c]->psyOutElement[i]->psyOutChannel[ch]; + + /* count dynamic bits */ + INT chDynBits = FDKaacEnc_dynBitCount( + hQC->hBitCounter, qcOutCh->quantSpec, qcOutCh->maxValueInSfb, + qcOutCh->scf, psyOutCh->lastWindowSequence, psyOutCh->sfbCnt, + psyOutCh->maxSfbPerGroup, psyOutCh->sfbPerGroup, + psyOutCh->sfbOffsets, &qcOutCh->sectionData, psyOutCh->noiseNrg, + psyOutCh->isBook, psyOutCh->isScale, syntaxFlags); + + /* sum up dynamic channel bits */ + qcElement[c][i]->dynBitsUsed += chDynBits; + } - } /* -end- sub frame counter */ + /* save dynBitsUsed for correction of bits2pe relation */ + if (hQC->hAdjThr->adjThrStateElem[i]->dynBitsLast == -1) { + hQC->hAdjThr->adjThrStateElem[i]->dynBitsLast = + qcElement[c][i]->dynBitsUsed; + } + /* hold total bit consumption in present element below maximum allowed + */ + if (qcElement[c][i]->dynBitsUsed > + ((nChannels * MIN_BUFSIZE_PER_EFF_CHAN) - + qcElement[c][i]->staticBitsUsed - + qcElement[c][i]->extBitsUsed)) { + constraintsFulfilled[c][i] = 0; + } + } while (!constraintsFulfilled[c][i]); - INT quantizationDone = 0; - INT sumDynBitsConsumedTotal = 0; - INT decreaseBitConsumption = -1; /* no direction yet! */ + } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ - /*-------------------------------------------- */ - /* -start- Quantization loop ... */ - /*-------------------------------------------- */ - do /* until max allowed bits per frame and maxDynBits!=-1*/ - { - quantizationDone = 0; - - c = 0; /* get frame to process */ - - for (i=0; inElements; i++) - { - ELEMENT_INFO elInfo = cm->elInfo[i]; - INT ch, nChannels = elInfo.nChannelsInEl; - - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - do /* until spectral values < MAX_QUANT */ - { - /*-------------------------------------------- */ - if (!constraintsFulfilled[c][i]) - { - FDKaacEnc_reduceBitConsumption(&iterations[c][i], - hQC->maxIterations, - (decreaseBitConsumption) ? 1 : -1, - chConstraintsFulfilled[c][i], - calculateQuant[c][i], - nChannels, - psyOut[c]->psyOutElement[i], - qcOut[c], - qcElement[c][i], - hQC->elementBits[i], - aot, - syntaxFlags, - epConfig); - } - - /*-------------------------------------------- */ - /*-------------------------------------------- */ - constraintsFulfilled[c][i] = 1 ; - - /*-------------------------------------------- */ - /* quantize spectrum (per each channel) */ - for (ch = 0; ch < nChannels; ch++) - { - /*-------------------------------------------- */ - chConstraintsFulfilled[c][i][ch] = 1; - - /*-------------------------------------------- */ - - if (calculateQuant[c][i][ch]) - { - QC_OUT_CHANNEL* qcOutCh = qcElement[c][i]->qcOutChannel[ch]; - PSY_OUT_CHANNEL* psyOutCh = psyOut[c]->psyOutElement[i]->psyOutChannel[ch]; - - calculateQuant[c][i][ch] = 0; /* calculate quantization only if necessary */ - - /*-------------------------------------------- */ - FDKaacEnc_QuantizeSpectrum(psyOutCh->sfbCnt, - psyOutCh->maxSfbPerGroup, - psyOutCh->sfbPerGroup, - psyOutCh->sfbOffsets, - qcOutCh->mdctSpectrum, - qcOutCh->globalGain, - qcOutCh->scf, - qcOutCh->quantSpec, - hQC->dZoneQuantEnable); - - /*-------------------------------------------- */ - if (FDKaacEnc_calcMaxValueInSfb(psyOutCh->sfbCnt, - psyOutCh->maxSfbPerGroup, - psyOutCh->sfbPerGroup, - psyOutCh->sfbOffsets, - qcOutCh->quantSpec, - qcOutCh->maxValueInSfb) > MAX_QUANT) - { - chConstraintsFulfilled[c][i][ch] = 0; - constraintsFulfilled[c][i] = 0 ; - /* if quanizted value out of range; increase global gain! */ - decreaseBitConsumption = 1; - } - - /*-------------------------------------------- */ - - } /* if calculateQuant[c][i][ch] */ - - } /* channel loop */ - - /*-------------------------------------------- */ - /* quantize spectrum (per each channel) */ - - /*-------------------------------------------- */ - - } while (!constraintsFulfilled[c][i]) ; /* does not regard bit consumption */ - - - /*-------------------------------------------- */ - /*-------------------------------------------- */ - qcElement[c][i]->dynBitsUsed = 0 ; /* reset dynamic bits */ - - /* quantization valid in current channel! */ - for (ch = 0; ch < nChannels; ch++) - { - QC_OUT_CHANNEL* qcOutCh = qcElement[c][i]->qcOutChannel[ch]; - PSY_OUT_CHANNEL *psyOutCh = psyOut[c]->psyOutElement[i]->psyOutChannel[ch]; - - /* count dynamic bits */ - INT chDynBits = FDKaacEnc_dynBitCount(hQC->hBitCounter, - qcOutCh->quantSpec, - qcOutCh->maxValueInSfb, - qcOutCh->scf, - psyOutCh->lastWindowSequence, - psyOutCh->sfbCnt, - psyOutCh->maxSfbPerGroup, - psyOutCh->sfbPerGroup, - psyOutCh->sfbOffsets, - &qcOutCh->sectionData, - psyOutCh->noiseNrg, - psyOutCh->isBook, - psyOutCh->isScale, - syntaxFlags) ; - - /* sum up dynamic channel bits */ - qcElement[c][i]->dynBitsUsed += chDynBits; - } - - /* save dynBitsUsed for correction of bits2pe relation */ - if(hQC->hAdjThr->adjThrStateElem[i]->dynBitsLast==-1) { - hQC->hAdjThr->adjThrStateElem[i]->dynBitsLast = qcElement[c][i]->dynBitsUsed; - } - } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ - - } /* -end- element loop */ - - /* update dynBits of current subFrame */ - FDKaacEnc_updateUsedDynBits(&qcOut[c]->usedDynBits, - qcElement[c], - cm); - - /* get total consumed bits, dyn bits in all sub frames have to be valid */ - sumDynBitsConsumedTotal = FDKaacEnc_getTotalConsumedDynBits(qcOut, nSubFrames); - - if (sumDynBitsConsumedTotal==-1) - { - quantizationDone = 0; /* bit consumption not valid in all sub frames */ - } - else - { - int sumBitsConsumedTotal = FDKaacEnc_getTotalConsumedBits(qcOut, qcElement, cm, hQC->globHdrBits, nSubFrames); - - /* in all frames are valid dynamic bits */ - if ( ((sumBitsConsumedTotal < totalAvailableBits) || qcOut[c]->usedDynBits==0) && (decreaseBitConsumption==1) && checkMinFrameBitsDemand(qcOut,hQC->minBitsPerFrame,nSubFrames) - /*()*/ ) - { - quantizationDone = 1; /* exit bit adjustment */ - } - if (sumBitsConsumedTotal > totalAvailableBits && (decreaseBitConsumption==0) ) -// /*()*/ ) - { - quantizationDone = 0; /* reset! */ - break; - } - } + } /* -end- element loop */ + /* update dynBits of current subFrame */ + FDKaacEnc_updateUsedDynBits(&qcOut[c]->usedDynBits, qcElement[c], cm); - /*-------------------------------------------- */ + /* get total consumed bits, dyn bits in all sub frames have to be valid */ + sumDynBitsConsumedTotal = + FDKaacEnc_getTotalConsumedDynBits(qcOut, nSubFrames); - int emergencyIterations = 1; - int dynBitsOvershoot = 0; - - for (c = 0 ; c < nSubFrames ; c++ ) - { - for (i=0; inElements; i++) - { - ELEMENT_INFO elInfo = cm->elInfo[i]; - - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - /* iteration limitation */ - emergencyIterations &= ((iterations[c][i] < hQC->maxIterations) ? 0 : 1); - } - } - /* detection if used dyn bits exceeds the maximal allowed criterion */ - dynBitsOvershoot |= ((qcOut[c]->usedDynBits > qcOut[c]->maxDynBits) ? 1 : 0); - } + if (sumDynBitsConsumedTotal == -1) { + quantizationDone = 0; /* bit consumption not valid in all sub frames */ + } else { + int sumBitsConsumedTotal = FDKaacEnc_getTotalConsumedBits( + qcOut, qcElement, cm, hQC->globHdrBits, nSubFrames); - if (quantizationDone==0 || dynBitsOvershoot) - { + /* in all frames are valid dynamic bits */ + if (((sumBitsConsumedTotal < totalAvailableBits) || + sumDynBitsConsumedTotal == 0) && + (decreaseBitConsumption == 1) && + checkMinFrameBitsDemand(qcOut, hQC->minBitsPerFrame, nSubFrames) + /*()*/) { + quantizationDone = 1; /* exit bit adjustment */ + } + if (sumBitsConsumedTotal > totalAvailableBits && + (decreaseBitConsumption == 0)) { + quantizationDone = 0; /* reset! */ + } + } - int sumBitsConsumedTotal = FDKaacEnc_getTotalConsumedBits(qcOut, qcElement, cm, hQC->globHdrBits, nSubFrames); + /*-------------------------------------------- */ - if ( (sumDynBitsConsumedTotal >= avgTotalDynBits) || (sumDynBitsConsumedTotal==0) ) { - quantizationDone = 1; - } - if (emergencyIterations && (sumBitsConsumedTotal < totalAvailableBits)) { - quantizationDone = 1; - } - if ((sumBitsConsumedTotal > totalAvailableBits) || !checkMinFrameBitsDemand(qcOut,hQC->minBitsPerFrame,nSubFrames)) { - quantizationDone = 0; - } - if ((sumBitsConsumedTotal < totalAvailableBits) && checkMinFrameBitsDemand(qcOut,hQC->minBitsPerFrame,nSubFrames)) { - decreaseBitConsumption = 0; - } - else { - decreaseBitConsumption = 1; - } + int emergencyIterations = 1; + int dynBitsOvershoot = 0; - if (dynBitsOvershoot) { - quantizationDone = 0; - decreaseBitConsumption = 1; - } + for (c = 0; c < nSubFrames; c++) { + for (i = 0; i < cm->nElements; i++) { + ELEMENT_INFO elInfo = cm->elInfo[i]; - /* reset constraints fullfilled flags */ - FDKmemclear(constraintsFulfilled, sizeof(constraintsFulfilled)); - FDKmemclear(chConstraintsFulfilled, sizeof(chConstraintsFulfilled)); + if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || + (elInfo.elType == ID_LFE)) { + /* iteration limitation */ + emergencyIterations &= + ((iterations[c][i] < hQC->maxIterations) ? 0 : 1); + } + } + /* detection if used dyn bits exceeds the maximal allowed criterion */ + dynBitsOvershoot |= + ((qcOut[c]->usedDynBits > qcOut[c]->maxDynBits) ? 1 : 0); + } + if (quantizationDone == 0 || dynBitsOvershoot) { + int sumBitsConsumedTotal = FDKaacEnc_getTotalConsumedBits( + qcOut, qcElement, cm, hQC->globHdrBits, nSubFrames); - }/* quantizationDone */ + if ((sumDynBitsConsumedTotal >= avgTotalDynBits) || + (sumDynBitsConsumedTotal == 0)) { + quantizationDone = 1; + } + if (emergencyIterations && (sumBitsConsumedTotal < totalAvailableBits)) { + quantizationDone = 1; + } + if ((sumBitsConsumedTotal > totalAvailableBits) || + !checkMinFrameBitsDemand(qcOut, hQC->minBitsPerFrame, nSubFrames)) { + quantizationDone = 0; + } + if ((sumBitsConsumedTotal < totalAvailableBits) && + checkMinFrameBitsDemand(qcOut, hQC->minBitsPerFrame, nSubFrames)) { + decreaseBitConsumption = 0; + } else { + decreaseBitConsumption = 1; + } - } while (!quantizationDone) ; + if (dynBitsOvershoot) { + quantizationDone = 0; + decreaseBitConsumption = 1; + } + + /* reset constraints fullfilled flags */ + FDKmemclear(constraintsFulfilled, sizeof(constraintsFulfilled)); + FDKmemclear(chConstraintsFulfilled, sizeof(chConstraintsFulfilled)); - /*-------------------------------------------- */ - /* ... -end- Quantization loop */ - /*-------------------------------------------- */ + } /* quantizationDone */ + + } while (!quantizationDone); + + /*-------------------------------------------- */ + /* ... -end- Quantization loop */ + /*-------------------------------------------- */ /*-------------------------------------------- */ /*-------------------------------------------- */ @@ -1178,112 +1132,98 @@ AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC, return AAC_ENC_OK; } - -static AAC_ENCODER_ERROR FDKaacEnc_reduceBitConsumption(int* iterations, - const int maxIterations, - int gainAdjustment, - int* chConstraintsFulfilled, - int* calculateQuant, - int nChannels, - PSY_OUT_ELEMENT* psyOutElement, - QC_OUT* qcOut, - QC_OUT_ELEMENT* qcOutElement, - ELEMENT_BITS* elBits, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig) -{ +static AAC_ENCODER_ERROR FDKaacEnc_reduceBitConsumption( + int* iterations, const int maxIterations, int gainAdjustment, + int* chConstraintsFulfilled, int* calculateQuant, int nChannels, + PSY_OUT_ELEMENT* psyOutElement, QC_OUT* qcOut, QC_OUT_ELEMENT* qcOutElement, + ELEMENT_BITS* elBits, AUDIO_OBJECT_TYPE aot, UINT syntaxFlags, + SCHAR epConfig) { int ch; /** SOLVING PROBLEM **/ - if ((*iterations)++ >= maxIterations) - { - if (qcOutElement->dynBitsUsed==0) { + if ((*iterations) < maxIterations) { + /* increase gain (+ next iteration) */ + for (ch = 0; ch < nChannels; ch++) { + if (!chConstraintsFulfilled[ch]) { + qcOutElement->qcOutChannel[ch]->globalGain += gainAdjustment; + calculateQuant[ch] = 1; /* global gain has changed, recalculate + quantization in next iteration! */ + } } - /* crash recovery */ - else { + } else if ((*iterations) == maxIterations) { + if (qcOutElement->dynBitsUsed == 0) { + return AAC_ENC_QUANT_ERROR; + } else { + /* crash recovery */ INT bitsToSave = 0; - if ( (bitsToSave = fixMax((qcOutElement->dynBitsUsed + 8) - (elBits->bitResLevelEl + qcOutElement->grantedDynBits), - (qcOutElement->dynBitsUsed + qcOutElement->staticBitsUsed + 8) - (elBits->maxBitsEl))) > 0 ) - { - FDKaacEnc_crashRecovery(nChannels, - psyOutElement, - qcOut, - qcOutElement, - bitsToSave, - aot, - syntaxFlags, - epConfig) ; - } - else - { - for (ch = 0; ch < nChannels; ch++) - { + if ((bitsToSave = fixMax( + (qcOutElement->dynBitsUsed + 8) - + (elBits->bitResLevelEl + qcOutElement->grantedDynBits), + (qcOutElement->dynBitsUsed + qcOutElement->staticBitsUsed + 8) - + (elBits->maxBitsEl))) > 0) { + FDKaacEnc_crashRecovery(nChannels, psyOutElement, qcOut, qcOutElement, + bitsToSave, aot, syntaxFlags, epConfig); + } else { + for (ch = 0; ch < nChannels; ch++) { qcOutElement->qcOutChannel[ch]->globalGain += 1; + } } - } - for (ch = 0; ch < nChannels; ch++) - { - calculateQuant[ch] = 1; - } - } - } - else /* iterations >= maxIterations */ - { - /* increase gain (+ next iteration) */ - for (ch = 0; ch < nChannels; ch++) - { - if(!chConstraintsFulfilled[ch]) - { - qcOutElement->qcOutChannel[ch]->globalGain += gainAdjustment ; - calculateQuant[ch] = 1; /* global gain has changed, recalculate quantization in next iteration! */ + for (ch = 0; ch < nChannels; ch++) { + calculateQuant[ch] = 1; } } + } else { + /* (*iterations) > maxIterations */ + return AAC_ENC_QUANT_ERROR; } + (*iterations)++; return AAC_ENC_OK; } -AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING* cm, - QC_STATE* qcKernel, - ELEMENT_BITS* RESTRICT elBits[(8)], - QC_OUT** qcOut) -{ +AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING* cm, + QC_STATE* qcKernel, + ELEMENT_BITS* RESTRICT elBits[((8))], + QC_OUT** qcOut) { switch (qcKernel->bitrateMode) { case QCDATA_BR_MODE_SFR: break; case QCDATA_BR_MODE_FF: - break; - + break; case QCDATA_BR_MODE_VBR_1: case QCDATA_BR_MODE_VBR_2: case QCDATA_BR_MODE_VBR_3: case QCDATA_BR_MODE_VBR_4: case QCDATA_BR_MODE_VBR_5: - qcOut[0]->totFillBits = (qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits)&7; /* precalculate alignment bits */ - qcOut[0]->totalBits = qcOut[0]->staticBits + qcOut[0]->usedDynBits + qcOut[0]->totFillBits + qcOut[0]->elementExtBits + qcOut[0]->globalExtBits; - qcOut[0]->totFillBits += ( fixMax(0, qcKernel->minBitsPerFrame - qcOut[0]->totalBits) + 7) & ~7; + qcOut[0]->totFillBits = + (qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits) & + 7; /* precalculate alignment bits */ + qcOut[0]->totalBits = qcOut[0]->staticBits + qcOut[0]->usedDynBits + + qcOut[0]->totFillBits + qcOut[0]->elementExtBits + + qcOut[0]->globalExtBits; + qcOut[0]->totFillBits += + (fixMax(0, qcKernel->minBitsPerFrame - qcOut[0]->totalBits) + 7) & ~7; break; - case QCDATA_BR_MODE_CBR: case QCDATA_BR_MODE_INVALID: default: - INT bitResSpace = qcKernel->bitResTotMax - qcKernel->bitResTot ; + INT bitResSpace = qcKernel->bitResTotMax - qcKernel->bitResTot; /* processing fill-bits */ - INT deltaBitRes = qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits ; - qcOut[0]->totFillBits = fixMax((deltaBitRes&7), (deltaBitRes - (fixMax(0,bitResSpace-7)&~7))); - qcOut[0]->totalBits = qcOut[0]->staticBits + qcOut[0]->usedDynBits + qcOut[0]->totFillBits + qcOut[0]->elementExtBits + qcOut[0]->globalExtBits; - qcOut[0]->totFillBits += ( fixMax(0, qcKernel->minBitsPerFrame - qcOut[0]->totalBits) + 7) & ~7; + INT deltaBitRes = qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits; + qcOut[0]->totFillBits = fixMax( + (deltaBitRes & 7), (deltaBitRes - (fixMax(0, bitResSpace - 7) & ~7))); + qcOut[0]->totalBits = qcOut[0]->staticBits + qcOut[0]->usedDynBits + + qcOut[0]->totFillBits + qcOut[0]->elementExtBits + + qcOut[0]->globalExtBits; + qcOut[0]->totFillBits += + (fixMax(0, qcKernel->minBitsPerFrame - qcOut[0]->totalBits) + 7) & ~7; break; } /* switch (qcKernel->bitrateMode) */ return AAC_ENC_OK; } - - - /********************************************************************************* functionname: FDKaacEnc_calcMaxValueInSfb @@ -1292,34 +1232,29 @@ AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING* cm, **********************************************************************************/ -static INT FDKaacEnc_calcMaxValueInSfb(INT sfbCnt, - INT maxSfbPerGroup, - INT sfbPerGroup, - INT *RESTRICT sfbOffset, - SHORT *RESTRICT quantSpectrum, - UINT *RESTRICT maxValue) -{ - INT sfbOffs,sfb; +static INT FDKaacEnc_calcMaxValueInSfb(INT sfbCnt, INT maxSfbPerGroup, + INT sfbPerGroup, INT* RESTRICT sfbOffset, + SHORT* RESTRICT quantSpectrum, + UINT* RESTRICT maxValue) { + INT sfbOffs, sfb; INT maxValueAll = 0; - for (sfbOffs=0;sfbOffsbitrateMode) { - case QCDATA_BR_MODE_FF: case QCDATA_BR_MODE_VBR_1: case QCDATA_BR_MODE_VBR_2: case QCDATA_BR_MODE_VBR_3: case QCDATA_BR_MODE_VBR_4: case QCDATA_BR_MODE_VBR_5: /* variable bitrate */ - qcKernel->bitResTot = FDKmin(qcKernel->maxBitsPerFrame, qcKernel->bitResTotMax); + qcKernel->bitResTot = + fMin(qcKernel->maxBitsPerFrame, qcKernel->bitResTotMax); break; - case QCDATA_BR_MODE_CBR: case QCDATA_BR_MODE_SFR: case QCDATA_BR_MODE_INVALID: @@ -1349,7 +1281,9 @@ void FDKaacEnc_updateBitres(CHANNEL_MAPPING *cm, int c = 0; /* constant bitrate */ { - qcKernel->bitResTot += qcOut[c]->grantedDynBits - (qcOut[c]->usedDynBits + qcOut[c]->totFillBits + qcOut[c]->alignBits); + qcKernel->bitResTot += qcOut[c]->grantedDynBits - + (qcOut[c]->usedDynBits + qcOut[c]->totFillBits + + qcOut[c]->alignBits); } break; } @@ -1362,57 +1296,59 @@ void FDKaacEnc_updateBitres(CHANNEL_MAPPING *cm, return: **********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(CHANNEL_MAPPING *cm, - QC_STATE *qcKernel, - QC_OUT *qcOut, - QC_OUT_ELEMENT** qcElement, - HANDLE_TRANSPORTENC hTpEnc, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig) -{ +AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption( + CHANNEL_MAPPING* cm, QC_STATE* qcKernel, QC_OUT* qcOut, + QC_OUT_ELEMENT** qcElement, HANDLE_TRANSPORTENC hTpEnc, + AUDIO_OBJECT_TYPE aot, UINT syntaxFlags, SCHAR epConfig) { QC_OUT_EXTENSION fillExtPayload; INT totFillBits, alignBits; /* Get total consumed bits in AU */ - qcOut->totalBits = qcOut->staticBits + qcOut->usedDynBits + qcOut->totFillBits + - qcOut->elementExtBits + qcOut->globalExtBits; - - if (qcKernel->bitrateMode==QCDATA_BR_MODE_CBR) { + qcOut->totalBits = qcOut->staticBits + qcOut->usedDynBits + + qcOut->totFillBits + qcOut->elementExtBits + + qcOut->globalExtBits; - /* Now we can get the exact transport bit amount, and hopefully it is equal to the estimated value */ + if (qcKernel->bitrateMode == QCDATA_BR_MODE_CBR) { + /* Now we can get the exact transport bit amount, and hopefully it is equal + * to the estimated value */ INT exactTpBits = transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits); if (exactTpBits != qcKernel->globHdrBits) { INT diffFillBits = 0; - /* How many bits can be taken by bitreservoir */ - const INT bitresSpace = qcKernel->bitResTotMax - (qcKernel->bitResTot + (qcOut->grantedDynBits - (qcOut->usedDynBits + qcOut->totFillBits) ) ); + /* How many bits can be take by bitreservoir */ + const INT bitresSpace = + qcKernel->bitResTotMax - + (qcKernel->bitResTot + + (qcOut->grantedDynBits - (qcOut->usedDynBits + qcOut->totFillBits))); /* Number of bits which can be moved to bitreservoir. */ const INT bitsToBitres = qcKernel->globHdrBits - exactTpBits; - FDK_ASSERT(bitsToBitres>=0); /* is always positive */ + FDK_ASSERT(bitsToBitres >= 0); /* is always positive */ - /* If bitreservoir can not take all bits, move ramaining bits to fillbits */ - diffFillBits = FDKmax(0, bitsToBitres - bitresSpace); + /* If bitreservoir can not take all bits, move ramaining bits to fillbits + */ + diffFillBits = fMax(0, bitsToBitres - bitresSpace); /* Assure previous alignment */ - diffFillBits = (diffFillBits+7)&~7; + diffFillBits = (diffFillBits + 7) & ~7; /* Move as many bits as possible to bitreservoir */ - qcKernel->bitResTot += (bitsToBitres-diffFillBits); + qcKernel->bitResTot += (bitsToBitres - diffFillBits); /* Write remaing bits as fill bits */ - qcOut->totFillBits += diffFillBits; - qcOut->totalBits += diffFillBits; - qcOut->grantedDynBits += diffFillBits; + qcOut->totFillBits += diffFillBits; + qcOut->totalBits += diffFillBits; + qcOut->grantedDynBits += diffFillBits; /* Get new header bits */ - qcKernel->globHdrBits = transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits); + qcKernel->globHdrBits = + transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits); if (qcKernel->globHdrBits != exactTpBits) { - /* In previous step, fill bits and corresponding total bits were changed when bitreservoir was completely filled. - Now we can take the too much taken bits caused by header overhead from bitreservoir. + /* In previous step, fill bits and corresponding total bits were changed + when bitreservoir was completely filled. Now we can take the too much + taken bits caused by header overhead from bitreservoir. */ qcKernel->bitResTot -= (qcKernel->globHdrBits - exactTpBits); } @@ -1432,26 +1368,28 @@ AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(CHANNEL_MAPPING *cm, fillExtPayload.type = EXT_FILL_DATA; fillExtPayload.nPayloadBits = totFillBits; - /* ask bitstream encoder how many of that bits can be written in a fill extension data entity */ - qcOut->totFillBits = FDKaacEnc_writeExtensionData( NULL, - &fillExtPayload, - 0, 0, - syntaxFlags, - aot, - epConfig ); + /* ask bitstream encoder how many of that bits can be written in a fill + * extension data entity */ + qcOut->totFillBits = FDKaacEnc_writeExtensionData(NULL, &fillExtPayload, 0, 0, + syntaxFlags, aot, epConfig); /* now distribute extra fillbits and alignbits */ - alignBits = 7 - (qcOut->staticBits + qcOut->usedDynBits + qcOut->elementExtBits - + qcOut->totFillBits + qcOut->globalExtBits -1)%8; + alignBits = + 7 - (qcOut->staticBits + qcOut->usedDynBits + qcOut->elementExtBits + + qcOut->totFillBits + qcOut->globalExtBits - 1) % + 8; /* Maybe we could remove this */ - if( ((alignBits + qcOut->totFillBits - totFillBits)==8) && (qcOut->totFillBits>8) ) - qcOut->totFillBits -= 8; + if (((alignBits + qcOut->totFillBits - totFillBits) == 8) && + (qcOut->totFillBits > 8)) + qcOut->totFillBits -= 8; - qcOut->totalBits = qcOut->staticBits + qcOut->usedDynBits + qcOut->totFillBits + - alignBits + qcOut->elementExtBits + qcOut->globalExtBits; + qcOut->totalBits = qcOut->staticBits + qcOut->usedDynBits + + qcOut->totFillBits + alignBits + qcOut->elementExtBits + + qcOut->globalExtBits; - if ( (qcOut->totalBits>qcKernel->maxBitsPerFrame) || (qcOut->totalBitsminBitsPerFrame) ) { + if ((qcOut->totalBits > qcKernel->maxBitsPerFrame) || + (qcOut->totalBits < qcKernel->minBitsPerFrame)) { return AAC_ENC_QUANT_ERROR; } @@ -1460,8 +1398,6 @@ AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(CHANNEL_MAPPING *cm, return AAC_ENC_OK; } - - /********************************************************************************* functionname: FDKaacEnc_crashRecovery @@ -1472,93 +1408,82 @@ AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(CHANNEL_MAPPING *cm, **********************************************************************************/ -static void FDKaacEnc_crashRecovery(INT nChannels, - PSY_OUT_ELEMENT* psyOutElement, - QC_OUT* qcOut, - QC_OUT_ELEMENT *qcElement, - INT bitsToSave, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig) -{ - INT ch ; - INT savedBits = 0 ; - INT sfb, sfbGrp ; - INT bitsPerScf[(2)][MAX_GROUPED_SFB] ; - INT sectionToScf[(2)][MAX_GROUPED_SFB] ; - INT *sfbOffset ; - INT sect, statBitsNew ; - QC_OUT_CHANNEL **qcChannel = qcElement->qcOutChannel; - PSY_OUT_CHANNEL **psyChannel = psyOutElement->psyOutChannel; +static void FDKaacEnc_crashRecovery(INT nChannels, + PSY_OUT_ELEMENT* psyOutElement, + QC_OUT* qcOut, QC_OUT_ELEMENT* qcElement, + INT bitsToSave, AUDIO_OBJECT_TYPE aot, + UINT syntaxFlags, SCHAR epConfig) { + INT ch; + INT savedBits = 0; + INT sfb, sfbGrp; + INT bitsPerScf[(2)][MAX_GROUPED_SFB]; + INT sectionToScf[(2)][MAX_GROUPED_SFB]; + INT* sfbOffset; + INT sect, statBitsNew; + QC_OUT_CHANNEL** qcChannel = qcElement->qcOutChannel; + PSY_OUT_CHANNEL** psyChannel = psyOutElement->psyOutChannel; /* create a table which converts frq-bins to bit-demand... [bitsPerScf] */ /* ...and another one which holds the corresponding sections [sectionToScf] */ - for (ch = 0; ch < nChannels; ch++) - { - sfbOffset = psyChannel[ch]->sfbOffsets ; + for (ch = 0; ch < nChannels; ch++) { + sfbOffset = psyChannel[ch]->sfbOffsets; - for (sect = 0; sect < qcChannel[ch]->sectionData.noOfSections; sect++) - { - INT sfb ; - INT codeBook = qcChannel[ch]->sectionData.huffsection[sect].codeBook ; + for (sect = 0; sect < qcChannel[ch]->sectionData.noOfSections; sect++) { + INT codeBook = qcChannel[ch]->sectionData.huffsection[sect].codeBook; for (sfb = qcChannel[ch]->sectionData.huffsection[sect].sfbStart; sfb < qcChannel[ch]->sectionData.huffsection[sect].sfbStart + - qcChannel[ch]->sectionData.huffsection[sect].sfbCnt; - sfb++) - { + qcChannel[ch]->sectionData.huffsection[sect].sfbCnt; + sfb++) { bitsPerScf[ch][sfb] = 0; - if ( (codeBook != CODE_BOOK_PNS_NO) /*&& - (sfb < (qcChannel[ch]->sectionData.noOfGroups*qcChannel[ch]->sectionData.maxSfbPerGroup))*/ ) - { - INT sfbStartLine = sfbOffset[sfb] ; - INT noOfLines = sfbOffset[sfb+1] - sfbStartLine ; - bitsPerScf[ch][sfb] = FDKaacEnc_countValues(&(qcChannel[ch]->quantSpec[sfbStartLine]), noOfLines, codeBook) ; + if ((codeBook != CODE_BOOK_PNS_NO) /*&& + (sfb < (qcChannel[ch]->sectionData.noOfGroups*qcChannel[ch]->sectionData.maxSfbPerGroup))*/) { + INT sfbStartLine = sfbOffset[sfb]; + INT noOfLines = sfbOffset[sfb + 1] - sfbStartLine; + bitsPerScf[ch][sfb] = FDKaacEnc_countValues( + &(qcChannel[ch]->quantSpec[sfbStartLine]), noOfLines, codeBook); } - sectionToScf[ch][sfb] = sect ; + sectionToScf[ch][sfb] = sect; } - } } /* LOWER [maxSfb] IN BOTH CHANNELS!! */ - /* Attention: in case of stereo: maxSfbL == maxSfbR, GroupingL == GroupingR ; */ + /* Attention: in case of stereo: maxSfbL == maxSfbR, GroupingL == GroupingR ; + */ - for (sfb = qcChannel[0]->sectionData.maxSfbPerGroup-1; sfb >= 0; sfb--) - { - for (sfbGrp = 0; sfbGrp < psyChannel[0]->sfbCnt; sfbGrp += psyChannel[0]->sfbPerGroup) - { - for (ch = 0; ch < nChannels; ch++) - { - int sect = sectionToScf[ch][sfbGrp+sfb]; - qcChannel[ch]->sectionData.huffsection[sect].sfbCnt-- ; - savedBits += bitsPerScf[ch][sfbGrp+sfb] ; + for (sfb = qcChannel[0]->sectionData.maxSfbPerGroup - 1; sfb >= 0; sfb--) { + for (sfbGrp = 0; sfbGrp < psyChannel[0]->sfbCnt; + sfbGrp += psyChannel[0]->sfbPerGroup) { + for (ch = 0; ch < nChannels; ch++) { + sect = sectionToScf[ch][sfbGrp + sfb]; + qcChannel[ch]->sectionData.huffsection[sect].sfbCnt--; + savedBits += bitsPerScf[ch][sfbGrp + sfb]; if (qcChannel[ch]->sectionData.huffsection[sect].sfbCnt == 0) { - savedBits += (psyChannel[ch]->lastWindowSequence!=SHORT_WINDOW) ? FDKaacEnc_sideInfoTabLong[0] - : FDKaacEnc_sideInfoTabShort[0]; + savedBits += (psyChannel[ch]->lastWindowSequence != SHORT_WINDOW) + ? FDKaacEnc_sideInfoTabLong[0] + : FDKaacEnc_sideInfoTabShort[0]; } } } /* ...have enough bits been saved? */ - if (savedBits >= bitsToSave) - break ; + if (savedBits >= bitsToSave) break; } /* sfb loop */ /* if not enough bits saved, clean whole spectrum and remove side info overhead */ if (sfb == -1) { - sfb = 0 ; + sfb = 0; } - for (ch = 0; ch < nChannels; ch++) - { - qcChannel[ch]->sectionData.maxSfbPerGroup = sfb ; - psyChannel[ch]->maxSfbPerGroup = sfb ; + for (ch = 0; ch < nChannels; ch++) { + qcChannel[ch]->sectionData.maxSfbPerGroup = sfb; + psyChannel[ch]->maxSfbPerGroup = sfb; /* when no spectrum is coded save tools info in bitstream */ - if(sfb==0) { + if (sfb == 0) { FDKmemclear(&psyChannel[ch]->tnsInfo, sizeof(TNS_INFO)); FDKmemclear(&psyOutElement->toolsInfo, sizeof(TOOLSINFO)); } @@ -1572,14 +1497,9 @@ static void FDKaacEnc_crashRecovery(INT nChannels, elInfo.nChannelsInEl = nChannels; elInfo.elType = (nChannels == 2) ? ID_CPE : ID_SCE; - FDKaacEnc_ChannelElementWrite( NULL, &elInfo, NULL, - psyOutElement, - psyChannel, - syntaxFlags, - aot, - epConfig, - &statBitsNew, - 0 ); + FDKaacEnc_ChannelElementWrite(NULL, &elInfo, NULL, psyOutElement, + psyChannel, syntaxFlags, aot, epConfig, + &statBitsNew, 0); } savedBits = qcElement->staticBitsUsed - statBitsNew; @@ -1588,30 +1508,23 @@ static void FDKaacEnc_crashRecovery(INT nChannels, qcElement->staticBitsUsed -= savedBits; qcElement->grantedDynBits += savedBits; - qcOut->staticBits -= savedBits; + qcOut->staticBits -= savedBits; qcOut->grantedDynBits += savedBits; - qcOut->maxDynBits += savedBits; - - + qcOut->maxDynBits += savedBits; } - - -void FDKaacEnc_QCClose (QC_STATE **phQCstate, QC_OUT **phQC) -{ +void FDKaacEnc_QCClose(QC_STATE** phQCstate, QC_OUT** phQC) { int n, i; - if (phQC!=NULL) { - - for (n=0;n<(1);n++) { + if (phQC != NULL) { + for (n = 0; n < (1); n++) { if (phQC[n] != NULL) { - QC_OUT *hQC = phQC[n]; - for (i=0; i<(8); i++) { + QC_OUT* hQC = phQC[n]; + for (i = 0; i < (8); i++) { } - for (i=0; i<(8); i++) { - if (hQC->qcElement[i]) - FreeRam_aacEnc_QCelement(&hQC->qcElement[i]); + for (i = 0; i < ((8)); i++) { + if (hQC->qcElement[i]) FreeRam_aacEnc_QCelement(&hQC->qcElement[i]); } FreeRam_aacEnc_QCout(&phQC[n]); @@ -1619,18 +1532,17 @@ void FDKaacEnc_QCClose (QC_STATE **phQCstate, QC_OUT **phQC) } } - if (phQCstate!=NULL) { + if (phQCstate != NULL) { if (*phQCstate != NULL) { - QC_STATE *hQCstate = *phQCstate; + QC_STATE* hQCstate = *phQCstate; - if (hQCstate->hAdjThr != NULL) - FDKaacEnc_AdjThrClose(&hQCstate->hAdjThr); + if (hQCstate->hAdjThr != NULL) FDKaacEnc_AdjThrClose(&hQCstate->hAdjThr); if (hQCstate->hBitCounter != NULL) FDKaacEnc_BCClose(&hQCstate->hBitCounter); - for (i=0; i<(8); i++) { - if (hQCstate->elementBits[i]!=NULL) { + for (i = 0; i < ((8)); i++) { + if (hQCstate->elementBits[i] != NULL) { FreeRam_aacEnc_ElementBits(&hQCstate->elementBits[i]); } } @@ -1638,4 +1550,3 @@ void FDKaacEnc_QCClose (QC_STATE **phQCstate, QC_OUT **phQC) } } } - diff --git a/libAACenc/src/qc_main.h b/libAACenc/src/qc_main.h index 4e8c042..b9e8e2d 100644 --- a/libAACenc/src/qc_main.h +++ b/libAACenc/src/qc_main.h @@ -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,17 +90,18 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Werner - Initial author: M. Werner - contents/description: Quantizing & coding + Description: Quantizing & coding -******************************************************************************/ -#ifndef _QC_MAIN_H -#define _QC_MAIN_H +*******************************************************************************/ +#ifndef QC_MAIN_H +#define QC_MAIN_H #include "aacenc.h" #include "qc_data.h" @@ -99,72 +111,48 @@ amm-info@iis.fraunhofer.de /* Quantizing & coding stage */ -AAC_ENCODER_ERROR FDKaacEnc_QCOutNew(QC_OUT **phQC, - const INT nElements, - const INT nChannels, - const INT nSubFrames - ,UCHAR *dynamic_RAM - ); +AAC_ENCODER_ERROR FDKaacEnc_QCOutNew(QC_OUT **phQC, const INT nElements, + const INT nChannels, const INT nSubFrames, + UCHAR *dynamic_RAM); -AAC_ENCODER_ERROR FDKaacEnc_QCOutInit(QC_OUT *phQC[(1)], - const INT nSubFrames, +AAC_ENCODER_ERROR FDKaacEnc_QCOutInit(QC_OUT *phQC[(1)], const INT nSubFrames, const CHANNEL_MAPPING *cm); -AAC_ENCODER_ERROR FDKaacEnc_QCNew(QC_STATE **phQC, - INT nElements - ,UCHAR* dynamic_RAM - ); +AAC_ENCODER_ERROR FDKaacEnc_QCNew(QC_STATE **phQC, INT nElements, + UCHAR *dynamic_RAM); -AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC, struct QC_INIT *init); +AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC, struct QC_INIT *init, + const ULONG initFlags); AAC_ENCODER_ERROR FDKaacEnc_QCMainPrepare( - ELEMENT_INFO *elInfo, - ATS_ELEMENT* RESTRICT adjThrStateElement, - PSY_OUT_ELEMENT* RESTRICT psyOutElement, - QC_OUT_ELEMENT* RESTRICT qcOutElement, /* returns error code */ - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig - ); - - -AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC, - PSY_OUT** psyOut, - QC_OUT** qcOut, - INT avgTotalBits, - CHANNEL_MAPPING* cm - ,AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig - ); - -AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING* cm, - QC_STATE* qcKernel, - ELEMENT_BITS* RESTRICT elBits[(8)], - QC_OUT** qcOut); - - -void FDKaacEnc_updateBitres( CHANNEL_MAPPING *cm, - QC_STATE *qcKernel, - QC_OUT **qcOut); - -AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption( CHANNEL_MAPPING *cm, - QC_STATE *hQC, - QC_OUT *qcOut, - QC_OUT_ELEMENT** qcElement, - HANDLE_TRANSPORTENC hTpEnc, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig - ); + ELEMENT_INFO *elInfo, ATS_ELEMENT *RESTRICT adjThrStateElement, + PSY_OUT_ELEMENT *RESTRICT psyOutElement, + QC_OUT_ELEMENT *RESTRICT qcOutElement, /* returns error code */ + AUDIO_OBJECT_TYPE aot, UINT syntaxFlags, SCHAR epConfig); + +AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE *RESTRICT hQC, PSY_OUT **psyOut, + QC_OUT **qcOut, INT avgTotalBits, + CHANNEL_MAPPING *cm, AUDIO_OBJECT_TYPE aot, + UINT syntaxFlags, SCHAR epConfig); + +AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING *cm, + QC_STATE *qcKernel, + ELEMENT_BITS *RESTRICT elBits[((8))], + QC_OUT **qcOut); + +void FDKaacEnc_updateBitres(CHANNEL_MAPPING *cm, QC_STATE *qcKernel, + QC_OUT **qcOut); + +AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption( + CHANNEL_MAPPING *cm, QC_STATE *hQC, QC_OUT *qcOut, + QC_OUT_ELEMENT **qcElement, HANDLE_TRANSPORTENC hTpEnc, + AUDIO_OBJECT_TYPE aot, UINT syntaxFlags, SCHAR epConfig); AAC_ENCODER_ERROR FDKaacEnc_AdjustBitrate(QC_STATE *RESTRICT hQC, - CHANNEL_MAPPING *RESTRICT cm, - INT *avgTotalBits, - INT bitRate, - INT sampleRate, - INT granuleLength); + CHANNEL_MAPPING *RESTRICT cm, + INT *avgTotalBits, INT bitRate, + INT sampleRate, INT granuleLength); -void FDKaacEnc_QCClose (QC_STATE **phQCstate, QC_OUT **phQC); +void FDKaacEnc_QCClose(QC_STATE **phQCstate, QC_OUT **phQC); -#endif /* _QC_MAIN_H */ +#endif /* QC_MAIN_H */ diff --git a/libAACenc/src/quantize.cpp b/libAACenc/src/quantize.cpp index a74da0e..4d25263 100644 --- a/libAACenc/src/quantize.cpp +++ b/libAACenc/src/quantize.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Quantization + Description: Quantization -******************************************************************************/ +*******************************************************************************/ #include "quantize.h" @@ -101,60 +113,61 @@ amm-info@iis.fraunhofer.de output: quantized spectrum *****************************************************************************/ -static void FDKaacEnc_quantizeLines(INT gain, - INT noOfLines, - FIXP_DBL *mdctSpectrum, - SHORT *quaSpectrum, - INT dZoneQuantEnable) -{ - int line; +static void FDKaacEnc_quantizeLines(INT gain, INT noOfLines, + const FIXP_DBL *mdctSpectrum, + SHORT *quaSpectrum, INT dZoneQuantEnable) { + int line; FIXP_DBL k = FL2FXCONST_DBL(0.0f); - FIXP_QTD quantizer = FDKaacEnc_quantTableQ[(-gain)&3]; - INT quantizershift = ((-gain)>>2)+1; - const INT kShift=16; + FIXP_QTD quantizer = FDKaacEnc_quantTableQ[(-gain) & 3]; + INT quantizershift = ((-gain) >> 2) + 1; + const INT kShift = 16; if (dZoneQuantEnable) - k = FL2FXCONST_DBL(0.23f)>>kShift; + k = FL2FXCONST_DBL(0.23f) >> kShift; else - k = FL2FXCONST_DBL(-0.0946f + 0.5f)>>kShift; + k = FL2FXCONST_DBL(-0.0946f + 0.5f) >> kShift; - for (line = 0; line < noOfLines; line++) - { - FIXP_DBL accu = fMultDiv2(mdctSpectrum[line],quantizer); + for (line = 0; line < noOfLines; line++) { + FIXP_DBL accu = fMultDiv2(mdctSpectrum[line], quantizer); - if (accu < FL2FXCONST_DBL(0.0f)) - { - accu=-accu; + if (accu < FL2FXCONST_DBL(0.0f)) { + accu = -accu; /* normalize */ - INT accuShift = CntLeadingZeros(accu) - 1; /* CountLeadingBits() is not necessary here since test value is always > 0 */ + INT accuShift = CntLeadingZeros(accu) - 1; /* CountLeadingBits() is not + necessary here since test + value is always > 0 */ accu <<= accuShift; - INT tabIndex = (INT)(accu>>(DFRACT_BITS-2-MANT_DIGITS))&(~MANT_SIZE); - INT totalShift = quantizershift-accuShift+1; - accu = fMultDiv2(FDKaacEnc_mTab_3_4[tabIndex],FDKaacEnc_quantTableE[totalShift&3]); - totalShift = (16-4)-(3*(totalShift>>2)); - FDK_ASSERT(totalShift >=0); /* MAX_QUANT_VIOLATION */ - accu >>= fixMin(totalShift,DFRACT_BITS-1); - quaSpectrum[line] = (SHORT)(-((LONG)(k + accu) >> (DFRACT_BITS-1-16))); - } - else if(accu > FL2FXCONST_DBL(0.0f)) - { + INT tabIndex = + (INT)(accu >> (DFRACT_BITS - 2 - MANT_DIGITS)) & (~MANT_SIZE); + INT totalShift = quantizershift - accuShift + 1; + accu = fMultDiv2(FDKaacEnc_mTab_3_4[tabIndex], + FDKaacEnc_quantTableE[totalShift & 3]); + totalShift = (16 - 4) - (3 * (totalShift >> 2)); + FDK_ASSERT(totalShift >= 0); /* MAX_QUANT_VIOLATION */ + accu >>= fixMin(totalShift, DFRACT_BITS - 1); + quaSpectrum[line] = + (SHORT)(-((LONG)(k + accu) >> (DFRACT_BITS - 1 - 16))); + } else if (accu > FL2FXCONST_DBL(0.0f)) { /* normalize */ - INT accuShift = CntLeadingZeros(accu) - 1; /* CountLeadingBits() is not necessary here since test value is always > 0 */ + INT accuShift = CntLeadingZeros(accu) - 1; /* CountLeadingBits() is not + necessary here since test + value is always > 0 */ accu <<= accuShift; - INT tabIndex = (INT)(accu>>(DFRACT_BITS-2-MANT_DIGITS))&(~MANT_SIZE); - INT totalShift = quantizershift-accuShift+1; - accu = fMultDiv2(FDKaacEnc_mTab_3_4[tabIndex],FDKaacEnc_quantTableE[totalShift&3]); - totalShift = (16-4)-(3*(totalShift>>2)); - FDK_ASSERT(totalShift >=0); /* MAX_QUANT_VIOLATION */ - accu >>= fixMin(totalShift,DFRACT_BITS-1); - quaSpectrum[line] = (SHORT)((LONG)(k + accu) >> (DFRACT_BITS-1-16)); + INT tabIndex = + (INT)(accu >> (DFRACT_BITS - 2 - MANT_DIGITS)) & (~MANT_SIZE); + INT totalShift = quantizershift - accuShift + 1; + accu = fMultDiv2(FDKaacEnc_mTab_3_4[tabIndex], + FDKaacEnc_quantTableE[totalShift & 3]); + totalShift = (16 - 4) - (3 * (totalShift >> 2)); + FDK_ASSERT(totalShift >= 0); /* MAX_QUANT_VIOLATION */ + accu >>= fixMin(totalShift, DFRACT_BITS - 1); + quaSpectrum[line] = (SHORT)((LONG)(k + accu) >> (DFRACT_BITS - 1 - 16)); + } else { + quaSpectrum[line] = 0; } - else - quaSpectrum[line]=0; } } - /***************************************************************************** functionname:iFDKaacEnc_quantizeLines @@ -164,90 +177,90 @@ static void FDKaacEnc_quantizeLines(INT gain, output: spectral data *****************************************************************************/ -static void FDKaacEnc_invQuantizeLines(INT gain, - INT noOfLines, - SHORT *quantSpectrum, - FIXP_DBL *mdctSpectrum) +static void FDKaacEnc_invQuantizeLines(INT gain, INT noOfLines, + SHORT *quantSpectrum, + FIXP_DBL *mdctSpectrum) { INT iquantizermod; INT iquantizershift; INT line; - iquantizermod = gain&3; - iquantizershift = gain>>2; + iquantizermod = gain & 3; + iquantizershift = gain >> 2; for (line = 0; line < noOfLines; line++) { - - if(quantSpectrum[line] < 0) { + if (quantSpectrum[line] < 0) { FIXP_DBL accu; - INT ex,specExp,tabIndex; - FIXP_DBL s,t; + INT ex, specExp, tabIndex; + FIXP_DBL s, t; - accu = (FIXP_DBL) -quantSpectrum[line]; + accu = (FIXP_DBL)-quantSpectrum[line]; ex = CountLeadingBits(accu); accu <<= ex; - specExp = (DFRACT_BITS-1) - ex; + specExp = (DFRACT_BITS - 1) - ex; - FDK_ASSERT(specExp < 14); /* this fails if abs(value) > 8191 */ + FDK_ASSERT(specExp < 14); /* this fails if abs(value) > 8191 */ - tabIndex = (INT)(accu>>(DFRACT_BITS-2-MANT_DIGITS))&(~MANT_SIZE); + tabIndex = (INT)(accu >> (DFRACT_BITS - 2 - MANT_DIGITS)) & (~MANT_SIZE); /* calculate "mantissa" ^4/3 */ s = FDKaacEnc_mTab_4_3Elc[tabIndex]; - /* get approperiate exponent multiplier for specExp^3/4 combined with scfMod */ + /* get approperiate exponent multiplier for specExp^3/4 combined with + * scfMod */ t = FDKaacEnc_specExpMantTableCombElc[iquantizermod][specExp]; /* multiply "mantissa" ^4/3 with exponent multiplier */ - accu = fMult(s,t); + accu = fMult(s, t); /* get approperiate exponent shifter */ - specExp = FDKaacEnc_specExpTableComb[iquantizermod][specExp]-1; /* -1 to avoid overflows in accu */ + specExp = FDKaacEnc_specExpTableComb[iquantizermod][specExp] - + 1; /* -1 to avoid overflows in accu */ - if ((-iquantizershift-specExp) < 0) - accu <<= -(-iquantizershift-specExp); + if ((-iquantizershift - specExp) < 0) + accu <<= -(-iquantizershift - specExp); else - accu >>= -iquantizershift-specExp; + accu >>= -iquantizershift - specExp; mdctSpectrum[line] = -accu; - } - else if (quantSpectrum[line] > 0) { + } else if (quantSpectrum[line] > 0) { FIXP_DBL accu; - INT ex,specExp,tabIndex; - FIXP_DBL s,t; + INT ex, specExp, tabIndex; + FIXP_DBL s, t; accu = (FIXP_DBL)(INT)quantSpectrum[line]; ex = CountLeadingBits(accu); accu <<= ex; - specExp = (DFRACT_BITS-1) - ex; + specExp = (DFRACT_BITS - 1) - ex; - FDK_ASSERT(specExp < 14); /* this fails if abs(value) > 8191 */ + FDK_ASSERT(specExp < 14); /* this fails if abs(value) > 8191 */ - tabIndex = (INT)(accu>>(DFRACT_BITS-2-MANT_DIGITS))&(~MANT_SIZE); + tabIndex = (INT)(accu >> (DFRACT_BITS - 2 - MANT_DIGITS)) & (~MANT_SIZE); /* calculate "mantissa" ^4/3 */ s = FDKaacEnc_mTab_4_3Elc[tabIndex]; - /* get approperiate exponent multiplier for specExp^3/4 combined with scfMod */ + /* get approperiate exponent multiplier for specExp^3/4 combined with + * scfMod */ t = FDKaacEnc_specExpMantTableCombElc[iquantizermod][specExp]; /* multiply "mantissa" ^4/3 with exponent multiplier */ - accu = fMult(s,t); + accu = fMult(s, t); /* get approperiate exponent shifter */ - specExp = FDKaacEnc_specExpTableComb[iquantizermod][specExp]-1; /* -1 to avoid overflows in accu */ + specExp = FDKaacEnc_specExpTableComb[iquantizermod][specExp] - + 1; /* -1 to avoid overflows in accu */ - if (( -iquantizershift-specExp) < 0) - accu <<= -(-iquantizershift-specExp); + if ((-iquantizershift - specExp) < 0) + accu <<= -(-iquantizershift - specExp); else - accu >>= -iquantizershift-specExp; + accu >>= -iquantizershift - specExp; mdctSpectrum[line] = accu; - } - else { + } else { mdctSpectrum[line] = FL2FXCONST_DBL(0.0f); } } @@ -262,34 +275,29 @@ static void FDKaacEnc_invQuantizeLines(INT gain, output: quantized spectrum *****************************************************************************/ -void FDKaacEnc_QuantizeSpectrum(INT sfbCnt, - INT maxSfbPerGroup, - INT sfbPerGroup, - INT *sfbOffset, - FIXP_DBL *mdctSpectrum, - INT globalGain, - INT *scalefactors, - SHORT *quantizedSpectrum, - INT dZoneQuantEnable) -{ - INT sfbOffs,sfb; +void FDKaacEnc_QuantizeSpectrum(INT sfbCnt, INT maxSfbPerGroup, INT sfbPerGroup, + const INT *sfbOffset, + const FIXP_DBL *mdctSpectrum, INT globalGain, + const INT *scalefactors, + SHORT *quantizedSpectrum, + INT dZoneQuantEnable) { + INT sfbOffs, sfb; /* in FDKaacEnc_quantizeLines quaSpectrum is calculated with: spec^(3/4) * 2^(-3/16*QSS) * 2^(3/4*scale) + k simplify scaling calculation and reduce QSS before: spec^(3/4) * 2^(-3/16*(QSS - 4*scale)) */ - for(sfbOffs=0;sfbOffsMAX_QUANT) { + if (fAbs(quantSpectrum[i]) > MAX_QUANT) { return FL2FXCONST_DBL(0.0f); } /* inverse quantization */ - FDKaacEnc_invQuantizeLines(gain,1,&quantSpectrum[i],&invQuantSpec); + FDKaacEnc_invQuantizeLines(gain, 1, &quantSpectrum[i], &invQuantSpec); /* dist */ - diff = fixp_abs(fixp_abs(invQuantSpec) - fixp_abs(mdctSpectrum[i]>>1)); + diff = fixp_abs(fixp_abs(invQuantSpec) - fixp_abs(mdctSpectrum[i] >> 1)); scale = CountLeadingBits(diff); diff = scaleValue(diff, scale); diff = fPow2(diff); - scale = fixMin(2*(scale-1), DFRACT_BITS-1); + scale = fixMin(2 * (scale - 1), DFRACT_BITS - 1); diff = scaleValue(diff, -scale); @@ -358,48 +359,43 @@ FIXP_DBL FDKaacEnc_calcSfbDist(FIXP_DBL *mdctSpectrum, *****************************************************************************/ void FDKaacEnc_calcSfbQuantEnergyAndDist(FIXP_DBL *mdctSpectrum, - SHORT *quantSpectrum, - INT noOfLines, - INT gain, - FIXP_DBL *en, - FIXP_DBL *dist) -{ - INT i,scale; + SHORT *quantSpectrum, INT noOfLines, + INT gain, FIXP_DBL *en, + FIXP_DBL *dist) { + INT i, scale; FIXP_DBL invQuantSpec; FIXP_DBL diff; FIXP_DBL energy = FL2FXCONST_DBL(0.0f); FIXP_DBL distortion = FL2FXCONST_DBL(0.0f); - for (i=0; iMAX_QUANT) { - *en = FL2FXCONST_DBL(0.0f); + for (i = 0; i < noOfLines; i++) { + if (fAbs(quantSpectrum[i]) > MAX_QUANT) { + *en = FL2FXCONST_DBL(0.0f); *dist = FL2FXCONST_DBL(0.0f); return; } /* inverse quantization */ - FDKaacEnc_invQuantizeLines(gain,1,&quantSpectrum[i],&invQuantSpec); + FDKaacEnc_invQuantizeLines(gain, 1, &quantSpectrum[i], &invQuantSpec); /* energy */ energy += fPow2(invQuantSpec); /* dist */ - diff = fixp_abs(fixp_abs(invQuantSpec) - fixp_abs(mdctSpectrum[i]>>1)); + diff = fixp_abs(fixp_abs(invQuantSpec) - fixp_abs(mdctSpectrum[i] >> 1)); scale = CountLeadingBits(diff); diff = scaleValue(diff, scale); diff = fPow2(diff); - scale = fixMin(2*(scale-1), DFRACT_BITS-1); + scale = fixMin(2 * (scale - 1), DFRACT_BITS - 1); diff = scaleValue(diff, -scale); distortion += diff; } - *en = CalcLdData(energy)+FL2FXCONST_DBL(0.03125f); + *en = CalcLdData(energy) + FL2FXCONST_DBL(0.03125f); *dist = CalcLdData(distortion); } - diff --git a/libAACenc/src/quantize.h b/libAACenc/src/quantize.h index 16d3d4e..dfc2206 100644 --- a/libAACenc/src/quantize.h +++ b/libAACenc/src/quantize.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,17 +90,18 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Quantization + Description: Quantization -******************************************************************************/ +*******************************************************************************/ -#ifndef _QUANTIZE_H_ -#define _QUANTIZE_H_ +#ifndef QUANTIZE_H +#define QUANTIZE_H #include "common_fix.h" @@ -97,25 +109,19 @@ amm-info@iis.fraunhofer.de #define MAX_QUANT 8191 -void FDKaacEnc_QuantizeSpectrum(INT sfbCnt, - INT maxSfbPerGroup, - INT sfbPerGroup, - INT *sfbOffset, FIXP_DBL *mdctSpectrum, - INT globalGain, INT *scalefactors, - SHORT *quantizedSpectrum, - INT dZoneQuantEnable); +void FDKaacEnc_QuantizeSpectrum(INT sfbCnt, INT maxSfbPerGroup, INT sfbPerGroup, + const INT *sfbOffset, + const FIXP_DBL *mdctSpectrum, INT globalGain, + const INT *scalefactors, + SHORT *quantizedSpectrum, INT dZoneQuantEnable); -FIXP_DBL FDKaacEnc_calcSfbDist(FIXP_DBL *mdctSpectrum, - SHORT *quantSpectrum, - INT noOfLines, - INT gain, - INT dZoneQuantEnable); +FIXP_DBL FDKaacEnc_calcSfbDist(const FIXP_DBL *mdctSpectrum, + SHORT *quantSpectrum, INT noOfLines, INT gain, + INT dZoneQuantEnable); void FDKaacEnc_calcSfbQuantEnergyAndDist(FIXP_DBL *mdctSpectrum, - SHORT *quantSpectrum, - INT noOfLines, - INT gain, - FIXP_DBL *en, - FIXP_DBL *dist); + SHORT *quantSpectrum, INT noOfLines, + INT gain, FIXP_DBL *en, + FIXP_DBL *dist); -#endif /* _QUANTIZE_H_ */ +#endif /* QUANTIZE_H */ diff --git a/libAACenc/src/sf_estim.cpp b/libAACenc/src/sf_estim.cpp index 1cb243b..17a8ae2 100644 --- a/libAACenc/src/sf_estim.cpp +++ b/libAACenc/src/sf_estim.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,33 +90,35 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Werner - Initial author: M. Werner - contents/description: Scale factor estimation + Description: Scale factor estimation -******************************************************************************/ +*******************************************************************************/ #include "sf_estim.h" #include "aacEnc_rom.h" #include "quantize.h" #include "bit_cnt.h" +#ifdef __arm__ +#endif - - +#define UPCOUNT_LIMIT 1 #define AS_PE_FAC_SHIFT 7 -#define DIST_FAC_SHIFT 3 +#define DIST_FAC_SHIFT 3 #define AS_PE_FAC_FLOAT (float)(1 << AS_PE_FAC_SHIFT) static const INT MAX_SCF_DELTA = 60; - -static const FIXP_DBL PE_C1 = FL2FXCONST_DBL(3.0f/AS_PE_FAC_FLOAT); /* (log(8.0)/log(2)) >> AS_PE_FAC_SHIFT */ -static const FIXP_DBL PE_C2 = FL2FXCONST_DBL(1.3219281f/AS_PE_FAC_FLOAT); /* (log(2.5)/log(2)) >> AS_PE_FAC_SHIFT */ -static const FIXP_DBL PE_C3 = FL2FXCONST_DBL(0.5593573f); /* 1-C2/C1 */ - +static const FIXP_DBL PE_C1 = FL2FXCONST_DBL( + 3.0f / AS_PE_FAC_FLOAT); /* (log(8.0)/log(2)) >> AS_PE_FAC_SHIFT */ +static const FIXP_DBL PE_C2 = FL2FXCONST_DBL( + 1.3219281f / AS_PE_FAC_FLOAT); /* (log(2.5)/log(2)) >> AS_PE_FAC_SHIFT */ +static const FIXP_DBL PE_C3 = FL2FXCONST_DBL(0.5593573f); /* 1-C2/C1 */ /* Function; FDKaacEnc_FDKaacEnc_CalcFormFactorChannel @@ -113,30 +126,32 @@ static const FIXP_DBL PE_C3 = FL2FXCONST_DBL(0.5593573f); /* Description: Calculates the formfactor sf: scale factor of the mdct spectrum - sfbFormFactorLdData is scaled with the factor 1/(((2^sf)^0.5) * (2^FORM_FAC_SHIFT)) + sfbFormFactorLdData is scaled with the factor 1/(((2^sf)^0.5) * + (2^FORM_FAC_SHIFT)) */ -static void -FDKaacEnc_FDKaacEnc_CalcFormFactorChannel(FIXP_DBL *RESTRICT sfbFormFactorLdData, - PSY_OUT_CHANNEL *RESTRICT psyOutChan) -{ +static void FDKaacEnc_FDKaacEnc_CalcFormFactorChannel( + FIXP_DBL *RESTRICT sfbFormFactorLdData, + PSY_OUT_CHANNEL *RESTRICT psyOutChan) { INT j, sfb, sfbGrp; FIXP_DBL formFactor; int tmp0 = psyOutChan->sfbCnt; int tmp1 = psyOutChan->maxSfbPerGroup; int step = psyOutChan->sfbPerGroup; - for(sfbGrp = 0; sfbGrp < tmp0; sfbGrp += step) { + for (sfbGrp = 0; sfbGrp < tmp0; sfbGrp += step) { for (sfb = 0; sfb < tmp1; sfb++) { formFactor = FL2FXCONST_DBL(0.0f); /* calc sum of sqrt(spec) */ - for(j=psyOutChan->sfbOffsets[sfbGrp+sfb]; jsfbOffsets[sfbGrp+sfb+1]; j++ ) { - formFactor += sqrtFixp(fixp_abs(psyOutChan->mdctSpectrum[j]))>>FORM_FAC_SHIFT; + for (j = psyOutChan->sfbOffsets[sfbGrp + sfb]; + j < psyOutChan->sfbOffsets[sfbGrp + sfb + 1]; j++) { + formFactor += + sqrtFixp(fixp_abs(psyOutChan->mdctSpectrum[j])) >> FORM_FAC_SHIFT; } - sfbFormFactorLdData[sfbGrp+sfb] = CalcLdData(formFactor); + sfbFormFactorLdData[sfbGrp + sfb] = CalcLdData(formFactor); } /* set sfbFormFactor for sfbs with zero spec to zero. Just for debugging. */ - for ( ; sfb < psyOutChan->sfbPerGroup; sfb++) { - sfbFormFactorLdData[sfbGrp+sfb] = FL2FXCONST_DBL(-1.0f); + for (; sfb < psyOutChan->sfbPerGroup; sfb++) { + sfbFormFactorLdData[sfbGrp + sfb] = FL2FXCONST_DBL(-1.0f); } } } @@ -144,17 +159,17 @@ FDKaacEnc_FDKaacEnc_CalcFormFactorChannel(FIXP_DBL *RESTRICT sfbFormFactorLdData /* Function: FDKaacEnc_CalcFormFactor - Description: Calls FDKaacEnc_FDKaacEnc_CalcFormFactorChannel() for each channel + Description: Calls FDKaacEnc_FDKaacEnc_CalcFormFactorChannel() for each + channel */ -void -FDKaacEnc_CalcFormFactor(QC_OUT_CHANNEL *qcOutChannel[(2)], - PSY_OUT_CHANNEL *psyOutChannel[(2)], - const INT nChannels) -{ +void FDKaacEnc_CalcFormFactor(QC_OUT_CHANNEL *qcOutChannel[(2)], + PSY_OUT_CHANNEL *psyOutChannel[(2)], + const INT nChannels) { INT j; - for (j=0; jsfbFormFactorLdData, psyOutChannel[j]); + for (j = 0; j < nChannels; j++) { + FDKaacEnc_FDKaacEnc_CalcFormFactorChannel( + qcOutChannel[j]->sfbFormFactorLdData, psyOutChannel[j]); } } @@ -165,40 +180,44 @@ FDKaacEnc_CalcFormFactor(QC_OUT_CHANNEL *qcOutChannel[(2)], sfbNRelevantLines is scaled with the factor 1/((2^FORM_FAC_SHIFT) * 2.0) */ -static void -FDKaacEnc_calcSfbRelevantLines( const FIXP_DBL *const sfbFormFactorLdData, - const FIXP_DBL *const sfbEnergyLdData, - const FIXP_DBL *const sfbThresholdLdData, - const INT *const sfbOffsets, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup, - FIXP_DBL *sfbNRelevantLines) -{ +static void FDKaacEnc_calcSfbRelevantLines( + const FIXP_DBL *const sfbFormFactorLdData, + const FIXP_DBL *const sfbEnergyLdData, + const FIXP_DBL *const sfbThresholdLdData, const INT *const sfbOffsets, + const INT sfbCnt, const INT sfbPerGroup, const INT maxSfbPerGroup, + FIXP_DBL *sfbNRelevantLines) { INT sfbOffs, sfb; FIXP_DBL sfbWidthLdData; - FIXP_DBL asPeFacLdData = FL2FXCONST_DBL(0.109375); /* AS_PE_FAC_SHIFT*ld64(2) */ + FIXP_DBL asPeFacLdData = + FL2FXCONST_DBL(0.109375); /* AS_PE_FAC_SHIFT*ld64(2) */ FIXP_DBL accu; - /* sfbNRelevantLines[i] = 2^( (sfbFormFactorLdData[i] - 0.25 * (sfbEnergyLdData[i] - ld64(sfbWidth[i]/(2^7)) - AS_PE_FAC_SHIFT*ld64(2)) * 64); */ + /* sfbNRelevantLines[i] = 2^( (sfbFormFactorLdData[i] - 0.25 * + * (sfbEnergyLdData[i] - ld64(sfbWidth[i]/(2^7)) - AS_PE_FAC_SHIFT*ld64(2)) * + * 64); */ FDKmemclear(sfbNRelevantLines, sfbCnt * sizeof(FIXP_DBL)); - for (sfbOffs=0; sfbOffs (FIXP_DBL)sfbThresholdLdData[sfbOffs+sfb]) { - INT sfbWidth = sfbOffsets[sfbOffs+sfb+1] - sfbOffsets[sfbOffs+sfb]; - - /* avgFormFactorLdData = sqrtFixp(sqrtFixp(sfbEnergyLdData[sfbOffs+sfb]/sfbWidth)); */ - /* sfbNRelevantLines[sfbOffs+sfb] = sfbFormFactor[sfbOffs+sfb] / avgFormFactorLdData; */ - sfbWidthLdData = (FIXP_DBL)(sfbWidth << (DFRACT_BITS-1-AS_PE_FAC_SHIFT)); + if ((FIXP_DBL)sfbEnergyLdData[sfbOffs + sfb] > + (FIXP_DBL)sfbThresholdLdData[sfbOffs + sfb]) { + INT sfbWidth = + sfbOffsets[sfbOffs + sfb + 1] - sfbOffsets[sfbOffs + sfb]; + + /* avgFormFactorLdData = + * sqrtFixp(sqrtFixp(sfbEnergyLdData[sfbOffs+sfb]/sfbWidth)); */ + /* sfbNRelevantLines[sfbOffs+sfb] = sfbFormFactor[sfbOffs+sfb] / + * avgFormFactorLdData; */ + sfbWidthLdData = + (FIXP_DBL)(sfbWidth << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT)); sfbWidthLdData = CalcLdData(sfbWidthLdData); - accu = sfbEnergyLdData[sfbOffs+sfb] - sfbWidthLdData - asPeFacLdData; - accu = sfbFormFactorLdData[sfbOffs+sfb] - (accu >> 2); + accu = sfbEnergyLdData[sfbOffs + sfb] - sfbWidthLdData - asPeFacLdData; + accu = sfbFormFactorLdData[sfbOffs + sfb] - (accu >> 2); - sfbNRelevantLines[sfbOffs+sfb] = CalcInvLdData(accu) >> 1; + sfbNRelevantLines[sfbOffs + sfb] = CalcInvLdData(accu) >> 1; } } } @@ -211,14 +230,14 @@ FDKaacEnc_calcSfbRelevantLines( const FIXP_DBL *const sfbFormFactorLdData, scfBitsFract is scaled by 1/(2^(2*AS_PE_FAC_SHIFT)) */ -static FIXP_DBL FDKaacEnc_countSingleScfBits(INT scf, INT scfLeft, INT scfRight) -{ +static FIXP_DBL FDKaacEnc_countSingleScfBits(INT scf, INT scfLeft, + INT scfRight) { FIXP_DBL scfBitsFract; - scfBitsFract = (FIXP_DBL) ( FDKaacEnc_bitCountScalefactorDelta(scfLeft-scf) - + FDKaacEnc_bitCountScalefactorDelta(scf-scfRight) ); + scfBitsFract = (FIXP_DBL)(FDKaacEnc_bitCountScalefactorDelta(scfLeft - scf) + + FDKaacEnc_bitCountScalefactorDelta(scf - scfRight)); - scfBitsFract = scfBitsFract << (DFRACT_BITS-1-(2*AS_PE_FAC_SHIFT)); + scfBitsFract = scfBitsFract << (DFRACT_BITS - 1 - (2 * AS_PE_FAC_SHIFT)); return scfBitsFract; /* output scaled by 1/(2^(2*AS_PE_FAC)) */ } @@ -228,21 +247,21 @@ static FIXP_DBL FDKaacEnc_countSingleScfBits(INT scf, INT scfLeft, INT scfRight) specPe is scaled by 1/(2^(2*AS_PE_FAC_SHIFT)) */ -static FIXP_DBL FDKaacEnc_calcSingleSpecPe(INT scf, FIXP_DBL sfbConstPePart, FIXP_DBL nLines) -{ +static FIXP_DBL FDKaacEnc_calcSingleSpecPe(INT scf, FIXP_DBL sfbConstPePart, + FIXP_DBL nLines) { FIXP_DBL specPe = FL2FXCONST_DBL(0.0f); FIXP_DBL ldRatio; FIXP_DBL scfFract; - scfFract = (FIXP_DBL)(scf << (DFRACT_BITS-1-AS_PE_FAC_SHIFT)); + scfFract = (FIXP_DBL)(scf << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT)); - ldRatio = sfbConstPePart - fMult(FL2FXCONST_DBL(0.375f),scfFract); + ldRatio = sfbConstPePart - fMult(FL2FXCONST_DBL(0.375f), scfFract); if (ldRatio >= PE_C1) { - specPe = fMult(FL2FXCONST_DBL(0.7f),fMult(nLines,ldRatio)); - } - else { - specPe = fMult(FL2FXCONST_DBL(0.7f),fMult(nLines,(PE_C2 + fMult(PE_C3,ldRatio)))); + specPe = fMult(FL2FXCONST_DBL(0.7f), fMult(nLines, ldRatio)); + } else { + specPe = fMult(FL2FXCONST_DBL(0.7f), + fMult(nLines, (PE_C2 + fMult(PE_C3, ldRatio)))); } return specPe; /* output scaled by 1/(2^(2*AS_PE_FAC)) */ @@ -253,12 +272,8 @@ static FIXP_DBL FDKaacEnc_calcSingleSpecPe(INT scf, FIXP_DBL sfbConstPePart, FIX scfBitsDiff is scaled by 1/(2^(2*AS_PE_FAC_SHIFT)) */ -static FIXP_DBL FDKaacEnc_countScfBitsDiff(INT *scfOld, - INT *scfNew, - INT sfbCnt, - INT startSfb, - INT stopSfb) -{ +static FIXP_DBL FDKaacEnc_countScfBitsDiff(INT *scfOld, INT *scfNew, INT sfbCnt, + INT startSfb, INT stopSfb) { FIXP_DBL scfBitsFract; INT scfBitsDiff = 0; INT sfb = 0, sfbLast; @@ -266,32 +281,33 @@ static FIXP_DBL FDKaacEnc_countScfBitsDiff(INT *scfOld, /* search for first relevant sfb */ sfbLast = startSfb; - while ((sfbLast=0) && (scfOld[sfbPrev]==FDK_INT_MIN)) - sfbPrev--; - if (sfbPrev>=0) - scfBitsDiff += FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbPrev]-scfNew[sfbLast]) - - FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbPrev]-scfOld[sfbLast]); + while ((sfbPrev >= 0) && (scfOld[sfbPrev] == FDK_INT_MIN)) sfbPrev--; + if (sfbPrev >= 0) + scfBitsDiff += + FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbPrev] - scfNew[sfbLast]) - + FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbPrev] - scfOld[sfbLast]); /* now loop through all sfbs and count diffs of relevant sfbs */ - for (sfb=sfbLast+1; sfbsfbEnergy[sfb] * 6.75f / sfbFormFactor[sfb]) * LOG2_1; */ - /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for log2 */ + /* sfbConstPePart[sfb] = (float)log(psyOutChan->sfbEnergy[sfb] * 6.75f / + * sfbFormFactor[sfb]) * LOG2_1; */ + /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for + * log2 */ /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */ if (sfbConstPePart[sfb] == (FIXP_DBL)FDK_INT_MIN) - sfbConstPePart[sfb] = ((psyOutChan->sfbEnergyLdData[sfb] - sfbFormFactorLdData[sfb] - FL2FXCONST_DBL(0.09375f)) >> 1) + FL2FXCONST_DBL(0.02152255861f); + sfbConstPePart[sfb] = + ((psyOutChan->sfbEnergyLdData[sfb] - sfbFormFactorLdData[sfb] - + FL2FXCONST_DBL(0.09375f)) >> + 1) + + FL2FXCONST_DBL(0.02152255861f); - scfFract = (FIXP_DBL) (scfOld[sfb] << (DFRACT_BITS-1-AS_PE_FAC_SHIFT)); - ldRatioOld = sfbConstPePart[sfb] - fMult(FL2FXCONST_DBL(0.375f),scfFract); + scfFract = (FIXP_DBL)(scfOld[sfb] << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT)); + ldRatioOld = + sfbConstPePart[sfb] - fMult(FL2FXCONST_DBL(0.375f), scfFract); - scfFract = (FIXP_DBL) (scfNew[sfb] << (DFRACT_BITS-1-AS_PE_FAC_SHIFT)); - ldRatioNew = sfbConstPePart[sfb] - fMult(FL2FXCONST_DBL(0.375f),scfFract); + scfFract = (FIXP_DBL)(scfNew[sfb] << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT)); + ldRatioNew = + sfbConstPePart[sfb] - fMult(FL2FXCONST_DBL(0.375f), scfFract); if (ldRatioOld >= PE_C1) pOld = ldRatioOld; else - pOld = PE_C2 + fMult(PE_C3,ldRatioOld); + pOld = PE_C2 + fMult(PE_C3, ldRatioOld); if (ldRatioNew >= PE_C1) pNew = ldRatioNew; else - pNew = PE_C2 + fMult(PE_C3,ldRatioNew); + pNew = PE_C2 + fMult(PE_C3, ldRatioNew); - specPeDiff += fMult(FL2FXCONST_DBL(0.7f),fMult(sfbNRelevantLines[sfb],(pNew - pOld))); + specPeDiff += fMult(FL2FXCONST_DBL(0.7f), + fMult(sfbNRelevantLines[sfb], (pNew - pOld))); } } @@ -352,123 +371,96 @@ static FIXP_DBL FDKaacEnc_calcSpecPeDiff(PSY_OUT_CHANNEL *psyOutChan, /* Function: FDKaacEnc_improveScf - Description: Calculate the distortion by quantization and inverse quantization of the spectrum with - various scalefactors. The scalefactor which provides the best results will be used. + Description: Calculate the distortion by quantization and inverse quantization + of the spectrum with various scalefactors. The scalefactor which provides the + best results will be used. */ -static INT FDKaacEnc_improveScf(FIXP_DBL *spec, - SHORT *quantSpec, - SHORT *quantSpecTmp, - INT sfbWidth, - FIXP_DBL threshLdData, - INT scf, - INT minScf, - FIXP_DBL *distLdData, - INT *minScfCalculated, - INT dZoneQuantEnable - ) -{ - FIXP_DBL sfbDistLdData; - INT scfBest = scf; - INT k; - FIXP_DBL distFactorLdData = FL2FXCONST_DBL(-0.0050301265); /* ld64(1/1.25) */ - - /* calc real distortion */ - sfbDistLdData = FDKaacEnc_calcSfbDist(spec, - quantSpec, - sfbWidth, - scf, - dZoneQuantEnable); - *minScfCalculated = scf; - /* nmr > 1.25 -> try to improve nmr */ - if (sfbDistLdData > (threshLdData-distFactorLdData)) { - INT scfEstimated = scf; - FIXP_DBL sfbDistBestLdData = sfbDistLdData; - INT cnt; - /* improve by bigger scf ? */ - cnt = 0; - - while ((sfbDistLdData > (threshLdData-distFactorLdData)) && (cnt++ < 3)) { - scf++; - sfbDistLdData = FDKaacEnc_calcSfbDist(spec, - quantSpecTmp, - sfbWidth, - scf, - dZoneQuantEnable); - - if (sfbDistLdData < sfbDistBestLdData) { - scfBest = scf; - sfbDistBestLdData = sfbDistLdData; - for (k=0; k 1.25 -> try to improve nmr */ + if (sfbDistLdData > (threshLdData - distFactorLdData)) { + INT scfEstimated = scf; + FIXP_DBL sfbDistBestLdData = sfbDistLdData; + INT cnt; + /* improve by bigger scf ? */ + cnt = 0; + + while ((sfbDistLdData > (threshLdData - distFactorLdData)) && + (cnt++ < UPCOUNT_LIMIT)) { + scf++; + sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf, + dZoneQuantEnable); + + if (sfbDistLdData < sfbDistBestLdData) { + scfBest = scf; + sfbDistBestLdData = sfbDistLdData; + for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k]; } - /* improve by smaller scf ? */ - cnt = 0; - scf = scfEstimated; - sfbDistLdData = sfbDistBestLdData; - while ((sfbDistLdData > (threshLdData-distFactorLdData)) && (cnt++ < 1) && (scf > minScf)) { - scf--; - sfbDistLdData = FDKaacEnc_calcSfbDist(spec, - quantSpecTmp, - sfbWidth, - scf, - dZoneQuantEnable); - - if (sfbDistLdData < sfbDistBestLdData) { - scfBest = scf; - sfbDistBestLdData = sfbDistLdData; - for (k=0; k (threshLdData - distFactorLdData)) && (cnt++ < 1) && + (scf > minScf)) { + scf--; + sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf, + dZoneQuantEnable); + + if (sfbDistLdData < sfbDistBestLdData) { + scfBest = scf; + sfbDistBestLdData = sfbDistLdData; + for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k]; } - *distLdData = sfbDistBestLdData; - } - else { /* nmr <= 1.25 -> try to find bigger scf to use less bits */ - FIXP_DBL sfbDistBestLdData = sfbDistLdData; - FIXP_DBL sfbDistAllowedLdData = fixMin(sfbDistLdData-distFactorLdData,threshLdData); - int cnt; - for (cnt=0; cnt<3; cnt++) { - scf++; - sfbDistLdData = FDKaacEnc_calcSfbDist(spec, - quantSpecTmp, - sfbWidth, - scf, - dZoneQuantEnable); - - if (sfbDistLdData < sfbDistAllowedLdData) { - *minScfCalculated = scfBest+1; - scfBest = scf; - sfbDistBestLdData = sfbDistLdData; - for (k=0; k try to find bigger scf to use less bits */ + FIXP_DBL sfbDistBestLdData = sfbDistLdData; + FIXP_DBL sfbDistAllowedLdData = + fixMin(sfbDistLdData - distFactorLdData, threshLdData); + int cnt; + for (cnt = 0; cnt < UPCOUNT_LIMIT; cnt++) { + scf++; + sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf, + dZoneQuantEnable); + + if (sfbDistLdData < sfbDistAllowedLdData) { + *minScfCalculated = scfBest + 1; + scfBest = scf; + sfbDistBestLdData = sfbDistLdData; + for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k]; } - *distLdData = sfbDistBestLdData; - } + } + *distLdData = sfbDistBestLdData; + } - /* return best scalefactor */ - return scfBest; + /* return best scalefactor */ + return scfBest; } /* Function: FDKaacEnc_assimilateSingleScf */ -static void FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan, - QC_OUT_CHANNEL *qcOutChannel, - SHORT *quantSpec, - SHORT *quantSpecTmp, - INT dZoneQuantEnable, - INT *scf, - INT *minScf, - FIXP_DBL *sfbDist, - FIXP_DBL *sfbConstPePart, - FIXP_DBL *sfbFormFactorLdData, - FIXP_DBL *sfbNRelevantLines, - INT *minScfCalculated, - INT restartOnSuccess) -{ +static void FDKaacEnc_assimilateSingleScf( + const PSY_OUT_CHANNEL *psyOutChan, const QC_OUT_CHANNEL *qcOutChannel, + SHORT *quantSpec, SHORT *quantSpecTmp, INT dZoneQuantEnable, INT *scf, + const INT *minScf, FIXP_DBL *sfbDist, FIXP_DBL *sfbConstPePart, + const FIXP_DBL *sfbFormFactorLdData, const FIXP_DBL *sfbNRelevantLines, + INT *minScfCalculated, INT restartOnSuccess) { INT sfbLast, sfbAct, sfbNext; INT scfAct, *scfLast, *scfNext, scfMin, scfMax; INT sfbWidth, sfbOffs; @@ -483,77 +475,82 @@ static void FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan, FIXP_DBL deltaPeLast[MAX_GROUPED_SFB]; INT updateMinScfCalculated; - for (i=0; isfbCnt; i++) { + for (i = 0; i < psyOutChan->sfbCnt; i++) { prevScfLast[i] = FDK_INT_MAX; prevScfNext[i] = FDK_INT_MAX; deltaPeLast[i] = (FIXP_DBL)FDK_INT_MAX; } sfbLast = -1; - sfbAct = -1; + sfbAct = -1; sfbNext = -1; scfLast = 0; scfNext = 0; - scfMin = FDK_INT_MAX; - scfMax = FDK_INT_MAX; + scfMin = FDK_INT_MAX; + scfMax = FDK_INT_MAX; do { /* search for new relevant sfb */ sfbNext++; while ((sfbNext < psyOutChan->sfbCnt) && (scf[sfbNext] == FDK_INT_MIN)) sfbNext++; - if ((sfbLast>=0) && (sfbAct>=0) && (sfbNextsfbCnt)) { + if ((sfbLast >= 0) && (sfbAct >= 0) && (sfbNext < psyOutChan->sfbCnt)) { /* relevant scfs to the left and to the right */ - scfAct = scf[sfbAct]; + scfAct = scf[sfbAct]; scfLast = scf + sfbLast; scfNext = scf + sfbNext; - scfMin = fixMin(*scfLast, *scfNext); - scfMax = fixMax(*scfLast, *scfNext); - } - else if ((sfbLast==-1) && (sfbAct>=0) && (sfbNextsfbCnt)) { + scfMin = fixMin(*scfLast, *scfNext); + scfMax = fixMax(*scfLast, *scfNext); + } else if ((sfbLast == -1) && (sfbAct >= 0) && + (sfbNext < psyOutChan->sfbCnt)) { /* first relevant scf */ - scfAct = scf[sfbAct]; + scfAct = scf[sfbAct]; scfLast = &scfAct; scfNext = scf + sfbNext; - scfMin = *scfNext; - scfMax = *scfNext; - } - else if ((sfbLast>=0) && (sfbAct>=0) && (sfbNext==psyOutChan->sfbCnt)) { + scfMin = *scfNext; + scfMax = *scfNext; + } else if ((sfbLast >= 0) && (sfbAct >= 0) && + (sfbNext == psyOutChan->sfbCnt)) { /* last relevant scf */ - scfAct = scf[sfbAct]; + scfAct = scf[sfbAct]; scfLast = scf + sfbLast; scfNext = &scfAct; - scfMin = *scfLast; - scfMax = *scfLast; + scfMin = *scfLast; + scfMax = *scfLast; } - if (sfbAct>=0) - scfMin = fixMax(scfMin, minScf[sfbAct]); - - if ((sfbAct >= 0) && - (sfbLast>=0 || sfbNextsfbCnt) && - (scfAct > scfMin) && - (scfAct <= scfMin+MAX_SCF_DELTA) && - (scfAct >= scfMax-MAX_SCF_DELTA) && - (*scfLast != prevScfLast[sfbAct] || - *scfNext != prevScfNext[sfbAct] || + if (sfbAct >= 0) scfMin = fixMax(scfMin, minScf[sfbAct]); + + if ((sfbAct >= 0) && (sfbLast >= 0 || sfbNext < psyOutChan->sfbCnt) && + (scfAct > scfMin) && (scfAct <= scfMin + MAX_SCF_DELTA) && + (scfAct >= scfMax - MAX_SCF_DELTA) && + (scfAct <= + fixMin(scfMin, fixMin(*scfLast, *scfNext)) + MAX_SCF_DELTA) && + (*scfLast != prevScfLast[sfbAct] || *scfNext != prevScfNext[sfbAct] || deltaPe < deltaPeLast[sfbAct])) { /* bigger than neighbouring scf found, try to use smaller scf */ success = 0; - sfbWidth = psyOutChan->sfbOffsets[sfbAct+1] - psyOutChan->sfbOffsets[sfbAct]; + sfbWidth = + psyOutChan->sfbOffsets[sfbAct + 1] - psyOutChan->sfbOffsets[sfbAct]; sfbOffs = psyOutChan->sfbOffsets[sfbAct]; /* estimate required bits for actual scf */ enLdData = qcOutChannel->sfbEnergyLdData[sfbAct]; - /* sfbConstPePart[sfbAct] = (float)log(6.75f*en/sfbFormFactor[sfbAct]) * LOG2_1; */ - /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for log2 */ + /* sfbConstPePart[sfbAct] = (float)log(6.75f*en/sfbFormFactor[sfbAct]) * + * LOG2_1; */ + /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for + * log2 */ /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */ if (sfbConstPePart[sfbAct] == (FIXP_DBL)FDK_INT_MIN) { - sfbConstPePart[sfbAct] = ((enLdData - sfbFormFactorLdData[sfbAct] - FL2FXCONST_DBL(0.09375f)) >> 1) + FL2FXCONST_DBL(0.02152255861f); + sfbConstPePart[sfbAct] = ((enLdData - sfbFormFactorLdData[sfbAct] - + FL2FXCONST_DBL(0.09375f)) >> + 1) + + FL2FXCONST_DBL(0.02152255861f); } - sfbPeOld = FDKaacEnc_calcSingleSpecPe(scfAct,sfbConstPePart[sfbAct],sfbNRelevantLines[sfbAct]) - +FDKaacEnc_countSingleScfBits(scfAct, *scfLast, *scfNext); + sfbPeOld = FDKaacEnc_calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct], + sfbNRelevantLines[sfbAct]) + + FDKaacEnc_countSingleScfBits(scfAct, *scfLast, *scfNext); deltaPeNew = deltaPe; updateMinScfCalculated = 1; @@ -562,10 +559,12 @@ static void FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan, /* estimate required bits for smaller scf */ scfAct--; /* check only if the same check was not done before */ - if (scfAct < minScfCalculated[sfbAct] && scfAct>=scfMax-MAX_SCF_DELTA){ + if (scfAct < minScfCalculated[sfbAct] && + scfAct >= scfMax - MAX_SCF_DELTA) { /* estimate required bits for new scf */ - sfbPeNew = FDKaacEnc_calcSingleSpecPe(scfAct,sfbConstPePart[sfbAct],sfbNRelevantLines[sfbAct]) - +FDKaacEnc_countSingleScfBits(scfAct,*scfLast, *scfNext); + sfbPeNew = FDKaacEnc_calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct], + sfbNRelevantLines[sfbAct]) + + FDKaacEnc_countSingleScfBits(scfAct, *scfLast, *scfNext); /* use new scf if no increase in pe and quantization error is smaller */ @@ -573,28 +572,24 @@ static void FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan, /* 0.0006103515625f = 10.0f/(2^(2*AS_PE_FAC_SHIFT)) */ if (deltaPeTmp < FL2FXCONST_DBL(0.0006103515625f)) { /* distortion of new scf */ - sfbDistNew = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs, - quantSpecTmp+sfbOffs, - sfbWidth, - scfAct, - dZoneQuantEnable); + sfbDistNew = FDKaacEnc_calcSfbDist( + qcOutChannel->mdctSpectrum + sfbOffs, quantSpecTmp + sfbOffs, + sfbWidth, scfAct, dZoneQuantEnable); if (sfbDistNew < sfbDist[sfbAct]) { /* success, replace scf by new one */ scf[sfbAct] = scfAct; sfbDist[sfbAct] = sfbDistNew; - for (k=0; ksfbCnt); } @@ -632,18 +626,11 @@ static void FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan, Function: FDKaacEnc_assimilateMultipleScf */ -static void FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan, - QC_OUT_CHANNEL *qcOutChannel, - SHORT *quantSpec, - SHORT *quantSpecTmp, - INT dZoneQuantEnable, - INT *scf, - INT *minScf, - FIXP_DBL *sfbDist, - FIXP_DBL *sfbConstPePart, - FIXP_DBL *sfbFormFactorLdData, - FIXP_DBL *sfbNRelevantLines) -{ +static void FDKaacEnc_assimilateMultipleScf( + PSY_OUT_CHANNEL *psyOutChan, QC_OUT_CHANNEL *qcOutChannel, SHORT *quantSpec, + SHORT *quantSpecTmp, INT dZoneQuantEnable, INT *scf, const INT *minScf, + FIXP_DBL *sfbDist, FIXP_DBL *sfbConstPePart, FIXP_DBL *sfbFormFactorLdData, + FIXP_DBL *sfbNRelevantLines) { INT sfb, startSfb, stopSfb; INT scfTmp[MAX_GROUPED_SFB], scfMin, scfMax, scfAct; INT possibleRegionFound; @@ -658,31 +645,29 @@ static void FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan, /* calc min and max scalfactors */ scfMin = FDK_INT_MAX; scfMax = FDK_INT_MIN; - for (sfb=0; sfb scfAct)) + while (sfb < sfbCnt && (scf[sfb] == FDK_INT_MIN || scf[sfb] > scfAct)) sfb++; stopSfb = sfb; @@ -690,7 +675,7 @@ static void FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan, possibleRegionFound = 0; if (startSfb < sfbCnt) { possibleRegionFound = 1; - for (sfb=startSfb; sfb> DIST_FAC_SHIFT; - sfbWidth = psyOutChan->sfbOffsets[sfb+1] - psyOutChan->sfbOffsets[sfb]; + sfbWidth = psyOutChan->sfbOffsets[sfb + 1] - + psyOutChan->sfbOffsets[sfb]; sfbOffs = psyOutChan->sfbOffsets[sfb]; - sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs, - quantSpecTmp+sfbOffs, - sfbWidth, - scfAct, - dZoneQuantEnable); + sfbDistNew[sfb] = FDKaacEnc_calcSfbDist( + qcOutChannel->mdctSpectrum + sfbOffs, + quantSpecTmp + sfbOffs, sfbWidth, scfAct, dZoneQuantEnable); - if (sfbDistNew[sfb] >qcOutChannel->sfbThresholdLdData[sfb]) { + if (sfbDistNew[sfb] > qcOutChannel->sfbThresholdLdData[sfb]) { /* no improvement, skip further dist. calculations */ distNewSum = distOldSum << 1; break; @@ -746,20 +729,19 @@ static void FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan, /* distortion smaller ? -> use new scalefactors */ if (distNewSum < distOldSum) { deltaPe = deltaPeNew; - for (sfb=startSfb; sfbsfbOffsets[sfb+1] - + sfbWidth = psyOutChan->sfbOffsets[sfb + 1] - psyOutChan->sfbOffsets[sfb]; sfbOffs = psyOutChan->sfbOffsets[sfb]; scf[sfb] = scfAct; sfbDist[sfb] = sfbDistNew[sfb]; - for (k=0; ksfbCnt; INT bSuccess, bCheckScf; - INT i,k; + INT i, k; /* calc min and max scalfactors */ scfMin = FDK_INT_MAX; scfMax = FDK_INT_MIN; - for (sfb=0; sfb scf[startSfb]) { /* calculate the allowed distortion */ - for (sfb=startSfb; sfbsfbThreshold[sfb]*sfbDist[sfb]*sfbDist[sfb],1.0f/3.0f); */ - /* sfbDistMax[sfb] = fixMax(sfbDistMax[sfb],qcOutChannel->sfbEnergy[sfb]*FL2FXCONST_DBL(1.e-3f)); */ + /* sfbDistMax[sfb] = + * (float)pow(qcOutChannel->sfbThreshold[sfb]*sfbDist[sfb]*sfbDist[sfb],1.0f/3.0f); + */ + /* sfbDistMax[sfb] = + * fixMax(sfbDistMax[sfb],qcOutChannel->sfbEnergy[sfb]*FL2FXCONST_DBL(1.e-3f)); + */ /* -0.15571537944 = ld64(1.e-3f)*/ - sfbDistMax[sfb] = fMult(FL2FXCONST_DBL(1.0f/3.0f),qcOutChannel->sfbThresholdLdData[sfb])+fMult(FL2FXCONST_DBL(1.0f/3.0f),sfbDist[sfb])+fMult(FL2FXCONST_DBL(1.0f/3.0f),sfbDist[sfb]); - sfbDistMax[sfb] = fixMax(sfbDistMax[sfb],qcOutChannel->sfbEnergyLdData[sfb]-FL2FXCONST_DBL(0.15571537944)); - sfbDistMax[sfb] = fixMin(sfbDistMax[sfb],qcOutChannel->sfbThresholdLdData[sfb]); + sfbDistMax[sfb] = fMult(FL2FXCONST_DBL(1.0f / 3.0f), + qcOutChannel->sfbThresholdLdData[sfb]) + + fMult(FL2FXCONST_DBL(1.0f / 3.0f), sfbDist[sfb]) + + fMult(FL2FXCONST_DBL(1.0f / 3.0f), sfbDist[sfb]); + sfbDistMax[sfb] = + fixMax(sfbDistMax[sfb], qcOutChannel->sfbEnergyLdData[sfb] - + FL2FXCONST_DBL(0.15571537944)); + sfbDistMax[sfb] = + fixMin(sfbDistMax[sfb], qcOutChannel->sfbThresholdLdData[sfb]); } } /* loop over all possible scf values for this region */ bCheckScf = 1; - for (scfNew=scf[startSfb]+1; scfNew<=scfHi; scfNew++) { - for (k=0; kmdctSpectrum+sfbOffs[sfb], - quantSpecTmp+sfbOffs[sfb], - sfbOffs[sfb+1]-sfbOffs[sfb], - scfNew, - dZoneQuantEnable); + sfbDistNew[sfb] = FDKaacEnc_calcSfbDist( + qcOutChannel->mdctSpectrum + sfbOffs[sfb], + quantSpecTmp + sfbOffs[sfb], + sfbOffs[sfb + 1] - sfbOffs[sfb], scfNew, dZoneQuantEnable); if (sfbDistNew[sfb] > sfbDistMax[sfb]) { /* no improvement, skip further dist. calculations */ @@ -908,18 +891,19 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh } } } - if (bCheckScf==0) /* further calculations useless ? */ - break; + if (bCheckScf == 0) /* further calculations useless ? */ + break; /* distortion small enough ? -> use new scalefactors */ if (bSuccess) { deltaPe = deltaPeNew; - for (sfb=startSfb; sfb= minScf[sfb] */ - for (sfb=startSfb; sfb> DIST_FAC_SHIFT; - sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs[sfb], - quantSpecTmp+sfbOffs[sfb], - sfbOffs[sfb+1]-sfbOffs[sfb], - scfNew, - dZoneQuantEnable); + sfbDistNew[sfb] = FDKaacEnc_calcSfbDist( + qcOutChannel->mdctSpectrum + sfbOffs[sfb], + quantSpecTmp + sfbOffs[sfb], sfbOffs[sfb + 1] - sfbOffs[sfb], + scfNew, dZoneQuantEnable); if (sfbDistNew[sfb] > qcOutChannel->sfbThresholdLdData[sfb]) { /* no improvement, skip further dist. calculations */ @@ -986,15 +965,15 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh } } /* distortion smaller ? -> use new scalefactors */ - if (distNewSum < fMult(FL2FXCONST_DBL(0.8f),distOldSum)) { + if (distNewSum < fMult(FL2FXCONST_DBL(0.8f), distOldSum)) { deltaPe = deltaPeNew; - for (sfb=startSfb; sfbmdctSpectrum+sfbOffs[sfb], - quantSpec+sfbOffs[sfb], - sfbOffs[sfb+1]-sfbOffs[sfb], scfNew, - &sfbEnQ, &sfbDistNew[sfb]); + FDKaacEnc_calcSfbQuantEnergyAndDist( + qcOutChannel->mdctSpectrum + sfbOffs[sfb], + quantSpec + sfbOffs[sfb], sfbOffs[sfb + 1] - sfbOffs[sfb], + scfNew, &sfbEnQ, &sfbDistNew[sfb]); distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT; distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT; /* 0.00259488556167 = ld64(1.122f) */ /* -0.00778722686652 = ld64(0.7079f) */ - if ((sfbDistNew[sfb] > (sfbDist[sfb]+FL2FXCONST_DBL(0.00259488556167f))) || (sfbEnQ < (qcOutChannel->sfbEnergyLdData[sfb] - FL2FXCONST_DBL(0.00778722686652f)))){ + if ((sfbDistNew[sfb] > + (sfbDist[sfb] + FL2FXCONST_DBL(0.00259488556167f))) || + (sfbEnQ < (qcOutChannel->sfbEnergyLdData[sfb] - + FL2FXCONST_DBL(0.00778722686652f)))) { bSuccess = 0; break; } @@ -1048,7 +1029,7 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh /* distortion smaller ? -> use new scalefactors */ if (distNewSum < distOldSum && bSuccess) { deltaPe = deltaPeNew; - for (sfb=startSfb; sfb C1/2^8 */ - + FIXP_DBL threshConstLdData = + FL2FXCONST_DBL(0.04304511722f); /* log10(6.75)/log10(2.0)/64.0 */ + FIXP_DBL convConst = FL2FXCONST_DBL(0.30102999566f); /* log10(2.0) */ + FIXP_DBL c1Const = + FL2FXCONST_DBL(-0.27083183594f); /* C1 = -69.33295 => C1/2^8 */ - - if (invQuant>0) { - FDKmemclear(quantSpec, (1024)*sizeof(SHORT)); + if (invQuant > 0) { + FDKmemclear(quantSpec, (1024) * sizeof(SHORT)); } /* scfs without energy or with thresh>energy are marked with FDK_INT_MIN */ - for(i=0; isfbCnt; i++) { + for (i = 0; i < psyOutChannel->sfbCnt; i++) { scf[i] = FDK_INT_MIN; } - for (i=0; isfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) { - for(sfb=0; sfbmaxSfbPerGroup; sfb++) { - - threshLdData = qcOutChannel->sfbThresholdLdData[sfbOffs+sfb]; - energyLdData = qcOutChannel->sfbEnergyLdData[sfbOffs+sfb]; - - sfbDistLdData[sfbOffs+sfb] = energyLdData; + for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt; + sfbOffs += psyOutChannel->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { + threshLdData = qcOutChannel->sfbThresholdLdData[sfbOffs + sfb]; + energyLdData = qcOutChannel->sfbEnergyLdData[sfbOffs + sfb]; + sfbDistLdData[sfbOffs + sfb] = energyLdData; if (energyLdData > threshLdData) { FIXP_DBL tmp; /* energyPart = (float)log10(sfbFormFactor[sfbOffs+sfb]); */ /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */ - energyPartLdData = sfbFormFactorLdData[sfbOffs+sfb] + FL2FXCONST_DBL(0.09375f); + energyPartLdData = + sfbFormFactorLdData[sfbOffs + sfb] + FL2FXCONST_DBL(0.09375f); /* influence of allowed distortion */ /* thresholdPart = (float)log10(6.75*thresh+FLT_MIN); */ @@ -1133,165 +1106,166 @@ FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL *qcOutChannel, /* scfFloat = 8.8585f * (thresholdPart - energyPart); */ scfFract = thresholdPartLdData - energyPartLdData; /* conversion from log2 to log10 */ - scfFract = fMult(convConst,scfFract); + scfFract = fMult(convConst, scfFract); /* (8.8585f * scfFract)/8 = 8/8 * scfFract + 0.8585 * scfFract/8 */ - scfFract = scfFract + fMult(FL2FXCONST_DBL(0.8585f),scfFract >> 3); + scfFract = scfFract + fMult(FL2FXCONST_DBL(0.8585f), scfFract >> 3); /* integer scalefactor */ /* scfInt = (int)floor(scfFloat); */ - scfInt = (INT)(scfFract>>((DFRACT_BITS-1)-3-LD_DATA_SHIFT)); /* 3 bits => scfFract/8.0; 6 bits => ld64 */ + scfInt = + (INT)(scfFract >> + ((DFRACT_BITS - 1) - 3 - + LD_DATA_SHIFT)); /* 3 bits => scfFract/8.0; 6 bits => ld64 */ /* maximum of spectrum */ maxSpec = FL2FXCONST_DBL(0.0f); - for(j=psyOutChannel->sfbOffsets[sfbOffs+sfb]; jsfbOffsets[sfbOffs+sfb+1]; j++ ){ - absSpec = fixp_abs(qcOutChannel->mdctSpectrum[j]); - maxSpec = (absSpec > maxSpec) ? absSpec : maxSpec; + /* Unroll by 4, allow dual memory access */ + DWORD_ALIGNED(qcOutChannel->mdctSpectrum); + for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb]; + j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j += 4) { + maxSpec = fMax(maxSpec, + fMax(fMax(fAbs(qcOutChannel->mdctSpectrum[j + 0]), + fAbs(qcOutChannel->mdctSpectrum[j + 1])), + fMax(fAbs(qcOutChannel->mdctSpectrum[j + 2]), + fAbs(qcOutChannel->mdctSpectrum[j + 3])))); } - /* lower scf limit to avoid quantized values bigger than MAX_QUANT */ /* C1 = -69.33295f, C2 = 5.77078f = 4/log(2) */ /* minSfMaxQuant[sfbOffs+sfb] = (int)ceil(C1 + C2*log(maxSpec)); */ - /* C1/2^8 + 4/log(2.0)*log(maxSpec)/2^8 => C1/2^8 + log(maxSpec)/log(2.0)*4/2^8 => C1/2^8 + log(maxSpec)/log(2.0)/64.0 */ + /* C1/2^8 + 4/log(2.0)*log(maxSpec)/2^8 => C1/2^8 + + * log(maxSpec)/log(2.0)*4/2^8 => C1/2^8 + log(maxSpec)/log(2.0)/64.0 */ - //minSfMaxQuant[sfbOffs+sfb] = ((INT) ((c1Const + CalcLdData(maxSpec)) >> ((DFRACT_BITS-1)-8))) + 1; + // minSfMaxQuant[sfbOffs+sfb] = ((INT) ((c1Const + CalcLdData(maxSpec)) + // >> ((DFRACT_BITS-1)-8))) + 1; tmp = CalcLdData(maxSpec); - if (c1Const>FL2FXCONST_DBL(-1.f)-tmp) { - minSfMaxQuant[sfbOffs+sfb] = ((INT) ((c1Const + tmp) >> ((DFRACT_BITS-1)-8))) + 1; + if (c1Const > FL2FXCONST_DBL(-1.f) - tmp) { + minSfMaxQuant[sfbOffs + sfb] = + ((INT)((c1Const + tmp) >> ((DFRACT_BITS - 1) - 8))) + 1; + } else { + minSfMaxQuant[sfbOffs + sfb] = + ((INT)(FL2FXCONST_DBL(-1.f) >> ((DFRACT_BITS - 1) - 8))) + 1; } - else { - minSfMaxQuant[sfbOffs+sfb] = ((INT) (FL2FXCONST_DBL(-1.f) >> ((DFRACT_BITS-1)-8))) + 1; - } - - scfInt = fixMax(scfInt, minSfMaxQuant[sfbOffs+sfb]); + scfInt = fixMax(scfInt, minSfMaxQuant[sfbOffs + sfb]); /* find better scalefactor with analysis by synthesis */ - if (invQuant>0) { - scfInt = FDKaacEnc_improveScf(qcOutChannel->mdctSpectrum+psyOutChannel->sfbOffsets[sfbOffs+sfb], - quantSpec+psyOutChannel->sfbOffsets[sfbOffs+sfb], - quantSpecTmp+psyOutChannel->sfbOffsets[sfbOffs+sfb], - psyOutChannel->sfbOffsets[sfbOffs+sfb+1]-psyOutChannel->sfbOffsets[sfbOffs+sfb], - threshLdData, scfInt, minSfMaxQuant[sfbOffs+sfb], - &sfbDistLdData[sfbOffs+sfb], &minScfCalculated[sfbOffs+sfb], - dZoneQuantEnable - ); + if (invQuant > 0) { + scfInt = FDKaacEnc_improveScf( + qcOutChannel->mdctSpectrum + + psyOutChannel->sfbOffsets[sfbOffs + sfb], + quantSpec + psyOutChannel->sfbOffsets[sfbOffs + sfb], + quantSpecTmp + psyOutChannel->sfbOffsets[sfbOffs + sfb], + psyOutChannel->sfbOffsets[sfbOffs + sfb + 1] - + psyOutChannel->sfbOffsets[sfbOffs + sfb], + threshLdData, scfInt, minSfMaxQuant[sfbOffs + sfb], + &sfbDistLdData[sfbOffs + sfb], &minScfCalculated[sfbOffs + sfb], + dZoneQuantEnable); } - scf[sfbOffs+sfb] = scfInt; + scf[sfbOffs + sfb] = scfInt; } } } - - if (invQuant>1) { + if (invQuant > 0) { /* try to decrease scf differences */ FIXP_DBL sfbConstPePart[MAX_GROUPED_SFB]; FIXP_DBL sfbNRelevantLines[MAX_GROUPED_SFB]; - for (i=0; isfbCnt; i++) + for (i = 0; i < psyOutChannel->sfbCnt; i++) sfbConstPePart[i] = (FIXP_DBL)FDK_INT_MIN; - FDKaacEnc_calcSfbRelevantLines( sfbFormFactorLdData, - qcOutChannel->sfbEnergyLdData, - qcOutChannel->sfbThresholdLdData, - psyOutChannel->sfbOffsets, - psyOutChannel->sfbCnt, - psyOutChannel->sfbPerGroup, - psyOutChannel->maxSfbPerGroup, - sfbNRelevantLines); - - - FDKaacEnc_assimilateSingleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, - dZoneQuantEnable, - scf, - minSfMaxQuant, sfbDistLdData, sfbConstPePart, - sfbFormFactorLdData, sfbNRelevantLines, minScfCalculated, 1); - - if(invQuant > 1) { - FDKaacEnc_assimilateMultipleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, - dZoneQuantEnable, - scf, - minSfMaxQuant, sfbDistLdData, sfbConstPePart, - sfbFormFactorLdData, sfbNRelevantLines); - - FDKaacEnc_assimilateMultipleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, - dZoneQuantEnable, - scf, - minSfMaxQuant, sfbDistLdData, sfbConstPePart, - sfbFormFactorLdData, sfbNRelevantLines); - - - FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, - dZoneQuantEnable, - scf, - minSfMaxQuant, sfbDistLdData, sfbConstPePart, - sfbFormFactorLdData, sfbNRelevantLines); + FDKaacEnc_calcSfbRelevantLines( + sfbFormFactorLdData, qcOutChannel->sfbEnergyLdData, + qcOutChannel->sfbThresholdLdData, psyOutChannel->sfbOffsets, + psyOutChannel->sfbCnt, psyOutChannel->sfbPerGroup, + psyOutChannel->maxSfbPerGroup, sfbNRelevantLines); + + FDKaacEnc_assimilateSingleScf( + psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, dZoneQuantEnable, + scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart, sfbFormFactorLdData, + sfbNRelevantLines, minScfCalculated, 1); + + if (invQuant > 1) { + FDKaacEnc_assimilateMultipleScf( + psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, + dZoneQuantEnable, scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart, + sfbFormFactorLdData, sfbNRelevantLines); + + FDKaacEnc_FDKaacEnc_assimilateMultipleScf2( + psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, + dZoneQuantEnable, scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart, + sfbFormFactorLdData, sfbNRelevantLines); } } - /* get min scalefac */ minSf = FDK_INT_MAX; - for (sfbOffs=0; sfbOffssfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) { + for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt; + sfbOffs += psyOutChannel->sfbPerGroup) { for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { - if (scf[sfbOffs+sfb]!=FDK_INT_MIN) - minSf = fixMin(minSf,scf[sfbOffs+sfb]); + if (scf[sfbOffs + sfb] != FDK_INT_MIN) + minSf = fixMin(minSf, scf[sfbOffs + sfb]); } } /* limit scf delta */ - for (sfbOffs=0; sfbOffssfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) { + for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt; + sfbOffs += psyOutChannel->sfbPerGroup) { for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { - if ((scf[sfbOffs+sfb] != FDK_INT_MIN) && (minSf+MAX_SCF_DELTA) < scf[sfbOffs+sfb]) { - scf[sfbOffs+sfb] = minSf + MAX_SCF_DELTA; + if ((scf[sfbOffs + sfb] != FDK_INT_MIN) && + (minSf + MAX_SCF_DELTA) < scf[sfbOffs + sfb]) { + scf[sfbOffs + sfb] = minSf + MAX_SCF_DELTA; if (invQuant > 0) { /* changed bands need to be quantized again */ - sfbDistLdData[sfbOffs+sfb] = - FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+psyOutChannel->sfbOffsets[sfbOffs+sfb], - quantSpec+psyOutChannel->sfbOffsets[sfbOffs+sfb], - psyOutChannel->sfbOffsets[sfbOffs+sfb+1]-psyOutChannel->sfbOffsets[sfbOffs+sfb], - scf[sfbOffs+sfb], - dZoneQuantEnable - ); + sfbDistLdData[sfbOffs + sfb] = FDKaacEnc_calcSfbDist( + qcOutChannel->mdctSpectrum + + psyOutChannel->sfbOffsets[sfbOffs + sfb], + quantSpec + psyOutChannel->sfbOffsets[sfbOffs + sfb], + psyOutChannel->sfbOffsets[sfbOffs + sfb + 1] - + psyOutChannel->sfbOffsets[sfbOffs + sfb], + scf[sfbOffs + sfb], dZoneQuantEnable); } } } } - /* get max scalefac for global gain */ maxSf = FDK_INT_MIN; - for (sfbOffs=0; sfbOffssfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) { + for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt; + sfbOffs += psyOutChannel->sfbPerGroup) { for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { - maxSf = fixMax(maxSf,scf[sfbOffs+sfb]); + maxSf = fixMax(maxSf, scf[sfbOffs + sfb]); } } /* calc loop scalefactors, if spec is not all zero (i.e. maxSf == -99) */ - if( maxSf > FDK_INT_MIN ) { + if (maxSf > FDK_INT_MIN) { *globalGain = maxSf; - for (sfbOffs=0; sfbOffssfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) { + for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt; + sfbOffs += psyOutChannel->sfbPerGroup) { for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { - if( scf[sfbOffs+sfb] == FDK_INT_MIN ) { - scf[sfbOffs+sfb] = 0; + if (scf[sfbOffs + sfb] == FDK_INT_MIN) { + scf[sfbOffs + sfb] = 0; /* set band explicitely to zero */ - for(j=psyOutChannel->sfbOffsets[sfbOffs+sfb]; jsfbOffsets[sfbOffs+sfb+1]; j++ ) { + for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb]; + j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j++) { qcOutChannel->mdctSpectrum[j] = FL2FXCONST_DBL(0.0f); } - } - else { - scf[sfbOffs+sfb] = maxSf - scf[sfbOffs+sfb]; + } else { + scf[sfbOffs + sfb] = maxSf - scf[sfbOffs + sfb]; } } } - } - else{ + } else { *globalGain = 0; /* set spectrum explicitely to zero */ - for (sfbOffs=0; sfbOffssfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) { + for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt; + sfbOffs += psyOutChannel->sfbPerGroup) { for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { - scf[sfbOffs+sfb] = 0; + scf[sfbOffs + sfb] = 0; /* set band explicitely to zero */ - for(j=psyOutChannel->sfbOffsets[sfbOffs+sfb]; jsfbOffsets[sfbOffs+sfb+1]; j++ ) { + for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb]; + j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j++) { qcOutChannel->mdctSpectrum[j] = FL2FXCONST_DBL(0.0f); } } @@ -1299,32 +1273,20 @@ FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL *qcOutChannel, } /* free quantSpecTmp from scratch */ - C_ALLOC_SCRATCH_END(quantSpecTmp, SHORT, (1024)); - - + C_ALLOC_SCRATCH_END(quantSpecTmp, SHORT, (1024)) } -void -FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[], - QC_OUT_CHANNEL* qcOutChannel[], - const int invQuant, - const INT dZoneQuantEnable, - const int nChannels) -{ +void FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[], + QC_OUT_CHANNEL *qcOutChannel[], + const INT invQuant, + const INT dZoneQuantEnable, + const INT nChannels) { int ch; - for (ch = 0; ch < nChannels; ch++) - { - FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(qcOutChannel[ch], - psyOutChannel[ch], - qcOutChannel[ch]->scf, - &qcOutChannel[ch]->globalGain, - qcOutChannel[ch]->sfbFormFactorLdData - ,invQuant, - qcOutChannel[ch]->quantSpec, - dZoneQuantEnable - ); + for (ch = 0; ch < nChannels; ch++) { + FDKaacEnc_EstimateScaleFactorsChannel( + qcOutChannel[ch], psyOutChannel[ch], qcOutChannel[ch]->scf, + &qcOutChannel[ch]->globalGain, qcOutChannel[ch]->sfbFormFactorLdData, + invQuant, qcOutChannel[ch]->quantSpec, dZoneQuantEnable); } - } - diff --git a/libAACenc/src/sf_estim.h b/libAACenc/src/sf_estim.h index ef8d366..ab2d3c2 100644 --- a/libAACenc/src/sf_estim.h +++ b/libAACenc/src/sf_estim.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,40 +90,35 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M. Werner - contents/description: Scale factor estimation + Author(s): M. Werner -******************************************************************************/ + Description: Scale factor estimation -#ifndef _SF_ESTIM_H -#define _SF_ESTIM_H +*******************************************************************************/ -#include "common_fix.h" +#ifndef SF_ESTIM_H +#define SF_ESTIM_H +#include "common_fix.h" #include "psy_const.h" #include "qc_data.h" #include "interface.h" -#define FORM_FAC_SHIFT 6 - - -void -FDKaacEnc_CalcFormFactor(QC_OUT_CHANNEL *qcOutChannel[(2)], - PSY_OUT_CHANNEL *psyOutChannel[(2)], - const INT nChannels); - -void -FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[], - QC_OUT_CHANNEL* qcOutChannel[], - const int invQuant, - const INT dZoneQuantEnable, - const int nChannels); +#define FORM_FAC_SHIFT 6 +void FDKaacEnc_CalcFormFactor(QC_OUT_CHANNEL *qcOutChannel[(2)], + PSY_OUT_CHANNEL *psyOutChannel[(2)], + const INT nChannels); +void FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[], + QC_OUT_CHANNEL *qcOutChannel[], + const INT invQuant, + const INT dZoneQuantEnable, + const INT nChannels); #endif diff --git a/libAACenc/src/spreading.cpp b/libAACenc/src/spreading.cpp index 852da1e..0fb43bb 100644 --- a/libAACenc/src/spreading.cpp +++ b/libAACenc/src/spreading.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,36 +90,36 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Spreading of energy + Description: Spreading of energy -******************************************************************************/ +*******************************************************************************/ #include "spreading.h" -void FDKaacEnc_SpreadingMax(const INT pbCnt, - const FIXP_DBL *RESTRICT maskLowFactor, - const FIXP_DBL *RESTRICT maskHighFactor, - FIXP_DBL *RESTRICT pbSpreadEnergy) -{ - int i; - FIXP_DBL delay; - - /* slope to higher frequencies */ - delay = pbSpreadEnergy[0]; - for (i=1; i=0; i--) { - delay = fixMax(pbSpreadEnergy[i], fMult(maskLowFactor[i],delay)); - pbSpreadEnergy[i] = delay; - } +void FDKaacEnc_SpreadingMax(const INT pbCnt, + const FIXP_DBL *RESTRICT maskLowFactor, + const FIXP_DBL *RESTRICT maskHighFactor, + FIXP_DBL *RESTRICT pbSpreadEnergy) { + int i; + FIXP_DBL delay; + + /* slope to higher frequencies */ + delay = pbSpreadEnergy[0]; + for (i = 1; i < pbCnt; i++) { + delay = fixMax(pbSpreadEnergy[i], fMult(maskHighFactor[i], delay)); + pbSpreadEnergy[i] = delay; + } + + /* slope to lower frequencies */ + delay = pbSpreadEnergy[pbCnt - 1]; + for (i = pbCnt - 2; i >= 0; i--) { + delay = fixMax(pbSpreadEnergy[i], fMult(maskLowFactor[i], delay)); + pbSpreadEnergy[i] = delay; + } } diff --git a/libAACenc/src/spreading.h b/libAACenc/src/spreading.h index e1b506c..e693031 100644 --- a/libAACenc/src/spreading.h +++ b/libAACenc/src/spreading.h @@ -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,24 +90,24 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M.Werner - contents/description: Spreading of energy and weighted tonality + Author(s): M.Werner -******************************************************************************/ + Description: Spreading of energy and weighted tonality -#ifndef _SPREADING_H -#define _SPREADING_H +*******************************************************************************/ -#include "common_fix.h" +#ifndef SPREADING_H +#define SPREADING_H +#include "common_fix.h" -void FDKaacEnc_SpreadingMax(const INT pbCnt, - const FIXP_DBL *RESTRICT maskLowFactor, - const FIXP_DBL *RESTRICT maskHighFactor, - FIXP_DBL *RESTRICT pbSpreadEnergy); +void FDKaacEnc_SpreadingMax(const INT pbCnt, + const FIXP_DBL *RESTRICT maskLowFactor, + const FIXP_DBL *RESTRICT maskHighFactor, + FIXP_DBL *RESTRICT pbSpreadEnergy); -#endif /* #ifndef _SPREADING_H */ +#endif /* #ifndef SPREADING_H */ diff --git a/libAACenc/src/tns_func.h b/libAACenc/src/tns_func.h index 5e5265d..6099bc7 100644 --- a/libAACenc/src/tns_func.h +++ b/libAACenc/src/tns_func.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,67 +90,40 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): Alex Goeschel - Initial author: Alex Goeschel - contents/description: Temporal noise shaping + Description: Temporal noise shaping -******************************************************************************/ +*******************************************************************************/ -#ifndef _TNS_FUNC_H -#define _TNS_FUNC_H +#ifndef TNS_FUNC_H +#define TNS_FUNC_H #include "common_fix.h" #include "psy_configuration.h" -AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitrate, - INT samplerate, - INT channels, - INT blocktype, - INT granuleLength, - INT isLowDelay, - INT ldSbrPresent, - TNS_CONFIG *tnsConfig, - PSY_CONFIGURATION *psyConfig, - INT active, - INT useTnsPeak ); - -INT FDKaacEnc_TnsDetect( - TNS_DATA *tnsData, - const TNS_CONFIG *tC, - TNS_INFO* tnsInfo, - INT sfbCnt, - FIXP_DBL *spectrum, - INT subBlockNumber, - INT blockType - ); - - - -void FDKaacEnc_TnsSync( - TNS_DATA *tnsDataDest, - const TNS_DATA *tnsDataSrc, - TNS_INFO *tnsInfoDest, - TNS_INFO *tnsInfoSrc, - const INT blockTypeDest, - const INT blockTypeSrc, - const TNS_CONFIG *tC - ); - -INT FDKaacEnc_TnsEncode( - TNS_INFO* tnsInfo, - TNS_DATA* tnsData, - const INT numOfSfb, - const TNS_CONFIG *tC, - const INT lowPassLine, - FIXP_DBL* spectrum, - const INT subBlockNumber, - const INT blockType - ); - - - -#endif /* _TNS_FUNC_H */ +AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration( + INT bitrate, INT samplerate, INT channels, INT blocktype, INT granuleLength, + INT isLowDelay, INT ldSbrPresent, TNS_CONFIG *tnsConfig, + PSY_CONFIGURATION *psyConfig, INT active, INT useTnsPeak); + +INT FDKaacEnc_TnsDetect(TNS_DATA *tnsData, const TNS_CONFIG *tC, + TNS_INFO *tnsInfo, INT sfbCnt, const FIXP_DBL *spectrum, + INT subBlockNumber, INT blockType); + +void FDKaacEnc_TnsSync(TNS_DATA *tnsDataDest, const TNS_DATA *tnsDataSrc, + TNS_INFO *tnsInfoDest, TNS_INFO *tnsInfoSrc, + const INT blockTypeDest, const INT blockTypeSrc, + const TNS_CONFIG *tC); + +INT FDKaacEnc_TnsEncode(TNS_INFO *tnsInfo, TNS_DATA *tnsData, + const INT numOfSfb, const TNS_CONFIG *tC, + const INT lowPassLine, FIXP_DBL *spectrum, + const INT subBlockNumber, const INT blockType); + +#endif /* TNS_FUNC_H */ diff --git a/libAACenc/src/tonality.cpp b/libAACenc/src/tonality.cpp index 7246a34..334e0f1 100644 --- a/libAACenc/src/tonality.cpp +++ b/libAACenc/src/tonality.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,74 +90,77 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Werner - author: M. Werner - contents/description: Convert chaos measure to the tonality index + Description: Convert chaos measure to the tonality index -******************************************************************************/ +*******************************************************************************/ #include "tonality.h" + #include "chaosmeasure.h" -static const FIXP_DBL normlog = (FIXP_DBL)0xd977d949; /*FL2FXCONST_DBL(-0.4342944819f * FDKlog(2.0)/FDKlog(2.7182818)); */ - -static void FDKaacEnc_CalcSfbTonality(FIXP_DBL *RESTRICT spectrum, - INT *RESTRICT sfbMaxScaleSpec, - FIXP_DBL *RESTRICT chaosMeasure, - FIXP_SGL *RESTRICT sfbTonality, - INT sfbCnt, - const INT *RESTRICT sfbOffset, - FIXP_DBL *RESTRICT sfbEnergyLD64 ); - - -void FDKaacEnc_CalculateFullTonality(FIXP_DBL *RESTRICT spectrum, - INT *RESTRICT sfbMaxScaleSpec, - FIXP_DBL *RESTRICT sfbEnergyLD64, - FIXP_SGL *RESTRICT sfbTonality, - INT sfbCnt, - const INT *sfbOffset, - INT usePns) -{ - INT j; -#if defined(ARCH_PREFER_MULT_32x16) - FIXP_SGL alpha_0 = FL2FXCONST_SGL(0.25f); /* used in smooth ChaosMeasure */ - FIXP_SGL alpha_1 = FL2FXCONST_SGL(1.0f-0.25f); /* used in smooth ChaosMeasure */ -#else - FIXP_DBL alpha_0 = FL2FXCONST_DBL(0.25f); /* used in smooth ChaosMeasure */ - FIXP_DBL alpha_1 = FL2FXCONST_DBL(1.0f-0.25f); /* used in smooth ChaosMeasure */ +#if defined(__arm__) #endif + +static const FIXP_DBL normlog = + (FIXP_DBL)0xd977d949; /*FL2FXCONST_DBL(-0.4342944819f * + FDKlog(2.0)/FDKlog(2.7182818)); */ + +static void FDKaacEnc_CalcSfbTonality(FIXP_DBL *RESTRICT spectrum, + INT *RESTRICT sfbMaxScaleSpec, + FIXP_DBL *RESTRICT chaosMeasure, + FIXP_SGL *RESTRICT sfbTonality, + INT sfbCnt, const INT *RESTRICT sfbOffset, + FIXP_DBL *RESTRICT sfbEnergyLD64); + +void FDKaacEnc_CalculateFullTonality(FIXP_DBL *RESTRICT spectrum, + INT *RESTRICT sfbMaxScaleSpec, + FIXP_DBL *RESTRICT sfbEnergyLD64, + FIXP_SGL *RESTRICT sfbTonality, INT sfbCnt, + const INT *sfbOffset, INT usePns) { + INT j; INT numberOfLines = sfbOffset[sfbCnt]; - if (!usePns) - return; + if (usePns) { + C_ALLOC_SCRATCH_START(chaosMeasurePerLine, FIXP_DBL, (1024)) + + /* calculate chaos measure */ + FDKaacEnc_CalculateChaosMeasure(spectrum, numberOfLines, + chaosMeasurePerLine); + + /* smooth ChaosMeasure */ + FIXP_DBL left = chaosMeasurePerLine[0]; + FIXP_DBL right; + for (j = 1; j < (numberOfLines - 1); j += 2) { + right = chaosMeasurePerLine[j]; + right = right - (right >> 2); + left = right + (left >> 2); + chaosMeasurePerLine[j] = left; /* 0.25 left + 0.75 right */ + + right = chaosMeasurePerLine[j + 1]; + right = right - (right >> 2); + left = right + (left >> 2); + chaosMeasurePerLine[j + 1] = left; + } + if (j == (numberOfLines - 1)) { + right = chaosMeasurePerLine[j]; + right = right - (right >> 2); + left = right + (left >> 2); + chaosMeasurePerLine[j] = left; + } - C_ALLOC_SCRATCH_START(chaosMeasurePerLine, FIXP_DBL, (1024)); - /* calculate chaos measure */ - FDKaacEnc_CalculateChaosMeasure(spectrum, - numberOfLines, - chaosMeasurePerLine); + FDKaacEnc_CalcSfbTonality(spectrum, sfbMaxScaleSpec, chaosMeasurePerLine, + sfbTonality, sfbCnt, sfbOffset, sfbEnergyLD64); - /* smooth ChaosMeasure */ - for (j=1;j 7/2 = 4 (spc*spc) */ - - FIXP_DBL chaosMeasureSfb = FL2FXCONST_DBL(0.0); - - /* calc chaosMeasurePerSfb */ - for (j=(sfbOffset[i+1]-sfbOffset[i])-1; j>=0; j--) { - FIXP_DBL tmp = (*spectrum++)< 7/2 = 4 (spc*spc) */ + + INT j; + FIXP_DBL chaosMeasureSfb = FL2FXCONST_DBL(0.0); + + /* calc chaosMeasurePerSfb */ + for (j = (sfbOffset[i + 1] - sfbOffset[i]) - 1; j >= 0; j--) { + FIXP_DBL tmp = (*spectrum++) << shiftBits; + FIXP_DBL lineNrg = fMultDiv2(tmp, tmp); + chaosMeasureSfb = fMultAddDiv2(chaosMeasureSfb, lineNrg, *chaosMeasure++); + } + + /* calc tonalityPerSfb */ + if (chaosMeasureSfb != FL2FXCONST_DBL(0.0)) { + /* add ld(convtone)/64 and 2/64 bec.fMultDiv2 */ + chaosMeasureSfbLD64 = CalcLdData((chaosMeasureSfb)) - sfbEnergyLD64[i]; + chaosMeasureSfbLD64 += FL2FXCONST_DBL(3.0f / 64) - + ((FIXP_DBL)(shiftBits) << (DFRACT_BITS - 6)); + + if (chaosMeasureSfbLD64 > + FL2FXCONST_DBL(-0.0519051)) /* > ld(0.05)+ld(2) */ { - /* add ld(convtone)/64 and 2/64 bec.fMultDiv2 */ - chaosMeasureSfbLD64 = CalcLdData((chaosMeasureSfb)) - sfbEnergyLD64[i]; - chaosMeasureSfbLD64 += FL2FXCONST_DBL(3.0f/64) - ((FIXP_DBL)(shiftBits)<<(DFRACT_BITS-6)); - - if (chaosMeasureSfbLD64 > FL2FXCONST_DBL(-0.0519051) ) /* > ld(0.05)+ld(2) */ - { - if (chaosMeasureSfbLD64 <= FL2FXCONST_DBL(0.0) ) - sfbTonality[i] = FX_DBL2FX_SGL(fMultDiv2( chaosMeasureSfbLD64 , normlog ) << 7); - else - sfbTonality[i] = FL2FXCONST_SGL(0.0); - } + if (chaosMeasureSfbLD64 <= FL2FXCONST_DBL(0.0)) + sfbTonality[i] = + FX_DBL2FX_SGL(fMultDiv2(chaosMeasureSfbLD64, normlog) << 7); else - sfbTonality[i] = (FIXP_SGL)MAXVAL_SGL; - } - else + sfbTonality[i] = FL2FXCONST_SGL(0.0); + } else sfbTonality[i] = (FIXP_SGL)MAXVAL_SGL; - } + } else + sfbTonality[i] = (FIXP_SGL)MAXVAL_SGL; + } } diff --git a/libAACenc/src/tonality.h b/libAACenc/src/tonality.h index fbe78ee..c5cf4c5 100644 --- a/libAACenc/src/tonality.h +++ b/libAACenc/src/tonality.h @@ -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,30 +90,26 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ - -/******************************** MPEG Audio Encoder ************************** +----------------------------------------------------------------------------- */ - author: M. Lohwasser - contents/description: Calculate tonality index +/**************************** AAC encoder library ****************************** -******************************************************************************/ + Author(s): M. Lohwasser -#ifndef __TONALITY_H -#define __TONALITY_H + Description: Calculate tonality index -#include "common_fix.h" +*******************************************************************************/ +#ifndef TONALITY_H +#define TONALITY_H +#include "common_fix.h" #include "chaosmeasure.h" +void FDKaacEnc_CalculateFullTonality(FIXP_DBL *RESTRICT spectrum, + INT *RESTRICT sfbMaxScaleSpec, + FIXP_DBL *RESTRICT sfbEnergyLD64, + FIXP_SGL *RESTRICT sfbTonality, INT sfbCnt, + const INT *sfbOffset, INT usePns); -void FDKaacEnc_CalculateFullTonality( FIXP_DBL *RESTRICT spectrum, - INT *RESTRICT sfbMaxScaleSpec, - FIXP_DBL *RESTRICT sfbEnergyLD64, - FIXP_SGL *RESTRICT sfbTonality, - INT sfbCnt, - const INT *sfbOffset, - INT usePns); - -#endif +#endif /* TONALITY_H */ diff --git a/libAACenc/src/transform.cpp b/libAACenc/src/transform.cpp index 690b82e..08b1c2f 100644 --- a/libAACenc/src/transform.cpp +++ b/libAACenc/src/transform.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,9 +90,11 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/***************************************************************************** + Author(s): Tobias Chalupka Description: FDKaacLdEnc_MdctTransform480: The module FDKaacLdEnc_MdctTransform will perform the MDCT. @@ -90,175 +103,192 @@ amm-info@iis.fraunhofer.de can be divided in Windowing, PreModulation, Fft and PostModulation. -******************************************************************************/ +*******************************************************************************/ #include "transform.h" - #include "dct.h" #include "psy_const.h" #include "aacEnc_rom.h" #include "FDK_tools_rom.h" -INT FDKaacEnc_Transform_Real (const INT_PCM * pTimeData, - FIXP_DBL *RESTRICT mdctData, - const INT blockType, - const INT windowShape, - INT *prevWindowShape, - const INT frameLength, - INT *mdctData_e, - INT filterType - ,FIXP_DBL * RESTRICT overlapAddBuffer - ) -{ - const INT_PCM * RESTRICT timeData; - - INT i; - /* 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 tl, fl, nl, fr, nr; +#if defined(__arm__) +#endif - const FIXP_WTP * RESTRICT pLeftWindowPart; - const FIXP_WTP * RESTRICT pRightWindowPart; +INT FDKaacEnc_Transform_Real(const INT_PCM *pTimeData, + FIXP_DBL *RESTRICT mdctData, const INT blockType, + const INT windowShape, INT *prevWindowShape, + H_MDCT mdctPers, const INT frameLength, + INT *pMdctData_e, INT filterType) { + const INT_PCM *RESTRICT timeData; - /* - * MDCT scale: - * + 1: fMultDiv2() in windowing. - * + 1: Because of factor 1/2 in Princen-Bradley compliant windowed TDAC. - */ - *mdctData_e = 1+1; + UINT numSpec; + UINT numMdctLines; + UINT offset; + int fr; /* fr: right window slope length */ + SHORT mdctData_e[8]; - tl = frameLength; timeData = pTimeData; - switch( blockType ) { + if (blockType == SHORT_WINDOW) { + numSpec = 8; + numMdctLines = frameLength >> 3; + } else { + numSpec = 1; + numMdctLines = frameLength; + } + + offset = (windowShape == LOL_WINDOW) ? ((frameLength * 3) >> 2) : 0; + switch (blockType) { case LONG_WINDOW: - { - int offset = (windowShape == LOL_WINDOW) ? ((frameLength * 3)>>2) : 0; - fl = frameLength - offset; - fr = frameLength - offset; - } - break; case STOP_WINDOW: - fl = frameLength >> 3; - fr = frameLength; + fr = frameLength - offset; break; case START_WINDOW: /* or StopStartSequence */ - fl = frameLength; - fr = frameLength >> 3; - break; case SHORT_WINDOW: - fl = fr = frameLength >> 3; - tl >>= 3; - timeData = pTimeData + 3*fl + (fl/2); + fr = frameLength >> 3; break; default: FDK_ASSERT(0); return -1; - break; } - /* Taken from FDK_tools/src/mdct.cpp Derive NR and NL */ - nr = (tl - fr)>>1; - nl = (tl - fl)>>1; - - pLeftWindowPart = FDKgetWindowSlope(fl, *prevWindowShape); - pRightWindowPart = FDKgetWindowSlope(fr, windowShape); - - /* windowing */ - if (filterType != FB_ELD) - { - /* Left window slope offset */ - for (i=0; i> ( 1 ); -#else - mdctData[(tl/2)+i] = - (FIXP_DBL) timeData[tl-i-1] << (DFRACT_BITS - SAMPLE_BITS - 1); -#endif - } - /* Left window slope */ - for (i=0; i> (1); -#else - mdctData[(tl/2)-1-i] = - (FIXP_DBL) timeData[tl+i] << (DFRACT_BITS - SAMPLE_BITS - 1); -#endif - } - /* Right window slope */ - for (i=0; i> (-WTS1)); - outval += (fMultDiv2((FIXP_PCM)timeData[L+N*3/4+i], pWindowELD[N+N/2+i]) >> (-WTS1) ); - outval += (fMultDiv2(overlapAddBuffer[N/2+i], pWindowELD[2*N+i])>> (-WTS2-1)); + timeData = pTimeData; - overlapAddBuffer[N/2+i] = overlapAddBuffer[i]; + if (blockType != LONG_WINDOW) { + return -1; + } - overlapAddBuffer[i] = z0; - mdctData[i] = overlapAddBuffer[N/2+i] + (fMultDiv2(overlapAddBuffer[N+N/2-1-i], pWindowELD[2*N+N/2+i]) >> (-WTS2-1)); + /* + * MDCT scale: + * + 1: fMultDiv2() in windowing. + * + 1: Because of factor 1/2 in Princen-Bradley compliant windowed TDAC. + */ + *mdctData_e = 1 + 1; - mdctData[N-1-i] = outval; - overlapAddBuffer[N+N/2-1-i] = outval; - } + switch (frameLength) { + case 512: + pWindowELD = ELDAnalysis512; + break; + case 480: + pWindowELD = ELDAnalysis480; + break; + case 256: + pWindowELD = ELDAnalysis256; + *mdctData_e += 1; + break; + case 240: + pWindowELD = ELDAnalysis240; + *mdctData_e += 1; + break; + case 128: + pWindowELD = ELDAnalysis128; + *mdctData_e += 2; + break; + case 120: + pWindowELD = ELDAnalysis120; + *mdctData_e += 2; + break; + default: + FDK_ASSERT(0); + return -1; + } + + for (i = 0; i < N / 4; i++) { + FIXP_DBL z0, outval; + + z0 = (fMult((FIXP_PCM)timeData[L + N * 3 / 4 - 1 - i], + pWindowELD[N / 2 - 1 - i]) + << (WTS0 - 1)) + + (fMult((FIXP_PCM)timeData[L + N * 3 / 4 + i], pWindowELD[N / 2 + i]) + << (WTS0 - 1)); + + outval = (fMultDiv2((FIXP_PCM)timeData[L + N * 3 / 4 - 1 - i], + pWindowELD[N + N / 2 - 1 - i]) >> + (-WTS1)); + outval += (fMultDiv2((FIXP_PCM)timeData[L + N * 3 / 4 + i], + pWindowELD[N + N / 2 + i]) >> + (-WTS1)); + outval += (fMultDiv2(overlapAddBuffer[N / 2 + i], pWindowELD[2 * N + i]) >> + (-WTS2 - 1)); + + overlapAddBuffer[N / 2 + i] = overlapAddBuffer[i]; + + overlapAddBuffer[i] = z0; + mdctData[i] = overlapAddBuffer[N / 2 + i] + + (fMultDiv2(overlapAddBuffer[N + N / 2 - 1 - i], + pWindowELD[2 * N + N / 2 + i]) >> + (-WTS2 - 1)); + + mdctData[N - 1 - i] = outval; + overlapAddBuffer[N + N / 2 - 1 - i] = outval; + } - for(i=N/4;i> (-WTS1)) ; - outval += (fMultDiv2(overlapAddBuffer[N/2+i], pWindowELD[2*N+i]) >> (-WTS2-1)); + outval = (fMultDiv2((FIXP_PCM)timeData[L + N * 3 / 4 - 1 - i], + pWindowELD[N + N / 2 - 1 - i]) >> + (-WTS1)); + outval += (fMultDiv2(overlapAddBuffer[N / 2 + i], pWindowELD[2 * N + i]) >> + (-WTS2 - 1)); - overlapAddBuffer[N/2+i] = overlapAddBuffer[i] + (fMult((FIXP_PCM)timeData[L-N/4+i], pWindowELD[N/2+i])<< (WTS0-1) ); + overlapAddBuffer[N / 2 + i] = + overlapAddBuffer[i] + + (fMult((FIXP_PCM)timeData[L - N / 4 + i], pWindowELD[N / 2 + i]) + << (WTS0 - 1)); - overlapAddBuffer[i] = z0; - mdctData[i] = overlapAddBuffer[N/2+i] + (fMultDiv2(overlapAddBuffer[N+N/2-1-i], pWindowELD[2*N+N/2+i]) >> (-WTS2-1)); + overlapAddBuffer[i] = z0; + mdctData[i] = overlapAddBuffer[N / 2 + i] + + (fMultDiv2(overlapAddBuffer[N + N / 2 - 1 - i], + pWindowELD[2 * N + N / 2 + i]) >> + (-WTS2 - 1)); - mdctData[N-1-i] = outval; - overlapAddBuffer[N+N/2-1-i] = outval; - } + mdctData[N - 1 - i] = outval; + overlapAddBuffer[N + N / 2 - 1 - i] = outval; } - - dct_IV(mdctData, tl, mdctData_e); + dct_IV(mdctData, frameLength, mdctData_e); *prevWindowShape = windowShape; return 0; } - diff --git a/libAACenc/src/transform.h b/libAACenc/src/transform.h index 5053174..8f5ff46 100644 --- a/libAACenc/src/transform.h +++ b/libAACenc/src/transform.h @@ -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,18 +90,20 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Werner - Initial author: M. Werner - contents/description: MDCT Transform + Description: MDCT Transform -******************************************************************************/ +*******************************************************************************/ -#ifndef _TRANSFORM_H -#define _TRANSFORM_H +#ifndef TRANSFORM_H +#define TRANSFORM_H +#include "mdct.h" #include "common_fix.h" #define WTS0 1 @@ -105,19 +118,46 @@ amm-info@iis.fraunhofer.de * LONG_WINDOW, START_WINDOW, SHORT_WINDOW or STOP_WINDOW. * \param windowShape index indicating the window slope type to be used. * Values allowed are either SINE_WINDOW or KBD_WINDOW. - * \param frameLength length of the block. + * \param previndowShape index indicating the window slope type used + * in the last frame. + * Values allowed are either SINE_WINDOW or KBD_WINDOW. + * \param frameLength length of the block. Either 1024 or 960. + * \param mdctData_e pointer to an INT where the exponent of the frequency + * domain output data is stored into. + * \param filterType xxx + * \return 0 in case of success, non-zero in case of error (inconsistent + * parameters). + */ +INT FDKaacEnc_Transform_Real(const INT_PCM* pTimeData, + FIXP_DBL* RESTRICT mdctData, const INT blockType, + const INT windowShape, INT* prevWindowShape, + H_MDCT mdctPers, const INT frameLength, + INT* pMdctData_e, INT filterType); + +/** + * \brief: Performe ELD filterbnank transform of time domain data. + * \param timeData pointer to time domain input signal. + * \param mdctData pointer to store frequency domain output data. + * \param blockType index indicating the type of block. Either + * LONG_WINDOW, START_WINDOW, SHORT_WINDOW or STOP_WINDOW. + * \param windowShape index indicating the window slope type to be used. + * Values allowed are either SINE_WINDOW or KBD_WINDOW. + * \param previndowShape index indicating the window slope type used + * in the last frame. + * Values allowed are either SINE_WINDOW or KBD_WINDOW. + * \param frameLength length of the block. Either 1024 or 960. * \param mdctData_e pointer to an INT where the exponent of the frequency * domain output data is stored into. - * \return 0 in case of success, non-zero in case of error (inconsistent parameters). + * \param filterType xxx + * \param overlapAddBuffer overlap add buffer for overlap of ELD filterbank + * \return 0 in case of success, non-zero in case of error (inconsistent + * parameters). */ -INT FDKaacEnc_Transform_Real (const INT_PCM *timeData, - FIXP_DBL *RESTRICT mdctData, - const INT blockType, - const INT windowShape, - INT *prevWindowShape, - const INT frameLength, - INT *mdctData_e, - INT filterType - ,FIXP_DBL * RESTRICT overlapAddBuffer - ); -#endif +INT FDKaacEnc_Transform_Real_Eld(const INT_PCM* pTimeData, + FIXP_DBL* RESTRICT mdctData, + const INT blockType, const INT windowShape, + INT* prevWindowShape, const INT frameLength, + INT* mdctData_e, INT filterType, + FIXP_DBL* RESTRICT overlapAddBuffer); + +#endif /* #!defined (TRANSFORM_H) */ -- cgit v1.2.3