aboutsummaryrefslogtreecommitdiffstats
path: root/libSACenc
diff options
context:
space:
mode:
authorFraunhofer IIS FDK <audio-fdk@iis.fraunhofer.de>2018-02-26 20:17:00 +0100
committerJean-Michel Trivi <jmtrivi@google.com>2018-04-19 11:21:15 -0700
commit6cfabd35363c3ef5e3b209b867169a500b3ccc3c (patch)
tree01c0a19f2735e8b5d2407555fe992d4230d089eb /libSACenc
parent6288a1e34c4dede4c2806beb1736ece6580558c7 (diff)
downloadfdk-aac-6cfabd35363c3ef5e3b209b867169a500b3ccc3c.tar.gz
fdk-aac-6cfabd35363c3ef5e3b209b867169a500b3ccc3c.tar.bz2
fdk-aac-6cfabd35363c3ef5e3b209b867169a500b3ccc3c.zip
Upgrade to FDKv2
Bug: 71430241 Test: CTS DecoderTest and DecoderTestAacDrc original-Change-Id: Iaa20f749b8a04d553b20247cfe1a8930ebbabe30 Apply clang-format also on header files. original-Change-Id: I14de1ef16bbc79ec0283e745f98356a10efeb2e4 Fixes for MPEG-D DRC original-Change-Id: If1de2d74bbbac84b3f67de3b88b83f6a23b8a15c Catch unsupported tw_mdct at an early stage original-Change-Id: Ied9dd00d754162a0e3ca1ae3e6b854315d818afe Fixing PVC transition frames original-Change-Id: Ib75725abe39252806c32d71176308f2c03547a4e Move qmf bands sanity check original-Change-Id: Iab540c3013c174d9490d2ae100a4576f51d8dbc4 Initialize scaling variable original-Change-Id: I3c4087101b70e998c71c1689b122b0d7762e0f9e Add 16 qmf band configuration to getSlotNrgHQ() original-Change-Id: I49a5d30f703a1b126ff163df9656db2540df21f1 Always apply byte alignment at the end of the AudioMuxElement original-Change-Id: I42d560287506d65d4c3de8bfe3eb9a4ebeb4efc7 Setup SBR element only if no parse error exists original-Change-Id: I1915b73704bc80ab882b9173d6bec59cbd073676 Additional array index check in HCR original-Change-Id: I18cc6e501ea683b5009f1bbee26de8ddd04d8267 Fix fade-in index selection in concealment module original-Change-Id: Ibf802ed6ed8c05e9257e1f3b6d0ac1162e9b81c1 Enable explicit backward compatible parser for AAC_LD original-Change-Id: I27e9c678dcb5d40ed760a6d1e06609563d02482d Skip spatial specific config in explicit backward compatible ASC original-Change-Id: Iff7cc365561319e886090cedf30533f562ea4d6e Update flags description in decoder API original-Change-Id: I9a5b4f8da76bb652f5580cbd3ba9760425c43830 Add QMF domain reset function original-Change-Id: I4f89a8a2c0277d18103380134e4ed86996e9d8d6 DRC upgrade v2.1.0 original-Change-Id: I5731c0540139dab220094cd978ef42099fc45b74 Fix integer overflow in sqrtFixp_lookup() original-Change-Id: I429a6f0d19aa2cc957e0f181066f0ca73968c914 Fix integer overflow in invSqrtNorm2() original-Change-Id: I84de5cbf9fb3adeb611db203fe492fabf4eb6155 Fix integer overflow in GenerateRandomVector() original-Change-Id: I3118a641008bd9484d479e5b0b1ee2b5d7d44d74 Fix integer overflow in adjustTimeSlot_EldGrid() original-Change-Id: I29d503c247c5c8282349b79df940416a512fb9d5 Fix integer overflow in FDKsbrEnc_codeEnvelope() original-Change-Id: I6b34b61ebb9d525b0c651ed08de2befc1f801449 Follow-up on: Fix integer overflow in adjustTimeSlot_EldGrid() original-Change-Id: I6f8f578cc7089e5eb7c7b93e580b72ca35ad689a Fix integer overflow in get_pk_v2() original-Change-Id: I63375bed40d45867f6eeaa72b20b1f33e815938c Fix integer overflow in Syn_filt_zero() original-Change-Id: Ie0c02fdfbe03988f9d3b20d10cd9fe4c002d1279 Fix integer overflow in CFac_CalcFacSignal() original-Change-Id: Id2d767c40066c591b51768e978eb8af3b803f0c5 Fix integer overflow in FDKaacEnc_FDKaacEnc_calcPeNoAH() original-Change-Id: Idcbd0f4a51ae2550ed106aa6f3d678d1f9724841 Fix integer overflow in sbrDecoder_calculateGainVec() original-Change-Id: I7081bcbe29c5cede9821b38d93de07c7add2d507 Fix integer overflow in CLpc_SynthesisLattice() original-Change-Id: I4a95ddc18de150102352d4a1845f06094764c881 Fix integer overflow in Pred_Lt4() original-Change-Id: I4dbd012b2de7d07c3e70a47b92e3bfae8dbc750a Fix integer overflow in FDKsbrEnc_InitSbrFastTransientDetector() original-Change-Id: I788cbec1a4a00f44c2f3a72ad7a4afa219807d04 Fix unsigned integer overflow in FDKaacEnc_WriteBitstream() original-Change-Id: I68fc75166e7d2cd5cd45b18dbe3d8c2a92f1822a Fix unsigned integer overflow in FDK_MetadataEnc_Init() original-Change-Id: Ie8d025f9bcdb2442c704bd196e61065c03c10af4 Fix overflow in pseudo random number generators original-Change-Id: I3e2551ee01356297ca14e3788436ede80bd5513c Fix unsigned integer overflow in sbrDecoder_Parse() original-Change-Id: I3f231b2f437e9c37db4d5b964164686710eee971 Fix unsigned integer overflow in longsub() original-Change-Id: I73c2bc50415cac26f1f5a29e125bbe75f9180a6e Fix unsigned integer overflow in CAacDecoder_DecodeFrame() original-Change-Id: Ifce2db4b1454b46fa5f887e9d383f1cc43b291e4 Fix overflow at CLpdChannelStream_Read() original-Change-Id: Idb9d822ce3a4272e4794b643644f5434e2d4bf3f Fix unsigned integer overflow in Hcr_State_BODY_SIGN_ESC__ESC_WORD() original-Change-Id: I1ccf77c0015684b85534c5eb97162740a870b71c Fix unsigned integer overflow in UsacConfig_Parse() original-Change-Id: Ie6d27f84b6ae7eef092ecbff4447941c77864d9f Fix unsigned integer overflow in aacDecoder_drcParse() original-Change-Id: I713f28e883eea3d70b6fa56a7b8f8c22bcf66ca0 Fix unsigned integer overflow in aacDecoder_drcReadCompression() original-Change-Id: Ia34dfeb88c4705c558bce34314f584965cafcf7a Fix unsigned integer overflow in CDataStreamElement_Read() original-Change-Id: Iae896cc1d11f0a893d21be6aa90bd3e60a2c25f0 Fix unsigned integer overflow in transportDec_AdjustEndOfAccessUnit() original-Change-Id: I64cf29a153ee784bb4a16fdc088baabebc0007dc Fix unsigned integer overflow in transportDec_GetAuBitsRemaining() original-Change-Id: I975b3420faa9c16a041874ba0db82e92035962e4 Fix unsigned integer overflow in extractExtendedData() original-Change-Id: I2a59eb09e2053cfb58dfb75fcecfad6b85a80a8f Fix signed integer overflow in CAacDecoder_ExtPayloadParse() original-Change-Id: I4ad5ca4e3b83b5d964f1c2f8c5e7b17c477c7929 Fix unsigned integer overflow in CAacDecoder_DecodeFrame() original-Change-Id: I29a39df77d45c52a0c9c5c83c1ba81f8d0f25090 Follow-up on: Fix integer overflow in CLpc_SynthesisLattice() original-Change-Id: I8fb194ffc073a3432a380845be71036a272d388f Fix signed integer overflow in _interpolateDrcGain() original-Change-Id: I879ec9ab14005069a7c47faf80e8bc6e03d22e60 Fix unsigned integer overflow in FDKreadBits() original-Change-Id: I1f47a6a8037ff70375aa8844947d5681bb4287ad Fix unsigned integer overflow in FDKbyteAlign() original-Change-Id: Id5f3a11a0c9e50fc6f76ed6c572dbd4e9f2af766 Fix unsigned integer overflow in FDK_get32() original-Change-Id: I9d33b8e97e3d38cbb80629cb859266ca0acdce96 Fix unsigned integer overflow in FDK_pushBack() original-Change-Id: Ic87f899bc8c6acf7a377a8ca7f3ba74c3a1e1c19 Fix unsigned integer overflow in FDK_pushForward() original-Change-Id: I3b754382f6776a34be1602e66694ede8e0b8effc Fix unsigned integer overflow in ReadPsData() original-Change-Id: I25361664ba8139e32bbbef2ca8c106a606ce9c37 Fix signed integer overflow in E_UTIL_residu() original-Change-Id: I8c3abd1f437ee869caa8fb5903ce7d3d641b6aad REVERT: Follow-up on: Integer overflow in CLpc_SynthesisLattice(). original-Change-Id: I3d340099acb0414795c8dfbe6362bc0a8f045f9b Follow-up on: Fix integer overflow in CLpc_SynthesisLattice() original-Change-Id: I4aedb8b3a187064e9f4d985175aa55bb99cc7590 Follow-up on: Fix unsigned integer overflow in aacDecoder_drcParse() original-Change-Id: I2aa2e13916213bf52a67e8b0518e7bf7e57fb37d Fix integer overflow in acelp original-Change-Id: Ie6390c136d84055f8b728aefbe4ebef6e029dc77 Fix unsigned integer overflow in aacDecoder_UpdateBitStreamCounters() original-Change-Id: I391ffd97ddb0b2c184cba76139bfb356a3b4d2e2 Adjust concealment default settings original-Change-Id: I6a95db935a327c47df348030bcceafcb29f54b21 Saturate estimatedStartPos original-Change-Id: I27be2085e0ae83ec9501409f65e003f6bcba1ab6 Negative shift exponent in _interpolateDrcGain() original-Change-Id: I18edb26b26d002aafd5e633d4914960f7a359c29 Negative shift exponent in calculateICC() original-Change-Id: I3dcd2ae98d2eb70ee0d59750863cbb2a6f4f8aba Too large shift exponent in FDK_put() original-Change-Id: Ib7d9aaa434d2d8de4a13b720ca0464b31ca9b671 Too large shift exponent in CalcInvLdData() original-Change-Id: I43e6e78d4cd12daeb1dcd5d82d1798bdc2550262 Member access within null pointer of type SBR_CHANNEL original-Change-Id: Idc5e4ea8997810376d2f36bbdf628923b135b097 Member access within null pointer of type CpePersistentData original-Change-Id: Ib6c91cb0d37882768e5baf63324e429589de0d9d Member access within null pointer FDKaacEnc_psyMain() original-Change-Id: I7729b7f4479970531d9dc823abff63ca52e01997 Member access within null pointer FDKaacEnc_GetPnsParam() original-Change-Id: I9aa3b9f3456ae2e0f7483dbd5b3dde95fc62da39 Member access within null pointer FDKsbrEnc_EnvEncodeFrame() original-Change-Id: I67936f90ea714e90b3e81bc0dd1472cc713eb23a Add HCR sanity check original-Change-Id: I6c1d9732ebcf6af12f50b7641400752f74be39f7 Fix memory issue for HBE edge case with 8:3 SBR original-Change-Id: I11ea58a61e69fbe8bf75034b640baee3011e63e9 Additional SBR parametrization sanity check for ELD original-Change-Id: Ie26026fbfe174c2c7b3691f6218b5ce63e322140 Add MPEG-D DRC channel layout check original-Change-Id: Iea70a74f171b227cce636a9eac4ba662777a2f72 Additional out-of-bounds checks in MPEG-D DRC original-Change-Id: Ife4a8c3452c6fde8a0a09e941154a39a769777d4 Change-Id: Ic63cb2f628720f54fe9b572b0cb528e2599c624e
Diffstat (limited to 'libSACenc')
-rw-r--r--libSACenc/include/sacenc_lib.h405
-rw-r--r--libSACenc/src/sacenc_bitstream.cpp826
-rw-r--r--libSACenc/src/sacenc_bitstream.h296
-rw-r--r--libSACenc/src/sacenc_const.h126
-rw-r--r--libSACenc/src/sacenc_delay.cpp472
-rw-r--r--libSACenc/src/sacenc_delay.h175
-rw-r--r--libSACenc/src/sacenc_dmx_tdom_enh.cpp639
-rw-r--r--libSACenc/src/sacenc_dmx_tdom_enh.h134
-rw-r--r--libSACenc/src/sacenc_filter.cpp207
-rw-r--r--libSACenc/src/sacenc_filter.h133
-rw-r--r--libSACenc/src/sacenc_framewindowing.cpp568
-rw-r--r--libSACenc/src/sacenc_framewindowing.h181
-rw-r--r--libSACenc/src/sacenc_huff_tab.cpp997
-rw-r--r--libSACenc/src/sacenc_huff_tab.h222
-rw-r--r--libSACenc/src/sacenc_lib.cpp2042
-rw-r--r--libSACenc/src/sacenc_nlc_enc.cpp1436
-rw-r--r--libSACenc/src/sacenc_nlc_enc.h141
-rw-r--r--libSACenc/src/sacenc_onsetdetect.cpp381
-rw-r--r--libSACenc/src/sacenc_onsetdetect.h154
-rw-r--r--libSACenc/src/sacenc_paramextract.cpp725
-rw-r--r--libSACenc/src/sacenc_paramextract.h214
-rw-r--r--libSACenc/src/sacenc_staticgain.cpp446
-rw-r--r--libSACenc/src/sacenc_staticgain.h177
-rw-r--r--libSACenc/src/sacenc_tree.cpp488
-rw-r--r--libSACenc/src/sacenc_tree.h168
-rw-r--r--libSACenc/src/sacenc_vectorfunctions.cpp450
-rw-r--r--libSACenc/src/sacenc_vectorfunctions.h488
27 files changed, 12691 insertions, 0 deletions
diff --git a/libSACenc/include/sacenc_lib.h b/libSACenc/include/sacenc_lib.h
new file mode 100644
index 0000000..758cc0f
--- /dev/null
+++ b/libSACenc/include/sacenc_lib.h
@@ -0,0 +1,405 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): Max Neuendorf
+
+ Description: Encoder Library Interface
+ Encoder API
+
+*******************************************************************************/
+
+/**************************************************************************/ /**
+ \file
+ ******************************************************************************/
+
+#ifndef SACENC_LIB_H
+#define SACENC_LIB_H
+
+/* Includes ******************************************************************/
+#include "machine_type.h"
+#include "FDK_audio.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* Defines *******************************************************************/
+
+/* Data Types ****************************************************************/
+
+/**
+ * Space encoder error codes.
+ */
+typedef enum {
+ SACENC_OK = 0x00000000, /*!< No error happened. All fine. */
+ SACENC_INVALID_HANDLE =
+ 0x00000080, /*!< Handle passed to function call was invalid. */
+ SACENC_MEMORY_ERROR = 0x00000800, /*!< Memory allocation failed. */
+ SACENC_INIT_ERROR = 0x00008000, /*!< General initialization error. */
+ SACENC_ENCODE_ERROR =
+ 0x00080000, /*!< The encoding process was interrupted by an unexpected
+ error. */
+ SACENC_PARAM_ERROR = 0x00800000, /*!< Invalid runtime parameter. */
+ SACENC_UNSUPPORTED_PARAMETER = 0x00800001, /*!< Parameter not available. */
+ SACENC_INVALID_CONFIG = 0x00800002, /*!< Configuration not provided. */
+ SACENC_UNKNOWN_ERROR = 0x08000000 /*!< Unknown error. */
+
+} FDK_SACENC_ERROR;
+
+typedef enum {
+ SACENC_INVALID_MODE = 0,
+ SACENC_212 = 8,
+ SACENC_ESCAPE = 15
+
+} MP4SPACEENC_MODE;
+
+typedef enum {
+ SACENC_BANDS_INVALID = 0,
+ SACENC_BANDS_4 = 4,
+ SACENC_BANDS_5 = 5,
+ SACENC_BANDS_7 = 7,
+ SACENC_BANDS_9 = 9,
+ SACENC_BANDS_12 = 12,
+ SACENC_BANDS_15 = 15,
+ SACENC_BANDS_23 = 23
+
+} MP4SPACEENC_BANDS_CONFIG;
+
+typedef enum {
+ SACENC_QUANTMODE_INVALID = -1,
+ SACENC_QUANTMODE_FINE = 0,
+ SACENC_QUANTMODE_EBQ1 = 1,
+ SACENC_QUANTMODE_EBQ2 = 2,
+ SACENC_QUANTMODE_RSVD3 = 3
+
+} MP4SPACEENC_QUANTMODE;
+
+typedef enum {
+ SACENC_DMXGAIN_INVALID = -1,
+ SACENC_DMXGAIN_0_dB = 0,
+ SACENC_DMXGAIN_1_5_dB = 1,
+ SACENC_DMXGAIN_3_dB = 2,
+ SACENC_DMXGAIN_4_5_dB = 3,
+ SACENC_DMXGAIN_6_dB = 4,
+ SACENC_DMXGAIN_7_5_dB = 5,
+ SACENC_DMXGAIN_9_dB = 6,
+ SACENC_DMXGAIN_12_dB = 7
+
+} MP4SPACEENC_DMX_GAIN;
+
+/**
+ * \brief Space Encoder setting parameters.
+ *
+ * Use FDK_sacenc_setParam() function to configure the internal status of the
+ * following parameters.
+ */
+typedef enum {
+ SACENC_LOWDELAY, /*!< Configure lowdelay MPEG Surround.
+ - 0: Disable Lowdelay. (default)
+ - 1: Enable Lowdelay.
+ - 2: Enable Lowdelay including keep frame. */
+
+ SACENC_ENC_MODE, /*!< Configure encoder tree mode. See ::MP4SPACEENC_MODE for
+ available values. */
+
+ SACENC_SAMPLERATE, /*!< Configure encoder sampling rate. */
+
+ SACENC_FRAME_TIME_SLOTS, /*!< Configure number of slots per spatial frame. */
+
+ SACENC_PARAM_BANDS, /*!< Configure number of parameter bands. See
+ ::MP4SPACEENC_BANDS_CONFIG for available values. */
+
+ SACENC_TIME_DOM_DMX, /*!< Configure time domain downmix.
+ - 0: No time domain downmix. (default)
+ - 1: Static time domain downmix.
+ - 2: Enhanced time domain downmix, stereo to mono
+ only. */
+
+ SACENC_DMX_GAIN, /*!< Configure downmix gain. See ::MP4SPACEENC_DMX_GAIN for
+ available values. */
+
+ SACENC_COARSE_QUANT, /*!< Use coarse parameter quantization.
+ - 0: No (default)
+ - 1: Yes */
+
+ SACENC_QUANT_MODE, /*!< Configure quanitzation mode. See
+ ::MP4SPACEENC_QUANTMODE for available values. */
+
+ SACENC_TIME_ALIGNMENT, /*!< Configure time alignment in samples. */
+
+ SACENC_INDEPENDENCY_COUNT, /*!< Configure the independency count. (count == 0
+ means independencyFlag == 1) */
+
+ SACENC_INDEPENDENCY_FACTOR, /*!< How often should we set the independency flag
+ */
+
+ SACENC_NONE /*!< ------ */
+
+} SPACEENC_PARAM;
+
+/**
+ * Describes Spatial Specific Config.
+ */
+typedef struct {
+ INT nSscSizeBits; /*!< Number of valid bits in pSsc buffer. */
+ UCHAR *pSsc; /*!< SpatialSpecificConfig buffer in binary format. */
+
+} MPEG4SPACEENC_SSCBUF;
+
+/**
+ * Provides some info about the encoder configuration.
+ */
+typedef struct {
+ INT nSampleRate; /*!< Configured sampling rate.*/
+ INT nSamplesFrame; /*!< Frame length in samples. */
+ INT nTotalInputChannels; /*!< Number of expected audio input channels. */
+ INT nDmxDelay; /*!< Delay of the downmixed signal. */
+ INT nCodecDelay; /*!< Delay of the whole en-/decoded signal, including
+ core-coder delay. */
+ INT nDecoderDelay; /*!< Delay added by the MP4SPACE decoder. */
+ INT nPayloadDelay; /*!< Delay of the payload. */
+ INT nDiscardOutFrames; /*!< Number of dmx frames to discard for alignment with
+ bitstream. */
+
+ MPEG4SPACEENC_SSCBUF
+ *pSscBuf; /*!< Pointer to Spatial Specific Config structure. */
+
+} MP4SPACEENC_INFO;
+
+/**
+ * MPEG Surround encoder handle.
+ */
+typedef struct MP4SPACE_ENCODER *HANDLE_MP4SPACE_ENCODER;
+
+/**
+ * Defines the input arguments for a FDK_sacenc_encode() call.
+ */
+typedef struct {
+ INT nInputSamples; /*!< Number of valid input audio samples (multiple of input
+ channels). */
+ UINT inputBufferSizePerChannel; /*!< Size of input buffer (input audio
+ samples) per channel. */
+ UINT isInputInterleaved; /*!< Indicates if input audio samples are represented
+ in blocks or interleaved:
+ - 0 : in blocks.
+ - 1 : interleaved. */
+
+} SACENC_InArgs;
+
+/**
+ * Defines the output arguments for a FDK_sacenc_encode() call.
+ */
+typedef struct {
+ INT nOutputBits; /*!< Number of valid payload bits generated during
+ FDK_sacenc_encode(). */
+ INT nOutputSamples; /*!< Number of valid output audio samples generated during
+ FDK_sacenc_encode(). */
+ UINT nSamplesConsumed; /*!< Number of input audio samples consumed in
+ FDK_sacenc_encode(). */
+
+} SACENC_OutArgs;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+
+/**
+ * \brief Opens a new instace of the MPEG Surround encoder.
+ *
+ * \param phMp4SpaceEnc Pointer to the encoder handle to be deallocated.
+ *
+ * \return
+ * - SACENC_OK, on success.
+ * - SACENC_INVALID_HANDLE, SACENC_MEMORY_ERROR, on failure.
+ */
+FDK_SACENC_ERROR FDK_sacenc_open(HANDLE_MP4SPACE_ENCODER *phMp4SpaceEnc);
+
+/**
+ * \brief Finalizes opening process of MPEG Surround encoder.
+ *
+ * Shows, how many samples are needed as input
+ *
+ * \param hMp4SpaceEnc A valid MPEG Surround encoder handle.
+ * \param dmxDelay Downmix delay.
+ *
+ * \return
+ * - SACENC_OK, on success.
+ * - SACENC_INVALID_HANDLE, SACENC_INIT_ERROR, SACENC_INVALID_CONFIG,
+ * on failure.
+ */
+FDK_SACENC_ERROR FDK_sacenc_init(HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc,
+ const INT dmxDelay);
+
+/**
+ * \brief Close the MPEG Surround encoder instance.
+ *
+ * Deallocate encoder instance and free whole memory.
+ *
+ * \param phMp4SpaceEnc Pointer to the encoder handle to be deallocated.
+ *
+ * \return
+ * - SACENC_OK, on success.
+ * - SACENC_INVALID_HANDLE, on failure.
+ */
+FDK_SACENC_ERROR FDK_sacenc_close(HANDLE_MP4SPACE_ENCODER *phMp4SpaceEnc);
+
+/**
+ * \brief MPEG surround parameter extraction, framwise.
+ *
+ * \param hMp4SpaceEnc A valid MPEG Surround encoder handle.
+ *
+ * \return
+ * - SACENC_OK, on success.
+ * - SACENC_INVALID_HANDLE, on failure.
+ */
+FDK_SACENC_ERROR FDK_sacenc_encode(const HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc,
+ const FDK_bufDescr *inBufDesc,
+ const FDK_bufDescr *outBufDesc,
+ const SACENC_InArgs *inargs,
+ SACENC_OutArgs *outargs);
+
+/**
+ * \brief Provides information on produced bitstream.
+ *
+ * \param hMp4SpaceEnc A valid MPEG Surround encoder handle.
+ * \param pInfo Pointer to an encoder info struct, filled on
+ * return.
+ *
+ * \return
+ * - SACENC_OK, on success.
+ * - SACENC_INVALID_HANDLE, on failure.
+ */
+FDK_SACENC_ERROR FDK_sacenc_getInfo(const HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc,
+ MP4SPACEENC_INFO *const pInfo);
+
+/**
+ * \brief Set one single MPEG Surround encoder parameter.
+ *
+ * This function allows configuration of all encoder parameters specified in
+ * ::SPACEENC_PARAM. Each parameter must be set with a separate function call.
+ * An internal validation of the configuration value range will be done.
+ *
+ * \param hMp4SpaceEnc A valid MPEG Surround encoder handle.
+ * \param param Parameter to be set. See ::SPACEENC_PARAM.
+ * \param value Parameter value. See parameter description in
+ * ::SPACEENC_PARAM.
+ *
+ * \return
+ * - SACENC_OK, on success.
+ * - SACENC_INVALID_HANDLE, SACENC_UNSUPPORTED_PARAMETER,
+ * SACENC_INVALID_CONFIG, on failure.
+ */
+FDK_SACENC_ERROR FDK_sacenc_setParam(HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc,
+ const SPACEENC_PARAM param,
+ const UINT value);
+
+/**
+ * \brief Get information about MPEG Surround encoder library build.
+ *
+ * Fill a given LIB_INFO structure with library version information.
+ *
+ * \param info Pointer to an allocated LIB_INFO struct.
+ *
+ * \return
+ * - SACENC_OK, on success.
+ * - SACENC_INVALID_HANDLE, SACENC_INIT_ERROR, on failure.
+ */
+FDK_SACENC_ERROR FDK_sacenc_getLibInfo(LIB_INFO *info);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SACENC_LIB_H */
diff --git a/libSACenc/src/sacenc_bitstream.cpp b/libSACenc/src/sacenc_bitstream.cpp
new file mode 100644
index 0000000..dacfc27
--- /dev/null
+++ b/libSACenc/src/sacenc_bitstream.cpp
@@ -0,0 +1,826 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s):
+
+ Description: Encoder Library Interface
+ Bitstream Writer
+
+*******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_bitstream.h"
+#include "sacenc_const.h"
+
+#include "genericStds.h"
+#include "common_fix.h"
+
+#include "FDK_matrixCalloc.h"
+#include "sacenc_nlc_enc.h"
+
+/* Defines *******************************************************************/
+#define MAX_FREQ_RES_INDEX 8
+#define MAX_SAMPLING_FREQUENCY_INDEX 13
+#define SAMPLING_FREQUENCY_INDEX_ESCAPE 15
+
+/* Data Types ****************************************************************/
+typedef struct {
+ SCHAR cld_old[SACENC_MAX_NUM_BOXES][MAX_NUM_BINS];
+ SCHAR icc_old[SACENC_MAX_NUM_BOXES][MAX_NUM_BINS];
+ UCHAR quantCoarseCldPrev[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAMS];
+ UCHAR quantCoarseIccPrev[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAMS];
+
+} PREV_OTTDATA;
+
+typedef struct {
+ PREV_OTTDATA prevOttData;
+
+} STATIC_SPATIALFRAME;
+
+typedef struct BSF_INSTANCE {
+ SPATIALSPECIFICCONFIG spatialSpecificConfig;
+ SPATIALFRAME frame;
+ STATIC_SPATIALFRAME prevFrameData;
+
+} BSF_INSTANCE;
+
+/* Constants *****************************************************************/
+static const INT SampleRateTable[MAX_SAMPLING_FREQUENCY_INDEX] = {
+ 96000, 88200, 64000, 48000, 44100, 32000, 24000,
+ 22050, 16000, 12000, 11025, 8000, 7350};
+
+static const UCHAR FreqResBinTable_LD[MAX_FREQ_RES_INDEX] = {0, 23, 15, 12,
+ 9, 7, 5, 4};
+static const UCHAR FreqResStrideTable_LD[] = {1, 2, 5, 23};
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+static FDK_SACENC_ERROR DuplicateLosslessData(
+ const INT startBox, const INT stopBox,
+ const LOSSLESSDATA *const hLosslessDataFrom, const INT setFrom,
+ LOSSLESSDATA *const hLosslessDataTo, const INT setTo) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((NULL == hLosslessDataFrom) || (NULL == hLosslessDataTo)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int i;
+
+ for (i = startBox; i < stopBox; i++) {
+ hLosslessDataTo->bsXXXDataMode[i][setTo] =
+ hLosslessDataFrom->bsXXXDataMode[i][setFrom];
+ hLosslessDataTo->bsDataPair[i][setTo] =
+ hLosslessDataFrom->bsDataPair[i][setFrom];
+ hLosslessDataTo->bsQuantCoarseXXX[i][setTo] =
+ hLosslessDataFrom->bsQuantCoarseXXX[i][setFrom];
+ hLosslessDataTo->bsFreqResStrideXXX[i][setTo] =
+ hLosslessDataFrom->bsFreqResStrideXXX[i][setFrom];
+ }
+ }
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_duplicateParameterSet(
+ const SPATIALFRAME *const hFrom, const INT setFrom, SPATIALFRAME *const hTo,
+ const INT setTo) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((NULL == hFrom) || (NULL == hTo)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int box;
+ /* Only Copy Parameter Set selective stuff */
+
+ /* OTT-Data */
+ for (box = 0; box < SACENC_MAX_NUM_BOXES; box++) {
+ FDKmemcpy(hTo->ottData.cld[box][setTo], hFrom->ottData.cld[box][setFrom],
+ sizeof(hFrom->ottData.cld[0][0]));
+ FDKmemcpy(hTo->ottData.icc[box][setTo], hFrom->ottData.icc[box][setFrom],
+ sizeof(hFrom->ottData.icc[0][0]));
+ }
+
+ /* LOSSLESSDATA */
+ DuplicateLosslessData(0, SACENC_MAX_NUM_BOXES, &hFrom->CLDLosslessData,
+ setFrom, &hTo->CLDLosslessData, setTo);
+ DuplicateLosslessData(0, SACENC_MAX_NUM_BOXES, &hFrom->ICCLosslessData,
+ setFrom, &hTo->ICCLosslessData, setTo);
+
+ } /* valid handle */
+
+ return error;
+}
+
+/* set frame defaults */
+static void clearFrame(SPATIALFRAME *const pFrame) {
+ FDKmemclear(pFrame, sizeof(SPATIALFRAME));
+
+ pFrame->bsIndependencyFlag = 1;
+ pFrame->framingInfo.numParamSets = 1;
+}
+
+static void fine2coarse(SCHAR *const data, const DATA_TYPE dataType,
+ const INT startBand, const INT numBands) {
+ int i;
+ if (dataType == t_CLD) {
+ for (i = startBand; i < startBand + numBands; i++) {
+ data[i] /= 2;
+ }
+ } else {
+ for (i = startBand; i < startBand + numBands; i++) {
+ data[i] >>= 1;
+ }
+ }
+}
+
+static void coarse2fine(SCHAR *const data, const DATA_TYPE dataType,
+ const INT startBand, const INT numBands) {
+ int i;
+
+ for (i = startBand; i < startBand + numBands; i++) {
+ data[i] <<= 1;
+ }
+
+ if (dataType == t_CLD) {
+ for (i = startBand; i < startBand + numBands; i++) {
+ if (data[i] == -14) {
+ data[i] = -15;
+ } else if (data[i] == 14) {
+ data[i] = 15;
+ }
+ }
+ } /* (dataType == t_CLD) */
+}
+
+static UCHAR getBsFreqResStride(const INT index) {
+ const UCHAR *pFreqResStrideTable = NULL;
+ int freqResStrideTableSize = 0;
+
+ pFreqResStrideTable = FreqResStrideTable_LD;
+ freqResStrideTableSize =
+ sizeof(FreqResStrideTable_LD) / sizeof(*FreqResStrideTable_LD);
+
+ return (((NULL != pFreqResStrideTable) && (index >= 0) &&
+ (index < freqResStrideTableSize))
+ ? pFreqResStrideTable[index]
+ : 1);
+}
+
+/* write data to bitstream */
+static void ecData(HANDLE_FDK_BITSTREAM bitstream,
+ SCHAR data[MAX_NUM_PARAMS][MAX_NUM_BINS],
+ SCHAR oldData[MAX_NUM_BINS],
+ UCHAR quantCoarseXXXprev[MAX_NUM_PARAMS],
+ LOSSLESSDATA *const losslessData, const DATA_TYPE dataType,
+ const INT paramIdx, const INT numParamSets,
+ const INT independencyFlag, const INT startBand,
+ const INT stopBand, const INT defaultValue) {
+ int ps, pb, strOffset, pbStride, dataBands, i;
+ int aStrides[MAX_NUM_BINS + 1] = {0};
+ SHORT cmpIdxData[2][MAX_NUM_BINS] = {{0}};
+ SHORT cmpOldData[MAX_NUM_BINS] = {0};
+
+ /* bsXXXDataMode */
+ if (independencyFlag || (losslessData->bsQuantCoarseXXX[paramIdx][0] !=
+ quantCoarseXXXprev[paramIdx])) {
+ losslessData->bsXXXDataMode[paramIdx][0] = FINECOARSE;
+ } else {
+ losslessData->bsXXXDataMode[paramIdx][0] = KEEP;
+ for (i = startBand; i < stopBand; i++) {
+ if (data[0][i] != oldData[i]) {
+ losslessData->bsXXXDataMode[paramIdx][0] = FINECOARSE;
+ break;
+ }
+ }
+ }
+
+ FDKwriteBits(bitstream, losslessData->bsXXXDataMode[paramIdx][0], 2);
+
+ for (ps = 1; ps < numParamSets; ps++) {
+ if (losslessData->bsQuantCoarseXXX[paramIdx][ps] !=
+ losslessData->bsQuantCoarseXXX[paramIdx][ps - 1]) {
+ losslessData->bsXXXDataMode[paramIdx][ps] = FINECOARSE;
+ } else {
+ losslessData->bsXXXDataMode[paramIdx][ps] = KEEP;
+ for (i = startBand; i < stopBand; i++) {
+ if (data[ps][i] != data[ps - 1][i]) {
+ losslessData->bsXXXDataMode[paramIdx][ps] = FINECOARSE;
+ break;
+ }
+ }
+ }
+
+ FDKwriteBits(bitstream, losslessData->bsXXXDataMode[paramIdx][ps], 2);
+ } /* for ps */
+
+ /* Create data pairs if possible */
+ for (ps = 0; ps < (numParamSets - 1); ps++) {
+ if (losslessData->bsXXXDataMode[paramIdx][ps] == FINECOARSE) {
+ /* Check if next parameter set is FINCOARSE */
+ if (losslessData->bsXXXDataMode[paramIdx][ps + 1] == FINECOARSE) {
+ /* We have to check if ps and ps+1 use the same bsXXXQuantMode */
+ /* and also have the same stride */
+ if ((losslessData->bsQuantCoarseXXX[paramIdx][ps + 1] ==
+ losslessData->bsQuantCoarseXXX[paramIdx][ps]) &&
+ (losslessData->bsFreqResStrideXXX[paramIdx][ps + 1] ==
+ losslessData->bsFreqResStrideXXX[paramIdx][ps])) {
+ losslessData->bsDataPair[paramIdx][ps] = 1;
+ losslessData->bsDataPair[paramIdx][ps + 1] = 1;
+
+ /* We have a data pair -> Jump to the ps after next ps*/
+ ps++;
+ continue;
+ }
+ }
+ /* dataMode of next ps is not FINECOARSE or does not use the same
+ * bsXXXQuantMode/stride */
+ /* -> no dataPair possible */
+ losslessData->bsDataPair[paramIdx][ps] = 0;
+
+ /* Initialize ps after next ps to Zero (only important for the last
+ * parameter set) */
+ losslessData->bsDataPair[paramIdx][ps + 1] = 0;
+ } else {
+ /* No FINECOARSE -> no data pair possible */
+ losslessData->bsDataPair[paramIdx][ps] = 0;
+
+ /* Initialize ps after next ps to Zero (only important for the last
+ * parameter set) */
+ losslessData->bsDataPair[paramIdx][ps + 1] = 0;
+ }
+ } /* for ps */
+
+ for (ps = 0; ps < numParamSets; ps++) {
+ if (losslessData->bsXXXDataMode[paramIdx][ps] == DEFAULT) {
+ /* Prepare old data */
+ for (i = startBand; i < stopBand; i++) {
+ oldData[i] = defaultValue;
+ }
+ quantCoarseXXXprev[paramIdx] = 0; /* Default data are always fine */
+ }
+
+ if (losslessData->bsXXXDataMode[paramIdx][ps] == FINECOARSE) {
+ FDKwriteBits(bitstream, losslessData->bsDataPair[paramIdx][ps], 1);
+ FDKwriteBits(bitstream, losslessData->bsQuantCoarseXXX[paramIdx][ps], 1);
+ FDKwriteBits(bitstream, losslessData->bsFreqResStrideXXX[paramIdx][ps],
+ 2);
+
+ if (losslessData->bsQuantCoarseXXX[paramIdx][ps] !=
+ quantCoarseXXXprev[paramIdx]) {
+ if (quantCoarseXXXprev[paramIdx]) {
+ coarse2fine(oldData, dataType, startBand, stopBand - startBand);
+ } else {
+ fine2coarse(oldData, dataType, startBand, stopBand - startBand);
+ }
+ }
+
+ /* Handle strides */
+ pbStride =
+ getBsFreqResStride(losslessData->bsFreqResStrideXXX[paramIdx][ps]);
+ dataBands = (stopBand - startBand - 1) / pbStride + 1;
+
+ aStrides[0] = startBand;
+ for (pb = 1; pb <= dataBands; pb++) {
+ aStrides[pb] = aStrides[pb - 1] + pbStride;
+ }
+
+ strOffset = 0;
+ while (aStrides[dataBands] > stopBand) {
+ if (strOffset < dataBands) {
+ strOffset++;
+ }
+ for (i = strOffset; i <= dataBands; i++) {
+ aStrides[i]--;
+ }
+ } /* while */
+
+ for (pb = 0; pb < dataBands; pb++) {
+ cmpOldData[startBand + pb] = oldData[aStrides[pb]];
+ cmpIdxData[0][startBand + pb] = data[ps][aStrides[pb]];
+
+ if (losslessData->bsDataPair[paramIdx][ps]) {
+ cmpIdxData[1][startBand + pb] = data[ps + 1][aStrides[pb]];
+ }
+ } /* for pb*/
+
+ /* Finally encode */
+ if (losslessData->bsDataPair[paramIdx][ps]) {
+ fdk_sacenc_ecDataPairEnc(bitstream, cmpIdxData, cmpOldData, dataType, 0,
+ startBand, dataBands,
+ losslessData->bsQuantCoarseXXX[paramIdx][ps],
+ independencyFlag && (ps == 0));
+ } else {
+ fdk_sacenc_ecDataSingleEnc(bitstream, cmpIdxData, cmpOldData, dataType,
+ 0, startBand, dataBands,
+ losslessData->bsQuantCoarseXXX[paramIdx][ps],
+ independencyFlag && (ps == 0));
+ }
+
+ /* Overwrite old data */
+ for (i = startBand; i < stopBand; i++) {
+ if (losslessData->bsDataPair[paramIdx][ps]) {
+ oldData[i] = data[ps + 1][i];
+ } else {
+ oldData[i] = data[ps][i];
+ }
+ }
+
+ quantCoarseXXXprev[paramIdx] =
+ losslessData->bsQuantCoarseXXX[paramIdx][ps];
+
+ /* Jump forward if we have encoded a data pair */
+ if (losslessData->bsDataPair[paramIdx][ps]) {
+ ps++;
+ }
+
+ } /* if (losslessData->bsXXXDataMode[paramIdx][ps] == FINECOARSE ) */
+ } /* for ps */
+}
+
+/****************************************************************************/
+/* Bitstream formatter interface functions */
+/****************************************************************************/
+static FDK_SACENC_ERROR getBsFreqResIndex(const INT numBands,
+ INT *const pbsFreqResIndex) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == pbsFreqResIndex) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ const UCHAR *pFreqResBinTable = FreqResBinTable_LD;
+ int i;
+ *pbsFreqResIndex = -1;
+
+ for (i = 0; i < MAX_FREQ_RES_INDEX; i++) {
+ if (numBands == pFreqResBinTable[i]) {
+ *pbsFreqResIndex = i;
+ break;
+ }
+ }
+ if (*pbsFreqResIndex < 0 || *pbsFreqResIndex >= MAX_FREQ_RES_INDEX) {
+ error = SACENC_INVALID_CONFIG;
+ }
+ }
+ return error;
+}
+
+static FDK_SACENC_ERROR getSamplingFrequencyIndex(
+ const INT bsSamplingFrequency, INT *const pbsSamplingFrequencyIndex) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == pbsSamplingFrequencyIndex) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int i;
+ *pbsSamplingFrequencyIndex = SAMPLING_FREQUENCY_INDEX_ESCAPE;
+
+ for (i = 0; i < MAX_SAMPLING_FREQUENCY_INDEX; i++) {
+ if (bsSamplingFrequency == SampleRateTable[i]) { /*spatial sampling rate*/
+ *pbsSamplingFrequencyIndex = i;
+ break;
+ }
+ }
+ }
+ return error;
+}
+
+/* destroy encoder instance */
+FDK_SACENC_ERROR fdk_sacenc_destroySpatialBitstreamEncoder(
+ HANDLE_BSF_INSTANCE *selfPtr) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((selfPtr == NULL) || (*selfPtr == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ if (*selfPtr != NULL) {
+ FDK_FREE_MEMORY_1D(*selfPtr);
+ }
+ }
+ return error;
+}
+
+/* create encoder instance */
+FDK_SACENC_ERROR fdk_sacenc_createSpatialBitstreamEncoder(
+ HANDLE_BSF_INSTANCE *selfPtr) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == selfPtr) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ /* allocate encoder struct */
+ FDK_ALLOCATE_MEMORY_1D(*selfPtr, 1, BSF_INSTANCE);
+ }
+ return error;
+
+bail:
+ fdk_sacenc_destroySpatialBitstreamEncoder(selfPtr);
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+/* init encoder instance */
+FDK_SACENC_ERROR fdk_sacenc_initSpatialBitstreamEncoder(
+ HANDLE_BSF_INSTANCE selfPtr) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (selfPtr == NULL) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ /* init/clear */
+ clearFrame(&selfPtr->frame);
+
+ } /* valid handle */
+ return error;
+}
+
+/* get SpatialSpecificConfig struct */
+SPATIALSPECIFICCONFIG *fdk_sacenc_getSpatialSpecificConfig(
+ HANDLE_BSF_INSTANCE selfPtr) {
+ return ((selfPtr == NULL) ? NULL : &(selfPtr->spatialSpecificConfig));
+}
+
+/* write SpatialSpecificConfig to stream */
+FDK_SACENC_ERROR fdk_sacenc_writeSpatialSpecificConfig(
+ SPATIALSPECIFICCONFIG *const spatialSpecificConfig,
+ UCHAR *const pOutputBuffer, const INT outputBufferSize,
+ INT *const pnOutputBits) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+ INT bsSamplingFrequencyIndex = 0;
+ INT bsFreqRes = 0;
+
+ if ((spatialSpecificConfig == NULL) || (pOutputBuffer == NULL) ||
+ (pnOutputBits == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ FDK_BITSTREAM bitstream;
+
+ /* Find FreqRes */
+ if (SACENC_OK != (error = getBsFreqResIndex(spatialSpecificConfig->numBands,
+ &bsFreqRes)))
+ goto bail;
+
+ /* Find SamplingFrequencyIndex */
+ if (SACENC_OK != (error = getSamplingFrequencyIndex(
+ spatialSpecificConfig->bsSamplingFrequency,
+ &bsSamplingFrequencyIndex)))
+ goto bail;
+
+ /* bind extern buffer to bitstream handle */
+ FDKinitBitStream(&bitstream, pOutputBuffer, outputBufferSize, 0, BS_WRITER);
+
+ /****************************************************************************/
+ /* write to bitstream */
+
+ FDKwriteBits(&bitstream, bsSamplingFrequencyIndex, 4);
+
+ if (bsSamplingFrequencyIndex == 15) {
+ FDKwriteBits(&bitstream, spatialSpecificConfig->bsSamplingFrequency, 24);
+ }
+
+ FDKwriteBits(&bitstream, spatialSpecificConfig->bsFrameLength, 5);
+
+ FDKwriteBits(&bitstream, bsFreqRes, 3);
+ FDKwriteBits(&bitstream, spatialSpecificConfig->bsTreeConfig, 4);
+ FDKwriteBits(&bitstream, spatialSpecificConfig->bsQuantMode, 2);
+
+ FDKwriteBits(&bitstream, 0, 1); /* bsArbitraryDownmix */
+
+ FDKwriteBits(&bitstream, spatialSpecificConfig->bsFixedGainDMX, 3);
+
+ FDKwriteBits(&bitstream, TEMPSHAPE_OFF, 2);
+ FDKwriteBits(&bitstream, spatialSpecificConfig->bsDecorrConfig, 2);
+
+ FDKbyteAlign(&bitstream, 0); /* byte alignment */
+
+ /* return number of valid bits in bitstream */
+ if ((*pnOutputBits = FDKgetValidBits(&bitstream)) >
+ (outputBufferSize * 8)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ /* terminate buffer with alignment */
+ FDKbyteAlign(&bitstream, 0);
+
+ } /* valid handle */
+
+bail:
+ return error;
+}
+
+/* get SpatialFrame struct */
+SPATIALFRAME *fdk_sacenc_getSpatialFrame(HANDLE_BSF_INSTANCE selfPtr,
+ const SPATIALFRAME_TYPE frameType) {
+ int idx = -1;
+
+ switch (frameType) {
+ case READ_SPATIALFRAME:
+ case WRITE_SPATIALFRAME:
+ idx = 0;
+ break;
+ default:
+ idx = -1; /* invalid configuration */
+ } /* switch frameType */
+
+ return (((selfPtr == NULL) || (idx == -1)) ? NULL : &selfPtr->frame);
+}
+
+static FDK_SACENC_ERROR writeFramingInfo(HANDLE_FDK_BITSTREAM hBitstream,
+ const FRAMINGINFO *const pFramingInfo,
+ const INT frameLength) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hBitstream == NULL) || (pFramingInfo == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ FDKwriteBits(hBitstream, pFramingInfo->bsFramingType, 1);
+ FDKwriteBits(hBitstream, pFramingInfo->numParamSets - 1, 1);
+
+ if (pFramingInfo->bsFramingType) {
+ int ps = 0;
+ int numParamSets = pFramingInfo->numParamSets;
+
+ {
+ for (ps = 0; ps < numParamSets; ps++) {
+ int bitsParamSlot = 0;
+ while ((1 << bitsParamSlot) < (frameLength + 1)) bitsParamSlot++;
+ if (bitsParamSlot > 0)
+ FDKwriteBits(hBitstream, pFramingInfo->bsParamSlots[ps],
+ bitsParamSlot);
+ }
+ }
+ } /* pFramingInfo->bsFramingType */
+ } /* valid handle */
+
+ return error;
+}
+
+static FDK_SACENC_ERROR writeSmgData(HANDLE_FDK_BITSTREAM hBitstream,
+ const SMGDATA *const pSmgData,
+ const INT numParamSets,
+ const INT dataBands) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hBitstream == NULL) || (pSmgData == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int i, j;
+
+ for (i = 0; i < numParamSets; i++) {
+ FDKwriteBits(hBitstream, pSmgData->bsSmoothMode[i], 2);
+
+ if (pSmgData->bsSmoothMode[i] >= 2) {
+ FDKwriteBits(hBitstream, pSmgData->bsSmoothTime[i], 2);
+ }
+ if (pSmgData->bsSmoothMode[i] == 3) {
+ const int stride = getBsFreqResStride(pSmgData->bsFreqResStride[i]);
+ FDKwriteBits(hBitstream, pSmgData->bsFreqResStride[i], 2);
+ for (j = 0; j < dataBands; j += stride) {
+ FDKwriteBits(hBitstream, pSmgData->bsSmgData[i][j], 1);
+ }
+ }
+ } /* for i */
+ } /* valid handle */
+
+ return error;
+}
+
+static FDK_SACENC_ERROR writeOttData(
+ HANDLE_FDK_BITSTREAM hBitstream, PREV_OTTDATA *const pPrevOttData,
+ OTTDATA *const pOttData, const OTTCONFIG ottConfig[SACENC_MAX_NUM_BOXES],
+ LOSSLESSDATA *const pCLDLosslessData, LOSSLESSDATA *const pICCLosslessData,
+ const INT numOttBoxes, const INT numBands, const INT numParamSets,
+ const INT bsIndependencyFlag) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hBitstream == NULL) || (pPrevOttData == NULL) || (pOttData == NULL) ||
+ (ottConfig == NULL) || (pCLDLosslessData == NULL) ||
+ (pICCLosslessData == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int i;
+ for (i = 0; i < numOttBoxes; i++) {
+ ecData(hBitstream, pOttData->cld[i], pPrevOttData->cld_old[i],
+ pPrevOttData->quantCoarseCldPrev[i], pCLDLosslessData, t_CLD, i,
+ numParamSets, bsIndependencyFlag, 0, ottConfig[i].bsOttBands, 15);
+ }
+ {
+ for (i = 0; i < numOttBoxes; i++) {
+ {
+ ecData(hBitstream, pOttData->icc[i], pPrevOttData->icc_old[i],
+ pPrevOttData->quantCoarseIccPrev[i], pICCLosslessData, t_ICC,
+ i, numParamSets, bsIndependencyFlag, 0, numBands, 0);
+ }
+ } /* for i */
+ }
+ } /* valid handle */
+
+ return error;
+}
+
+/* write extension frame data to stream */
+static FDK_SACENC_ERROR WriteSpatialExtensionFrame(
+ HANDLE_FDK_BITSTREAM bitstream, HANDLE_BSF_INSTANCE self) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((bitstream == NULL) || (self == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ FDKbyteAlign(bitstream, 0);
+ } /* valid handle */
+
+ return error;
+}
+
+/* write frame data to stream */
+FDK_SACENC_ERROR fdk_sacenc_writeSpatialFrame(UCHAR *const pOutputBuffer,
+ const INT outputBufferSize,
+ INT *const pnOutputBits,
+ HANDLE_BSF_INSTANCE selfPtr) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((pOutputBuffer == NULL) || (pnOutputBits == NULL) || (selfPtr == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ SPATIALFRAME *frame = NULL;
+ SPATIALSPECIFICCONFIG *config = NULL;
+ FDK_BITSTREAM bitstream;
+
+ int i, j, numParamSets, numOttBoxes;
+
+ if ((NULL ==
+ (frame = fdk_sacenc_getSpatialFrame(selfPtr, READ_SPATIALFRAME))) ||
+ (NULL == (config = &(selfPtr->spatialSpecificConfig)))) {
+ error = SACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ numOttBoxes = selfPtr->spatialSpecificConfig.treeDescription.numOttBoxes;
+
+ numParamSets = frame->framingInfo.numParamSets;
+
+ if (frame->bUseBBCues) {
+ for (i = 0; i < SACENC_MAX_NUM_BOXES; i++) {
+ /* If a transient was detected, force only the second ps broad band */
+ if (numParamSets == 1) {
+ frame->CLDLosslessData.bsFreqResStrideXXX[i][0] = 3;
+ frame->ICCLosslessData.bsFreqResStrideXXX[i][0] = 3;
+ } else {
+ for (j = 1; j < MAX_NUM_PARAMS; j++) {
+ frame->CLDLosslessData.bsFreqResStrideXXX[i][j] = 3;
+ frame->ICCLosslessData.bsFreqResStrideXXX[i][j] = 3;
+ }
+ }
+ }
+ } /* frame->bUseBBCues */
+
+ /* bind extern buffer to bitstream handle */
+ FDKinitBitStream(&bitstream, pOutputBuffer, outputBufferSize, 0, BS_WRITER);
+
+ if (SACENC_OK != (error = writeFramingInfo(
+ &bitstream, &(frame->framingInfo),
+ selfPtr->spatialSpecificConfig.bsFrameLength))) {
+ goto bail;
+ }
+
+ /* write bsIndependencyFlag */
+ FDKwriteBits(&bitstream, frame->bsIndependencyFlag, 1);
+
+ /* write spatial data to bitstream */
+ if (SACENC_OK !=
+ (error = writeOttData(&bitstream, &selfPtr->prevFrameData.prevOttData,
+ &frame->ottData, config->ottConfig,
+ &frame->CLDLosslessData, &frame->ICCLosslessData,
+ numOttBoxes, config->numBands, numParamSets,
+ frame->bsIndependencyFlag))) {
+ goto bail;
+ }
+ if (SACENC_OK != (error = writeSmgData(&bitstream, &frame->smgData,
+ numParamSets, config->numBands))) {
+ goto bail;
+ }
+
+ /* byte alignment */
+ FDKbyteAlign(&bitstream, 0);
+
+ /* Write SpatialExtensionFrame */
+ if (SACENC_OK !=
+ (error = WriteSpatialExtensionFrame(&bitstream, selfPtr))) {
+ goto bail;
+ }
+
+ if (NULL ==
+ (frame = fdk_sacenc_getSpatialFrame(selfPtr, WRITE_SPATIALFRAME))) {
+ error = SACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ clearFrame(frame);
+
+ /* return number of valid bits in bitstream */
+ if ((*pnOutputBits = FDKgetValidBits(&bitstream)) >
+ (outputBufferSize * 8)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ /* terminate buffer with alignment */
+ FDKbyteAlign(&bitstream, 0);
+
+ } /* valid handle */
+
+bail:
+ return error;
+}
diff --git a/libSACenc/src/sacenc_bitstream.h b/libSACenc/src/sacenc_bitstream.h
new file mode 100644
index 0000000..67b7b5a
--- /dev/null
+++ b/libSACenc/src/sacenc_bitstream.h
@@ -0,0 +1,296 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s):
+
+ Description: Encoder Library Interface
+ Bitstream Writer
+
+*******************************************************************************/
+
+#ifndef SACENC_BITSTREAM_H
+#define SACENC_BITSTREAM_H
+
+/* Includes ******************************************************************/
+#include "FDK_bitstream.h"
+#include "FDK_matrixCalloc.h"
+#include "sacenc_lib.h"
+#include "sacenc_const.h"
+
+/* Defines *******************************************************************/
+#define MAX_NUM_BINS 23
+#define MAX_NUM_PARAMS 2
+#define MAX_NUM_OUTPUTCHANNELS SACENC_MAX_OUTPUT_CHANNELS
+#define MAX_TIME_SLOTS 32
+
+typedef enum {
+ TREE_212 = 7,
+ TREE_ESCAPE = 15
+
+} TREECONFIG;
+
+typedef enum {
+ FREQ_RES_40 = 0,
+ FREQ_RES_20 = 1,
+ FREQ_RES_10 = 2,
+ FREQ_RES_5 = 3
+
+} FREQ;
+
+typedef enum {
+ QUANTMODE_INVALID = -1,
+ QUANTMODE_FINE = 0,
+ QUANTMODE_EBQ1 = 1,
+ QUANTMODE_EBQ2 = 2
+
+} QUANTMODE;
+
+typedef enum {
+ TEMPSHAPE_OFF = 0
+
+} TEMPSHAPECONFIG;
+
+typedef enum {
+ FIXEDGAINDMX_INVALID = -1,
+ FIXEDGAINDMX_0 = 0,
+ FIXEDGAINDMX_1 = 1,
+ FIXEDGAINDMX_2 = 2,
+ FIXEDGAINDMX_3 = 3,
+ FIXEDGAINDMX_4 = 4,
+ FIXEDGAINDMX_5 = 5,
+ FIXEDGAINDMX_6 = 6,
+ FIXEDGAINDMX_7 = 7
+
+} FIXEDGAINDMXCONFIG;
+
+typedef enum {
+ DECORR_INVALID = -1,
+ DECORR_QMFSPLIT0 = 0, /* QMF splitfreq: 3, 15, 24, 65 */
+ DECORR_QMFSPLIT1 = 1, /* QMF splitfreq: 3, 50, 65, 65 */
+ DECORR_QMFSPLIT2 = 2 /* QMF splitfreq: 0, 15, 65, 65 */
+
+} DECORRCONFIG;
+
+typedef enum {
+ DEFAULT = 0,
+ KEEP = 1,
+ INTERPOLATE = 2,
+ FINECOARSE = 3
+
+} DATA_MODE;
+
+typedef enum {
+ READ_SPATIALFRAME = 0,
+ WRITE_SPATIALFRAME = 1
+
+} SPATIALFRAME_TYPE;
+
+/* Data Types ****************************************************************/
+typedef struct {
+ INT numOttBoxes;
+ INT numInChan;
+ INT numOutChan;
+
+} TREEDESCRIPTION;
+
+typedef struct {
+ INT bsOttBands;
+
+} OTTCONFIG;
+
+typedef struct {
+ INT bsSamplingFrequency; /* for bsSamplingFrequencyIndex */
+ INT bsFrameLength;
+ INT numBands; /* for bsFreqRes */
+ TREECONFIG bsTreeConfig;
+ QUANTMODE bsQuantMode;
+ FIXEDGAINDMXCONFIG bsFixedGainDMX;
+ int bsEnvQuantMode;
+ DECORRCONFIG bsDecorrConfig;
+ TREEDESCRIPTION treeDescription;
+ OTTCONFIG ottConfig[SACENC_MAX_NUM_BOXES];
+
+} SPATIALSPECIFICCONFIG;
+
+typedef struct {
+ UCHAR bsFramingType;
+ UCHAR numParamSets;
+ UCHAR bsParamSlots[MAX_NUM_PARAMS];
+
+} FRAMINGINFO;
+
+typedef struct {
+ SCHAR cld[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAMS][MAX_NUM_BINS];
+ SCHAR icc[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAMS][MAX_NUM_BINS];
+
+} OTTDATA;
+
+typedef struct {
+ UCHAR bsSmoothMode[MAX_NUM_PARAMS];
+ UCHAR bsSmoothTime[MAX_NUM_PARAMS];
+ UCHAR bsFreqResStride[MAX_NUM_PARAMS];
+ UCHAR bsSmgData[MAX_NUM_PARAMS][MAX_NUM_BINS];
+
+} SMGDATA;
+
+typedef struct {
+ UCHAR bsEnvShapeChannel[MAX_NUM_OUTPUTCHANNELS];
+ UCHAR bsEnvShapeData[MAX_NUM_OUTPUTCHANNELS][MAX_TIME_SLOTS];
+
+} TEMPSHAPEDATA;
+
+typedef struct {
+ UCHAR bsXXXDataMode[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAMS];
+ UCHAR bsDataPair[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAMS];
+ UCHAR bsQuantCoarseXXX[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAMS];
+ UCHAR bsFreqResStrideXXX[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAMS];
+
+} LOSSLESSDATA;
+
+typedef struct {
+ FRAMINGINFO framingInfo;
+ UCHAR bsIndependencyFlag;
+ OTTDATA ottData;
+ SMGDATA smgData;
+ TEMPSHAPEDATA tempShapeData;
+ LOSSLESSDATA CLDLosslessData;
+ LOSSLESSDATA ICCLosslessData;
+ UCHAR bUseBBCues;
+
+} SPATIALFRAME;
+
+typedef struct BSF_INSTANCE *HANDLE_BSF_INSTANCE;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+/* destroy encoder instance */
+FDK_SACENC_ERROR fdk_sacenc_destroySpatialBitstreamEncoder(
+ HANDLE_BSF_INSTANCE *selfPtr);
+
+/* create encoder instance */
+FDK_SACENC_ERROR fdk_sacenc_createSpatialBitstreamEncoder(
+ HANDLE_BSF_INSTANCE *selfPtr);
+
+FDK_SACENC_ERROR fdk_sacenc_initSpatialBitstreamEncoder(
+ HANDLE_BSF_INSTANCE selfPtr);
+
+/* get SpatialSpecificConfig struct */
+SPATIALSPECIFICCONFIG *fdk_sacenc_getSpatialSpecificConfig(
+ HANDLE_BSF_INSTANCE selfPtr);
+
+/* write SpatialSpecificConfig to stream */
+FDK_SACENC_ERROR fdk_sacenc_writeSpatialSpecificConfig(
+ SPATIALSPECIFICCONFIG *const spatialSpecificConfig,
+ UCHAR *const pOutputBuffer, const INT outputBufferSize,
+ INT *const pnOutputBits);
+
+/* get SpatialFrame struct */
+SPATIALFRAME *fdk_sacenc_getSpatialFrame(HANDLE_BSF_INSTANCE selfPtr,
+ const SPATIALFRAME_TYPE frameType);
+
+/* write frame data to stream */
+FDK_SACENC_ERROR fdk_sacenc_writeSpatialFrame(UCHAR *const pOutputBuffer,
+ const INT outputBufferSize,
+ INT *const pnOutputBits,
+ HANDLE_BSF_INSTANCE selfPtr);
+
+/* Copy/Save spatial frame data for one parameter set */
+FDK_SACENC_ERROR fdk_sacenc_duplicateParameterSet(
+ const SPATIALFRAME *const hFrom, const INT setFrom, SPATIALFRAME *const hTo,
+ const INT setTo);
+
+#endif /* SACENC_BITSTREAM_H */
diff --git a/libSACenc/src/sacenc_const.h b/libSACenc/src/sacenc_const.h
new file mode 100644
index 0000000..c86e765
--- /dev/null
+++ b/libSACenc/src/sacenc_const.h
@@ -0,0 +1,126 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): Markus Multrus
+
+ Description: Encoder Library Interface
+ constants to MPEG-4 spatial encoder lib
+
+*******************************************************************************/
+
+#ifndef SACENC_CONST_H
+#define SACENC_CONST_H
+
+/* Includes ******************************************************************/
+#include "machine_type.h"
+
+/* Defines *******************************************************************/
+#define NUM_QMF_BANDS 64
+#define MAX_QMF_BANDS 128
+
+#define SACENC_MAX_NUM_BOXES 1
+#define SACENC_MAX_INPUT_CHANNELS 2
+#define SACENC_MAX_OUTPUT_CHANNELS 1
+
+#define SACENC_FLOAT_EPSILON (1e-9f)
+
+/* Data Types ****************************************************************/
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+
+#endif /* SACENC_CONST_H */
diff --git a/libSACenc/src/sacenc_delay.cpp b/libSACenc/src/sacenc_delay.cpp
new file mode 100644
index 0000000..f2ed6b0
--- /dev/null
+++ b/libSACenc/src/sacenc_delay.cpp
@@ -0,0 +1,472 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): Christian Goettlinger
+
+ Description: Encoder Library Interface
+ delay management of the encoder
+
+*******************************************************************************/
+
+/**************************************************************************/ /**
+ \file
+ This file contains all delay infrastructure
+ ******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_delay.h"
+#include "sacenc_const.h"
+#include "FDK_matrixCalloc.h"
+
+/* Defines *******************************************************************/
+
+/* Data Types ****************************************************************/
+struct DELAY {
+ struct DELAY_CONFIG {
+ /* Routing Config Switches*/
+ INT bDmxAlign;
+ INT bTimeDomDmx;
+ INT bMinimizeDelay;
+ INT bSacTimeAlignmentDynamicOut;
+
+ /* Needed Input Variables*/
+ INT nQmfLen;
+ INT nFrameLen;
+ INT nSurroundDelay;
+ INT nArbDmxDelay;
+ INT nLimiterDelay;
+ INT nCoreCoderDelay;
+ INT nSacStreamMuxDelay;
+ INT nSacTimeAlignment; /* Overwritten, if bSacTimeAlignmentDynamicOut */
+ } config;
+
+ /* Variable Delaybuffers -> Delays */
+ INT nDmxAlignBuffer;
+ INT nSurroundAnalysisBuffer;
+ INT nArbDmxAnalysisBuffer;
+ INT nOutputAudioBuffer;
+ INT nBitstreamFrameBuffer;
+ INT nOutputAudioQmfFrameBuffer;
+ INT nDiscardOutFrames;
+
+ /* Variable Delaybuffers Computation Variables */
+ INT nBitstreamFrameBufferSize;
+
+ /* Output: Infos */
+ INT nInfoDmxDelay; /* Delay of the downmixed signal after the space encoder */
+ INT nInfoCodecDelay; /* Delay of the whole en-/decoder including CoreCoder */
+ INT nInfoDecoderDelay; /* Delay of the Mpeg Surround decoder */
+};
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+
+/*-----------------------------------------------------------------------------
+functionname: fdk_sacenc_delay_Open()
+description: initializes Delays
+returns: noError on success, an apropriate error code else
+-----------------------------------------------------------------------------*/
+FDK_SACENC_ERROR fdk_sacenc_delay_Open(HANDLE_DELAY *phDelay) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == phDelay) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ FDK_ALLOCATE_MEMORY_1D(*phDelay, 1, struct DELAY);
+ }
+ return error;
+
+bail:
+ fdk_sacenc_delay_Close(phDelay);
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+/*-----------------------------------------------------------------------------
+functionname: fdk_sacenc_delay_Close()
+description: destructs Delay
+returns: noError on success, an apropriate error code else
+-----------------------------------------------------------------------------*/
+FDK_SACENC_ERROR fdk_sacenc_delay_Close(HANDLE_DELAY *phDelay) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == phDelay) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ if (NULL != *phDelay) {
+ FDK_FREE_MEMORY_1D(*phDelay);
+ }
+ }
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_delay_Init(HANDLE_DELAY hDelay, const INT nQmfLen,
+ const INT nFrameLen,
+ const INT nCoreCoderDelay,
+ const INT nSacStreamMuxDelay) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == hDelay) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ /* Fill structure before calculation */
+ FDKmemclear(&hDelay->config, sizeof(hDelay->config));
+
+ hDelay->config.nQmfLen = nQmfLen;
+ hDelay->config.nFrameLen = nFrameLen;
+ hDelay->config.nCoreCoderDelay = nCoreCoderDelay;
+ hDelay->config.nSacStreamMuxDelay = nSacStreamMuxDelay;
+ }
+ return error;
+}
+
+/*-----------------------------------------------------------------------------
+functionname: fdk_sacenc_delay_SubCalulateBufferDelays()
+description: Calculates the Delays of the buffers
+returns: Error Code
+-----------------------------------------------------------------------------*/
+FDK_SACENC_ERROR fdk_sacenc_delay_SubCalulateBufferDelays(HANDLE_DELAY hDel) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == hDel) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int nEncoderAnDelay, nEncoderSynDelay, nEncoderWinDelay, nDecoderAnDelay,
+ nDecoderSynDelay, nResidualCoderFrameDelay,
+ nArbDmxResidualCoderFrameDelay;
+
+ if (hDel->config.bSacTimeAlignmentDynamicOut > 0) {
+ hDel->config.nSacTimeAlignment = 0;
+ }
+
+ {
+ nEncoderAnDelay =
+ 2 * hDel->config.nQmfLen +
+ hDel->config.nQmfLen / 2; /* Only Ld-QMF Delay, no hybrid */
+ nEncoderSynDelay = 1 * hDel->config.nQmfLen + hDel->config.nQmfLen / 2;
+ nDecoderAnDelay = 2 * hDel->config.nQmfLen + hDel->config.nQmfLen / 2;
+ nDecoderSynDelay = 1 * hDel->config.nQmfLen + hDel->config.nQmfLen / 2;
+ nEncoderWinDelay =
+ hDel->config.nFrameLen / 2; /* WindowLookahead is just half a frame */
+ }
+
+ { nResidualCoderFrameDelay = 0; }
+
+ { nArbDmxResidualCoderFrameDelay = 0; }
+
+ /* Calculate variable Buffer-Delays */
+ if (hDel->config.bTimeDomDmx == 0) {
+ /* ArbitraryDmx and TdDmx off */
+ int tempDelay;
+
+ hDel->nSurroundAnalysisBuffer = 0;
+ hDel->nArbDmxAnalysisBuffer = 0;
+ tempDelay = nEncoderSynDelay + hDel->config.nLimiterDelay +
+ hDel->config.nCoreCoderDelay +
+ hDel->config.nSacTimeAlignment + nDecoderAnDelay;
+ tempDelay = (nResidualCoderFrameDelay * hDel->config.nFrameLen) +
+ hDel->config.nSacStreamMuxDelay - tempDelay;
+
+ if (tempDelay > 0) {
+ hDel->nBitstreamFrameBuffer = 0;
+ hDel->nOutputAudioBuffer = tempDelay;
+ } else {
+ tempDelay = -tempDelay;
+ hDel->nBitstreamFrameBuffer =
+ (tempDelay + hDel->config.nFrameLen - 1) / hDel->config.nFrameLen;
+ hDel->nOutputAudioBuffer =
+ (hDel->nBitstreamFrameBuffer * hDel->config.nFrameLen) - tempDelay;
+ }
+
+ hDel->nOutputAudioQmfFrameBuffer =
+ (hDel->nOutputAudioBuffer + (hDel->config.nQmfLen / 2) - 1) /
+ hDel->config.nQmfLen;
+
+ if (hDel->config.bDmxAlign > 0) {
+ tempDelay = nEncoderWinDelay + nEncoderAnDelay + nEncoderSynDelay +
+ hDel->nOutputAudioBuffer + hDel->config.nLimiterDelay +
+ hDel->config.nCoreCoderDelay;
+ hDel->nDiscardOutFrames =
+ (tempDelay + hDel->config.nFrameLen - 1) / hDel->config.nFrameLen;
+ hDel->nDmxAlignBuffer =
+ hDel->nDiscardOutFrames * hDel->config.nFrameLen - tempDelay;
+ } else {
+ hDel->nDiscardOutFrames = 0;
+ hDel->nDmxAlignBuffer = 0;
+ }
+
+ /* Output: Info-Variables */
+ hDel->nInfoDmxDelay = hDel->nSurroundAnalysisBuffer + nEncoderAnDelay +
+ nEncoderWinDelay + nEncoderSynDelay +
+ hDel->nOutputAudioBuffer +
+ hDel->config.nLimiterDelay;
+ hDel->nInfoCodecDelay =
+ hDel->nInfoDmxDelay + hDel->config.nCoreCoderDelay +
+ hDel->config.nSacTimeAlignment + nDecoderAnDelay + nDecoderSynDelay;
+
+ } else {
+ /* ArbitraryDmx or TdDmx on */
+ int tempDelay1, tempDelay2, tempDelay12, tempDelay3;
+
+ tempDelay1 = hDel->config.nArbDmxDelay - hDel->config.nSurroundDelay;
+
+ if (tempDelay1 >= 0) {
+ hDel->nSurroundAnalysisBuffer = tempDelay1;
+ hDel->nArbDmxAnalysisBuffer = 0;
+ } else {
+ hDel->nSurroundAnalysisBuffer = 0;
+ hDel->nArbDmxAnalysisBuffer = -tempDelay1;
+ }
+
+ tempDelay1 = nEncoderWinDelay + hDel->config.nSurroundDelay +
+ hDel->nSurroundAnalysisBuffer +
+ nEncoderAnDelay; /*Surround Path*/
+ tempDelay2 = nEncoderWinDelay + hDel->config.nArbDmxDelay +
+ hDel->nArbDmxAnalysisBuffer +
+ nEncoderAnDelay; /* ArbDmx Compare Path */
+ tempDelay3 = hDel->config.nArbDmxDelay + hDel->config.nLimiterDelay +
+ hDel->config.nCoreCoderDelay +
+ hDel->config.nSacTimeAlignment +
+ nDecoderAnDelay; /* ArbDmx Passthrough*/
+
+ tempDelay12 =
+ FDKmax(nResidualCoderFrameDelay, nArbDmxResidualCoderFrameDelay) *
+ hDel->config.nFrameLen;
+ tempDelay12 += hDel->config.nSacStreamMuxDelay;
+
+ if (tempDelay1 > tempDelay2) {
+ tempDelay12 += tempDelay1;
+ } else {
+ tempDelay12 += tempDelay2;
+ }
+
+ if (tempDelay3 > tempDelay12) {
+ if (hDel->config.bMinimizeDelay > 0) {
+ hDel->nBitstreamFrameBuffer =
+ (tempDelay3 - tempDelay12) / hDel->config.nFrameLen; /*floor*/
+ hDel->nOutputAudioBuffer = 0;
+ hDel->nSurroundAnalysisBuffer +=
+ (tempDelay3 - tempDelay12 -
+ (hDel->nBitstreamFrameBuffer * hDel->config.nFrameLen));
+ hDel->nArbDmxAnalysisBuffer +=
+ (tempDelay3 - tempDelay12 -
+ (hDel->nBitstreamFrameBuffer * hDel->config.nFrameLen));
+ } else {
+ hDel->nBitstreamFrameBuffer =
+ ((tempDelay3 - tempDelay12) + hDel->config.nFrameLen - 1) /
+ hDel->config.nFrameLen;
+ hDel->nOutputAudioBuffer =
+ hDel->nBitstreamFrameBuffer * hDel->config.nFrameLen +
+ tempDelay12 - tempDelay3;
+ }
+ } else {
+ hDel->nBitstreamFrameBuffer = 0;
+ hDel->nOutputAudioBuffer = tempDelay12 - tempDelay3;
+ }
+
+ if (hDel->config.bDmxAlign > 0) {
+ int tempDelay = hDel->config.nArbDmxDelay + hDel->nOutputAudioBuffer +
+ hDel->config.nLimiterDelay +
+ hDel->config.nCoreCoderDelay;
+ hDel->nDiscardOutFrames =
+ (tempDelay + hDel->config.nFrameLen - 1) / hDel->config.nFrameLen;
+ hDel->nDmxAlignBuffer =
+ hDel->nDiscardOutFrames * hDel->config.nFrameLen - tempDelay;
+ } else {
+ hDel->nDiscardOutFrames = 0;
+ hDel->nDmxAlignBuffer = 0;
+ }
+
+ /* Output: Info-Variables */
+ hDel->nInfoDmxDelay = hDel->config.nArbDmxDelay +
+ hDel->nOutputAudioBuffer +
+ hDel->config.nLimiterDelay;
+ hDel->nInfoCodecDelay =
+ hDel->nInfoDmxDelay + hDel->config.nCoreCoderDelay +
+ hDel->config.nSacTimeAlignment + nDecoderAnDelay + nDecoderSynDelay;
+ hDel->nInfoDecoderDelay = nDecoderAnDelay + nDecoderSynDelay;
+
+ } /* ArbitraryDmx or TdDmx on */
+
+ /* Additonal Variables needed for Computation Issues */
+ hDel->nBitstreamFrameBufferSize = hDel->nBitstreamFrameBuffer + 1;
+ }
+
+ return error;
+}
+
+static FDK_SACENC_ERROR assignParameterInRange(
+ const INT startRange, /* including startRange */
+ const INT stopRange, /* including stopRange */
+ const INT value, /* value to write*/
+ INT *const ptr /* destination pointer*/
+) {
+ FDK_SACENC_ERROR error = SACENC_INVALID_CONFIG;
+
+ if ((startRange <= value) && (value <= stopRange)) {
+ *ptr = value;
+ error = SACENC_OK;
+ }
+
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_delay_SetDmxAlign(HANDLE_DELAY hDelay,
+ const INT bDmxAlignIn) {
+ return (assignParameterInRange(0, 1, bDmxAlignIn, &hDelay->config.bDmxAlign));
+}
+
+FDK_SACENC_ERROR fdk_sacenc_delay_SetTimeDomDmx(HANDLE_DELAY hDelay,
+ const INT bTimeDomDmxIn) {
+ return (
+ assignParameterInRange(0, 1, bTimeDomDmxIn, &hDelay->config.bTimeDomDmx));
+}
+
+FDK_SACENC_ERROR fdk_sacenc_delay_SetSacTimeAlignmentDynamicOut(
+ HANDLE_DELAY hDelay, const INT bSacTimeAlignmentDynamicOutIn) {
+ return (assignParameterInRange(0, 1, bSacTimeAlignmentDynamicOutIn,
+ &hDelay->config.bSacTimeAlignmentDynamicOut));
+}
+
+FDK_SACENC_ERROR fdk_sacenc_delay_SetNSacTimeAlignment(
+ HANDLE_DELAY hDelay, const INT nSacTimeAlignmentIn) {
+ return (assignParameterInRange(-32768, 32767, nSacTimeAlignmentIn,
+ &hDelay->config.nSacTimeAlignment));
+}
+
+FDK_SACENC_ERROR fdk_sacenc_delay_SetMinimizeDelay(HANDLE_DELAY hDelay,
+ const INT bMinimizeDelay) {
+ return (assignParameterInRange(0, 1, bMinimizeDelay,
+ &hDelay->config.bMinimizeDelay));
+}
+
+INT fdk_sacenc_delay_GetOutputAudioBufferDelay(HANDLE_DELAY hDelay) {
+ return (hDelay->nOutputAudioBuffer);
+}
+
+INT fdk_sacenc_delay_GetSurroundAnalysisBufferDelay(HANDLE_DELAY hDelay) {
+ return (hDelay->nSurroundAnalysisBuffer);
+}
+
+INT fdk_sacenc_delay_GetArbDmxAnalysisBufferDelay(HANDLE_DELAY hDelay) {
+ return (hDelay->nArbDmxAnalysisBuffer);
+}
+
+INT fdk_sacenc_delay_GetBitstreamFrameBufferSize(HANDLE_DELAY hDelay) {
+ return (hDelay->nBitstreamFrameBufferSize);
+}
+
+INT fdk_sacenc_delay_GetDmxAlignBufferDelay(HANDLE_DELAY hDelay) {
+ return (hDelay->nDmxAlignBuffer);
+}
+
+INT fdk_sacenc_delay_GetDiscardOutFrames(HANDLE_DELAY hDelay) {
+ return (hDelay->nDiscardOutFrames);
+}
+
+INT fdk_sacenc_delay_GetInfoDmxDelay(HANDLE_DELAY hDelay) {
+ return (hDelay->nInfoDmxDelay);
+}
+
+INT fdk_sacenc_delay_GetInfoCodecDelay(HANDLE_DELAY hDelay) {
+ return (hDelay->nInfoCodecDelay);
+}
+
+INT fdk_sacenc_delay_GetInfoDecoderDelay(HANDLE_DELAY hDelay) {
+ return (hDelay->nInfoDecoderDelay);
+}
diff --git a/libSACenc/src/sacenc_delay.h b/libSACenc/src/sacenc_delay.h
new file mode 100644
index 0000000..38bfbc5
--- /dev/null
+++ b/libSACenc/src/sacenc_delay.h
@@ -0,0 +1,175 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): Christian Goettlinger
+
+ Description: Encoder Library Interface
+ delay management of the encoder
+
+*******************************************************************************/
+
+/**************************************************************************/ /**
+ \file
+ ******************************************************************************/
+#ifndef SACENC_DELAY_H
+#define SACENC_DELAY_H
+
+/* Includes ******************************************************************/
+#include "sacenc_lib.h"
+#include "machine_type.h"
+#include "FDK_matrixCalloc.h"
+
+/* Defines *******************************************************************/
+#define MAX_DELAY_INPUT 1024
+#define MAX_DELAY_OUTPUT 4096
+/* bumped from 0 to 5. this should be equal or larger to the dualrate sbr
+ * resampler filter length */
+#define MAX_DELAY_SURROUND_ANALYSIS 5
+#define MAX_BITSTREAM_DELAY 1
+
+/* Data Types ****************************************************************/
+typedef struct DELAY *HANDLE_DELAY;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+FDK_SACENC_ERROR fdk_sacenc_delay_Open(HANDLE_DELAY *phDelay);
+
+FDK_SACENC_ERROR fdk_sacenc_delay_Close(HANDLE_DELAY *phDelay);
+
+FDK_SACENC_ERROR fdk_sacenc_delay_Init(HANDLE_DELAY hDelay, const INT nQmfLen,
+ const INT nFrameLen,
+ const INT nCoreCoderDelay,
+ const INT nSacStreamMuxDelay);
+
+FDK_SACENC_ERROR fdk_sacenc_delay_SubCalulateBufferDelays(HANDLE_DELAY hDel);
+
+/* Set Expert Config Parameters */
+FDK_SACENC_ERROR fdk_sacenc_delay_SetDmxAlign(HANDLE_DELAY hDelay,
+ const INT bDmxAlignIn);
+
+FDK_SACENC_ERROR fdk_sacenc_delay_SetTimeDomDmx(HANDLE_DELAY hDelay,
+ const INT bTimeDomDmxIn);
+
+FDK_SACENC_ERROR fdk_sacenc_delay_SetSacTimeAlignmentDynamicOut(
+ HANDLE_DELAY hDelay, const INT bSacTimeAlignmentDynamicOutIn);
+
+FDK_SACENC_ERROR fdk_sacenc_delay_SetNSacTimeAlignment(
+ HANDLE_DELAY hDelay, const INT nSacTimeAlignmentIn);
+
+FDK_SACENC_ERROR fdk_sacenc_delay_SetMinimizeDelay(HANDLE_DELAY hDelay,
+ const INT bMinimizeDelay);
+
+/* Get Internal Variables */
+INT fdk_sacenc_delay_GetOutputAudioBufferDelay(HANDLE_DELAY hDelay);
+
+INT fdk_sacenc_delay_GetSurroundAnalysisBufferDelay(HANDLE_DELAY hDelay);
+
+INT fdk_sacenc_delay_GetArbDmxAnalysisBufferDelay(HANDLE_DELAY hDelay);
+
+INT fdk_sacenc_delay_GetBitstreamFrameBufferSize(HANDLE_DELAY hDelay);
+
+INT fdk_sacenc_delay_GetDmxAlignBufferDelay(HANDLE_DELAY hDelay);
+
+INT fdk_sacenc_delay_GetDiscardOutFrames(HANDLE_DELAY hDelay);
+
+INT fdk_sacenc_delay_GetInfoDmxDelay(HANDLE_DELAY hDelay);
+
+INT fdk_sacenc_delay_GetInfoCodecDelay(HANDLE_DELAY hDelay);
+
+INT fdk_sacenc_delay_GetInfoDecoderDelay(HANDLE_DELAY hDelay);
+
+#endif /* SACENC_DELAY_H */
diff --git a/libSACenc/src/sacenc_dmx_tdom_enh.cpp b/libSACenc/src/sacenc_dmx_tdom_enh.cpp
new file mode 100644
index 0000000..be66c83
--- /dev/null
+++ b/libSACenc/src/sacenc_dmx_tdom_enh.cpp
@@ -0,0 +1,639 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): M. Luis Valero
+
+ Description: Enhanced Time Domain Downmix
+
+*******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_dmx_tdom_enh.h"
+
+#include "FDK_matrixCalloc.h"
+#include "FDK_trigFcts.h"
+#include "fixpoint_math.h"
+
+/* Defines *******************************************************************/
+#define PI_FLT 3.1415926535897931f
+#define ALPHA_FLT 0.0001f
+
+#define PI_E (2)
+#define PI_M (FL2FXCONST_DBL(PI_FLT / (1 << PI_E)))
+
+#define ALPHA_E (13)
+#define ALPHA_M (FL2FXCONST_DBL(ALPHA_FLT * (1 << ALPHA_E)))
+
+enum { L = 0, R = 1 };
+
+/* Data Types ****************************************************************/
+typedef struct T_ENHANCED_TIME_DOMAIN_DMX {
+ int maxFramelength;
+
+ int framelength;
+
+ FIXP_DBL prev_gain_m[2];
+ INT prev_gain_e;
+ FIXP_DBL prev_H1_m[2];
+ INT prev_H1_e;
+
+ FIXP_DBL *sinusWindow_m;
+ SCHAR sinusWindow_e;
+
+ FIXP_DBL prev_Left_m;
+ INT prev_Left_e;
+ FIXP_DBL prev_Right_m;
+ INT prev_Right_e;
+ FIXP_DBL prev_XNrg_m;
+ INT prev_XNrg_e;
+
+ FIXP_DBL lin_bbCld_weight_m;
+ INT lin_bbCld_weight_e;
+ FIXP_DBL gain_weight_m[2];
+ INT gain_weight_e;
+
+} ENHANCED_TIME_DOMAIN_DMX;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+static void calculateRatio(const FIXP_DBL sqrt_linCld_m,
+ const INT sqrt_linCld_e, const FIXP_DBL lin_Cld_m,
+ const INT lin_Cld_e, const FIXP_DBL Icc_m,
+ const INT Icc_e, FIXP_DBL G_m[2], INT *G_e);
+
+static void calculateDmxGains(const FIXP_DBL lin_Cld_m, const INT lin_Cld_e,
+ const FIXP_DBL lin_Cld2_m, const INT lin_Cld2_e,
+ const FIXP_DBL Icc_m, const INT Icc_e,
+ const FIXP_DBL G_m[2], const INT G_e,
+ FIXP_DBL H1_m[2], INT *pH1_e);
+
+/* Function / Class Definition ***********************************************/
+static FIXP_DBL invSqrtNorm2(const FIXP_DBL op_m, const INT op_e,
+ INT *const result_e) {
+ FIXP_DBL src_m = op_m;
+ int src_e = op_e;
+
+ if (src_e & 1) {
+ src_m >>= 1;
+ src_e += 1;
+ }
+
+ src_m = invSqrtNorm2(src_m, result_e);
+ *result_e = (*result_e) - (src_e >> 1);
+
+ return src_m;
+}
+
+static FIXP_DBL sqrtFixp(const FIXP_DBL op_m, const INT op_e,
+ INT *const result_e) {
+ FIXP_DBL src_m = op_m;
+ int src_e = op_e;
+
+ if (src_e & 1) {
+ src_m >>= 1;
+ src_e += 1;
+ }
+
+ *result_e = (src_e >> 1);
+ return sqrtFixp(src_m);
+}
+
+static FIXP_DBL fixpAdd(const FIXP_DBL src1_m, const INT src1_e,
+ const FIXP_DBL src2_m, const INT src2_e,
+ INT *const dst_e) {
+ FIXP_DBL dst_m;
+
+ if (src1_m == FL2FXCONST_DBL(0.f)) {
+ *dst_e = src2_e;
+ dst_m = src2_m;
+ } else if (src2_m == FL2FXCONST_DBL(0.f)) {
+ *dst_e = src1_e;
+ dst_m = src1_m;
+ } else {
+ *dst_e = fixMax(src1_e, src2_e) + 1;
+ dst_m =
+ scaleValue(src1_m, fixMax((src1_e - (*dst_e)), -(DFRACT_BITS - 1))) +
+ scaleValue(src2_m, fixMax((src2_e - (*dst_e)), -(DFRACT_BITS - 1)));
+ }
+ return dst_m;
+}
+
+/**
+ * \brief Sum up fixpoint values with best possible accuracy.
+ *
+ * \param value1 First input value.
+ * \param q1 Scaling factor of first input value.
+ * \param pValue2 Pointer to second input value, will be modified on
+ * return.
+ * \param pQ2 Pointer to second scaling factor, will be modified on
+ * return.
+ *
+ * \return void
+ */
+static void fixpAddNorm(const FIXP_DBL value1, const INT q1,
+ FIXP_DBL *const pValue2, INT *const pQ2) {
+ const int headroom1 = fNormz(fixp_abs(value1)) - 1;
+ const int headroom2 = fNormz(fixp_abs(*pValue2)) - 1;
+ int resultScale = fixMax(q1 - headroom1, (*pQ2) - headroom2);
+
+ if ((value1 != FL2FXCONST_DBL(0.f)) && (*pValue2 != FL2FXCONST_DBL(0.f))) {
+ resultScale++;
+ }
+
+ *pValue2 =
+ scaleValue(value1, q1 - resultScale) +
+ scaleValue(*pValue2, fixMax(-(DFRACT_BITS - 1), ((*pQ2) - resultScale)));
+ *pQ2 = (*pValue2 != (FIXP_DBL)0) ? resultScale : DFRACT_BITS - 1;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_open_enhancedTimeDomainDmx(
+ HANDLE_ENHANCED_TIME_DOMAIN_DMX *phEnhancedTimeDmx, const INT framelength) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+ HANDLE_ENHANCED_TIME_DOMAIN_DMX hEnhancedTimeDmx = NULL;
+
+ if (NULL == phEnhancedTimeDmx) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ FDK_ALLOCATE_MEMORY_1D(hEnhancedTimeDmx, 1, ENHANCED_TIME_DOMAIN_DMX);
+ FDK_ALLOCATE_MEMORY_1D(hEnhancedTimeDmx->sinusWindow_m, 1 + framelength,
+ FIXP_DBL);
+ hEnhancedTimeDmx->maxFramelength = framelength;
+ *phEnhancedTimeDmx = hEnhancedTimeDmx;
+ }
+ return error;
+
+bail:
+ fdk_sacenc_close_enhancedTimeDomainDmx(&hEnhancedTimeDmx);
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+FDK_SACENC_ERROR fdk_sacenc_init_enhancedTimeDomainDmx(
+ HANDLE_ENHANCED_TIME_DOMAIN_DMX hEnhancedTimeDmx,
+ const FIXP_DBL *const pInputGain_m, const INT inputGain_e,
+ const FIXP_DBL outputGain_m, const INT outputGain_e,
+ const INT framelength) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (hEnhancedTimeDmx == NULL) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int smp;
+ if (framelength > hEnhancedTimeDmx->maxFramelength) {
+ error = SACENC_INIT_ERROR;
+ goto bail;
+ }
+
+ hEnhancedTimeDmx->framelength = framelength;
+
+ INT deltax_e;
+ FIXP_DBL deltax_m;
+
+ deltax_m = fDivNormHighPrec(
+ PI_M, (FIXP_DBL)(2 * hEnhancedTimeDmx->framelength), &deltax_e);
+ deltax_m = scaleValue(deltax_m, PI_E + deltax_e - (DFRACT_BITS - 1) - 1);
+ deltax_e = 1;
+
+ for (smp = 0; smp < hEnhancedTimeDmx->framelength + 1; smp++) {
+ hEnhancedTimeDmx->sinusWindow_m[smp] =
+ fMult(ALPHA_M, fPow2(fixp_sin(smp * deltax_m, deltax_e)));
+ }
+ hEnhancedTimeDmx->sinusWindow_e = -ALPHA_E;
+
+ hEnhancedTimeDmx->prev_Left_m = hEnhancedTimeDmx->prev_Right_m =
+ hEnhancedTimeDmx->prev_XNrg_m = FL2FXCONST_DBL(0.f);
+ hEnhancedTimeDmx->prev_Left_e = hEnhancedTimeDmx->prev_Right_e =
+ hEnhancedTimeDmx->prev_XNrg_e = DFRACT_BITS - 1;
+
+ hEnhancedTimeDmx->lin_bbCld_weight_m =
+ fDivNormHighPrec(fPow2(pInputGain_m[L]), fPow2(pInputGain_m[R]),
+ &hEnhancedTimeDmx->lin_bbCld_weight_e);
+
+ hEnhancedTimeDmx->gain_weight_m[L] = fMult(pInputGain_m[L], outputGain_m);
+ hEnhancedTimeDmx->gain_weight_m[R] = fMult(pInputGain_m[R], outputGain_m);
+ hEnhancedTimeDmx->gain_weight_e =
+ -fNorm(fixMax(hEnhancedTimeDmx->gain_weight_m[L],
+ hEnhancedTimeDmx->gain_weight_m[R]));
+
+ hEnhancedTimeDmx->gain_weight_m[L] = scaleValue(
+ hEnhancedTimeDmx->gain_weight_m[L], -hEnhancedTimeDmx->gain_weight_e);
+ hEnhancedTimeDmx->gain_weight_m[R] = scaleValue(
+ hEnhancedTimeDmx->gain_weight_m[R], -hEnhancedTimeDmx->gain_weight_e);
+ hEnhancedTimeDmx->gain_weight_e += inputGain_e + outputGain_e;
+
+ hEnhancedTimeDmx->prev_gain_m[L] = hEnhancedTimeDmx->gain_weight_m[L] >> 1;
+ hEnhancedTimeDmx->prev_gain_m[R] = hEnhancedTimeDmx->gain_weight_m[R] >> 1;
+ hEnhancedTimeDmx->prev_gain_e = hEnhancedTimeDmx->gain_weight_e + 1;
+
+ hEnhancedTimeDmx->prev_H1_m[L] =
+ scaleValue(hEnhancedTimeDmx->gain_weight_m[L], -4);
+ hEnhancedTimeDmx->prev_H1_m[R] =
+ scaleValue(hEnhancedTimeDmx->gain_weight_m[R], -4);
+ hEnhancedTimeDmx->prev_H1_e = 2 + 2 + hEnhancedTimeDmx->gain_weight_e;
+ }
+bail:
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_apply_enhancedTimeDomainDmx(
+ HANDLE_ENHANCED_TIME_DOMAIN_DMX hEnhancedTimeDmx,
+ const INT_PCM *const *const inputTime, INT_PCM *const outputTimeDmx,
+ const INT InputDelay) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((NULL == hEnhancedTimeDmx) || (NULL == inputTime) ||
+ (NULL == inputTime[L]) || (NULL == inputTime[R]) ||
+ (NULL == outputTimeDmx)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int smp;
+ FIXP_DBL lin_bbCld_m, lin_Cld_m, bbCorr_m, sqrt_linCld_m, G_m[2], H1_m[2],
+ gainLeft_m, gainRight_m;
+ FIXP_DBL bbNrgLeft_m, bbNrgRight_m, bbXNrg_m, nrgLeft_m, nrgRight_m, nrgX_m;
+ INT lin_bbCld_e, lin_Cld_e, bbCorr_e, sqrt_linCld_e, G_e, H1_e;
+ INT bbNrgLeft_e, bbNrgRight_e, bbXNrg_e, nrgLeft_e, nrgRight_e, nrgX_e;
+
+ /* Increase energy time resolution with shorter processing blocks. 128 is an
+ * empiric value. */
+ const int granuleLength = fixMin(128, hEnhancedTimeDmx->framelength);
+ int granuleShift =
+ (granuleLength > 1)
+ ? ((DFRACT_BITS - 1) - fNorm((FIXP_DBL)(granuleLength - 1)))
+ : 0;
+ granuleShift = fixMax(
+ 3, granuleShift +
+ 1); /* one bit more headroom for worst case accumulation */
+
+ smp = 0;
+
+ /* Prevent division by zero. */
+ bbNrgLeft_m = bbNrgRight_m = bbXNrg_m = (FIXP_DBL)(1);
+ bbNrgLeft_e = bbNrgRight_e = bbXNrg_e = 0;
+
+ do {
+ const int offset = smp;
+ FIXP_DBL partialL, partialR, partialX;
+ partialL = partialR = partialX = FL2FXCONST_DBL(0.f);
+
+ int in_margin = FDKmin(
+ getScalefactorPCM(
+ &inputTime[L][offset],
+ fixMin(offset + granuleLength, hEnhancedTimeDmx->framelength) -
+ offset,
+ 1),
+ getScalefactorPCM(
+ &inputTime[R][offset],
+ fixMin(offset + granuleLength, hEnhancedTimeDmx->framelength) -
+ offset,
+ 1));
+
+ /* partial energy */
+ for (smp = offset;
+ smp < fixMin(offset + granuleLength, hEnhancedTimeDmx->framelength);
+ smp++) {
+ FIXP_PCM inputL =
+ scaleValue((FIXP_PCM)inputTime[L][smp], in_margin - 1);
+ FIXP_PCM inputR =
+ scaleValue((FIXP_PCM)inputTime[R][smp], in_margin - 1);
+
+ partialL += fPow2Div2(inputL) >> (granuleShift - 3);
+ partialR += fPow2Div2(inputR) >> (granuleShift - 3);
+ partialX += fMultDiv2(inputL, inputR) >> (granuleShift - 3);
+ }
+
+ fixpAddNorm(partialL, granuleShift - 2 * in_margin, &bbNrgLeft_m,
+ &bbNrgLeft_e);
+ fixpAddNorm(partialR, granuleShift - 2 * in_margin, &bbNrgRight_m,
+ &bbNrgRight_e);
+ fixpAddNorm(partialX, granuleShift - 2 * in_margin, &bbXNrg_m, &bbXNrg_e);
+ } while (smp < hEnhancedTimeDmx->framelength);
+
+ nrgLeft_m =
+ fixpAdd(hEnhancedTimeDmx->prev_Left_m, hEnhancedTimeDmx->prev_Left_e,
+ bbNrgLeft_m, bbNrgLeft_e, &nrgLeft_e);
+ nrgRight_m =
+ fixpAdd(hEnhancedTimeDmx->prev_Right_m, hEnhancedTimeDmx->prev_Right_e,
+ bbNrgRight_m, bbNrgRight_e, &nrgRight_e);
+ nrgX_m =
+ fixpAdd(hEnhancedTimeDmx->prev_XNrg_m, hEnhancedTimeDmx->prev_XNrg_e,
+ bbXNrg_m, bbXNrg_e, &nrgX_e);
+
+ lin_bbCld_m = fMult(hEnhancedTimeDmx->lin_bbCld_weight_m,
+ fDivNorm(nrgLeft_m, nrgRight_m, &lin_bbCld_e));
+ lin_bbCld_e +=
+ hEnhancedTimeDmx->lin_bbCld_weight_e + nrgLeft_e - nrgRight_e;
+
+ bbCorr_m = fMult(nrgX_m, invSqrtNorm2(fMult(nrgLeft_m, nrgRight_m),
+ nrgLeft_e + nrgRight_e, &bbCorr_e));
+ bbCorr_e += nrgX_e;
+
+ hEnhancedTimeDmx->prev_Left_m = bbNrgLeft_m;
+ hEnhancedTimeDmx->prev_Left_e = bbNrgLeft_e;
+ hEnhancedTimeDmx->prev_Right_m = bbNrgRight_m;
+ hEnhancedTimeDmx->prev_Right_e = bbNrgRight_e;
+ hEnhancedTimeDmx->prev_XNrg_m = bbXNrg_m;
+ hEnhancedTimeDmx->prev_XNrg_e = bbXNrg_e;
+
+ /*
+ bbCld = 10.f*log10(lin_bbCld)
+
+ lin_Cld = pow(10,bbCld/20)
+ = pow(10,10.f*log10(lin_bbCld)/20.f)
+ = sqrt(lin_bbCld)
+
+ lin_Cld2 = lin_Cld*lin_Cld
+ = sqrt(lin_bbCld)*sqrt(lin_bbCld)
+ = lin_bbCld
+ */
+ lin_Cld_m = sqrtFixp(lin_bbCld_m, lin_bbCld_e, &lin_Cld_e);
+ sqrt_linCld_m = sqrtFixp(lin_Cld_m, lin_Cld_e, &sqrt_linCld_e);
+
+ /*calculate how much right and how much left signal, to avoid signal
+ * cancellations*/
+ calculateRatio(sqrt_linCld_m, sqrt_linCld_e, lin_Cld_m, lin_Cld_e, bbCorr_m,
+ bbCorr_e, G_m, &G_e);
+
+ /*calculate downmix gains*/
+ calculateDmxGains(lin_Cld_m, lin_Cld_e, lin_bbCld_m, lin_bbCld_e, bbCorr_m,
+ bbCorr_e, G_m, G_e, H1_m, &H1_e);
+
+ /*adapt output gains*/
+ H1_m[L] = fMult(H1_m[L], hEnhancedTimeDmx->gain_weight_m[L]);
+ H1_m[R] = fMult(H1_m[R], hEnhancedTimeDmx->gain_weight_m[R]);
+ H1_e += hEnhancedTimeDmx->gain_weight_e;
+
+ gainLeft_m = hEnhancedTimeDmx->prev_gain_m[L];
+ gainRight_m = hEnhancedTimeDmx->prev_gain_m[R];
+
+ INT intermediate_gain_e =
+ +hEnhancedTimeDmx->sinusWindow_e + H1_e - hEnhancedTimeDmx->prev_gain_e;
+
+ for (smp = 0; smp < hEnhancedTimeDmx->framelength; smp++) {
+ const INT N = hEnhancedTimeDmx->framelength;
+ FIXP_DBL intermediate_gainLeft_m, intermediate_gainRight_m, tmp;
+
+ intermediate_gainLeft_m =
+ scaleValue((fMult(hEnhancedTimeDmx->sinusWindow_m[smp], H1_m[L]) +
+ fMult(hEnhancedTimeDmx->sinusWindow_m[N - smp],
+ hEnhancedTimeDmx->prev_H1_m[L])),
+ intermediate_gain_e);
+ intermediate_gainRight_m =
+ scaleValue((fMult(hEnhancedTimeDmx->sinusWindow_m[smp], H1_m[R]) +
+ fMult(hEnhancedTimeDmx->sinusWindow_m[N - smp],
+ hEnhancedTimeDmx->prev_H1_m[R])),
+ intermediate_gain_e);
+
+ gainLeft_m = intermediate_gainLeft_m +
+ fMult(FL2FXCONST_DBL(1.f - ALPHA_FLT), gainLeft_m);
+ gainRight_m = intermediate_gainRight_m +
+ fMult(FL2FXCONST_DBL(1.f - ALPHA_FLT), gainRight_m);
+
+ tmp = fMultDiv2(gainLeft_m, (FIXP_PCM)inputTime[L][smp + InputDelay]) +
+ fMultDiv2(gainRight_m, (FIXP_PCM)inputTime[R][smp + InputDelay]);
+ outputTimeDmx[smp] = (INT_PCM)SATURATE_SHIFT(
+ tmp,
+ -(hEnhancedTimeDmx->prev_gain_e + 1 - (DFRACT_BITS - SAMPLE_BITS)),
+ SAMPLE_BITS);
+ }
+
+ hEnhancedTimeDmx->prev_gain_m[L] = gainLeft_m;
+ hEnhancedTimeDmx->prev_gain_m[R] = gainRight_m;
+
+ hEnhancedTimeDmx->prev_H1_m[L] = H1_m[L];
+ hEnhancedTimeDmx->prev_H1_m[R] = H1_m[R];
+ hEnhancedTimeDmx->prev_H1_e = H1_e;
+ }
+
+ return error;
+}
+
+static void calculateRatio(const FIXP_DBL sqrt_linCld_m,
+ const INT sqrt_linCld_e, const FIXP_DBL lin_Cld_m,
+ const INT lin_Cld_e, const FIXP_DBL Icc_m,
+ const INT Icc_e, FIXP_DBL G_m[2], INT *G_e) {
+#define G_SCALE_FACTOR (2)
+
+ if (Icc_m >= FL2FXCONST_DBL(0.f)) {
+ G_m[0] = G_m[1] = FL2FXCONST_DBL(1.f / (float)(1 << G_SCALE_FACTOR));
+ G_e[0] = G_SCALE_FACTOR;
+ } else {
+ const FIXP_DBL max_gain_factor =
+ FL2FXCONST_DBL(2.f / (float)(1 << G_SCALE_FACTOR));
+ FIXP_DBL tmp1_m, tmp2_m, numerator_m, denominator_m, r_m, r4_m, q;
+ INT tmp1_e, tmp2_e, numerator_e, denominator_e, r_e, r4_e;
+
+ /* r = (lin_Cld + 1 + 2*Icc*sqrt_linCld) / (lin_Cld + 1 -
+ * 2*Icc*sqrt_linCld) = (tmp1 + tmp2) / (tmp1 - tmp2)
+ */
+ tmp1_m =
+ fixpAdd(lin_Cld_m, lin_Cld_e, FL2FXCONST_DBL(1.f / 2.f), 1, &tmp1_e);
+
+ tmp2_m = fMult(Icc_m, sqrt_linCld_m);
+ tmp2_e = 1 + Icc_e + sqrt_linCld_e;
+ numerator_m = fixpAdd(tmp1_m, tmp1_e, tmp2_m, tmp2_e, &numerator_e);
+ denominator_m = fixpAdd(tmp1_m, tmp1_e, -tmp2_m, tmp2_e, &denominator_e);
+
+ if ((numerator_m > FL2FXCONST_DBL(0.f)) &&
+ (denominator_m > FL2FXCONST_DBL(0.f))) {
+ r_m = fDivNorm(numerator_m, denominator_m, &r_e);
+ r_e += numerator_e - denominator_e;
+
+ /* r_4 = sqrt( sqrt( r ) ) */
+ r4_m = sqrtFixp(r_m, r_e, &r4_e);
+ r4_m = sqrtFixp(r4_m, r4_e, &r4_e);
+
+ r4_e -= G_SCALE_FACTOR;
+
+ /* q = min(r4_m, max_gain_factor) */
+ q = ((r4_e >= 0) && (r4_m >= (max_gain_factor >> r4_e)))
+ ? max_gain_factor
+ : scaleValue(r4_m, r4_e);
+ } else {
+ q = FL2FXCONST_DBL(0.f);
+ }
+
+ G_m[0] = max_gain_factor - q;
+ G_m[1] = q;
+
+ *G_e = G_SCALE_FACTOR;
+ }
+}
+
+static void calculateDmxGains(const FIXP_DBL lin_Cld_m, const INT lin_Cld_e,
+ const FIXP_DBL lin_Cld2_m, const INT lin_Cld2_e,
+ const FIXP_DBL Icc_m, const INT Icc_e,
+ const FIXP_DBL G_m[2], const INT G_e,
+ FIXP_DBL H1_m[2], INT *pH1_e) {
+#define H1_SCALE_FACTOR (2)
+ const FIXP_DBL max_gain_factor =
+ FL2FXCONST_DBL(2.f / (float)(1 << H1_SCALE_FACTOR));
+
+ FIXP_DBL nrgRight_m, nrgLeft_m, crossNrg_m, inv_weight_num_m,
+ inv_weight_denom_m, inverse_weight_m, inverse_weight_limited;
+ INT nrgRight_e, nrgLeft_e, crossNrg_e, inv_weight_num_e, inv_weight_denom_e,
+ inverse_weight_e;
+
+ /* nrgRight = sqrt(1/(lin_Cld2 + 1) */
+ nrgRight_m = fixpAdd(lin_Cld2_m, lin_Cld2_e, FL2FXCONST_DBL(1.f / 2.f), 1,
+ &nrgRight_e);
+ nrgRight_m = invSqrtNorm2(nrgRight_m, nrgRight_e, &nrgRight_e);
+
+ /* nrgLeft = lin_Cld * nrgRight */
+ nrgLeft_m = fMult(lin_Cld_m, nrgRight_m);
+ nrgLeft_e = lin_Cld_e + nrgRight_e;
+
+ /* crossNrg = sqrt(nrgLeft*nrgRight) */
+ crossNrg_m = sqrtFixp(fMult(nrgLeft_m, nrgRight_m), nrgLeft_e + nrgRight_e,
+ &crossNrg_e);
+
+ /* inverse_weight = sqrt((nrgLeft + nrgRight) / ( (G[0]*G[0]*nrgLeft) +
+ * (G[1]*G[1]*nrgRight) + 2*G[0]*G[1]*Icc*crossNrg)) = sqrt(inv_weight_num /
+ * inv_weight_denom)
+ */
+ inv_weight_num_m =
+ fixpAdd(nrgRight_m, nrgRight_e, nrgLeft_m, nrgLeft_e, &inv_weight_num_e);
+
+ inv_weight_denom_m =
+ fixpAdd(fMult(fPow2(G_m[0]), nrgLeft_m), 2 * G_e + nrgLeft_e,
+ fMult(fPow2(G_m[1]), nrgRight_m), 2 * G_e + nrgRight_e,
+ &inv_weight_denom_e);
+
+ inv_weight_denom_m =
+ fixpAdd(fMult(fMult(fMult(G_m[0], G_m[1]), crossNrg_m), Icc_m),
+ 1 + 2 * G_e + crossNrg_e + Icc_e, inv_weight_denom_m,
+ inv_weight_denom_e, &inv_weight_denom_e);
+
+ if (inv_weight_denom_m > FL2FXCONST_DBL(0.f)) {
+ inverse_weight_m =
+ fDivNorm(inv_weight_num_m, inv_weight_denom_m, &inverse_weight_e);
+ inverse_weight_m =
+ sqrtFixp(inverse_weight_m,
+ inverse_weight_e + inv_weight_num_e - inv_weight_denom_e,
+ &inverse_weight_e);
+ inverse_weight_e -= H1_SCALE_FACTOR;
+
+ /* inverse_weight_limited = min(max_gain_factor, inverse_weight) */
+ inverse_weight_limited =
+ ((inverse_weight_e >= 0) &&
+ (inverse_weight_m >= (max_gain_factor >> inverse_weight_e)))
+ ? max_gain_factor
+ : scaleValue(inverse_weight_m, inverse_weight_e);
+ } else {
+ inverse_weight_limited = max_gain_factor;
+ }
+
+ H1_m[0] = fMult(G_m[0], inverse_weight_limited);
+ H1_m[1] = fMult(G_m[1], inverse_weight_limited);
+
+ *pH1_e = G_e + H1_SCALE_FACTOR;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_close_enhancedTimeDomainDmx(
+ HANDLE_ENHANCED_TIME_DOMAIN_DMX *phEnhancedTimeDmx) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (phEnhancedTimeDmx == NULL) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ if (*phEnhancedTimeDmx != NULL) {
+ if ((*phEnhancedTimeDmx)->sinusWindow_m != NULL) {
+ FDK_FREE_MEMORY_1D((*phEnhancedTimeDmx)->sinusWindow_m);
+ }
+ FDK_FREE_MEMORY_1D(*phEnhancedTimeDmx);
+ }
+ }
+ return error;
+}
diff --git a/libSACenc/src/sacenc_dmx_tdom_enh.h b/libSACenc/src/sacenc_dmx_tdom_enh.h
new file mode 100644
index 0000000..0b39911
--- /dev/null
+++ b/libSACenc/src/sacenc_dmx_tdom_enh.h
@@ -0,0 +1,134 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): M. Luis Valero
+
+ Description: Enhanced Time Domain Downmix
+
+*******************************************************************************/
+
+#ifndef SACENC_DMX_TDOM_ENH_H
+#define SACENC_DMX_TDOM_ENH_H
+
+/* Includes ******************************************************************/
+#include "sacenc_lib.h"
+#include "common_fix.h"
+
+/* Defines *******************************************************************/
+
+/* Data Types ****************************************************************/
+typedef struct T_ENHANCED_TIME_DOMAIN_DMX *HANDLE_ENHANCED_TIME_DOMAIN_DMX;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+FDK_SACENC_ERROR fdk_sacenc_open_enhancedTimeDomainDmx(
+ HANDLE_ENHANCED_TIME_DOMAIN_DMX *hEnhancedTimeDmx, const INT framelength);
+
+FDK_SACENC_ERROR fdk_sacenc_init_enhancedTimeDomainDmx(
+ HANDLE_ENHANCED_TIME_DOMAIN_DMX hEnhancedTimeDmx,
+ const FIXP_DBL *const pInputGain_m, const INT inputGain_e,
+ const FIXP_DBL outputGain_m, const INT outputGain_e, const INT framelength);
+
+FDK_SACENC_ERROR fdk_sacenc_apply_enhancedTimeDomainDmx(
+ HANDLE_ENHANCED_TIME_DOMAIN_DMX hEnhancedTimeDmx,
+ const INT_PCM *const *const inputTime, INT_PCM *const outputTimeDmx,
+ const INT InputDelay);
+
+FDK_SACENC_ERROR fdk_sacenc_close_enhancedTimeDomainDmx(
+ HANDLE_ENHANCED_TIME_DOMAIN_DMX *hEnhancedTimeDmx);
+
+#endif /* SACENC_DMX_TDOM_ENH_H */
diff --git a/libSACenc/src/sacenc_filter.cpp b/libSACenc/src/sacenc_filter.cpp
new file mode 100644
index 0000000..79f0797
--- /dev/null
+++ b/libSACenc/src/sacenc_filter.cpp
@@ -0,0 +1,207 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): M. Multrus
+
+ Description: Encoder Library
+ Filter functions
+
+*******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_filter.h"
+
+/* Defines *******************************************************************/
+
+/* Data Types ****************************************************************/
+typedef struct T_DC_FILTER {
+ FIXP_DBL c__FDK;
+ FIXP_DBL state__FDK;
+
+} DC_FILTER;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+FDK_SACENC_ERROR fdk_sacenc_createDCFilter(HANDLE_DC_FILTER *hDCFilter) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == hDCFilter) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ FDK_ALLOCATE_MEMORY_1D(*hDCFilter, 1, DC_FILTER);
+ }
+ return error;
+
+bail:
+ fdk_sacenc_destroyDCFilter(hDCFilter);
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+FDK_SACENC_ERROR fdk_sacenc_initDCFilter(HANDLE_DC_FILTER hDCFilter,
+ const UINT sampleRate) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ FIXP_DBL expC;
+ int s;
+
+ /* Conversion for use of CalcInvLdData: e^x = 2^(x*log10(e)/log10(2) =
+ CalcInvLdData(x*log10(e)/log10(2)/64.0) 1.44269504089 = log10(e)/log10(2)
+ 0.5 = scale constant value with 1 Bits
+ */
+ expC = fDivNormHighPrec((FIXP_DBL)20, (FIXP_DBL)sampleRate, &s);
+ expC = fMultDiv2(FL2FXCONST_DBL(-1.44269504089 * 0.5), expC) >>
+ (LD_DATA_SHIFT - 1 - 1);
+
+ if (s < 0)
+ expC = expC >> (-s);
+ else
+ expC = expC << (s);
+
+ expC = CalcInvLdData(expC);
+
+ hDCFilter->c__FDK = expC;
+ hDCFilter->state__FDK = FL2FXCONST_DBL(0.0f);
+
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_destroyDCFilter(HANDLE_DC_FILTER *hDCFilter) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hDCFilter != NULL) && (*hDCFilter != NULL)) {
+ FDKfree(*hDCFilter);
+
+ *hDCFilter = NULL;
+ }
+
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_applyDCFilter(HANDLE_DC_FILTER hDCFilter,
+ const INT_PCM *const signalIn,
+ INT_PCM *const signalOut,
+ const INT signalLength) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hDCFilter == NULL) || (signalIn == NULL) || (signalOut == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ const INT_PCM *const x = signalIn;
+ INT_PCM *const y = signalOut;
+ const FIXP_DBL c = hDCFilter->c__FDK;
+ FIXP_DBL *const state = &hDCFilter->state__FDK;
+ int i;
+ FIXP_DBL x0, x1, y1;
+
+ x1 = x0 = FX_PCM2FX_DBL(x[0]) >> DC_FILTER_SF;
+ y1 = x0 + (*state);
+
+ for (i = 1; i < signalLength; i++) {
+ x0 = FX_PCM2FX_DBL(x[i]) >> DC_FILTER_SF;
+ y[i - 1] = FX_DBL2FX_PCM(y1);
+ y1 = x0 - x1 + fMult(c, y1);
+ x1 = x0;
+ }
+
+ *state = fMult(c, y1) - x1;
+ y[i - 1] = FX_DBL2FX_PCM(y1);
+ }
+
+ return error;
+}
diff --git a/libSACenc/src/sacenc_filter.h b/libSACenc/src/sacenc_filter.h
new file mode 100644
index 0000000..10e3abd
--- /dev/null
+++ b/libSACenc/src/sacenc_filter.h
@@ -0,0 +1,133 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): M. Multrus
+
+ Description: Encoder Library Interface
+ Filter functions
+
+*******************************************************************************/
+
+#ifndef SACENC_FILTER_H
+#define SACENC_FILTER_H
+
+/* Includes ******************************************************************/
+#include "common_fix.h"
+#include "sacenc_lib.h"
+#include "FDK_matrixCalloc.h"
+
+/* Defines *******************************************************************/
+#define DC_FILTER_SF 1
+
+/* Data Types ****************************************************************/
+typedef struct T_DC_FILTER *HANDLE_DC_FILTER;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+FDK_SACENC_ERROR fdk_sacenc_createDCFilter(HANDLE_DC_FILTER *hDCFilter);
+
+FDK_SACENC_ERROR fdk_sacenc_initDCFilter(HANDLE_DC_FILTER hDCFilter,
+ const UINT sampleRate);
+
+FDK_SACENC_ERROR fdk_sacenc_destroyDCFilter(HANDLE_DC_FILTER *hDCFilter);
+
+FDK_SACENC_ERROR fdk_sacenc_applyDCFilter(HANDLE_DC_FILTER hDCFilter,
+ const INT_PCM *const signalIn,
+ INT_PCM *const signalOut,
+ const INT signalLength);
+
+#endif /* SACENC_FILTER_H */
diff --git a/libSACenc/src/sacenc_framewindowing.cpp b/libSACenc/src/sacenc_framewindowing.cpp
new file mode 100644
index 0000000..15f0f0a
--- /dev/null
+++ b/libSACenc/src/sacenc_framewindowing.cpp
@@ -0,0 +1,568 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): Max Neuendorf
+
+ Description: Encoder Library Interface
+ Get windows for framing
+
+*******************************************************************************/
+
+/**************************************************************************/ /**
+ \file
+ Description of file contents
+ ******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_framewindowing.h"
+#include "sacenc_vectorfunctions.h"
+
+/* Defines *******************************************************************/
+
+/* Data Types ****************************************************************/
+typedef struct T_FRAMEWINDOW {
+ INT nTimeSlotsMax;
+ INT bFrameKeep;
+ INT startSlope;
+ INT stopSlope;
+ INT startRect;
+ INT stopRect;
+
+ INT taperAnaLen;
+ INT taperSynLen;
+ FIXP_WIN pTaperAna__FDK[MAX_TIME_SLOTS];
+ FIXP_WIN pTaperSyn__FDK[MAX_TIME_SLOTS];
+
+} FRAMEWINDOW;
+
+typedef enum {
+ FIX_INVALID = -1,
+ FIX_RECT_SMOOTH = 0,
+ FIX_SMOOTH_RECT = 1,
+ FIX_LARGE_SMOOTH = 2,
+ FIX_RECT_TRIANG = 3
+
+} FIX_TYPE;
+
+typedef enum {
+ VAR_INVALID = -1,
+ VAR_HOLD = 0,
+ VAR_ISOLATE = 1
+
+} VAR_TYPE;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+static void calcTaperWin(FIXP_WIN *pTaperWin, INT timeSlots) {
+ FIXP_DBL x;
+ int i, scale;
+
+ for (i = 0; i < timeSlots; i++) {
+ x = fDivNormHighPrec((FIXP_DBL)i, (FIXP_DBL)timeSlots, &scale);
+
+ if (scale < 0) {
+ pTaperWin[i] = FX_DBL2FX_WIN(x >> (-scale));
+ } else {
+ pTaperWin[i] = FX_DBL2FX_WIN(x << (scale));
+ }
+ }
+ pTaperWin[timeSlots] = FX_DBL2FX_WIN((FIXP_DBL)MAXVAL_DBL);
+}
+
+FDK_SACENC_ERROR fdk_sacenc_frameWindow_Create(
+ HANDLE_FRAMEWINDOW *phFrameWindow) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == phFrameWindow) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ /* Memory Allocation */
+ FDK_ALLOCATE_MEMORY_1D(*phFrameWindow, 1, FRAMEWINDOW);
+ }
+ return error;
+
+bail:
+ fdk_sacenc_frameWindow_Destroy(phFrameWindow);
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+FDK_SACENC_ERROR fdk_sacenc_frameWindow_Init(
+ HANDLE_FRAMEWINDOW hFrameWindow,
+ const FRAMEWINDOW_CONFIG *const pFrameWindowConfig) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hFrameWindow == NULL) || (pFrameWindowConfig == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else if (pFrameWindowConfig->nTimeSlotsMax < 0) {
+ error = SACENC_INIT_ERROR;
+ } else {
+ int ts;
+ hFrameWindow->bFrameKeep = pFrameWindowConfig->bFrameKeep;
+ hFrameWindow->nTimeSlotsMax = pFrameWindowConfig->nTimeSlotsMax;
+
+ FIXP_WIN winMaxVal = FX_DBL2FX_WIN((FIXP_DBL)MAXVAL_DBL);
+ int timeSlots = pFrameWindowConfig->nTimeSlotsMax;
+ {
+ hFrameWindow->startSlope = 0;
+ hFrameWindow->stopSlope = ((3 * timeSlots) >> 1) - 1;
+ hFrameWindow->startRect = timeSlots >> 1;
+ hFrameWindow->stopRect = timeSlots;
+ calcTaperWin(hFrameWindow->pTaperSyn__FDK, timeSlots >> 1);
+ hFrameWindow->taperSynLen = timeSlots >> 1;
+ }
+
+ /* Calculate Taper for non-rect. ana. windows */
+ hFrameWindow->taperAnaLen =
+ hFrameWindow->startRect - hFrameWindow->startSlope;
+ for (ts = 0; ts < hFrameWindow->taperAnaLen; ts++) {
+ { hFrameWindow->pTaperAna__FDK[ts] = winMaxVal; }
+ }
+ }
+
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_frameWindow_Destroy(
+ HANDLE_FRAMEWINDOW *phFrameWindow) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((NULL != phFrameWindow) && (NULL != *phFrameWindow)) {
+ FDKfree(*phFrameWindow);
+ *phFrameWindow = NULL;
+ }
+ return error;
+}
+
+static FDK_SACENC_ERROR FrameWinList_Reset(FRAMEWIN_LIST *const pFrameWinList) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == pFrameWinList) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int k = 0;
+ for (k = 0; k < MAX_NUM_PARAMS; k++) {
+ pFrameWinList->dat[k].slot = -1;
+ pFrameWinList->dat[k].hold = FW_INTP;
+ }
+ pFrameWinList->n = 0;
+ }
+ return error;
+}
+
+static FDK_SACENC_ERROR FrameWindowList_Add(FRAMEWIN_LIST *const pFrameWinList,
+ const INT slot,
+ const FW_SLOTTYPE hold) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == pFrameWinList) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ if (pFrameWinList->n >= MAX_NUM_PARAMS) { /* Place left in List ?*/
+ error = SACENC_PARAM_ERROR;
+ } else if (pFrameWinList->n > 0 &&
+ pFrameWinList->dat[pFrameWinList->n - 1].slot - slot > 0) {
+ error = SACENC_PARAM_ERROR;
+ } else {
+ pFrameWinList->dat[pFrameWinList->n].slot = slot;
+ pFrameWinList->dat[pFrameWinList->n].hold = hold;
+ pFrameWinList->n++;
+ }
+ }
+ return error;
+}
+
+static FDK_SACENC_ERROR FrameWindowList_Remove(
+ FRAMEWIN_LIST *const pFrameWinList, const INT idx) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == pFrameWinList) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int k = 0;
+ if (idx < 0 || idx >= MAX_NUM_PARAMS) {
+ error = SACENC_PARAM_ERROR;
+ } else if (pFrameWinList->n > 0) {
+ if (idx == MAX_NUM_PARAMS - 1) {
+ pFrameWinList->dat[idx].slot = -1;
+ pFrameWinList->dat[idx].hold = FW_INTP;
+ } else {
+ for (k = idx; k < MAX_NUM_PARAMS - 1; k++) {
+ pFrameWinList->dat[k] = pFrameWinList->dat[k + 1];
+ }
+ }
+ pFrameWinList->n--;
+ }
+ }
+ return error;
+}
+
+static FDK_SACENC_ERROR FrameWindowList_Limit(
+ FRAMEWIN_LIST *const pFrameWinList, const INT ll /*lower limit*/,
+ const INT ul /*upper limit*/
+) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == pFrameWinList) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int k = 0;
+ for (k = 0; k < pFrameWinList->n; k++) {
+ if (pFrameWinList->dat[k].slot < ll || pFrameWinList->dat[k].slot > ul) {
+ FrameWindowList_Remove(pFrameWinList, k);
+ --k;
+ }
+ }
+ }
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_frameWindow_GetWindow(
+ HANDLE_FRAMEWINDOW hFrameWindow, INT tr_pos[MAX_NUM_PARAMS],
+ const INT timeSlots, FRAMINGINFO *const pFramingInfo,
+ FIXP_WIN *pWindowAna__FDK[MAX_NUM_PARAMS],
+ FRAMEWIN_LIST *const pFrameWinList, const INT avoid_keep) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hFrameWindow == NULL) || (tr_pos == NULL) || (pFramingInfo == NULL) ||
+ (pFrameWinList == NULL) || (pWindowAna__FDK == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ const VAR_TYPE varType = VAR_HOLD;
+ const int tranL = 4;
+ int winCnt = 0;
+ int w, ps;
+
+ int startSlope = hFrameWindow->startSlope;
+ int stopSlope = hFrameWindow->stopSlope;
+ int startRect = hFrameWindow->startRect;
+ int stopRect = hFrameWindow->stopRect;
+ int taperAnaLen = hFrameWindow->taperAnaLen;
+
+ FIXP_WIN winMaxVal = FX_DBL2FX_WIN((FIXP_DBL)MAXVAL_DBL);
+ FIXP_WIN applyRightWindowGain__FDK[MAX_NUM_PARAMS];
+ FIXP_WIN *pTaperAna__FDK = hFrameWindow->pTaperAna__FDK;
+
+ /* sanity check */
+ for (ps = 0; ps < MAX_NUM_PARAMS; ps++) {
+ if (pWindowAna__FDK[ps] == NULL) {
+ error = SACENC_INVALID_HANDLE;
+ goto bail;
+ }
+ }
+
+ if ((timeSlots > hFrameWindow->nTimeSlotsMax) || (timeSlots < 0)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ /* Reset */
+ if (SACENC_OK != (error = FrameWinList_Reset(pFrameWinList))) goto bail;
+
+ FDKmemclear(applyRightWindowGain__FDK, sizeof(applyRightWindowGain__FDK));
+
+ if (tr_pos[0] > -1) { /* Transients in first (left) half? */
+ int p_l = tr_pos[0];
+ winCnt = 0;
+
+ /* Create Parameter Positions */
+ switch (varType) {
+ case VAR_HOLD:
+ if (SACENC_OK !=
+ (error = FrameWindowList_Add(pFrameWinList, p_l - 1, FW_HOLD)))
+ goto bail;
+ if (SACENC_OK !=
+ (error = FrameWindowList_Add(pFrameWinList, p_l, FW_INTP)))
+ goto bail;
+ break;
+ case VAR_ISOLATE:
+ if (SACENC_OK !=
+ (error = FrameWindowList_Add(pFrameWinList, p_l - 1, FW_HOLD)))
+ goto bail;
+ if (SACENC_OK !=
+ (error = FrameWindowList_Add(pFrameWinList, p_l, FW_INTP)))
+ goto bail;
+ if (SACENC_OK != (error = FrameWindowList_Add(pFrameWinList,
+ p_l + tranL, FW_HOLD)))
+ goto bail;
+ if (SACENC_OK != (error = FrameWindowList_Add(
+ pFrameWinList, p_l + tranL + 1, FW_INTP)))
+ goto bail;
+ break;
+ default:
+ error = SACENC_INVALID_CONFIG;
+ break;
+ }
+
+ /* Outside of frame? => Kick Out */
+ if (SACENC_OK !=
+ (error = FrameWindowList_Limit(pFrameWinList, 0, timeSlots - 1)))
+ goto bail;
+
+ /* Add timeSlots as temporary border for window creation */
+ if (SACENC_OK !=
+ (error = FrameWindowList_Add(pFrameWinList, timeSlots - 1, FW_HOLD)))
+ goto bail;
+
+ /* Create Windows */
+ for (ps = 0; ps < pFrameWinList->n - 1; ps++) {
+ if (FW_HOLD != pFrameWinList->dat[ps].hold) {
+ int const start = pFrameWinList->dat[ps].slot;
+ int const stop = pFrameWinList->dat[ps + 1].slot;
+
+ /* Analysis Window */
+ FDKmemset_flex(pWindowAna__FDK[winCnt], FX_DBL2FX_WIN((FIXP_DBL)0),
+ start);
+ FDKmemset_flex(&pWindowAna__FDK[winCnt][start], winMaxVal,
+ stop - start + 1);
+ FDKmemset_flex(&pWindowAna__FDK[winCnt][stop + 1],
+ FX_DBL2FX_WIN((FIXP_DBL)0), timeSlots - stop - 1);
+
+ applyRightWindowGain__FDK[winCnt] =
+ pWindowAna__FDK[winCnt][timeSlots - 1];
+ winCnt++;
+ }
+ } /* ps */
+
+ /* Pop temporary frame border */
+ if (SACENC_OK !=
+ (error = FrameWindowList_Remove(pFrameWinList, pFrameWinList->n - 1)))
+ goto bail;
+ } else { /* No transient in left half of ana. window */
+ winCnt = 0;
+
+ /* Add paramter set at end of frame */
+ if (SACENC_OK !=
+ (error = FrameWindowList_Add(pFrameWinList, timeSlots - 1, FW_INTP)))
+ goto bail;
+ /* Analysis Window */
+ FDKmemset_flex(pWindowAna__FDK[winCnt], FX_DBL2FX_WIN((FIXP_DBL)0),
+ startSlope);
+ FDKmemcpy_flex(&pWindowAna__FDK[winCnt][startSlope], 1, pTaperAna__FDK, 1,
+ taperAnaLen);
+ FDKmemset_flex(&pWindowAna__FDK[winCnt][startRect], winMaxVal,
+ timeSlots - startRect);
+
+ applyRightWindowGain__FDK[winCnt] = winMaxVal;
+ winCnt++;
+ } /* if (tr_pos[0] > -1) */
+
+ for (w = 0; w < winCnt; w++) {
+ if (applyRightWindowGain__FDK[w] > (FIXP_WIN)0) {
+ if (tr_pos[1] > -1) { /* Transients in second (right) half? */
+ int p_r = tr_pos[1];
+
+ /* Analysis Window */
+ FDKmemset_flex(&pWindowAna__FDK[w][timeSlots], winMaxVal,
+ p_r - timeSlots);
+ FDKmemset_flex(&pWindowAna__FDK[w][p_r], FX_DBL2FX_WIN((FIXP_DBL)0),
+ 2 * timeSlots - p_r);
+
+ } else { /* No transient in right half of ana. window */
+ /* Analysis Window */
+ FDKmemset_flex(&pWindowAna__FDK[w][timeSlots], winMaxVal,
+ stopRect - timeSlots + 1);
+ FDKmemcpy_flex(&pWindowAna__FDK[w][stopRect], 1,
+ &pTaperAna__FDK[taperAnaLen - 1], -1, taperAnaLen);
+ FDKmemset_flex(&pWindowAna__FDK[w][stopSlope + 1],
+ FX_DBL2FX_WIN((FIXP_DBL)0),
+ 2 * timeSlots - stopSlope - 1);
+
+ } /* if (tr_pos[1] > -1) */
+
+ /* Weight */
+ if (applyRightWindowGain__FDK[w] < winMaxVal) {
+ int ts;
+ for (ts = 0; ts < timeSlots; ts++) {
+ pWindowAna__FDK[w][timeSlots + ts] =
+ FX_DBL2FX_WIN(fMult(pWindowAna__FDK[w][timeSlots + ts],
+ applyRightWindowGain__FDK[w]));
+ }
+ }
+ } /* if (applyRightWindowGain[w] > 0.0f) */
+ else {
+ /* All Zero */
+ FDKmemset_flex(&pWindowAna__FDK[w][timeSlots],
+ FX_DBL2FX_WIN((FIXP_DBL)0), timeSlots);
+ }
+ } /* loop over windows */
+
+ if (hFrameWindow->bFrameKeep == 1) {
+ FDKmemcpy_flex(&pWindowAna__FDK[0][2 * timeSlots], 1,
+ &pWindowAna__FDK[0][timeSlots], 1, timeSlots);
+ FDKmemcpy_flex(&pWindowAna__FDK[0][timeSlots], 1, pWindowAna__FDK[0], 1,
+ timeSlots);
+
+ if (avoid_keep != 0) {
+ FDKmemset_flex(pWindowAna__FDK[0], FX_DBL2FX_WIN((FIXP_DBL)0),
+ timeSlots);
+ } else {
+ FDKmemset_flex(pWindowAna__FDK[0], winMaxVal, timeSlots);
+ }
+ } /* if (hFrameWindow->bFrameKeep==1) */
+
+ /* Feed Info to Bitstream Formatter */
+ pFramingInfo->numParamSets = pFrameWinList->n;
+ pFramingInfo->bsFramingType = 1; /* variable framing */
+ for (ps = 0; ps < pFramingInfo->numParamSets; ps++) {
+ pFramingInfo->bsParamSlots[ps] = pFrameWinList->dat[ps].slot;
+ }
+
+ /* if there is just one param set at last slot,
+ use fixed framing to save some bits */
+ if ((pFramingInfo->numParamSets == 1) &&
+ (pFramingInfo->bsParamSlots[0] == timeSlots - 1)) {
+ pFramingInfo->bsFramingType = 0;
+ }
+
+ } /* valid handle */
+
+bail:
+
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_analysisWindowing(
+ const INT nTimeSlots, const INT startTimeSlot,
+ FIXP_WIN *pFrameWindowAna__FDK, const FIXP_DPK *const *const ppDataIn__FDK,
+ FIXP_DPK *const *const ppDataOut__FDK, const INT nHybridBands,
+ const INT dim) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((pFrameWindowAna__FDK == NULL) || (ppDataIn__FDK == NULL) ||
+ (ppDataOut__FDK == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int i, ts;
+ FIXP_WIN maxVal = FX_DBL2FX_WIN((FIXP_DBL)MAXVAL_DBL);
+
+ if (dim == FW_CHANGE_DIM) {
+ for (ts = startTimeSlot; ts < nTimeSlots; ts++) {
+ FIXP_WIN win = pFrameWindowAna__FDK[ts];
+ if (win == maxVal) {
+ for (i = 0; i < nHybridBands; i++) {
+ ppDataOut__FDK[i][ts].v.re = ppDataIn__FDK[ts][i].v.re;
+ ppDataOut__FDK[i][ts].v.im = ppDataIn__FDK[ts][i].v.im;
+ }
+ } else {
+ for (i = 0; i < nHybridBands; i++) {
+ ppDataOut__FDK[i][ts].v.re = fMult(win, ppDataIn__FDK[ts][i].v.re);
+ ppDataOut__FDK[i][ts].v.im = fMult(win, ppDataIn__FDK[ts][i].v.im);
+ }
+ }
+ } /* ts */
+ } else {
+ for (ts = startTimeSlot; ts < nTimeSlots; ts++) {
+ FIXP_WIN win = pFrameWindowAna__FDK[ts];
+ if (win == maxVal) {
+ for (i = 0; i < nHybridBands; i++) {
+ ppDataOut__FDK[ts][i].v.re = ppDataIn__FDK[ts][i].v.re;
+ ppDataOut__FDK[ts][i].v.im = ppDataIn__FDK[ts][i].v.im;
+ }
+ } else {
+ for (i = 0; i < nHybridBands; i++) {
+ ppDataOut__FDK[ts][i].v.re = fMult(win, ppDataIn__FDK[ts][i].v.re);
+ ppDataOut__FDK[ts][i].v.im = fMult(win, ppDataIn__FDK[ts][i].v.im);
+ }
+ }
+ } /* ts */
+ }
+ }
+
+ return error;
+}
diff --git a/libSACenc/src/sacenc_framewindowing.h b/libSACenc/src/sacenc_framewindowing.h
new file mode 100644
index 0000000..6b22dc9
--- /dev/null
+++ b/libSACenc/src/sacenc_framewindowing.h
@@ -0,0 +1,181 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): Max Neuendorf
+
+ Description: Encoder Library Interface
+ Get windows for framing
+
+*******************************************************************************/
+
+#ifndef SACENC_FRAMEWINDOWING_H
+#define SACENC_FRAMEWINDOWING_H
+
+/**************************************************************************/ /**
+ \file
+ Description of file contents
+ ******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "genericStds.h"
+#include "common_fix.h"
+#include "sacenc_lib.h"
+#include "sacenc_bitstream.h"
+
+/* Defines *******************************************************************/
+#define FIXP_WIN FIXP_DBL
+#define FX_DBL2FX_WIN(x) (x)
+#define DALDATATYPE_WIN DALDATATYPE_DFRACT
+
+typedef enum {
+ FW_INTP = 0,
+ FW_HOLD = 1
+
+} FW_SLOTTYPE;
+
+typedef enum {
+ FW_LEAVE_DIM = 0,
+ FW_CHANGE_DIM = 1
+
+} FW_DIMENSION;
+
+/* Data Types ****************************************************************/
+typedef struct T_FRAMEWINDOW *HANDLE_FRAMEWINDOW;
+
+typedef struct T_FRAMEWINDOW_CONFIG {
+ INT nTimeSlotsMax;
+ INT bFrameKeep;
+
+} FRAMEWINDOW_CONFIG;
+
+typedef struct {
+ INT slot;
+ FW_SLOTTYPE hold;
+
+} FRAMEWIN_DATA;
+
+typedef struct {
+ FRAMEWIN_DATA dat[MAX_NUM_PARAMS];
+ INT n;
+
+} FRAMEWIN_LIST;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+FDK_SACENC_ERROR fdk_sacenc_frameWindow_Create(
+ HANDLE_FRAMEWINDOW *phFrameWindow);
+
+FDK_SACENC_ERROR fdk_sacenc_frameWindow_Init(
+ HANDLE_FRAMEWINDOW hFrameWindow,
+ const FRAMEWINDOW_CONFIG *const pFrameWindowConfig);
+
+FDK_SACENC_ERROR fdk_sacenc_frameWindow_Destroy(
+ HANDLE_FRAMEWINDOW *phFrameWindow);
+
+FDK_SACENC_ERROR fdk_sacenc_frameWindow_GetWindow(
+ HANDLE_FRAMEWINDOW hFrameWindow, INT tr_pos[MAX_NUM_PARAMS],
+ const INT timeSlots, FRAMINGINFO *const pFramingInfo,
+ FIXP_WIN *pWindowAna__FDK[MAX_NUM_PARAMS],
+ FRAMEWIN_LIST *const pFrameWinList, const INT avoid_keep);
+
+FDK_SACENC_ERROR fdk_sacenc_analysisWindowing(
+ const INT nTimeSlots, const INT startTimeSlot,
+ FIXP_WIN *pFrameWindowAna__FDK, const FIXP_DPK *const *const ppDataIn__FDK,
+ FIXP_DPK *const *const ppDataOut__FDK, const INT nHybridBands,
+ const INT dim);
+
+#endif /* SACENC_FRAMEWINDOWING_H */
diff --git a/libSACenc/src/sacenc_huff_tab.cpp b/libSACenc/src/sacenc_huff_tab.cpp
new file mode 100644
index 0000000..7b28ecd
--- /dev/null
+++ b/libSACenc/src/sacenc_huff_tab.cpp
@@ -0,0 +1,997 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): Markus Lohwasser
+
+ Description: SAC-Encoder constant huffman tables
+
+*******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_huff_tab.h"
+
+/* Defines *******************************************************************/
+
+/* Data Types ****************************************************************/
+
+/* Constants *****************************************************************/
+const HUFF_CLD_TABLE fdk_sacenc_huffCLDTab = {
+ {/* h1D[2][31] */
+ {HUFF_PACK(0x00000000, 1), HUFF_PACK(0x00000002, 2),
+ HUFF_PACK(0x00000006, 3), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x0000003e, 6),
+ HUFF_PACK(0x0000007e, 7), HUFF_PACK(0x000000fe, 8),
+ HUFF_PACK(0x000001fe, 9), HUFF_PACK(0x000003fe, 10),
+ HUFF_PACK(0x000007fe, 11), HUFF_PACK(0x00000ffe, 12),
+ HUFF_PACK(0x00001ffe, 13), HUFF_PACK(0x00007ffe, 15),
+ HUFF_PACK(0x00007ffc, 15), HUFF_PACK(0x0000fffe, 16),
+ HUFF_PACK(0x0000fffa, 16), HUFF_PACK(0x0001fffe, 17),
+ HUFF_PACK(0x0001fff6, 17), HUFF_PACK(0x0003fffe, 18),
+ HUFF_PACK(0x0003ffff, 18), HUFF_PACK(0x0007ffde, 19),
+ HUFF_PACK(0x0003ffee, 18), HUFF_PACK(0x000fffbe, 20),
+ HUFF_PACK(0x001fff7e, 21), HUFF_PACK(0x00fffbfc, 24),
+ HUFF_PACK(0x00fffbfd, 24), HUFF_PACK(0x00fffbfe, 24),
+ HUFF_PACK(0x00fffbff, 24), HUFF_PACK(0x007ffdfc, 23),
+ HUFF_PACK(0x007ffdfd, 23)},
+ {HUFF_PACK(0x00000000, 1), HUFF_PACK(0x00000002, 2),
+ HUFF_PACK(0x00000006, 3), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x0000003e, 6),
+ HUFF_PACK(0x0000007e, 7), HUFF_PACK(0x000001fe, 9),
+ HUFF_PACK(0x000001fc, 9), HUFF_PACK(0x000003fe, 10),
+ HUFF_PACK(0x000003fa, 10), HUFF_PACK(0x000007fe, 11),
+ HUFF_PACK(0x000007f6, 11), HUFF_PACK(0x00000ffe, 12),
+ HUFF_PACK(0x00000fee, 12), HUFF_PACK(0x00001ffe, 13),
+ HUFF_PACK(0x00001fde, 13), HUFF_PACK(0x00003ffe, 14),
+ HUFF_PACK(0x00003fbe, 14), HUFF_PACK(0x00003fbf, 14),
+ HUFF_PACK(0x00007ffe, 15), HUFF_PACK(0x0000fffe, 16),
+ HUFF_PACK(0x0001fffe, 17), HUFF_PACK(0x0007fffe, 19),
+ HUFF_PACK(0x0007fffc, 19), HUFF_PACK(0x000ffffa, 20),
+ HUFF_PACK(0x001ffffc, 21), HUFF_PACK(0x001ffffd, 21),
+ HUFF_PACK(0x001ffffe, 21), HUFF_PACK(0x001fffff, 21),
+ HUFF_PACK(0x000ffffb, 20)}},
+ { /* HUFF_CLD_TAB_2D */
+ { /* HUFF_CLD_TAB_2D[0][] */
+ {/* HUFF_CLD_TAB_2D[0][0] */
+ {
+ /* LAV3_2D */
+ {{HUFF_PACK(0x00000002, 2), HUFF_PACK(0x00000002, 3),
+ HUFF_PACK(0x00000004, 5), HUFF_PACK(0x0000003e, 8)},
+ {HUFF_PACK(0x00000006, 4), HUFF_PACK(0x00000007, 4),
+ HUFF_PACK(0x0000000e, 6), HUFF_PACK(0x000000fe, 10)},
+ {HUFF_PACK(0x0000007e, 9), HUFF_PACK(0x0000001e, 7),
+ HUFF_PACK(0x0000000c, 6), HUFF_PACK(0x00000005, 5)},
+ {HUFF_PACK(0x000000ff, 10), HUFF_PACK(0x0000000d, 6),
+ HUFF_PACK(0x00000000, 3), HUFF_PACK(0x00000003, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV5_2D */
+ {{HUFF_PACK(0x00000002, 3), HUFF_PACK(0x00000003, 3),
+ HUFF_PACK(0x00000010, 5), HUFF_PACK(0x0000007c, 7),
+ HUFF_PACK(0x000000d6, 8), HUFF_PACK(0x000003ee, 10)},
+ {HUFF_PACK(0x0000000a, 4), HUFF_PACK(0x0000000c, 4),
+ HUFF_PACK(0x00000016, 5), HUFF_PACK(0x00000034, 6),
+ HUFF_PACK(0x000000fe, 8), HUFF_PACK(0x00001f7e, 13)},
+ {HUFF_PACK(0x0000007e, 7), HUFF_PACK(0x00000036, 6),
+ HUFF_PACK(0x00000026, 6), HUFF_PACK(0x00000046, 7),
+ HUFF_PACK(0x0000011e, 9), HUFF_PACK(0x000001f6, 9)},
+ {HUFF_PACK(0x0000011f, 9), HUFF_PACK(0x000000d7, 8),
+ HUFF_PACK(0x0000008e, 8), HUFF_PACK(0x000000ff, 8),
+ HUFF_PACK(0x0000006a, 7), HUFF_PACK(0x0000004e, 7)},
+ {HUFF_PACK(0x00000fbe, 12), HUFF_PACK(0x000007de, 11),
+ HUFF_PACK(0x0000004f, 7), HUFF_PACK(0x00000037, 6),
+ HUFF_PACK(0x00000017, 5), HUFF_PACK(0x0000001e, 5)},
+ {HUFF_PACK(0x00001f7f, 13), HUFF_PACK(0x000000fa, 8),
+ HUFF_PACK(0x00000022, 6), HUFF_PACK(0x00000012, 5),
+ HUFF_PACK(0x0000000e, 4), HUFF_PACK(0x00000000, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV7_2D */
+ {{HUFF_PACK(0x0000000e, 4), HUFF_PACK(0x0000000a, 4),
+ HUFF_PACK(0x0000000a, 5), HUFF_PACK(0x0000007c, 7),
+ HUFF_PACK(0x000000be, 8), HUFF_PACK(0x0000017a, 9),
+ HUFF_PACK(0x000000ee, 9), HUFF_PACK(0x000007b6, 11)},
+ {HUFF_PACK(0x00000006, 4), HUFF_PACK(0x0000000c, 4),
+ HUFF_PACK(0x00000016, 5), HUFF_PACK(0x00000026, 6),
+ HUFF_PACK(0x0000003e, 7), HUFF_PACK(0x0000002e, 7),
+ HUFF_PACK(0x000001ec, 9), HUFF_PACK(0x000047ce, 15)},
+ {HUFF_PACK(0x00000016, 6), HUFF_PACK(0x0000003c, 6),
+ HUFF_PACK(0x00000022, 6), HUFF_PACK(0x0000004e, 7),
+ HUFF_PACK(0x0000003f, 7), HUFF_PACK(0x0000005e, 8),
+ HUFF_PACK(0x000008fa, 12), HUFF_PACK(0x000008fb, 12)},
+ {HUFF_PACK(0x0000005f, 8), HUFF_PACK(0x000000fa, 8),
+ HUFF_PACK(0x000000bf, 8), HUFF_PACK(0x0000003a, 7),
+ HUFF_PACK(0x000001f6, 9), HUFF_PACK(0x000001de, 10),
+ HUFF_PACK(0x000003da, 10), HUFF_PACK(0x000007b7, 11)},
+ {HUFF_PACK(0x000001df, 10), HUFF_PACK(0x000003ee, 10),
+ HUFF_PACK(0x0000017b, 9), HUFF_PACK(0x000003ef, 10),
+ HUFF_PACK(0x000001ee, 9), HUFF_PACK(0x0000008e, 8),
+ HUFF_PACK(0x000001ef, 9), HUFF_PACK(0x000001fe, 9)},
+ {HUFF_PACK(0x000008f8, 12), HUFF_PACK(0x0000047e, 11),
+ HUFF_PACK(0x0000047f, 11), HUFF_PACK(0x00000076, 8),
+ HUFF_PACK(0x0000003c, 7), HUFF_PACK(0x00000046, 7),
+ HUFF_PACK(0x0000007a, 7), HUFF_PACK(0x0000007e, 7)},
+ {HUFF_PACK(0x000023e6, 14), HUFF_PACK(0x000011f2, 13),
+ HUFF_PACK(0x000001ff, 9), HUFF_PACK(0x0000003d, 7),
+ HUFF_PACK(0x0000004f, 7), HUFF_PACK(0x0000002e, 6),
+ HUFF_PACK(0x00000012, 5), HUFF_PACK(0x00000004, 4)},
+ {HUFF_PACK(0x000047cf, 15), HUFF_PACK(0x0000011e, 9),
+ HUFF_PACK(0x000000bc, 8), HUFF_PACK(0x000000fe, 8),
+ HUFF_PACK(0x0000001c, 6), HUFF_PACK(0x00000010, 5),
+ HUFF_PACK(0x0000000d, 4), HUFF_PACK(0x00000000, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV9_2D */
+ {{HUFF_PACK(0x00000006, 4), HUFF_PACK(0x00000007, 4),
+ HUFF_PACK(0x00000006, 5), HUFF_PACK(0x0000007e, 7),
+ HUFF_PACK(0x0000000a, 7), HUFF_PACK(0x0000001e, 8),
+ HUFF_PACK(0x0000008a, 9), HUFF_PACK(0x0000004e, 10),
+ HUFF_PACK(0x00000276, 10), HUFF_PACK(0x000002e2, 11)},
+ {HUFF_PACK(0x00000000, 4), HUFF_PACK(0x0000000a, 4),
+ HUFF_PACK(0x00000016, 5), HUFF_PACK(0x00000026, 6),
+ HUFF_PACK(0x00000076, 7), HUFF_PACK(0x000000f2, 8),
+ HUFF_PACK(0x00000012, 8), HUFF_PACK(0x0000005e, 8),
+ HUFF_PACK(0x0000008b, 9), HUFF_PACK(0x00002e76, 15)},
+ {HUFF_PACK(0x00000012, 6), HUFF_PACK(0x00000007, 5),
+ HUFF_PACK(0x00000038, 6), HUFF_PACK(0x0000007c, 7),
+ HUFF_PACK(0x00000008, 7), HUFF_PACK(0x00000046, 8),
+ HUFF_PACK(0x000000f6, 8), HUFF_PACK(0x000001ca, 9),
+ HUFF_PACK(0x0000173a, 14), HUFF_PACK(0x00001738, 14)},
+ {HUFF_PACK(0x0000009e, 8), HUFF_PACK(0x0000004a, 7),
+ HUFF_PACK(0x00000026, 7), HUFF_PACK(0x0000000c, 7),
+ HUFF_PACK(0x0000004e, 8), HUFF_PACK(0x000000f7, 8),
+ HUFF_PACK(0x0000013a, 9), HUFF_PACK(0x0000009e, 11),
+ HUFF_PACK(0x000009fe, 12), HUFF_PACK(0x0000013e, 12)},
+ {HUFF_PACK(0x00000026, 9), HUFF_PACK(0x0000001a, 8),
+ HUFF_PACK(0x000001e6, 9), HUFF_PACK(0x000001e2, 9),
+ HUFF_PACK(0x000000ee, 8), HUFF_PACK(0x000001ce, 9),
+ HUFF_PACK(0x00000277, 10), HUFF_PACK(0x000003ce, 10),
+ HUFF_PACK(0x000002e6, 11), HUFF_PACK(0x000004fc, 11)},
+ {HUFF_PACK(0x000002e3, 11), HUFF_PACK(0x00000170, 10),
+ HUFF_PACK(0x00000172, 10), HUFF_PACK(0x000000ba, 9),
+ HUFF_PACK(0x0000003e, 9), HUFF_PACK(0x000001e3, 9),
+ HUFF_PACK(0x0000001b, 8), HUFF_PACK(0x0000003f, 9),
+ HUFF_PACK(0x0000009e, 9), HUFF_PACK(0x0000009f, 9)},
+ {HUFF_PACK(0x00000b9e, 13), HUFF_PACK(0x000009ff, 12),
+ HUFF_PACK(0x000004fd, 11), HUFF_PACK(0x000004fe, 11),
+ HUFF_PACK(0x000001cf, 9), HUFF_PACK(0x000000ef, 8),
+ HUFF_PACK(0x00000044, 8), HUFF_PACK(0x0000005f, 8),
+ HUFF_PACK(0x000000e4, 8), HUFF_PACK(0x000000f0, 8)},
+ {HUFF_PACK(0x00002e72, 15), HUFF_PACK(0x0000013f, 12),
+ HUFF_PACK(0x00000b9f, 13), HUFF_PACK(0x0000013e, 9),
+ HUFF_PACK(0x000000fe, 8), HUFF_PACK(0x00000047, 8),
+ HUFF_PACK(0x0000000e, 7), HUFF_PACK(0x0000007d, 7),
+ HUFF_PACK(0x00000010, 6), HUFF_PACK(0x00000024, 6)},
+ {HUFF_PACK(0x00002e77, 15), HUFF_PACK(0x00005ce6, 16),
+ HUFF_PACK(0x000000bb, 9), HUFF_PACK(0x000000e6, 8),
+ HUFF_PACK(0x00000016, 8), HUFF_PACK(0x000000ff, 8),
+ HUFF_PACK(0x0000007a, 7), HUFF_PACK(0x0000003a, 6),
+ HUFF_PACK(0x00000017, 5), HUFF_PACK(0x00000002, 4)},
+ {HUFF_PACK(0x00005ce7, 16), HUFF_PACK(0x000003cf, 10),
+ HUFF_PACK(0x00000017, 8), HUFF_PACK(0x000001cb, 9),
+ HUFF_PACK(0x0000009c, 8), HUFF_PACK(0x0000004b, 7),
+ HUFF_PACK(0x00000016, 6), HUFF_PACK(0x0000000a, 5),
+ HUFF_PACK(0x00000008, 4), HUFF_PACK(0x00000006, 3)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ }},
+ {/* HUFF_CLD_TAB_2D[0][1] */
+ {
+ /* LAV3_2D */
+ {{HUFF_PACK(0x00000000, 1), HUFF_PACK(0x0000003e, 6),
+ HUFF_PACK(0x0000076e, 11), HUFF_PACK(0x00000ede, 12)},
+ {HUFF_PACK(0x00000006, 3), HUFF_PACK(0x0000003f, 6),
+ HUFF_PACK(0x000003b6, 10), HUFF_PACK(0x0000003a, 6)},
+ {HUFF_PACK(0x0000001c, 5), HUFF_PACK(0x000000ee, 8),
+ HUFF_PACK(0x000001da, 9), HUFF_PACK(0x0000001e, 5)},
+ {HUFF_PACK(0x000000ef, 8), HUFF_PACK(0x00000edf, 12),
+ HUFF_PACK(0x000000ec, 8), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV5_2D */
+ {{HUFF_PACK(0x00000006, 3), HUFF_PACK(0x0000001c, 5),
+ HUFF_PACK(0x0000007e, 8), HUFF_PACK(0x00000efc, 12),
+ HUFF_PACK(0x0000effe, 16), HUFF_PACK(0x0001dffe, 17)},
+ {HUFF_PACK(0x00000004, 3), HUFF_PACK(0x0000000a, 4),
+ HUFF_PACK(0x0000003e, 7), HUFF_PACK(0x00000efe, 12),
+ HUFF_PACK(0x000077fe, 15), HUFF_PACK(0x00000076, 7)},
+ {HUFF_PACK(0x00000006, 4), HUFF_PACK(0x00000016, 5),
+ HUFF_PACK(0x000000be, 8), HUFF_PACK(0x00000efd, 12),
+ HUFF_PACK(0x000000ee, 8), HUFF_PACK(0x0000000e, 5)},
+ {HUFF_PACK(0x0000003e, 6), HUFF_PACK(0x0000002e, 6),
+ HUFF_PACK(0x000001de, 9), HUFF_PACK(0x000003be, 10),
+ HUFF_PACK(0x0000007e, 7), HUFF_PACK(0x0000001e, 5)},
+ {HUFF_PACK(0x0000007f, 7), HUFF_PACK(0x0000005e, 7),
+ HUFF_PACK(0x00003bfe, 14), HUFF_PACK(0x000000fe, 9),
+ HUFF_PACK(0x0000001e, 6), HUFF_PACK(0x00000002, 3)},
+ {HUFF_PACK(0x000000bf, 8), HUFF_PACK(0x0001dfff, 17),
+ HUFF_PACK(0x00001dfe, 13), HUFF_PACK(0x000000ff, 9),
+ HUFF_PACK(0x0000003a, 6), HUFF_PACK(0x00000000, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV7_2D */
+ {{HUFF_PACK(0x00000002, 3), HUFF_PACK(0x0000001c, 5),
+ HUFF_PACK(0x000000bc, 8), HUFF_PACK(0x000005fc, 11),
+ HUFF_PACK(0x00005ffe, 15), HUFF_PACK(0x0002ffde, 18),
+ HUFF_PACK(0x000bff7e, 20), HUFF_PACK(0x0017feff, 21)},
+ {HUFF_PACK(0x00000004, 3), HUFF_PACK(0x0000000a, 4),
+ HUFF_PACK(0x0000000e, 7), HUFF_PACK(0x000002fa, 10),
+ HUFF_PACK(0x000001fe, 13), HUFF_PACK(0x0000bff2, 16),
+ HUFF_PACK(0x0005ffbe, 19), HUFF_PACK(0x000000ee, 8)},
+ {HUFF_PACK(0x00000002, 4), HUFF_PACK(0x00000016, 5),
+ HUFF_PACK(0x000000f6, 8), HUFF_PACK(0x000005fe, 11),
+ HUFF_PACK(0x000001ff, 13), HUFF_PACK(0x0000bff6, 16),
+ HUFF_PACK(0x000001de, 9), HUFF_PACK(0x0000007e, 7)},
+ {HUFF_PACK(0x00000000, 5), HUFF_PACK(0x0000003c, 6),
+ HUFF_PACK(0x0000000e, 8), HUFF_PACK(0x0000003e, 10),
+ HUFF_PACK(0x00002ffe, 14), HUFF_PACK(0x000002fb, 10),
+ HUFF_PACK(0x000000f7, 8), HUFF_PACK(0x0000002e, 6)},
+ {HUFF_PACK(0x00000006, 6), HUFF_PACK(0x0000007a, 7),
+ HUFF_PACK(0x0000000a, 8), HUFF_PACK(0x0000007e, 11),
+ HUFF_PACK(0x000000fe, 12), HUFF_PACK(0x00000016, 9),
+ HUFF_PACK(0x00000006, 7), HUFF_PACK(0x00000002, 5)},
+ {HUFF_PACK(0x0000000f, 7), HUFF_PACK(0x00000076, 7),
+ HUFF_PACK(0x00000017, 9), HUFF_PACK(0x00005ff8, 15),
+ HUFF_PACK(0x00000bfe, 12), HUFF_PACK(0x0000001e, 9),
+ HUFF_PACK(0x0000007f, 7), HUFF_PACK(0x00000003, 4)},
+ {HUFF_PACK(0x00000004, 7), HUFF_PACK(0x000000bd, 8),
+ HUFF_PACK(0x0000bff3, 16), HUFF_PACK(0x00005fff, 15),
+ HUFF_PACK(0x00000bfa, 12), HUFF_PACK(0x0000017c, 9),
+ HUFF_PACK(0x0000003a, 6), HUFF_PACK(0x00000003, 3)},
+ {HUFF_PACK(0x0000017e, 9), HUFF_PACK(0x0017fefe, 21),
+ HUFF_PACK(0x00017fee, 17), HUFF_PACK(0x00005ffa, 15),
+ HUFF_PACK(0x00000bfb, 12), HUFF_PACK(0x000001df, 9),
+ HUFF_PACK(0x0000003e, 6), HUFF_PACK(0x00000006, 3)}},
+ HUFF_PACK(0x0017feff, 21) /* escape */
+ },
+ {
+ /* LAV9_2D */
+ {{HUFF_PACK(0x0000000e, 4), HUFF_PACK(0x00000014, 5),
+ HUFF_PACK(0x0000008e, 8), HUFF_PACK(0x000004fe, 11),
+ HUFF_PACK(0x000023fe, 14), HUFF_PACK(0x00008ffe, 16),
+ HUFF_PACK(0x0005ffbc, 19), HUFF_PACK(0x0017fef7, 21),
+ HUFF_PACK(0x0017fef7, 21), HUFF_PACK(0x0017fef7, 21)},
+ {HUFF_PACK(0x00000002, 3), HUFF_PACK(0x00000002, 4),
+ HUFF_PACK(0x00000044, 7), HUFF_PACK(0x0000027e, 10),
+ HUFF_PACK(0x000017fc, 13), HUFF_PACK(0x0000bff6, 16),
+ HUFF_PACK(0x0005ffbe, 19), HUFF_PACK(0x00011ff8, 17),
+ HUFF_PACK(0x000bff7a, 20), HUFF_PACK(0x000000bc, 8)},
+ {HUFF_PACK(0x00000006, 4), HUFF_PACK(0x00000016, 5),
+ HUFF_PACK(0x0000001a, 7), HUFF_PACK(0x000000fe, 10),
+ HUFF_PACK(0x000011f6, 13), HUFF_PACK(0x0000bffe, 16),
+ HUFF_PACK(0x00011ff9, 17), HUFF_PACK(0x0017fef6, 21),
+ HUFF_PACK(0x0000011e, 9), HUFF_PACK(0x00000056, 7)},
+ {HUFF_PACK(0x00000010, 5), HUFF_PACK(0x0000003e, 6),
+ HUFF_PACK(0x0000009e, 8), HUFF_PACK(0x000007fe, 11),
+ HUFF_PACK(0x000011f7, 13), HUFF_PACK(0x00005ff8, 15),
+ HUFF_PACK(0x00017fee, 17), HUFF_PACK(0x000007ff, 11),
+ HUFF_PACK(0x000000ae, 8), HUFF_PACK(0x0000001e, 7)},
+ {HUFF_PACK(0x00000026, 6), HUFF_PACK(0x0000000e, 6),
+ HUFF_PACK(0x000001ee, 9), HUFF_PACK(0x0000047e, 11),
+ HUFF_PACK(0x00000bfc, 12), HUFF_PACK(0x0000bfff, 16),
+ HUFF_PACK(0x000008fa, 12), HUFF_PACK(0x0000006e, 9),
+ HUFF_PACK(0x000001ef, 9), HUFF_PACK(0x0000007e, 7)},
+ {HUFF_PACK(0x0000007a, 7), HUFF_PACK(0x0000004e, 7),
+ HUFF_PACK(0x0000007e, 9), HUFF_PACK(0x000000de, 10),
+ HUFF_PACK(0x000011fe, 13), HUFF_PACK(0x00002ffe, 14),
+ HUFF_PACK(0x000004ff, 11), HUFF_PACK(0x000000ff, 10),
+ HUFF_PACK(0x000000bd, 8), HUFF_PACK(0x0000002e, 6)},
+ {HUFF_PACK(0x000000fe, 8), HUFF_PACK(0x000000af, 8),
+ HUFF_PACK(0x000001ec, 9), HUFF_PACK(0x000001be, 11),
+ HUFF_PACK(0x00011ffe, 17), HUFF_PACK(0x00002ffa, 14),
+ HUFF_PACK(0x000008fe, 12), HUFF_PACK(0x000003fe, 10),
+ HUFF_PACK(0x00000046, 7), HUFF_PACK(0x00000012, 5)},
+ {HUFF_PACK(0x0000003e, 8), HUFF_PACK(0x00000045, 7),
+ HUFF_PACK(0x000002fe, 10), HUFF_PACK(0x000bff7e, 20),
+ HUFF_PACK(0x00005ff9, 15), HUFF_PACK(0x00005ffa, 15),
+ HUFF_PACK(0x00000bfd, 12), HUFF_PACK(0x0000013e, 9),
+ HUFF_PACK(0x0000000c, 6), HUFF_PACK(0x00000007, 4)},
+ {HUFF_PACK(0x000000be, 8), HUFF_PACK(0x00000036, 8),
+ HUFF_PACK(0x000bff7f, 20), HUFF_PACK(0x00023ffe, 18),
+ HUFF_PACK(0x00011ffa, 17), HUFF_PACK(0x00005ffe, 15),
+ HUFF_PACK(0x000001bf, 11), HUFF_PACK(0x000001ed, 9),
+ HUFF_PACK(0x0000002a, 6), HUFF_PACK(0x00000000, 3)},
+ {HUFF_PACK(0x0000017e, 9), HUFF_PACK(0x0017fef7, 21),
+ HUFF_PACK(0x00047ffe, 19), HUFF_PACK(0x00047fff, 19),
+ HUFF_PACK(0x00011ffb, 17), HUFF_PACK(0x00002ffb, 14),
+ HUFF_PACK(0x0000047c, 11), HUFF_PACK(0x000001fe, 9),
+ HUFF_PACK(0x0000003c, 6), HUFF_PACK(0x00000006, 3)}},
+ HUFF_PACK(0x0017fef7, 21) /* escape */
+ }}},
+ { /* HUFF_CLD_TAB_2D[1][] */
+ {/* HUFF_CLD_TAB_2D[1][0] */
+ {
+ /* LAV3_2D */
+ {{HUFF_PACK(0x00000000, 1), HUFF_PACK(0x0000001e, 5),
+ HUFF_PACK(0x000003be, 10), HUFF_PACK(0x00000efe, 12)},
+ {HUFF_PACK(0x00000006, 3), HUFF_PACK(0x0000001c, 5),
+ HUFF_PACK(0x000001de, 9), HUFF_PACK(0x000000ea, 8)},
+ {HUFF_PACK(0x00000074, 7), HUFF_PACK(0x000000ee, 8),
+ HUFF_PACK(0x000000eb, 8), HUFF_PACK(0x0000001f, 5)},
+ {HUFF_PACK(0x0000077e, 11), HUFF_PACK(0x00000eff, 12),
+ HUFF_PACK(0x00000076, 7), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV5_2D */
+ {{HUFF_PACK(0x00000000, 2), HUFF_PACK(0x00000006, 4),
+ HUFF_PACK(0x00000024, 7), HUFF_PACK(0x0000025e, 11),
+ HUFF_PACK(0x00003cfe, 14), HUFF_PACK(0x000079fe, 15)},
+ {HUFF_PACK(0x00000006, 3), HUFF_PACK(0x00000007, 4),
+ HUFF_PACK(0x00000078, 7), HUFF_PACK(0x000003ce, 10),
+ HUFF_PACK(0x00001e7e, 13), HUFF_PACK(0x000000be, 9)},
+ {HUFF_PACK(0x00000008, 5), HUFF_PACK(0x0000003e, 6),
+ HUFF_PACK(0x00000026, 7), HUFF_PACK(0x0000012e, 10),
+ HUFF_PACK(0x000000bf, 9), HUFF_PACK(0x0000002e, 7)},
+ {HUFF_PACK(0x00000027, 7), HUFF_PACK(0x0000007a, 7),
+ HUFF_PACK(0x000001e4, 9), HUFF_PACK(0x00000096, 9),
+ HUFF_PACK(0x0000007b, 7), HUFF_PACK(0x0000003f, 6)},
+ {HUFF_PACK(0x000001e6, 9), HUFF_PACK(0x000001e5, 9),
+ HUFF_PACK(0x00000f3e, 12), HUFF_PACK(0x0000005e, 8),
+ HUFF_PACK(0x00000016, 6), HUFF_PACK(0x0000000e, 4)},
+ {HUFF_PACK(0x0000079e, 11), HUFF_PACK(0x000079ff, 15),
+ HUFF_PACK(0x0000025f, 11), HUFF_PACK(0x0000004a, 8),
+ HUFF_PACK(0x0000000a, 5), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV7_2D */
+ {{HUFF_PACK(0x00000000, 2), HUFF_PACK(0x00000006, 4),
+ HUFF_PACK(0x000000de, 8), HUFF_PACK(0x0000069e, 11),
+ HUFF_PACK(0x000034fe, 14), HUFF_PACK(0x0001a7fe, 17),
+ HUFF_PACK(0x00069ff6, 19), HUFF_PACK(0x00069ff7, 19)},
+ {HUFF_PACK(0x00000002, 3), HUFF_PACK(0x0000000c, 4),
+ HUFF_PACK(0x0000006a, 7), HUFF_PACK(0x0000034e, 10),
+ HUFF_PACK(0x00001fde, 13), HUFF_PACK(0x000069fe, 15),
+ HUFF_PACK(0x0001a7fc, 17), HUFF_PACK(0x00000372, 10)},
+ {HUFF_PACK(0x0000003e, 6), HUFF_PACK(0x0000003c, 6),
+ HUFF_PACK(0x000000df, 8), HUFF_PACK(0x000001ee, 10),
+ HUFF_PACK(0x00000dde, 12), HUFF_PACK(0x000069fa, 15),
+ HUFF_PACK(0x00000373, 10), HUFF_PACK(0x0000007a, 8)},
+ {HUFF_PACK(0x0000003e, 7), HUFF_PACK(0x00000068, 7),
+ HUFF_PACK(0x000001ba, 9), HUFF_PACK(0x000003f6, 10),
+ HUFF_PACK(0x00000d3e, 12), HUFF_PACK(0x0000034c, 10),
+ HUFF_PACK(0x000001fa, 9), HUFF_PACK(0x000000d2, 8)},
+ {HUFF_PACK(0x0000007e, 8), HUFF_PACK(0x0000007f, 8),
+ HUFF_PACK(0x000001f8, 9), HUFF_PACK(0x000006ee, 11),
+ HUFF_PACK(0x000003de, 11), HUFF_PACK(0x000001b8, 9),
+ HUFF_PACK(0x000001fc, 9), HUFF_PACK(0x0000006b, 7)},
+ {HUFF_PACK(0x000000f6, 9), HUFF_PACK(0x000001fe, 9),
+ HUFF_PACK(0x0000034d, 10), HUFF_PACK(0x00003fbe, 14),
+ HUFF_PACK(0x000007f6, 11), HUFF_PACK(0x000003fa, 10),
+ HUFF_PACK(0x0000003c, 7), HUFF_PACK(0x0000003d, 6)},
+ {HUFF_PACK(0x000003f7, 10), HUFF_PACK(0x00000376, 10),
+ HUFF_PACK(0x0001a7ff, 17), HUFF_PACK(0x00003fbf, 14),
+ HUFF_PACK(0x00000ddf, 12), HUFF_PACK(0x000001f9, 9),
+ HUFF_PACK(0x00000036, 6), HUFF_PACK(0x0000000e, 4)},
+ {HUFF_PACK(0x000003df, 11), HUFF_PACK(0x00034ffa, 18),
+ HUFF_PACK(0x000069fb, 15), HUFF_PACK(0x000034fc, 14),
+ HUFF_PACK(0x00000fee, 12), HUFF_PACK(0x000001ff, 9),
+ HUFF_PACK(0x0000000e, 5), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV9_2D */
+ {{HUFF_PACK(0x00000006, 3), HUFF_PACK(0x00000004, 4),
+ HUFF_PACK(0x00000012, 7), HUFF_PACK(0x000007fe, 11),
+ HUFF_PACK(0x00001f7e, 13), HUFF_PACK(0x0000fbfe, 16),
+ HUFF_PACK(0x0001f7fe, 17), HUFF_PACK(0x000b7dfe, 21),
+ HUFF_PACK(0x000b7dff, 21), HUFF_PACK(0x000b7dff, 21)},
+ {HUFF_PACK(0x00000000, 3), HUFF_PACK(0x00000006, 4),
+ HUFF_PACK(0x0000007c, 7), HUFF_PACK(0x00000046, 9),
+ HUFF_PACK(0x000007d0, 12), HUFF_PACK(0x00001f4e, 14),
+ HUFF_PACK(0x0000b7fe, 17), HUFF_PACK(0x00005bee, 16),
+ HUFF_PACK(0x00016fbe, 18), HUFF_PACK(0x000003ee, 10)},
+ {HUFF_PACK(0x00000006, 5), HUFF_PACK(0x0000000a, 5),
+ HUFF_PACK(0x0000002e, 7), HUFF_PACK(0x000003fe, 10),
+ HUFF_PACK(0x000007d2, 12), HUFF_PACK(0x00001f4f, 14),
+ HUFF_PACK(0x00002dfe, 15), HUFF_PACK(0x0000b7de, 17),
+ HUFF_PACK(0x000001fe, 10), HUFF_PACK(0x0000002e, 8)},
+ {HUFF_PACK(0x0000007a, 7), HUFF_PACK(0x0000007e, 7),
+ HUFF_PACK(0x0000007a, 8), HUFF_PACK(0x000001fa, 10),
+ HUFF_PACK(0x000007fe, 12), HUFF_PACK(0x00001f7c, 13),
+ HUFF_PACK(0x000016fa, 14), HUFF_PACK(0x0000009e, 10),
+ HUFF_PACK(0x00000020, 8), HUFF_PACK(0x00000021, 8)},
+ {HUFF_PACK(0x000000fe, 8), HUFF_PACK(0x00000016, 7),
+ HUFF_PACK(0x000000fe, 9), HUFF_PACK(0x0000016e, 10),
+ HUFF_PACK(0x0000009f, 10), HUFF_PACK(0x00000b7c, 13),
+ HUFF_PACK(0x000003de, 11), HUFF_PACK(0x000000b6, 9),
+ HUFF_PACK(0x000000be, 9), HUFF_PACK(0x0000007c, 8)},
+ {HUFF_PACK(0x0000005a, 8), HUFF_PACK(0x00000078, 8),
+ HUFF_PACK(0x00000047, 9), HUFF_PACK(0x00000044, 9),
+ HUFF_PACK(0x000007ff, 12), HUFF_PACK(0x000007d1, 12),
+ HUFF_PACK(0x000001f6, 10), HUFF_PACK(0x000001f7, 10),
+ HUFF_PACK(0x0000002f, 8), HUFF_PACK(0x0000002c, 7)},
+ {HUFF_PACK(0x000000fc, 9), HUFF_PACK(0x000001f6, 9),
+ HUFF_PACK(0x000000f6, 9), HUFF_PACK(0x000007ff, 11),
+ HUFF_PACK(0x000016fe, 14), HUFF_PACK(0x000002de, 11),
+ HUFF_PACK(0x000003ea, 11), HUFF_PACK(0x000000bf, 9),
+ HUFF_PACK(0x000000fa, 8), HUFF_PACK(0x0000000a, 6)},
+ {HUFF_PACK(0x0000004e, 9), HUFF_PACK(0x00000026, 8),
+ HUFF_PACK(0x000001ee, 10), HUFF_PACK(0x00005bfe, 16),
+ HUFF_PACK(0x00003efe, 14), HUFF_PACK(0x00000b7e, 13),
+ HUFF_PACK(0x000003eb, 11), HUFF_PACK(0x000001fe, 9),
+ HUFF_PACK(0x0000007b, 7), HUFF_PACK(0x00000007, 5)},
+ {HUFF_PACK(0x000001fb, 10), HUFF_PACK(0x00000045, 9),
+ HUFF_PACK(0x00016ffe, 18), HUFF_PACK(0x0001f7ff, 17),
+ HUFF_PACK(0x00002df6, 15), HUFF_PACK(0x00001f7d, 13),
+ HUFF_PACK(0x000003fe, 11), HUFF_PACK(0x0000005e, 8),
+ HUFF_PACK(0x0000003c, 6), HUFF_PACK(0x0000000e, 4)},
+ {HUFF_PACK(0x000003df, 11), HUFF_PACK(0x0005befe, 20),
+ HUFF_PACK(0x0002df7e, 19), HUFF_PACK(0x00016fff, 18),
+ HUFF_PACK(0x00007dfe, 15), HUFF_PACK(0x00000fa6, 13),
+ HUFF_PACK(0x000007de, 11), HUFF_PACK(0x00000079, 8),
+ HUFF_PACK(0x0000000e, 5), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x000b7dff, 21) /* escape */
+ }},
+ {/* HUFF_CLD_TAB_2D[1][1] */
+ {
+ /* LAV3_2D */
+ {{HUFF_PACK(0x00000000, 1), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x000000fa, 8), HUFF_PACK(0x000007de, 11)},
+ {HUFF_PACK(0x0000000c, 4), HUFF_PACK(0x0000001e, 5),
+ HUFF_PACK(0x000000fe, 8), HUFF_PACK(0x000001f6, 9)},
+ {HUFF_PACK(0x000000ff, 8), HUFF_PACK(0x0000007c, 7),
+ HUFF_PACK(0x0000007e, 7), HUFF_PACK(0x0000001a, 5)},
+ {HUFF_PACK(0x000007df, 11), HUFF_PACK(0x000003ee, 10),
+ HUFF_PACK(0x0000001b, 5), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV5_2D */
+ {{HUFF_PACK(0x00000006, 3), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x0000007c, 7), HUFF_PACK(0x000003fe, 10),
+ HUFF_PACK(0x00000fbe, 12), HUFF_PACK(0x00003efe, 14)},
+ {HUFF_PACK(0x00000000, 3), HUFF_PACK(0x00000001, 3),
+ HUFF_PACK(0x0000003c, 6), HUFF_PACK(0x0000005e, 8),
+ HUFF_PACK(0x000007de, 11), HUFF_PACK(0x000007be, 11)},
+ {HUFF_PACK(0x0000001e, 6), HUFF_PACK(0x0000000a, 5),
+ HUFF_PACK(0x0000001f, 6), HUFF_PACK(0x0000005f, 8),
+ HUFF_PACK(0x000001ee, 9), HUFF_PACK(0x000001f6, 9)},
+ {HUFF_PACK(0x000001fe, 9), HUFF_PACK(0x000000fe, 8),
+ HUFF_PACK(0x000000f6, 8), HUFF_PACK(0x000000fa, 8),
+ HUFF_PACK(0x0000007e, 7), HUFF_PACK(0x00000016, 6)},
+ {HUFF_PACK(0x000007bf, 11), HUFF_PACK(0x000003de, 10),
+ HUFF_PACK(0x000003ee, 10), HUFF_PACK(0x0000007a, 7),
+ HUFF_PACK(0x0000000e, 5), HUFF_PACK(0x00000006, 4)},
+ {HUFF_PACK(0x00003eff, 14), HUFF_PACK(0x00001f7e, 13),
+ HUFF_PACK(0x000003ff, 10), HUFF_PACK(0x0000002e, 7),
+ HUFF_PACK(0x00000004, 4), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV7_2D */
+ {{HUFF_PACK(0x00000002, 3), HUFF_PACK(0x0000000a, 4),
+ HUFF_PACK(0x0000001a, 6), HUFF_PACK(0x000001be, 9),
+ HUFF_PACK(0x000006e6, 11), HUFF_PACK(0x0000067a, 12),
+ HUFF_PACK(0x00000cf2, 13), HUFF_PACK(0x000033de, 15)},
+ {HUFF_PACK(0x0000000c, 4), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x0000000e, 5), HUFF_PACK(0x000000de, 8),
+ HUFF_PACK(0x00000372, 10), HUFF_PACK(0x000003d6, 11),
+ HUFF_PACK(0x00000678, 12), HUFF_PACK(0x00000cf6, 13)},
+ {HUFF_PACK(0x00000036, 6), HUFF_PACK(0x00000012, 5),
+ HUFF_PACK(0x0000003e, 6), HUFF_PACK(0x0000003c, 7),
+ HUFF_PACK(0x000001b8, 9), HUFF_PACK(0x000003d4, 11),
+ HUFF_PACK(0x0000033e, 11), HUFF_PACK(0x0000033f, 11)},
+ {HUFF_PACK(0x0000007e, 8), HUFF_PACK(0x0000006a, 7),
+ HUFF_PACK(0x0000004e, 7), HUFF_PACK(0x0000007e, 7),
+ HUFF_PACK(0x000001ba, 9), HUFF_PACK(0x000000ce, 9),
+ HUFF_PACK(0x000000f6, 9), HUFF_PACK(0x000001ee, 10)},
+ {HUFF_PACK(0x000001ef, 10), HUFF_PACK(0x0000013e, 9),
+ HUFF_PACK(0x0000007f, 8), HUFF_PACK(0x00000066, 8),
+ HUFF_PACK(0x000000d6, 8), HUFF_PACK(0x0000003e, 7),
+ HUFF_PACK(0x000000d7, 8), HUFF_PACK(0x0000009e, 8)},
+ {HUFF_PACK(0x000007ae, 12), HUFF_PACK(0x000001e8, 10),
+ HUFF_PACK(0x000001e9, 10), HUFF_PACK(0x0000027e, 10),
+ HUFF_PACK(0x00000032, 7), HUFF_PACK(0x00000018, 6),
+ HUFF_PACK(0x00000026, 6), HUFF_PACK(0x00000034, 6)},
+ {HUFF_PACK(0x00000cf3, 13), HUFF_PACK(0x000007aa, 12),
+ HUFF_PACK(0x000007ab, 12), HUFF_PACK(0x0000027f, 10),
+ HUFF_PACK(0x000001bf, 9), HUFF_PACK(0x0000001b, 6),
+ HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x0000000b, 4)},
+ {HUFF_PACK(0x000033df, 15), HUFF_PACK(0x000019ee, 14),
+ HUFF_PACK(0x000007af, 12), HUFF_PACK(0x000006e7, 11),
+ HUFF_PACK(0x000001bb, 9), HUFF_PACK(0x0000007f, 7),
+ HUFF_PACK(0x00000008, 4), HUFF_PACK(0x00000000, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV9_2D */
+ {{HUFF_PACK(0x0000000e, 4), HUFF_PACK(0x00000008, 4),
+ HUFF_PACK(0x0000007e, 7), HUFF_PACK(0x000001fe, 9),
+ HUFF_PACK(0x000001ba, 10), HUFF_PACK(0x00000dbe, 12),
+ HUFF_PACK(0x00000d7e, 13), HUFF_PACK(0x00001af6, 14),
+ HUFF_PACK(0x00007fec, 15), HUFF_PACK(0x0001ffb6, 17)},
+ {HUFF_PACK(0x0000000a, 4), HUFF_PACK(0x0000000c, 4),
+ HUFF_PACK(0x0000000c, 5), HUFF_PACK(0x00000036, 7),
+ HUFF_PACK(0x000000de, 9), HUFF_PACK(0x000005fe, 11),
+ HUFF_PACK(0x000006be, 12), HUFF_PACK(0x00001b7e, 13),
+ HUFF_PACK(0x00007fee, 15), HUFF_PACK(0x00006dfe, 15)},
+ {HUFF_PACK(0x0000001e, 6), HUFF_PACK(0x0000000e, 5),
+ HUFF_PACK(0x0000000a, 5), HUFF_PACK(0x0000006a, 7),
+ HUFF_PACK(0x000001ae, 9), HUFF_PACK(0x000006fe, 11),
+ HUFF_PACK(0x00000376, 11), HUFF_PACK(0x00000dfe, 13),
+ HUFF_PACK(0x00000dff, 13), HUFF_PACK(0x00000d7f, 13)},
+ {HUFF_PACK(0x000000b6, 8), HUFF_PACK(0x0000005e, 7),
+ HUFF_PACK(0x0000007c, 7), HUFF_PACK(0x0000006e, 7),
+ HUFF_PACK(0x0000006a, 8), HUFF_PACK(0x0000016a, 9),
+ HUFF_PACK(0x00000ffe, 12), HUFF_PACK(0x00000dfe, 12),
+ HUFF_PACK(0x00000ffc, 12), HUFF_PACK(0x00001bfe, 13)},
+ {HUFF_PACK(0x0000035e, 10), HUFF_PACK(0x000001b6, 9),
+ HUFF_PACK(0x0000005e, 8), HUFF_PACK(0x000000b4, 8),
+ HUFF_PACK(0x0000006c, 7), HUFF_PACK(0x0000017e, 9),
+ HUFF_PACK(0x0000036e, 10), HUFF_PACK(0x000003ee, 10),
+ HUFF_PACK(0x0000037e, 11), HUFF_PACK(0x00000377, 11)},
+ {HUFF_PACK(0x00000fff, 12), HUFF_PACK(0x000001ae, 10),
+ HUFF_PACK(0x000001be, 10), HUFF_PACK(0x000001f6, 9),
+ HUFF_PACK(0x000001be, 9), HUFF_PACK(0x000000da, 8),
+ HUFF_PACK(0x000000fe, 8), HUFF_PACK(0x0000016b, 9),
+ HUFF_PACK(0x000000d6, 9), HUFF_PACK(0x0000037e, 10)},
+ {HUFF_PACK(0x000017fe, 13), HUFF_PACK(0x00000bfe, 12),
+ HUFF_PACK(0x000007de, 11), HUFF_PACK(0x000006de, 11),
+ HUFF_PACK(0x000001b8, 10), HUFF_PACK(0x000000d6, 8),
+ HUFF_PACK(0x0000002e, 7), HUFF_PACK(0x00000034, 7),
+ HUFF_PACK(0x000000de, 8), HUFF_PACK(0x000000be, 8)},
+ {HUFF_PACK(0x00007fef, 15), HUFF_PACK(0x000006bc, 12),
+ HUFF_PACK(0x00001bff, 13), HUFF_PACK(0x00001ffa, 13),
+ HUFF_PACK(0x000001b9, 10), HUFF_PACK(0x000003fe, 10),
+ HUFF_PACK(0x000000fa, 8), HUFF_PACK(0x0000002e, 6),
+ HUFF_PACK(0x00000034, 6), HUFF_PACK(0x0000001f, 6)},
+ {HUFF_PACK(0x00006dff, 15), HUFF_PACK(0x00001af7, 14),
+ HUFF_PACK(0x000036fe, 14), HUFF_PACK(0x000006fe, 12),
+ HUFF_PACK(0x00000fbe, 12), HUFF_PACK(0x0000035f, 10),
+ HUFF_PACK(0x000000b7, 8), HUFF_PACK(0x0000002c, 6),
+ HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x00000009, 4)},
+ {HUFF_PACK(0x0001ffb7, 17), HUFF_PACK(0x0000ffda, 16),
+ HUFF_PACK(0x00000d7a, 13), HUFF_PACK(0x000017ff, 13),
+ HUFF_PACK(0x00000fbf, 12), HUFF_PACK(0x000002fe, 10),
+ HUFF_PACK(0x0000005f, 8), HUFF_PACK(0x00000016, 6),
+ HUFF_PACK(0x00000004, 4), HUFF_PACK(0x00000000, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ }}}}};
+
+const HUFF_ICC_TABLE fdk_sacenc_huffICCTab = {
+ {/* h1D[2][8] */
+ {HUFF_PACK(0x00000000, 1), HUFF_PACK(0x00000002, 2),
+ HUFF_PACK(0x00000006, 3), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x0000003e, 6),
+ HUFF_PACK(0x0000007e, 7), HUFF_PACK(0x0000007f, 7)},
+ {HUFF_PACK(0x00000000, 1), HUFF_PACK(0x00000002, 2),
+ HUFF_PACK(0x00000006, 3), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x0000003e, 6),
+ HUFF_PACK(0x0000007e, 7), HUFF_PACK(0x0000007f, 7)}},
+ { /* HUFF_ICC_TAB_2D */
+ { /* HUFF_ICC_TAB_2D[0][] */
+ {/* HUFF_ICC_TAB_2D[0][0] */
+ {
+ /* LAV1_2D */
+ {{HUFF_PACK(0x00000000, 1), HUFF_PACK(0x00000006, 3)},
+ {HUFF_PACK(0x00000007, 3), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV3_2D */
+ {{HUFF_PACK(0x00000002, 2), HUFF_PACK(0x00000000, 2),
+ HUFF_PACK(0x0000000a, 5), HUFF_PACK(0x0000007e, 8)},
+ {HUFF_PACK(0x0000000e, 5), HUFF_PACK(0x00000004, 4),
+ HUFF_PACK(0x00000016, 6), HUFF_PACK(0x000003fe, 11)},
+ {HUFF_PACK(0x000001fe, 10), HUFF_PACK(0x000000fe, 9),
+ HUFF_PACK(0x0000003e, 7), HUFF_PACK(0x0000001e, 6)},
+ {HUFF_PACK(0x000003ff, 11), HUFF_PACK(0x00000017, 6),
+ HUFF_PACK(0x00000006, 4), HUFF_PACK(0x00000003, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV5_2D */
+ {{HUFF_PACK(0x00000000, 2), HUFF_PACK(0x00000002, 3),
+ HUFF_PACK(0x0000000c, 5), HUFF_PACK(0x0000006a, 7),
+ HUFF_PACK(0x000000dc, 8), HUFF_PACK(0x000006ee, 11)},
+ {HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x0000000c, 4),
+ HUFF_PACK(0x0000000d, 5), HUFF_PACK(0x0000001e, 6),
+ HUFF_PACK(0x000001ae, 9), HUFF_PACK(0x0000ddff, 16)},
+ {HUFF_PACK(0x000000de, 8), HUFF_PACK(0x0000007e, 7),
+ HUFF_PACK(0x0000001f, 6), HUFF_PACK(0x000001be, 9),
+ HUFF_PACK(0x00006efe, 15), HUFF_PACK(0x0000ddfe, 16)},
+ {HUFF_PACK(0x0000377e, 14), HUFF_PACK(0x00001bbe, 13),
+ HUFF_PACK(0x00000dde, 12), HUFF_PACK(0x000001bf, 9),
+ HUFF_PACK(0x000000d6, 8), HUFF_PACK(0x00000376, 10)},
+ {HUFF_PACK(0x0000ddff, 16), HUFF_PACK(0x0000ddff, 16),
+ HUFF_PACK(0x000001ba, 9), HUFF_PACK(0x00000034, 6),
+ HUFF_PACK(0x0000003e, 6), HUFF_PACK(0x0000000e, 5)},
+ {HUFF_PACK(0x0000ddff, 16), HUFF_PACK(0x000001af, 9),
+ HUFF_PACK(0x0000007f, 7), HUFF_PACK(0x00000036, 6),
+ HUFF_PACK(0x0000000e, 4), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x0000ddff, 16) /* escape */
+ },
+ {
+ /* LAV7_2D */
+ {{HUFF_PACK(0x00000000, 2), HUFF_PACK(0x0000000c, 4),
+ HUFF_PACK(0x0000002e, 6), HUFF_PACK(0x00000044, 7),
+ HUFF_PACK(0x00000086, 8), HUFF_PACK(0x0000069e, 11),
+ HUFF_PACK(0x0000043e, 11), HUFF_PACK(0x0000087a, 12)},
+ {HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x0000002a, 6), HUFF_PACK(0x00000046, 7),
+ HUFF_PACK(0x0000015e, 9), HUFF_PACK(0x00000047, 7),
+ HUFF_PACK(0x0000034a, 10), HUFF_PACK(0x0000087b, 12)},
+ {HUFF_PACK(0x000000d6, 8), HUFF_PACK(0x00000026, 6),
+ HUFF_PACK(0x0000002f, 6), HUFF_PACK(0x000000d7, 8),
+ HUFF_PACK(0x0000006a, 7), HUFF_PACK(0x0000034e, 10),
+ HUFF_PACK(0x0000087b, 12), HUFF_PACK(0x0000087b, 12)},
+ {HUFF_PACK(0x000002be, 10), HUFF_PACK(0x000001a6, 9),
+ HUFF_PACK(0x000001be, 9), HUFF_PACK(0x00000012, 5),
+ HUFF_PACK(0x000001bf, 9), HUFF_PACK(0x0000087b, 12),
+ HUFF_PACK(0x0000087b, 12), HUFF_PACK(0x0000087b, 12)},
+ {HUFF_PACK(0x0000087b, 12), HUFF_PACK(0x0000087b, 12),
+ HUFF_PACK(0x0000087b, 12), HUFF_PACK(0x0000087b, 12),
+ HUFF_PACK(0x00000036, 6), HUFF_PACK(0x000000d0, 8),
+ HUFF_PACK(0x0000043c, 11), HUFF_PACK(0x0000043f, 11)},
+ {HUFF_PACK(0x0000087b, 12), HUFF_PACK(0x0000087b, 12),
+ HUFF_PACK(0x0000087b, 12), HUFF_PACK(0x0000034b, 10),
+ HUFF_PACK(0x00000027, 6), HUFF_PACK(0x00000020, 6),
+ HUFF_PACK(0x00000042, 7), HUFF_PACK(0x000000d1, 8)},
+ {HUFF_PACK(0x0000087b, 12), HUFF_PACK(0x0000087b, 12),
+ HUFF_PACK(0x000002bf, 10), HUFF_PACK(0x000000de, 8),
+ HUFF_PACK(0x000000ae, 8), HUFF_PACK(0x00000056, 7),
+ HUFF_PACK(0x00000016, 5), HUFF_PACK(0x00000014, 5)},
+ {HUFF_PACK(0x0000087b, 12), HUFF_PACK(0x0000069f, 11),
+ HUFF_PACK(0x000001a4, 9), HUFF_PACK(0x0000010e, 9),
+ HUFF_PACK(0x00000045, 7), HUFF_PACK(0x0000006e, 7),
+ HUFF_PACK(0x0000001f, 5), HUFF_PACK(0x00000001, 2)}},
+ HUFF_PACK(0x0000087b, 12) /* escape */
+ }},
+ {/* HUFF_ICC_TAB_2D[0][1] */
+ {
+ /* LAV1_2D */
+ {{HUFF_PACK(0x00000000, 1), HUFF_PACK(0x00000006, 3)},
+ {HUFF_PACK(0x00000007, 3), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV3_2D */
+ {{HUFF_PACK(0x00000002, 2), HUFF_PACK(0x00000004, 4),
+ HUFF_PACK(0x0000017e, 10), HUFF_PACK(0x000002fe, 11)},
+ {HUFF_PACK(0x00000000, 2), HUFF_PACK(0x0000000e, 5),
+ HUFF_PACK(0x000000be, 9), HUFF_PACK(0x00000016, 6)},
+ {HUFF_PACK(0x0000000f, 5), HUFF_PACK(0x00000014, 6),
+ HUFF_PACK(0x0000005e, 8), HUFF_PACK(0x00000006, 4)},
+ {HUFF_PACK(0x0000002e, 7), HUFF_PACK(0x000002ff, 11),
+ HUFF_PACK(0x00000015, 6), HUFF_PACK(0x00000003, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV5_2D */
+ {{HUFF_PACK(0x00000000, 2), HUFF_PACK(0x0000001e, 5),
+ HUFF_PACK(0x000003fc, 10), HUFF_PACK(0x0000fffa, 16),
+ HUFF_PACK(0x000fff9e, 20), HUFF_PACK(0x000fff9f, 20)},
+ {HUFF_PACK(0x00000006, 3), HUFF_PACK(0x00000004, 4),
+ HUFF_PACK(0x000000be, 9), HUFF_PACK(0x00007ffe, 15),
+ HUFF_PACK(0x0007ffce, 19), HUFF_PACK(0x000000fe, 8)},
+ {HUFF_PACK(0x00000006, 4), HUFF_PACK(0x0000001e, 6),
+ HUFF_PACK(0x000003fd, 10), HUFF_PACK(0x0000fffb, 16),
+ HUFF_PACK(0x00000ffe, 12), HUFF_PACK(0x0000003e, 6)},
+ {HUFF_PACK(0x0000000a, 5), HUFF_PACK(0x0000007e, 7),
+ HUFF_PACK(0x00001ffe, 13), HUFF_PACK(0x00007fff, 15),
+ HUFF_PACK(0x0000005e, 8), HUFF_PACK(0x0000000e, 5)},
+ {HUFF_PACK(0x0000001f, 6), HUFF_PACK(0x000003fe, 10),
+ HUFF_PACK(0x0001fff2, 17), HUFF_PACK(0x00000ffc, 12),
+ HUFF_PACK(0x0000002e, 7), HUFF_PACK(0x0000000e, 4)},
+ {HUFF_PACK(0x000000bf, 9), HUFF_PACK(0x0003ffe6, 18),
+ HUFF_PACK(0x0000fff8, 16), HUFF_PACK(0x00000ffd, 12),
+ HUFF_PACK(0x00000016, 6), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV7_2D */
+ {{HUFF_PACK(0x00000002, 2), HUFF_PACK(0x0000001e, 6),
+ HUFF_PACK(0x00000ffe, 12), HUFF_PACK(0x0000ffff, 16),
+ HUFF_PACK(0x0000fffe, 16), HUFF_PACK(0x0000ffff, 16),
+ HUFF_PACK(0x0000ffff, 16), HUFF_PACK(0x0000ffff, 16)},
+ {HUFF_PACK(0x00000006, 3), HUFF_PACK(0x00000008, 5),
+ HUFF_PACK(0x000007fe, 11), HUFF_PACK(0x0000ffff, 16),
+ HUFF_PACK(0x0000ffff, 16), HUFF_PACK(0x0000ffff, 16),
+ HUFF_PACK(0x0000ffff, 16), HUFF_PACK(0x0000005a, 8)},
+ {HUFF_PACK(0x00000006, 4), HUFF_PACK(0x0000007a, 7),
+ HUFF_PACK(0x00000164, 10), HUFF_PACK(0x00007ffa, 15),
+ HUFF_PACK(0x0000ffff, 16), HUFF_PACK(0x0000ffff, 16),
+ HUFF_PACK(0x00001fee, 13), HUFF_PACK(0x0000003c, 6)},
+ {HUFF_PACK(0x0000000e, 5), HUFF_PACK(0x000000fe, 8),
+ HUFF_PACK(0x000002ce, 11), HUFF_PACK(0x000002cf, 11),
+ HUFF_PACK(0x00007ffb, 15), HUFF_PACK(0x00001fec, 13),
+ HUFF_PACK(0x000000b0, 9), HUFF_PACK(0x0000002e, 7)},
+ {HUFF_PACK(0x0000003e, 6), HUFF_PACK(0x000003fe, 10),
+ HUFF_PACK(0x00000165, 10), HUFF_PACK(0x00007ffc, 15),
+ HUFF_PACK(0x00001fef, 13), HUFF_PACK(0x000007fa, 11),
+ HUFF_PACK(0x000007f8, 11), HUFF_PACK(0x0000001f, 6)},
+ {HUFF_PACK(0x0000002f, 7), HUFF_PACK(0x000000f6, 8),
+ HUFF_PACK(0x00001fed, 13), HUFF_PACK(0x0000ffff, 16),
+ HUFF_PACK(0x00007ffd, 15), HUFF_PACK(0x00000ff2, 12),
+ HUFF_PACK(0x000000b1, 9), HUFF_PACK(0x0000000a, 5)},
+ {HUFF_PACK(0x00000009, 5), HUFF_PACK(0x00000166, 10),
+ HUFF_PACK(0x0000ffff, 16), HUFF_PACK(0x0000ffff, 16),
+ HUFF_PACK(0x00007ffe, 15), HUFF_PACK(0x00003ffc, 14),
+ HUFF_PACK(0x0000005b, 8), HUFF_PACK(0x0000000e, 4)},
+ {HUFF_PACK(0x0000007e, 7), HUFF_PACK(0x0000ffff, 16),
+ HUFF_PACK(0x0000ffff, 16), HUFF_PACK(0x0000ffff, 16),
+ HUFF_PACK(0x0000ffff, 16), HUFF_PACK(0x00000ff3, 12),
+ HUFF_PACK(0x000000f7, 8), HUFF_PACK(0x00000000, 2)}},
+ HUFF_PACK(0x0000ffff, 16) /* escape */
+ }}},
+ { /* HUFF_ICC_TAB_2D[1][] */
+ {/* HUFF_ICC_TAB_2D[1][0] */
+ {
+ /* LAV1_2D */
+ {{HUFF_PACK(0x00000000, 1), HUFF_PACK(0x00000006, 3)},
+ {HUFF_PACK(0x00000007, 3), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV3_2D */
+ {{HUFF_PACK(0x00000002, 2), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x0000037e, 10), HUFF_PACK(0x00000dfe, 12)},
+ {HUFF_PACK(0x0000000f, 4), HUFF_PACK(0x0000000c, 4),
+ HUFF_PACK(0x000001ba, 9), HUFF_PACK(0x000001bb, 9)},
+ {HUFF_PACK(0x000000de, 8), HUFF_PACK(0x000000dc, 8),
+ HUFF_PACK(0x000001be, 9), HUFF_PACK(0x0000001a, 5)},
+ {HUFF_PACK(0x000006fe, 11), HUFF_PACK(0x00000dff, 12),
+ HUFF_PACK(0x00000036, 6), HUFF_PACK(0x00000000, 1)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV5_2D */
+ {{HUFF_PACK(0x00000000, 1), HUFF_PACK(0x0000000c, 4),
+ HUFF_PACK(0x000001b6, 9), HUFF_PACK(0x00001b7c, 13),
+ HUFF_PACK(0x0000dbfe, 16), HUFF_PACK(0x00036fff, 18)},
+ {HUFF_PACK(0x0000000e, 4), HUFF_PACK(0x0000001e, 5),
+ HUFF_PACK(0x000001be, 9), HUFF_PACK(0x00000dfe, 12),
+ HUFF_PACK(0x00036ffe, 18), HUFF_PACK(0x0000036e, 10)},
+ {HUFF_PACK(0x0000006e, 7), HUFF_PACK(0x000000fe, 8),
+ HUFF_PACK(0x000000d8, 8), HUFF_PACK(0x000036fe, 14),
+ HUFF_PACK(0x000006de, 11), HUFF_PACK(0x000000de, 8)},
+ {HUFF_PACK(0x000001fa, 9), HUFF_PACK(0x000000da, 8),
+ HUFF_PACK(0x00000dff, 12), HUFF_PACK(0x00001b7e, 13),
+ HUFF_PACK(0x000000d9, 8), HUFF_PACK(0x000000ff, 8)},
+ {HUFF_PACK(0x000003f6, 10), HUFF_PACK(0x000006fe, 11),
+ HUFF_PACK(0x00006dfe, 15), HUFF_PACK(0x0000037e, 10),
+ HUFF_PACK(0x000000fc, 8), HUFF_PACK(0x0000001a, 5)},
+ {HUFF_PACK(0x000007ee, 11), HUFF_PACK(0x0001b7fe, 17),
+ HUFF_PACK(0x00001b7d, 13), HUFF_PACK(0x000007ef, 11),
+ HUFF_PACK(0x0000003e, 6), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00036fff, 18) /* escape */
+ },
+ {
+ /* LAV7_2D */
+ {{HUFF_PACK(0x00000000, 1), HUFF_PACK(0x0000000c, 4),
+ HUFF_PACK(0x000007ee, 11), HUFF_PACK(0x00001e7e, 13),
+ HUFF_PACK(0x00003cfe, 14), HUFF_PACK(0x000079ff, 15),
+ HUFF_PACK(0x000079ff, 15), HUFF_PACK(0x000079ff, 15)},
+ {HUFF_PACK(0x0000000e, 4), HUFF_PACK(0x0000001a, 5),
+ HUFF_PACK(0x000001e6, 9), HUFF_PACK(0x00001fbe, 13),
+ HUFF_PACK(0x000079fe, 15), HUFF_PACK(0x000079ff, 15),
+ HUFF_PACK(0x000079ff, 15), HUFF_PACK(0x000006fc, 11)},
+ {HUFF_PACK(0x0000006c, 7), HUFF_PACK(0x000000f6, 8),
+ HUFF_PACK(0x000001ba, 9), HUFF_PACK(0x00000dfc, 12),
+ HUFF_PACK(0x00000dfd, 12), HUFF_PACK(0x000079ff, 15),
+ HUFF_PACK(0x00000f3e, 12), HUFF_PACK(0x000001bb, 9)},
+ {HUFF_PACK(0x000000dc, 8), HUFF_PACK(0x000001fe, 9),
+ HUFF_PACK(0x0000036e, 10), HUFF_PACK(0x000003fe, 10),
+ HUFF_PACK(0x000079ff, 15), HUFF_PACK(0x00000fde, 12),
+ HUFF_PACK(0x000001ee, 9), HUFF_PACK(0x000000f2, 8)},
+ {HUFF_PACK(0x000001fa, 9), HUFF_PACK(0x000003f6, 10),
+ HUFF_PACK(0x000001be, 9), HUFF_PACK(0x000079ff, 15),
+ HUFF_PACK(0x00001fbf, 13), HUFF_PACK(0x000003ce, 10),
+ HUFF_PACK(0x000003ff, 10), HUFF_PACK(0x000000de, 8)},
+ {HUFF_PACK(0x00000078, 7), HUFF_PACK(0x000000da, 8),
+ HUFF_PACK(0x000079ff, 15), HUFF_PACK(0x000079ff, 15),
+ HUFF_PACK(0x000006fd, 11), HUFF_PACK(0x0000036c, 10),
+ HUFF_PACK(0x000001ef, 9), HUFF_PACK(0x000000fe, 8)},
+ {HUFF_PACK(0x0000036f, 10), HUFF_PACK(0x00000dfe, 12),
+ HUFF_PACK(0x000079ff, 15), HUFF_PACK(0x000079ff, 15),
+ HUFF_PACK(0x000079ff, 15), HUFF_PACK(0x0000036d, 10),
+ HUFF_PACK(0x000000fc, 8), HUFF_PACK(0x0000003e, 6)},
+ {HUFF_PACK(0x00000dff, 12), HUFF_PACK(0x000079ff, 15),
+ HUFF_PACK(0x000079ff, 15), HUFF_PACK(0x000079ff, 15),
+ HUFF_PACK(0x000079ff, 15), HUFF_PACK(0x0000079e, 11),
+ HUFF_PACK(0x0000007a, 7), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x000079ff, 15) /* escape */
+ }},
+ {/* HUFF_ICC_TAB_2D[1][1] */
+ {
+ /* LAV1_2D */
+ {{HUFF_PACK(0x00000000, 1), HUFF_PACK(0x00000006, 3)},
+ {HUFF_PACK(0x00000007, 3), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV3_2D */
+ {{HUFF_PACK(0x00000002, 2), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x000000fc, 8), HUFF_PACK(0x00000fde, 12)},
+ {HUFF_PACK(0x0000000c, 4), HUFF_PACK(0x0000000d, 4),
+ HUFF_PACK(0x000001fe, 9), HUFF_PACK(0x000007ee, 11)},
+ {HUFF_PACK(0x000001fa, 9), HUFF_PACK(0x000001ff, 9),
+ HUFF_PACK(0x000000fe, 8), HUFF_PACK(0x0000003e, 6)},
+ {HUFF_PACK(0x00000fdf, 12), HUFF_PACK(0x000003f6, 10),
+ HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x00000000, 1)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV5_2D */
+ {{HUFF_PACK(0x00000000, 2), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x0000003a, 7), HUFF_PACK(0x00000676, 11),
+ HUFF_PACK(0x000019fe, 13), HUFF_PACK(0x0000cebe, 16)},
+ {HUFF_PACK(0x0000000f, 4), HUFF_PACK(0x00000002, 3),
+ HUFF_PACK(0x0000001e, 6), HUFF_PACK(0x000000fe, 9),
+ HUFF_PACK(0x000019d6, 13), HUFF_PACK(0x0000675e, 15)},
+ {HUFF_PACK(0x0000003e, 7), HUFF_PACK(0x00000032, 6),
+ HUFF_PACK(0x00000018, 5), HUFF_PACK(0x0000033e, 10),
+ HUFF_PACK(0x00000cfe, 12), HUFF_PACK(0x00000677, 11)},
+ {HUFF_PACK(0x00000674, 11), HUFF_PACK(0x0000019c, 9),
+ HUFF_PACK(0x000000ff, 9), HUFF_PACK(0x0000003b, 7),
+ HUFF_PACK(0x0000001c, 6), HUFF_PACK(0x0000007e, 8)},
+ {HUFF_PACK(0x000033fe, 14), HUFF_PACK(0x000033ff, 14),
+ HUFF_PACK(0x00000cea, 12), HUFF_PACK(0x00000066, 7),
+ HUFF_PACK(0x0000001a, 5), HUFF_PACK(0x00000006, 4)},
+ {HUFF_PACK(0x0000cebf, 16), HUFF_PACK(0x000033ae, 14),
+ HUFF_PACK(0x0000067e, 11), HUFF_PACK(0x0000019e, 9),
+ HUFF_PACK(0x0000001b, 5), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV7_2D */
+ {{HUFF_PACK(0x00000002, 2), HUFF_PACK(0x00000002, 4),
+ HUFF_PACK(0x000000fe, 9), HUFF_PACK(0x000007be, 12),
+ HUFF_PACK(0x00000ffc, 13), HUFF_PACK(0x00000ffd, 13),
+ HUFF_PACK(0x00001efe, 15), HUFF_PACK(0x00003dfe, 16)},
+ {HUFF_PACK(0x00000004, 4), HUFF_PACK(0x00000000, 3),
+ HUFF_PACK(0x0000003c, 7), HUFF_PACK(0x000000f6, 10),
+ HUFF_PACK(0x000001da, 11), HUFF_PACK(0x000003fe, 12),
+ HUFF_PACK(0x00003dfe, 15), HUFF_PACK(0x00003dff, 16)},
+ {HUFF_PACK(0x0000003c, 8), HUFF_PACK(0x0000003e, 7),
+ HUFF_PACK(0x0000000a, 5), HUFF_PACK(0x0000003a, 8),
+ HUFF_PACK(0x000003de, 11), HUFF_PACK(0x000007be, 13),
+ HUFF_PACK(0x00000f7e, 14), HUFF_PACK(0x00001efe, 14)},
+ {HUFF_PACK(0x000001de, 11), HUFF_PACK(0x000000ec, 10),
+ HUFF_PACK(0x0000007e, 9), HUFF_PACK(0x0000000c, 5),
+ HUFF_PACK(0x000001ee, 10), HUFF_PACK(0x00000f7e, 13),
+ HUFF_PACK(0x000007fc, 12), HUFF_PACK(0x00003dff, 15)},
+ {HUFF_PACK(0x00007ffe, 16), HUFF_PACK(0x000003be, 12),
+ HUFF_PACK(0x000000fe, 10), HUFF_PACK(0x000001fe, 10),
+ HUFF_PACK(0x0000001a, 6), HUFF_PACK(0x0000001c, 7),
+ HUFF_PACK(0x000007fd, 12), HUFF_PACK(0x00000ffe, 13)},
+ {HUFF_PACK(0x00003dff, 16), HUFF_PACK(0x000003bf, 12),
+ HUFF_PACK(0x00001ffe, 14), HUFF_PACK(0x000003ff, 12),
+ HUFF_PACK(0x0000003e, 8), HUFF_PACK(0x0000001b, 6),
+ HUFF_PACK(0x0000007e, 8), HUFF_PACK(0x000000f6, 9)},
+ {HUFF_PACK(0x00007fff, 16), HUFF_PACK(0x00003dff, 16),
+ HUFF_PACK(0x00003ffe, 15), HUFF_PACK(0x000001db, 11),
+ HUFF_PACK(0x000000ee, 10), HUFF_PACK(0x0000007a, 8),
+ HUFF_PACK(0x0000000e, 5), HUFF_PACK(0x0000000b, 5)},
+ {HUFF_PACK(0x00003dff, 16), HUFF_PACK(0x00003dff, 16),
+ HUFF_PACK(0x000003de, 12), HUFF_PACK(0x000001fe, 11),
+ HUFF_PACK(0x000001ee, 11), HUFF_PACK(0x0000007a, 9),
+ HUFF_PACK(0x00000006, 5), HUFF_PACK(0x00000003, 2)}},
+ HUFF_PACK(0x00003dff, 16) /* escape */
+ }}}}};
+
+const HUFF_PT0_TABLE fdk_sacenc_huffPart0Tab = {
+ {/* CLD */
+ HUFF_PACK(0x00000052, 8), HUFF_PACK(0x000000ae, 9),
+ HUFF_PACK(0x000000af, 9), HUFF_PACK(0x00000028, 7),
+ HUFF_PACK(0x0000006e, 7), HUFF_PACK(0x00000036, 6),
+ HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x0000000c, 4), HUFF_PACK(0x0000000a, 4),
+ HUFF_PACK(0x00000002, 4), HUFF_PACK(0x00000016, 5),
+ HUFF_PACK(0x00000012, 5), HUFF_PACK(0x00000017, 5),
+ HUFF_PACK(0x00000000, 4), HUFF_PACK(0x00000004, 4),
+ HUFF_PACK(0x00000006, 4), HUFF_PACK(0x00000008, 4),
+ HUFF_PACK(0x00000007, 4), HUFF_PACK(0x00000003, 4),
+ HUFF_PACK(0x00000001, 4), HUFF_PACK(0x0000001a, 5),
+ HUFF_PACK(0x00000013, 5), HUFF_PACK(0x0000003e, 6),
+ HUFF_PACK(0x00000016, 6), HUFF_PACK(0x00000017, 6),
+ HUFF_PACK(0x0000006f, 7), HUFF_PACK(0x0000002a, 7),
+ HUFF_PACK(0x00000056, 8), HUFF_PACK(0x00000053, 8),
+ HUFF_PACK(0x0000003f, 6)},
+ {/* ICC */
+ HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x00000006, 3), HUFF_PACK(0x00000000, 2),
+ HUFF_PACK(0x00000002, 2), HUFF_PACK(0x00000001, 2),
+ HUFF_PACK(0x0000003e, 6), HUFF_PACK(0x0000003f, 6)}};
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
diff --git a/libSACenc/src/sacenc_huff_tab.h b/libSACenc/src/sacenc_huff_tab.h
new file mode 100644
index 0000000..7d6c331
--- /dev/null
+++ b/libSACenc/src/sacenc_huff_tab.h
@@ -0,0 +1,222 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): Markus Lohwasser
+
+ Description: SAC-Encoder constant huffman tables
+
+*******************************************************************************/
+
+#ifndef SACENC_HUFF_TAB_H
+#define SACENC_HUFF_TAB_H
+
+/* Includes ******************************************************************/
+#include "machine_type.h"
+
+/* Defines *******************************************************************/
+#define HUFF_PACK(a, b) \
+ { \
+ ((((ULONG)a) & 0x00FFFFFF) << 8) | (((ULONG)b) & 0xFF) \
+ } /*!< Pack huffman value and length information. */
+#define HUFF_VALUE(a) \
+ (((a.packed >> 8) & 0x00FFFFFF)) /*!< Return value from packed table entry. \
+ */
+#define HUFF_LENGTH(a) \
+ ((a.packed & 0xFF)) /*!< Return length from packed table entry. */
+
+/* Data Types ****************************************************************/
+/**
+ * \brief This struct contains packed huffman entries.
+ *
+ * The packed entry consist of hffman value and length information.
+ *
+ * |---------------------------------|
+ * | value | length |
+ * |---------------------------------|
+ * |<------- 31...8 ------->|< 7..0 >|
+ */
+typedef struct {
+ ULONG packed; /*! Packed huffman entry:
+ - lower 8 bit are reservoed for length information
+ - upper 24 bit contains huffman value */
+} HUFF_ENTRY;
+
+typedef struct {
+ HUFF_ENTRY entry[2][2];
+ HUFF_ENTRY escape;
+
+} LAV1_2D;
+
+typedef struct {
+ HUFF_ENTRY entry[4][4];
+ HUFF_ENTRY escape;
+
+} LAV3_2D;
+
+typedef struct {
+ HUFF_ENTRY entry[6][6];
+ HUFF_ENTRY escape;
+
+} LAV5_2D;
+
+typedef struct {
+ HUFF_ENTRY entry[7][7];
+ HUFF_ENTRY escape;
+
+} LAV6_2D;
+
+typedef struct {
+ HUFF_ENTRY entry[8][8];
+ HUFF_ENTRY escape;
+
+} LAV7_2D;
+
+typedef struct {
+ HUFF_ENTRY entry[10][10];
+ HUFF_ENTRY escape;
+
+} LAV9_2D;
+
+typedef struct {
+ HUFF_ENTRY entry[13][13];
+ HUFF_ENTRY escape;
+
+} LAV12_2D;
+
+typedef struct {
+ LAV3_2D lav3;
+ LAV5_2D lav5;
+ LAV7_2D lav7;
+ LAV9_2D lav9;
+
+} HUFF_CLD_TAB_2D;
+
+typedef struct {
+ LAV1_2D lav1;
+ LAV3_2D lav3;
+ LAV5_2D lav5;
+ LAV7_2D lav7;
+
+} HUFF_ICC_TAB_2D;
+
+typedef struct {
+ HUFF_ENTRY h1D[2][31];
+ HUFF_CLD_TAB_2D h2D[2][2];
+
+} HUFF_CLD_TABLE;
+
+typedef struct {
+ HUFF_ENTRY h1D[2][8];
+ HUFF_ICC_TAB_2D h2D[2][2];
+
+} HUFF_ICC_TABLE;
+
+typedef struct {
+ HUFF_ENTRY cld[31];
+ HUFF_ENTRY icc[8];
+
+} HUFF_PT0_TABLE;
+
+typedef HUFF_ENTRY HUFF_RES_TABLE[5][8];
+
+/* Constants *****************************************************************/
+extern const HUFF_CLD_TABLE fdk_sacenc_huffCLDTab;
+extern const HUFF_ICC_TABLE fdk_sacenc_huffICCTab;
+extern const HUFF_PT0_TABLE fdk_sacenc_huffPart0Tab;
+
+/* Function / Class Declarations *********************************************/
+
+#endif /* SACENC_HUFF_TAB_H */
diff --git a/libSACenc/src/sacenc_lib.cpp b/libSACenc/src/sacenc_lib.cpp
new file mode 100644
index 0000000..d6a1658
--- /dev/null
+++ b/libSACenc/src/sacenc_lib.cpp
@@ -0,0 +1,2042 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): Max Neuendorf
+
+ Description: Encoder Library Interface
+ Interface to Spacial Audio Coding Encoder lib
+
+*******************************************************************************/
+
+/****************************************************************************
+\file
+Description of file contents
+******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_lib.h"
+#include "sacenc_const.h"
+#include "genericStds.h"
+#include "FDK_core.h"
+#include "sacenc_tree.h"
+#include "sacenc_bitstream.h"
+#include "sacenc_onsetdetect.h"
+#include "sacenc_framewindowing.h"
+#include "sacenc_filter.h"
+#include "sacenc_paramextract.h"
+#include "sacenc_staticgain.h"
+#include "sacenc_delay.h"
+#include "sacenc_dmx_tdom_enh.h"
+#include "sacenc_vectorfunctions.h"
+#include "qmf.h"
+
+/* Defines *******************************************************************/
+
+/* Encoder library info */
+#define SACENC_LIB_VL0 2
+#define SACENC_LIB_VL1 0
+#define SACENC_LIB_VL2 0
+#define SACENC_LIB_TITLE "MPEG Surround Encoder"
+#ifdef __ANDROID__
+#define SACENC_LIB_BUILD_DATE ""
+#define SACENC_LIB_BUILD_TIME ""
+#else
+#define SACENC_LIB_BUILD_DATE __DATE__
+#define SACENC_LIB_BUILD_TIME __TIME__
+#endif
+
+#define MAX_MPEGS_BYTES (1 << 14)
+#define MAX_SSC_BYTES (1 << 6)
+
+#define MAX_SPACE_TREE_CHANNELS 2
+#define NUM_KEEP_WINDOWS 3
+
+/* Data Types ****************************************************************/
+typedef struct {
+ MP4SPACEENC_MODE encMode;
+ MP4SPACEENC_BANDS_CONFIG nParamBands;
+ MP4SPACEENC_QUANTMODE quantMode;
+ UCHAR bUseCoarseQuant;
+ UCHAR bLdMode;
+ UCHAR bTimeDomainDmx;
+ UINT sampleRate;
+ UINT frameTimeSlots; /* e.g. 32 when used with HE-AAC */
+ UINT independencyFactor; /* how often should we set the independency flag */
+ INT timeAlignment; /* additional delay for downmix */
+
+} MP4SPACEENC_SETUP, *HANDLE_MP4SPACEENC_SETUP;
+
+struct ENC_CONFIG_SETUP {
+ UCHAR bEncMode_212;
+ UCHAR maxHybridInStaticSlots;
+ LONG maxSamplingrate;
+ INT maxAnalysisLengthTimeSlots;
+ INT maxHybridBands;
+ INT maxQmfBands;
+ INT maxChIn;
+ INT maxFrameTimeSlots;
+ INT maxFrameLength;
+ INT maxChOut;
+ INT maxChTotOut;
+};
+
+struct MP4SPACE_ENCODER {
+ MP4SPACEENC_SETUP user;
+
+ ENC_CONFIG_SETUP setup; /* describe allocated instance */
+
+ HANDLE_FRAMEWINDOW
+ hFrameWindow; /* Windowing, only created+updated, but not used */
+ INT nSamplesValid; /* Input Buffer Handling */
+
+ /* Routing Sensible Switches/Variables */
+ MP4SPACEENC_BANDS_CONFIG nParamBands;
+ UCHAR useTimeDomDownmix;
+
+ /* not Routing Sensible Switches/Varibles - must be contained in Check */
+ MP4SPACEENC_MODE encMode;
+ UCHAR bEncMode_212_only;
+
+ /* not Routing Sensible Switches/Varibles + lower Classes */
+ UCHAR useFrameKeep;
+ UINT independencyFactor;
+ UINT nSampleRate;
+ UCHAR nInputChannels;
+ UCHAR nOutputChannels;
+ UCHAR nFrameTimeSlots; /* e.g. 32 when used with HE-AAC */
+ UCHAR nQmfBands;
+ UCHAR nHybridBands;
+ UINT nFrameLength; /* number of output waveform samples/channel/frame */
+
+ /* not Routing Sensible Switches/Varibles + lower Classes, secondary computed
+ */
+ INT nSamplesNext;
+ INT nAnalysisLengthTimeSlots;
+ INT nAnalysisLookaheadTimeSlots;
+ INT nUpdateHybridPositionTimeSlots;
+ INT *pnOutputBits;
+ INT nInputDelay;
+ INT nOutputBufferDelay;
+ INT nSurroundAnalysisBufferDelay;
+ INT nBitstreamDelayBuffer;
+ INT nBitstreamBufferRead;
+ INT nBitstreamBufferWrite;
+ INT nDiscardOutFrames;
+ INT avoid_keep;
+
+ /* not Routing Sensible Switches/Varibles -> moved to lower Classes */
+ UCHAR useCoarseQuantCld; /* Only Used in SpaceTreeSetup */
+ UCHAR useCoarseQuantIcc; /* Only Used in SpaceTreeSetup */
+ UCHAR useCoarseQuantCpc; /* Only Used in SpaceTreeSetup */
+ UCHAR useCoarseQuantArbDmx; /* ArbitraryDmx,... not available yet */
+ MP4SPACEENC_QUANTMODE
+ quantMode; /* Used for quanitzation and in bitstream writer */
+ INT coreCoderDelay; /* Used in delay compensation */
+ INT timeAlignment; /* Used in delay compensation */
+
+ /* Local Processing Variables */
+ INT independencyCount;
+ INT independencyFlag;
+ INT **ppTrCurrPos; /* belongs somehow to Onset Detection */
+ INT trPrevPos[2 * MAX_NUM_TRANS]; /* belongs somehow to Onset Detection */
+
+ FRAMEWIN_LIST frameWinList;
+ SPATIALFRAME saveFrame;
+
+ /* Module-Handles */
+ SPACE_TREE_SETUP spaceTreeSetup;
+ MPEG4SPACEENC_SSCBUF sscBuf;
+ FIXP_WIN *pFrameWindowAna__FDK[MAX_NUM_PARAMS];
+ HANDLE_QMF_FILTER_BANK *phQmfFiltIn__FDK;
+ HANDLE_DC_FILTER phDCFilterSigIn[SACENC_MAX_INPUT_CHANNELS];
+ HANDLE_ONSET_DETECT phOnset[SACENC_MAX_INPUT_CHANNELS];
+ HANDLE_SPACE_TREE hSpaceTree;
+ HANDLE_BSF_INSTANCE hBitstreamFormatter;
+ HANDLE_STATIC_GAIN_CONFIG hStaticGainConfig;
+ HANDLE_STATIC_GAIN hStaticGain;
+ HANDLE_DELAY hDelay;
+
+ /* enhanced time domain downmix (for stereo input) */
+ HANDLE_ENHANCED_TIME_DOMAIN_DMX hEnhancedTimeDmx;
+
+ /* Data Buffers */
+ INT_PCM **ppTimeSigIn__FDK;
+ INT_PCM **ppTimeSigDelayIn__FDK;
+ INT_PCM **ppTimeSigOut__FDK;
+ FIXP_DPK ***pppHybridIn__FDK;
+ FIXP_DPK ***pppHybridInStatic__FDK;
+ FIXP_DPK ***pppProcDataIn__FDK;
+ INT_PCM *pOutputDelayBuffer__FDK;
+
+ UCHAR **ppBitstreamDelayBuffer;
+
+ UCHAR *pParameterBand2HybridBandOffset;
+ INT staticGainScale;
+
+ INT *pEncoderInputChScale;
+ INT *staticTimeDomainDmxInScale;
+};
+
+/* Constants *****************************************************************/
+static const UCHAR pValidBands_Ld[8] = {4, 5, 7, 9, 12, 15, 23, 40};
+
+static const UCHAR qmf2qmf[] = /* Bypass the HybridAnylyis/Synthesis*/
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127};
+
+/* Function / Class Declarations *********************************************/
+static FDK_SACENC_ERROR mp4SpaceEnc_create(
+ HANDLE_MP4SPACE_ENCODER *phMp4SpaceEnc);
+
+static FDK_SACENC_ERROR FillSpatialSpecificConfig(
+ const HANDLE_MP4SPACE_ENCODER hEnc, SPATIALSPECIFICCONFIG *const hSsc);
+
+static FDK_SACENC_ERROR mp4SpaceEnc_FillSpaceTreeSetup(
+ const HANDLE_MP4SPACE_ENCODER hEnc,
+ SPACE_TREE_SETUP *const hSpaceTreeSetup);
+
+static FDK_SACENC_ERROR mp4SpaceEnc_InitDelayCompensation(
+ HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc, const INT coreCoderDelay);
+
+static FDK_SACENC_ERROR mp4SpaceEnc_InitDefault(
+ HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc);
+
+static DECORRCONFIG mp4SpaceEnc_GetDecorrConfig(const MP4SPACEENC_MODE encMode);
+
+static FDK_SACENC_ERROR mp4SpaceEnc_InitNumParamBands(
+ HANDLE_MP4SPACE_ENCODER hEnc, const MP4SPACEENC_BANDS_CONFIG nParamBands);
+
+/* Function / Class Definition ***********************************************/
+static UINT mp4SpaceEnc_GetNumQmfBands(const UINT nSampleRate) {
+ UINT nQmfBands = 0;
+
+ if (nSampleRate < 27713)
+ nQmfBands = 32;
+ else if (nSampleRate < 55426)
+ nQmfBands = 64;
+
+ return nQmfBands;
+}
+
+static UINT updateQmfFlags(const UINT flags, const INT keepStates) {
+ UINT qmfFlags = flags;
+
+ qmfFlags = (qmfFlags & (~(UINT)QMF_FLAG_LP));
+ qmfFlags = (qmfFlags | QMF_FLAG_MPSLDFB);
+ qmfFlags = (keepStates) ? (qmfFlags | QMF_FLAG_KEEP_STATES)
+ : (qmfFlags & (~(UINT)QMF_FLAG_KEEP_STATES));
+
+ return qmfFlags;
+}
+
+static INT freq2HybridBand(const UINT nFrequency, const UINT nSampleRate,
+ const UINT nQmfBands) {
+ /*
+ nQmfSlotWidth = (nSampleRate/2) / nQmfBands;
+ nQmfBand = nFrequency / nQmfSlotWidth;
+ */
+ int nHybridBand = -1;
+ int scale = 0;
+ const FIXP_DBL temp = fDivNorm((FIXP_DBL)(2 * nFrequency * nQmfBands),
+ (FIXP_DBL)nSampleRate, &scale);
+ const int nQmfBand = scaleValue(temp, scale - (DFRACT_BITS - 1));
+
+ if ((nQmfBand > -1) && (nQmfBand < (int)nQmfBands)) {
+ nHybridBand = qmf2qmf[nQmfBand];
+ }
+
+ return nHybridBand;
+}
+
+/*
+ * Examine buffer descriptor regarding choosen type.
+ *
+ * \param pBufDesc Pointer to buffer descriptor
+ * \param type Buffer type to look for.
+
+ * \return - Buffer descriptor index.
+ * -1, if there is no entry available.
+ */
+static INT getBufDescIdx(const FDK_bufDescr *pBufDesc, const UINT type) {
+ INT i, idx = -1;
+
+ for (i = 0; i < (int)pBufDesc->numBufs; i++) {
+ if (pBufDesc->pBufType[i] == type) {
+ idx = i;
+ break;
+ }
+ }
+ return idx;
+}
+
+FDK_SACENC_ERROR FDK_sacenc_open(HANDLE_MP4SPACE_ENCODER *phMp4SpaceEnc) {
+ return mp4SpaceEnc_create(phMp4SpaceEnc);
+}
+
+static FDK_SACENC_ERROR mp4SpaceEnc_create(
+ HANDLE_MP4SPACE_ENCODER *phMp4SpaceEnc) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+ HANDLE_MP4SPACE_ENCODER hEnc = NULL;
+ ENC_CONFIG_SETUP setup;
+
+ if (NULL == phMp4SpaceEnc) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int i, ch;
+ FDKmemclear(&setup, sizeof(ENC_CONFIG_SETUP));
+
+ /* Allocate Encoder Instance */
+ FDK_ALLOCATE_MEMORY_1D(hEnc, 1, struct MP4SPACE_ENCODER);
+
+ /* Clear everything, also pointers. */
+ if (NULL != hEnc) {
+ FDKmemclear(hEnc, sizeof(struct MP4SPACE_ENCODER));
+ }
+
+ setup.maxSamplingrate = 48000;
+ setup.maxFrameTimeSlots = 16;
+
+ setup.maxAnalysisLengthTimeSlots = 3 * setup.maxFrameTimeSlots;
+ setup.maxQmfBands = mp4SpaceEnc_GetNumQmfBands(setup.maxSamplingrate);
+ ;
+ setup.maxHybridBands = setup.maxQmfBands;
+ setup.maxFrameLength = setup.maxQmfBands * setup.maxFrameTimeSlots;
+
+ setup.maxChIn = 2;
+ setup.maxChOut = 1;
+ setup.maxChTotOut = setup.maxChOut;
+ setup.bEncMode_212 = 1;
+ setup.maxHybridInStaticSlots = 24;
+
+ /* Open Static Gain*/
+ if (SACENC_OK !=
+ (error = fdk_sacenc_staticGain_OpenConfig(&hEnc->hStaticGainConfig))) {
+ goto bail;
+ }
+
+ /* enhanced time domain downmix (for stereo input) */
+ if (SACENC_OK != (error = fdk_sacenc_open_enhancedTimeDomainDmx(
+ &hEnc->hEnhancedTimeDmx, setup.maxFrameLength))) {
+ goto bail;
+ }
+
+ FDK_ALLOCATE_MEMORY_1D(hEnc->pParameterBand2HybridBandOffset,
+ MAX_NUM_PARAM_BANDS, UCHAR);
+
+ /* Create Space Tree first, to get number of in-/output channels */
+ if (SACENC_OK != (error = fdk_sacenc_spaceTree_Open(&hEnc->hSpaceTree))) {
+ goto bail;
+ }
+
+ FDK_ALLOCATE_MEMORY_1D(hEnc->pEncoderInputChScale, setup.maxChIn, INT);
+ FDK_ALLOCATE_MEMORY_1D(hEnc->staticTimeDomainDmxInScale, setup.maxChIn,
+ INT);
+
+ FDK_ALLOCATE_MEMORY_1D(hEnc->phQmfFiltIn__FDK, setup.maxChIn,
+ HANDLE_QMF_FILTER_BANK);
+
+ /* Allocate Analysis Filterbank Structs */
+ for (ch = 0; ch < setup.maxChIn; ch++) {
+ FDK_ALLOCATE_MEMORY_1D_INT(hEnc->phQmfFiltIn__FDK[ch], 1,
+ struct QMF_FILTER_BANK, SECT_DATA_L2)
+ FDK_ALLOCATE_MEMORY_1D_INT(hEnc->phQmfFiltIn__FDK[ch]->FilterStates,
+ 2 * 5 * setup.maxQmfBands, FIXP_QAS,
+ SECT_DATA_L2)
+ }
+
+ /* Allocate Synthesis Filterbank Structs for arbitrary downmix */
+
+ /* Allocate DC Filter Struct for normal signal input */
+ for (ch = 0; ch < setup.maxChIn; ch++) {
+ if (SACENC_OK !=
+ (error = fdk_sacenc_createDCFilter(&hEnc->phDCFilterSigIn[ch]))) {
+ goto bail;
+ }
+ }
+
+ /* Open Onset Detection */
+ for (ch = 0; ch < setup.maxChIn; ch++) {
+ if (SACENC_OK != (error = fdk_sacenc_onsetDetect_Open(
+ &hEnc->phOnset[ch], setup.maxFrameTimeSlots))) {
+ goto bail;
+ }
+ }
+
+ FDK_ALLOCATE_MEMORY_2D(hEnc->ppTrCurrPos, setup.maxChIn, MAX_NUM_TRANS,
+ INT);
+
+ /* Create Windowing */
+ if (SACENC_OK !=
+ (error = fdk_sacenc_frameWindow_Create(&hEnc->hFrameWindow))) {
+ goto bail;
+ }
+
+ /* Open static gain */
+ if (SACENC_OK != (error = fdk_sacenc_staticGain_Open(&hEnc->hStaticGain))) {
+ goto bail;
+ }
+
+ /* create bitstream encoder */
+ if (SACENC_OK != (error = fdk_sacenc_createSpatialBitstreamEncoder(
+ &hEnc->hBitstreamFormatter))) {
+ goto bail;
+ }
+
+ FDK_ALLOCATE_MEMORY_1D(hEnc->sscBuf.pSsc, MAX_SSC_BYTES, UCHAR);
+
+ {
+ FDK_ALLOCATE_MEMORY_2D(hEnc->ppTimeSigIn__FDK, setup.maxChIn,
+ setup.maxFrameLength + MAX_DELAY_SURROUND_ANALYSIS,
+ INT_PCM);
+ }
+ FDK_ALLOCATE_MEMORY_2D(hEnc->ppTimeSigDelayIn__FDK, setup.maxChIn,
+ MAX_DELAY_SURROUND_ANALYSIS, INT_PCM);
+
+ /* Create new buffers for several signals (including arbitrary downmix) */
+ if (setup.bEncMode_212 == 0) {
+ /* pOutputDelayBuffer__FDK buffer is not needed for SACENC_212 mode */
+ FDK_ALLOCATE_MEMORY_1D(
+ hEnc->pOutputDelayBuffer__FDK,
+ (setup.maxFrameLength + MAX_DELAY_OUTPUT) * setup.maxChOut, INT_PCM);
+ }
+
+ /* allocate buffers */
+ if (setup.bEncMode_212 == 0) {
+ /* ppTimeSigOut__FDK buffer is not needed for SACENC_212 mode */
+ FDK_ALLOCATE_MEMORY_2D(hEnc->ppTimeSigOut__FDK, setup.maxChTotOut,
+ setup.maxFrameLength, INT_PCM);
+ }
+
+ if (setup.bEncMode_212 == 1) {
+ /* pppHybridIn__FDK buffer can be reduced by maxFrameTimeSlots/2 slots for
+ * SACENC_212 mode */
+ FDK_ALLOCATE_MEMORY_3D(
+ hEnc->pppHybridIn__FDK, setup.maxChIn,
+ setup.maxAnalysisLengthTimeSlots - (setup.maxFrameTimeSlots >> 1),
+ setup.maxHybridBands, FIXP_DPK);
+ FDK_ALLOCATE_MEMORY_3D(hEnc->pppHybridInStatic__FDK, setup.maxChIn,
+ setup.maxHybridInStaticSlots, setup.maxHybridBands,
+ FIXP_DPK);
+ } else {
+ FDK_ALLOCATE_MEMORY_3D(hEnc->pppHybridIn__FDK, setup.maxChIn,
+ setup.maxAnalysisLengthTimeSlots,
+ setup.maxHybridBands, FIXP_DPK);
+ }
+
+ if (setup.bEncMode_212 == 0) {
+ /* pppProcDataIn__FDK buffer is not needed for SACENC_212 mode */
+ FDK_ALLOCATE_MEMORY_3D(hEnc->pppProcDataIn__FDK, MAX_SPACE_TREE_CHANNELS,
+ setup.maxAnalysisLengthTimeSlots,
+ setup.maxHybridBands, FIXP_DPK);
+ }
+ for (i = 0; i < MAX_NUM_PARAMS; i++) {
+ FDK_ALLOCATE_MEMORY_1D(hEnc->pFrameWindowAna__FDK[i],
+ setup.maxAnalysisLengthTimeSlots, FIXP_WIN);
+ } /* for i */
+
+ if (SACENC_OK != (error = fdk_sacenc_delay_Open(&hEnc->hDelay))) {
+ goto bail;
+ }
+
+ if (setup.bEncMode_212 == 0) {
+ /* ppBitstreamDelayBuffer buffer is not needed for SACENC_212 mode */
+ FDK_ALLOCATE_MEMORY_2D(hEnc->ppBitstreamDelayBuffer, MAX_BITSTREAM_DELAY,
+ MAX_MPEGS_BYTES, UCHAR);
+ }
+ FDK_ALLOCATE_MEMORY_1D(hEnc->pnOutputBits, MAX_BITSTREAM_DELAY, INT);
+
+ hEnc->setup = setup; /* save configuration used while encoder allocation. */
+ mp4SpaceEnc_InitDefault(hEnc);
+
+ if (NULL != phMp4SpaceEnc) {
+ *phMp4SpaceEnc = hEnc; /* return encoder handle */
+ }
+
+ } /* valid handle */
+
+ return error;
+
+bail:
+ if (NULL != hEnc) {
+ hEnc->setup = setup;
+ FDK_sacenc_close(&hEnc);
+ }
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+static FDK_SACENC_ERROR mp4SpaceEnc_InitDefault(HANDLE_MP4SPACE_ENCODER hEnc) {
+ FDK_SACENC_ERROR err = SACENC_OK;
+
+ /* Get default static gain configuration. */
+ if (SACENC_OK != (err = fdk_sacenc_staticGain_InitDefaultConfig(
+ hEnc->hStaticGainConfig))) {
+ goto bail;
+ }
+
+bail:
+ return err;
+}
+
+static FDK_SACENC_ERROR FDK_sacenc_configure(
+ HANDLE_MP4SPACE_ENCODER hEnc, const HANDLE_MP4SPACEENC_SETUP hSetup) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ hEnc->nSampleRate = hSetup->sampleRate;
+ hEnc->encMode = hSetup->encMode;
+ hEnc->nQmfBands = mp4SpaceEnc_GetNumQmfBands(hEnc->nSampleRate);
+
+ /* Make sure that we have set time domain downmix for 212 */
+ if (hSetup->encMode == SACENC_212 && hSetup->bTimeDomainDmx == 0) {
+ error = SACENC_INVALID_CONFIG;
+ } else {
+ hEnc->useTimeDomDownmix = hSetup->bTimeDomainDmx;
+ }
+
+ hEnc->timeAlignment = hSetup->timeAlignment;
+ hEnc->quantMode = hSetup->quantMode;
+
+ hEnc->useCoarseQuantCld = hSetup->bUseCoarseQuant;
+ hEnc->useCoarseQuantCpc = hSetup->bUseCoarseQuant;
+ hEnc->useFrameKeep = (hSetup->bLdMode == 2);
+ hEnc->useCoarseQuantIcc = 0; /* not available */
+ hEnc->useCoarseQuantArbDmx = 0; /* not available for user right now */
+ hEnc->independencyFactor = hSetup->independencyFactor;
+ hEnc->independencyCount = 0;
+ hEnc->independencyFlag = 1;
+
+ /* set number of Hybrid bands */
+ hEnc->nHybridBands = hEnc->nQmfBands;
+ hEnc->nFrameTimeSlots = hSetup->frameTimeSlots;
+ mp4SpaceEnc_InitNumParamBands(hEnc, hSetup->nParamBands);
+
+ return error;
+}
+
+FDK_SACENC_ERROR FDK_sacenc_init(HANDLE_MP4SPACE_ENCODER hEnc,
+ const INT dmxDelay) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ /* Sanity Checks */
+ if (NULL == hEnc) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ const int initStatesFlag = 1;
+
+ int ch; /* loop counter */
+ int nChInArbDmx;
+
+ if (SACENC_OK != (error = FDK_sacenc_configure(hEnc, &hEnc->user))) {
+ goto bail;
+ }
+
+ hEnc->bEncMode_212_only = hEnc->setup.bEncMode_212;
+
+ /* Slots per Frame and Frame Length */
+ if (hEnc->nFrameTimeSlots < 1) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+ hEnc->nFrameLength = hEnc->nQmfBands * hEnc->nFrameTimeSlots;
+
+ if (hEnc->useFrameKeep == 1) {
+ hEnc->nAnalysisLengthTimeSlots = 3 * hEnc->nFrameTimeSlots;
+ hEnc->nUpdateHybridPositionTimeSlots = hEnc->nFrameTimeSlots;
+ } else {
+ hEnc->nAnalysisLengthTimeSlots = 2 * hEnc->nFrameTimeSlots;
+ hEnc->nUpdateHybridPositionTimeSlots = 0;
+ }
+
+ {
+ hEnc->nAnalysisLookaheadTimeSlots =
+ hEnc->nAnalysisLengthTimeSlots - 3 * hEnc->nFrameTimeSlots / 2;
+ }
+
+ /* init parameterBand2hybridBandOffset table */
+ fdk_sacenc_calcParameterBand2HybridBandOffset(
+ (BOX_SUBBAND_CONFIG)hEnc->nParamBands, hEnc->nHybridBands,
+ hEnc->pParameterBand2HybridBandOffset);
+
+ /* Fill Setup structure for Space Tree */
+ if (SACENC_OK !=
+ (error = mp4SpaceEnc_FillSpaceTreeSetup(hEnc, &hEnc->spaceTreeSetup))) {
+ goto bail;
+ }
+
+ /* Init space tree configuration */
+ if (SACENC_OK !=
+ (error = fdk_sacenc_spaceTree_Init(
+ hEnc->hSpaceTree, &hEnc->spaceTreeSetup,
+ hEnc->pParameterBand2HybridBandOffset, hEnc->useFrameKeep))) {
+ goto bail;
+ }
+
+ /* Get space tree description and resulting number of input/output channels
+ */
+ {
+ SPACE_TREE_DESCRIPTION spaceTreeDescription;
+
+ if (SACENC_OK != (error = fdk_sacenc_spaceTree_GetDescription(
+ hEnc->hSpaceTree, &spaceTreeDescription))) {
+ goto bail;
+ }
+
+ hEnc->nInputChannels =
+ spaceTreeDescription.nOutChannels; /* space tree description
+ describes decoder
+ configuration */
+ hEnc->nOutputChannels =
+ spaceTreeDescription.nInChannels; /* space tree description
+ describes decoder
+ configuration */
+ }
+
+ nChInArbDmx = 0;
+
+ /* INITIALIZATION */
+ for (ch = 0; ch < hEnc->nInputChannels; ch++) {
+ /* scaling in analysis qmf filterbank (7) */
+ hEnc->pEncoderInputChScale[ch] = 7;
+
+ {
+ /* additional scaling in qmf prototype filter for low delay */
+ hEnc->pEncoderInputChScale[ch] += 1;
+ }
+
+ { hEnc->pEncoderInputChScale[ch] += DC_FILTER_SF; }
+ } /* nInputChannels */
+
+ /* Init analysis filterbank */
+ for (ch = 0; ch < hEnc->nInputChannels; ch++) {
+ hEnc->phQmfFiltIn__FDK[ch]->flags =
+ updateQmfFlags(hEnc->phQmfFiltIn__FDK[ch]->flags, !initStatesFlag);
+
+ if (0 != qmfInitAnalysisFilterBank(
+ hEnc->phQmfFiltIn__FDK[ch],
+ (FIXP_QAS *)hEnc->phQmfFiltIn__FDK[ch]->FilterStates, 1,
+ hEnc->nQmfBands, hEnc->nQmfBands, hEnc->nQmfBands,
+ hEnc->phQmfFiltIn__FDK[ch]->flags)) {
+ error = SACENC_INIT_ERROR;
+ goto bail;
+ }
+ }
+
+ /* Initialize DC Filter. */
+ {
+ for (ch = 0; ch < hEnc->nInputChannels; ch++) {
+ if (SACENC_OK != (error = fdk_sacenc_initDCFilter(
+ hEnc->phDCFilterSigIn[ch], hEnc->nSampleRate))) {
+ goto bail;
+ }
+ }
+ }
+
+ /* Init onset detect. */
+ {
+ /* init onset detect configuration struct */
+ ONSET_DETECT_CONFIG onsetDetectConfig;
+ onsetDetectConfig.maxTimeSlots = hEnc->nFrameTimeSlots;
+ onsetDetectConfig.lowerBoundOnsetDetection =
+ freq2HybridBand(1725, hEnc->nSampleRate, hEnc->nQmfBands);
+ onsetDetectConfig.upperBoundOnsetDetection = hEnc->nHybridBands;
+
+ for (ch = 0; ch < hEnc->nInputChannels; ch++) {
+ if (SACENC_OK != (error = fdk_sacenc_onsetDetect_Init(
+ hEnc->phOnset[ch], &onsetDetectConfig, 1))) {
+ goto bail;
+ }
+ }
+ }
+
+ {
+ /* init windowing */
+ FRAMEWINDOW_CONFIG framewindowConfig;
+ framewindowConfig.nTimeSlotsMax = hEnc->nFrameTimeSlots;
+ framewindowConfig.bFrameKeep = hEnc->useFrameKeep;
+
+ if (SACENC_OK != (error = fdk_sacenc_frameWindow_Init(
+ hEnc->hFrameWindow, &framewindowConfig))) {
+ goto bail;
+ }
+ }
+
+ /* Set encoder mode for static gain initialization. */
+ if (SACENC_OK != (error = fdk_sacenc_staticGain_SetEncMode(
+ hEnc->hStaticGainConfig, hEnc->encMode))) {
+ goto bail;
+ }
+
+ /* Init static gain. */
+ if (SACENC_OK != (error = fdk_sacenc_staticGain_Init(
+ hEnc->hStaticGain, hEnc->hStaticGainConfig,
+ &(hEnc->staticGainScale)))) {
+ goto bail;
+ }
+
+ for (ch = 0; ch < hEnc->nInputChannels; ch++) {
+ hEnc->pEncoderInputChScale[ch] += hEnc->staticGainScale;
+ }
+
+ /* enhanced downmix for stereo input*/
+ if (hEnc->useTimeDomDownmix != 0) {
+ if (SACENC_OK != (error = fdk_sacenc_init_enhancedTimeDomainDmx(
+ hEnc->hEnhancedTimeDmx,
+ fdk_sacenc_getPreGainPtrFDK(hEnc->hStaticGain),
+ hEnc->staticGainScale,
+ fdk_sacenc_getPostGainFDK(hEnc->hStaticGain),
+ hEnc->staticGainScale, hEnc->nFrameLength))) {
+ goto bail;
+ }
+ }
+
+ /* Create config structure for bitstream formatter including arbitrary
+ * downmix residual */
+ if (SACENC_OK != (error = fdk_sacenc_initSpatialBitstreamEncoder(
+ hEnc->hBitstreamFormatter))) {
+ goto bail;
+ }
+
+ if (SACENC_OK != (error = FillSpatialSpecificConfig(
+ hEnc, fdk_sacenc_getSpatialSpecificConfig(
+ hEnc->hBitstreamFormatter)))) {
+ goto bail;
+ }
+
+ if (SACENC_OK !=
+ (error = fdk_sacenc_writeSpatialSpecificConfig(
+ fdk_sacenc_getSpatialSpecificConfig(hEnc->hBitstreamFormatter),
+ hEnc->sscBuf.pSsc, MAX_SSC_BYTES, &hEnc->sscBuf.nSscSizeBits))) {
+ goto bail;
+ }
+
+ /* init delay compensation with dmx core coder delay; if no core coder is
+ * used, many other buffers are initialized nevertheless */
+ if (SACENC_OK !=
+ (error = mp4SpaceEnc_InitDelayCompensation(hEnc, dmxDelay))) {
+ goto bail;
+ }
+
+ /* How much input do we need? */
+ hEnc->nSamplesNext =
+ hEnc->nFrameLength * (hEnc->nInputChannels + nChInArbDmx);
+ hEnc->nSamplesValid = 0;
+ } /* valid handle */
+
+bail:
+ return error;
+}
+
+static INT getAnalysisLengthTimeSlots(FIXP_WIN *pFrameWindowAna,
+ INT nTimeSlots) {
+ int i;
+ for (i = nTimeSlots - 1; i >= 0; i--) {
+ if (pFrameWindowAna[i] != (FIXP_WIN)0) {
+ break;
+ }
+ }
+ nTimeSlots = i + 1;
+ return nTimeSlots;
+}
+
+static INT getAnalysisStartTimeSlot(FIXP_WIN *pFrameWindowAna, INT nTimeSlots) {
+ int startTimeSlot = 0;
+ int i;
+ for (i = 0; i < nTimeSlots; i++) {
+ if (pFrameWindowAna[i] != (FIXP_WIN)0) {
+ break;
+ }
+ }
+ startTimeSlot = i;
+ return startTimeSlot;
+}
+
+static FDK_SACENC_ERROR __FeedDeinterPreScale(
+ HANDLE_MP4SPACE_ENCODER hEnc, INT_PCM const *const pSamples,
+ INT_PCM *const pOutputSamples, INT const nSamples,
+ UINT const isInputInterleaved, UINT const inputBufferSizePerChannel,
+ UINT *const pnSamplesFed) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hEnc == NULL) || (pSamples == NULL) || (pnSamplesFed == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else if (nSamples == 0) {
+ error = SACENC_INVALID_CONFIG; /* Flushing not implemented */
+ } else {
+ int ch;
+ const INT nChIn = hEnc->nInputChannels;
+ const INT nChInWithDmx = nChIn;
+ const INT samplesToFeed =
+ FDKmin(nSamples, hEnc->nSamplesNext - hEnc->nSamplesValid);
+ const INT nSamplesPerChannel = samplesToFeed / nChInWithDmx;
+
+ if ((samplesToFeed < 0) || (samplesToFeed % nChInWithDmx != 0) ||
+ (samplesToFeed > nChInWithDmx * (INT)hEnc->nFrameLength)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+ int i;
+
+ const INT_PCM *pInput__FDK;
+ const INT_PCM *pInput2__FDK;
+
+ { /* no dmx align = default*/
+ pInput__FDK = pSamples;
+ pInput2__FDK = pSamples + (hEnc->nInputDelay * nChInWithDmx);
+ }
+
+ for (i = 0; i < hEnc->nInputChannels; i++) {
+ hEnc->staticTimeDomainDmxInScale[i] = hEnc->staticGainScale;
+ }
+
+ /***** N-channel-input *****/
+ for (ch = 0; ch < nChIn; ch++) {
+ /* Write delayed time signal into time signal buffer */
+ FDKmemcpy(&(hEnc->ppTimeSigIn__FDK[ch][0]),
+ &(hEnc->ppTimeSigDelayIn__FDK[ch][0]),
+ hEnc->nSurroundAnalysisBufferDelay * sizeof(INT_PCM));
+
+ if (isInputInterleaved) {
+ /* Add the new frame de-interleaved. Apply nSurroundAnalysisBufferDelay.
+ */
+ FDKmemcpy_flex(
+ &(hEnc->ppTimeSigIn__FDK[ch][hEnc->nSurroundAnalysisBufferDelay]),
+ 1, pInput__FDK + ch, nChInWithDmx, hEnc->nInputDelay);
+ FDKmemcpy_flex(
+ &(hEnc->ppTimeSigIn__FDK[ch][hEnc->nSurroundAnalysisBufferDelay +
+ hEnc->nInputDelay]),
+ 1, pInput2__FDK + ch, nChInWithDmx,
+ nSamplesPerChannel - hEnc->nInputDelay);
+ } else {
+ /* Input is already deinterleaved, just copy */
+ FDKmemcpy(
+ &(hEnc->ppTimeSigIn__FDK[ch][hEnc->nSurroundAnalysisBufferDelay]),
+ pInput__FDK + ch * inputBufferSizePerChannel,
+ hEnc->nInputDelay * sizeof(INT_PCM));
+ FDKmemcpy(
+ &(hEnc->ppTimeSigIn__FDK[ch][hEnc->nSurroundAnalysisBufferDelay +
+ hEnc->nInputDelay]),
+ pInput2__FDK + ch * inputBufferSizePerChannel,
+ (nSamplesPerChannel - hEnc->nInputDelay) * sizeof(INT_PCM));
+ }
+
+ /* Update time signal delay buffer */
+ FDKmemcpy(&(hEnc->ppTimeSigDelayIn__FDK[ch][0]),
+ &(hEnc->ppTimeSigIn__FDK[ch][hEnc->nFrameLength]),
+ hEnc->nSurroundAnalysisBufferDelay * sizeof(INT_PCM));
+ } /* for ch */
+
+ /***** No Arbitrary Downmix *****/
+ /* "Crude TD Dmx": Time DomainDownmix + NO Arbitrary Downmix, Delay Added at
+ * pOutputBuffer */
+ if ((hEnc->useTimeDomDownmix > 0)) {
+ if ((hEnc->useTimeDomDownmix == 1) || (hEnc->nInputChannels != 2)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ } else {
+ /* enhanced time domain downmix (for stereo input) */
+ if (hEnc->encMode == SACENC_212) {
+ if (pOutputSamples == NULL) {
+ error = SACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ fdk_sacenc_apply_enhancedTimeDomainDmx(
+ hEnc->hEnhancedTimeDmx, hEnc->ppTimeSigIn__FDK, pOutputSamples,
+ hEnc->nSurroundAnalysisBufferDelay);
+ } else {
+ if (&hEnc->ppTimeSigOut__FDK[0][0] == NULL) {
+ error = SACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ fdk_sacenc_apply_enhancedTimeDomainDmx(
+ hEnc->hEnhancedTimeDmx, hEnc->ppTimeSigIn__FDK,
+ &hEnc->ppTimeSigOut__FDK[0][0],
+ hEnc->nSurroundAnalysisBufferDelay);
+ }
+ }
+ }
+
+ /* update number of samples still to process */
+ hEnc->nSamplesValid += samplesToFeed;
+
+ /*return number of fed samples */
+ *pnSamplesFed = samplesToFeed;
+ }
+bail:
+ return error;
+}
+
+FDK_SACENC_ERROR FDK_sacenc_encode(const HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc,
+ const FDK_bufDescr *inBufDesc,
+ const FDK_bufDescr *outBufDesc,
+ const SACENC_InArgs *inargs,
+ SACENC_OutArgs *outargs) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ const INT_PCM *pInputSamples =
+ (const INT_PCM *)inBufDesc->ppBase[getBufDescIdx(
+ inBufDesc, (FDK_BUF_TYPE_INPUT | FDK_BUF_TYPE_PCM_DATA))];
+
+ INT_PCM *const pOutputSamples = (INT_PCM *)outBufDesc->ppBase[getBufDescIdx(
+ outBufDesc, (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_PCM_DATA))];
+
+ const int nOutputSamplesBufferSize =
+ outBufDesc->pBufSize[getBufDescIdx(
+ outBufDesc, (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_PCM_DATA))] /
+ outBufDesc->pEleSize[getBufDescIdx(
+ outBufDesc, (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_PCM_DATA))];
+
+ if ((hMp4SpaceEnc == NULL) || (pInputSamples == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int nOutputSamples;
+ int i, ch, ps, winCnt, ts, slot;
+ INT currTransPos = -1;
+ SPATIALFRAME *pFrameData = NULL;
+
+ /* Improve Code Readability */
+ const int nChIn = hMp4SpaceEnc->nInputChannels;
+ const int nChInWithDmx = nChIn;
+ const int nChOut = hMp4SpaceEnc->nOutputChannels;
+ const int nSamplesPerChannel = inargs->nInputSamples / nChInWithDmx;
+ const int nOutputSamplesMax = nSamplesPerChannel * nChOut;
+ const int nFrameTimeSlots = hMp4SpaceEnc->nFrameTimeSlots;
+
+ INT encoderInputChScale[SACENC_MAX_INPUT_CHANNELS];
+ INT nFrameTimeSlotsReduction = 0;
+
+ if (hMp4SpaceEnc->encMode == SACENC_212) {
+ nFrameTimeSlotsReduction = hMp4SpaceEnc->nFrameTimeSlots >> 1;
+ }
+
+ for (i = 0; i < nChIn; i++)
+ encoderInputChScale[i] = hMp4SpaceEnc->pEncoderInputChScale[i];
+
+ /* Sanity Check */
+ if ((0 != inargs->nInputSamples % nChInWithDmx)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ /*
+ * Get Frame Data Handle.
+ */
+
+ /* get bitstream handle (for storage of cld's, icc's and so on)
+ * get spatialframe 2 frames in the future; NOTE: this is necessary to
+ * synchronise spatial data and audio data */
+ if (NULL == (pFrameData = fdk_sacenc_getSpatialFrame(
+ hMp4SpaceEnc->hBitstreamFormatter, WRITE_SPATIALFRAME))) {
+ error = SACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ /* Independent Frames Counters*/
+ if (hMp4SpaceEnc->nDiscardOutFrames >
+ 0) { /* Independent Frames if they should be discarded, Reset Counter*/
+ hMp4SpaceEnc->independencyCount =
+ 0; /* Reset the counter, first valid frame is an independent one*/
+ hMp4SpaceEnc->independencyFlag = 1;
+ } else { /*hMp4SpaceEnc->nDiscardOutFrames == 0*/
+ hMp4SpaceEnc->independencyFlag =
+ (hMp4SpaceEnc->independencyCount == 0) ? 1 : 0;
+ if (hMp4SpaceEnc->independencyFactor > 0) {
+ hMp4SpaceEnc->independencyCount++;
+ hMp4SpaceEnc->independencyCount =
+ hMp4SpaceEnc->independencyCount %
+ ((int)hMp4SpaceEnc->independencyFactor);
+ } else { /* independencyFactor == 0 */
+ hMp4SpaceEnc->independencyCount = -1;
+ }
+ }
+
+ /*
+ * Time signal preprocessing:
+ * - Feed input buffer
+ * - Prescale time signal
+ * - Apply DC filter on input signal
+ */
+
+ /* Feed, Deinterleave, Pre-Scale the input time signals */
+ if (SACENC_OK !=
+ (error = __FeedDeinterPreScale(
+ hMp4SpaceEnc, pInputSamples, pOutputSamples, inargs->nInputSamples,
+ inargs->isInputInterleaved, inargs->inputBufferSizePerChannel,
+ &outargs->nSamplesConsumed))) {
+ goto bail;
+ }
+
+ if (hMp4SpaceEnc->nSamplesNext != hMp4SpaceEnc->nSamplesValid) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ if (hMp4SpaceEnc->encMode == SACENC_212 &&
+ hMp4SpaceEnc->bEncMode_212_only) {
+ for (ch = 0; ch < nChIn; ch++) {
+ for (slot = 0; slot < nFrameTimeSlots; slot++) {
+ setCplxVec(
+ hMp4SpaceEnc->pppHybridIn__FDK
+ [ch][hMp4SpaceEnc->nUpdateHybridPositionTimeSlots +
+ nFrameTimeSlots - nFrameTimeSlotsReduction + slot],
+ (FIXP_DBL)0, hMp4SpaceEnc->nHybridBands);
+ }
+ }
+ }
+
+ /*
+ * Time / Frequency:
+ * - T/F audio input channels
+ * - T/F arbitrary downmix input channels
+ */
+ for (ch = 0; ch < nChIn; ch++) {
+ C_AALLOC_SCRATCH_START(pQmfInReal, FIXP_DBL, MAX_QMF_BANDS)
+ C_AALLOC_SCRATCH_START(pQmfInImag, FIXP_DBL, MAX_QMF_BANDS)
+ FIXP_GAIN *pPreGain =
+ fdk_sacenc_getPreGainPtrFDK(hMp4SpaceEnc->hStaticGain);
+
+ for (ts = 0; ts < nFrameTimeSlots; ts++) {
+ FIXP_DBL *pSpecReal;
+ FIXP_DBL *pSpecImag;
+
+ INT_PCM *pTimeIn =
+ &hMp4SpaceEnc->ppTimeSigIn__FDK[ch][(ts * hMp4SpaceEnc->nQmfBands)];
+
+ {
+ /* Apply DC filter on input channels */
+ if (SACENC_OK != (error = fdk_sacenc_applyDCFilter(
+ hMp4SpaceEnc->phDCFilterSigIn[ch], pTimeIn,
+ pTimeIn, hMp4SpaceEnc->nQmfBands))) {
+ goto bail;
+ }
+ }
+
+ /* QMF filterbank */
+ C_ALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL, (MAX_QMF_BANDS << 1));
+
+ qmfAnalysisFilteringSlot(hMp4SpaceEnc->phQmfFiltIn__FDK[ch], pQmfInReal,
+ pQmfInImag, pTimeIn, 1, pWorkBuffer);
+
+ C_ALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, (MAX_QMF_BANDS << 1));
+
+ pSpecReal = pQmfInReal;
+ pSpecImag = pQmfInImag;
+
+ /* Apply pre-scale after filterbank */
+ if (MAXVAL_GAIN != pPreGain[ch]) {
+ for (i = 0; i < hMp4SpaceEnc->nHybridBands; i++) {
+ hMp4SpaceEnc
+ ->pppHybridIn__FDK[ch]
+ [hMp4SpaceEnc->nAnalysisLookaheadTimeSlots +
+ ts][i]
+ .v.re = fMult(pSpecReal[i], pPreGain[ch]);
+ hMp4SpaceEnc
+ ->pppHybridIn__FDK[ch]
+ [hMp4SpaceEnc->nAnalysisLookaheadTimeSlots +
+ ts][i]
+ .v.im = fMult(pSpecImag[i], pPreGain[ch]);
+ }
+ } else {
+ for (i = 0; i < hMp4SpaceEnc->nHybridBands; i++) {
+ hMp4SpaceEnc
+ ->pppHybridIn__FDK[ch]
+ [hMp4SpaceEnc->nAnalysisLookaheadTimeSlots +
+ ts][i]
+ .v.re = pSpecReal[i];
+ hMp4SpaceEnc
+ ->pppHybridIn__FDK[ch]
+ [hMp4SpaceEnc->nAnalysisLookaheadTimeSlots +
+ ts][i]
+ .v.im = pSpecImag[i];
+ }
+ }
+ } /* ts */
+ C_AALLOC_SCRATCH_END(pQmfInImag, FIXP_DBL, MAX_QMF_BANDS)
+ C_AALLOC_SCRATCH_END(pQmfInReal, FIXP_DBL, MAX_QMF_BANDS)
+
+ if (SACENC_OK != error) {
+ goto bail;
+ }
+ } /* ch */
+
+ if (hMp4SpaceEnc->encMode == SACENC_212 &&
+ hMp4SpaceEnc->bEncMode_212_only) {
+ for (ch = 0; ch < nChIn; ch++) {
+ for (slot = 0;
+ slot < (int)(hMp4SpaceEnc->nUpdateHybridPositionTimeSlots +
+ nFrameTimeSlots - nFrameTimeSlotsReduction);
+ slot++) {
+ copyCplxVec(hMp4SpaceEnc->pppHybridIn__FDK[ch][slot],
+ hMp4SpaceEnc->pppHybridInStatic__FDK[ch][slot],
+ hMp4SpaceEnc->nHybridBands);
+ }
+ }
+ for (ch = 0; ch < nChIn; ch++) {
+ for (slot = 0;
+ slot < (int)(hMp4SpaceEnc->nUpdateHybridPositionTimeSlots +
+ nFrameTimeSlots - nFrameTimeSlotsReduction);
+ slot++) {
+ copyCplxVec(
+ hMp4SpaceEnc->pppHybridInStatic__FDK[ch][slot],
+ hMp4SpaceEnc->pppHybridIn__FDK[ch][nFrameTimeSlots + slot],
+ hMp4SpaceEnc->nHybridBands);
+ }
+ }
+ }
+
+ /*
+ * Onset Detection:
+ * - detection of transients
+ * - build framing
+ */
+ for (ch = 0; ch < nChIn; ch++) {
+ if (ch != 3) { /* !LFE */
+ if (SACENC_OK !=
+ (error = fdk_sacenc_onsetDetect_Apply(
+ hMp4SpaceEnc->phOnset[ch], nFrameTimeSlots,
+ hMp4SpaceEnc->nHybridBands,
+ &hMp4SpaceEnc->pppHybridIn__FDK
+ [ch][hMp4SpaceEnc->nAnalysisLookaheadTimeSlots],
+ encoderInputChScale[ch],
+ hMp4SpaceEnc->trPrevPos[1], /* contains previous Transient */
+ hMp4SpaceEnc->ppTrCurrPos[ch]))) {
+ goto bail;
+ }
+
+ if ((1) && (hMp4SpaceEnc->useFrameKeep == 0)) {
+ hMp4SpaceEnc->ppTrCurrPos[ch][0] = -1;
+ }
+
+ /* Find first Transient Position */
+ if ((hMp4SpaceEnc->ppTrCurrPos[ch][0] >= 0) &&
+ ((currTransPos < 0) ||
+ (hMp4SpaceEnc->ppTrCurrPos[ch][0] < currTransPos))) {
+ currTransPos = hMp4SpaceEnc->ppTrCurrPos[ch][0];
+ }
+ } /* !LFE */
+ } /* ch */
+
+ if (hMp4SpaceEnc->useFrameKeep == 1) {
+ if ((currTransPos != -1) || (hMp4SpaceEnc->independencyFlag == 1)) {
+ hMp4SpaceEnc->avoid_keep = NUM_KEEP_WINDOWS;
+ currTransPos = -1;
+ }
+ }
+
+ /* Save previous Transient Position */
+ hMp4SpaceEnc->trPrevPos[0] =
+ FDKmax(-1, hMp4SpaceEnc->trPrevPos[1] - (INT)nFrameTimeSlots);
+ hMp4SpaceEnc->trPrevPos[1] = currTransPos;
+
+ /* Update Onset Detection Energy Buffer */
+ for (ch = 0; ch < nChIn; ch++) {
+ if (SACENC_OK != (error = fdk_sacenc_onsetDetect_Update(
+ hMp4SpaceEnc->phOnset[ch], nFrameTimeSlots))) {
+ goto bail;
+ }
+ }
+
+ /* Framing */
+ if (SACENC_OK !=
+ (error = fdk_sacenc_frameWindow_GetWindow(
+ hMp4SpaceEnc->hFrameWindow, hMp4SpaceEnc->trPrevPos,
+ nFrameTimeSlots, &pFrameData->framingInfo,
+ hMp4SpaceEnc->pFrameWindowAna__FDK, &hMp4SpaceEnc->frameWinList,
+ hMp4SpaceEnc->avoid_keep))) {
+ goto bail;
+ }
+
+ /*
+ * MPS Processing:
+ */
+ for (ps = 0, winCnt = 0; ps < hMp4SpaceEnc->frameWinList.n; ++ps) {
+ /* Analysis Windowing */
+ if (hMp4SpaceEnc->frameWinList.dat[ps].hold == FW_HOLD) {
+ /* ************************************** */
+ /* ONLY COPY AND HOLD PREVIOUS PARAMETERS */
+ if (SACENC_OK != (error = fdk_sacenc_duplicateParameterSet(
+ &hMp4SpaceEnc->saveFrame, 0, pFrameData, ps))) {
+ goto bail;
+ }
+
+ } else { /* !FW_HOLD */
+ /* ************************************** */
+ /* NEW WINDOW */
+
+ INT nAnalysisLengthTimeSlots, analysisStartTimeSlot;
+
+ nAnalysisLengthTimeSlots = getAnalysisLengthTimeSlots(
+ hMp4SpaceEnc->pFrameWindowAna__FDK[winCnt],
+ hMp4SpaceEnc->nAnalysisLengthTimeSlots);
+
+ analysisStartTimeSlot =
+ getAnalysisStartTimeSlot(hMp4SpaceEnc->pFrameWindowAna__FDK[winCnt],
+ hMp4SpaceEnc->nAnalysisLengthTimeSlots);
+
+ /* perform main signal analysis windowing in
+ * fdk_sacenc_spaceTree_Apply() */
+ FIXP_WIN *pFrameWindowAna__FDK =
+ hMp4SpaceEnc->pFrameWindowAna__FDK[winCnt];
+ FIXP_DPK ***pppHybridIn__FDK = hMp4SpaceEnc->pppHybridIn__FDK;
+ FIXP_DPK ***pppProcDataIn__FDK = hMp4SpaceEnc->pppProcDataIn__FDK;
+
+ if (hMp4SpaceEnc->encMode == SACENC_212 &&
+ hMp4SpaceEnc->bEncMode_212_only) {
+ pppProcDataIn__FDK = pppHybridIn__FDK;
+ }
+
+ if (SACENC_OK !=
+ (error = fdk_sacenc_spaceTree_Apply(
+ hMp4SpaceEnc->hSpaceTree, ps, nChIn, nAnalysisLengthTimeSlots,
+ analysisStartTimeSlot, hMp4SpaceEnc->nHybridBands,
+ pFrameWindowAna__FDK, pppHybridIn__FDK,
+ pppProcDataIn__FDK, /* multi-channel input */
+ pFrameData, hMp4SpaceEnc->avoid_keep, encoderInputChScale))) {
+ goto bail;
+ }
+
+ /* Save spatial frame for potential hold parameter set */
+ if (SACENC_OK != (error = fdk_sacenc_duplicateParameterSet(
+ pFrameData, ps, &hMp4SpaceEnc->saveFrame, 0))) {
+ goto bail;
+ }
+
+ ++winCnt;
+ }
+ if (hMp4SpaceEnc->avoid_keep > 0) {
+ hMp4SpaceEnc->avoid_keep--;
+ }
+ } /* Loop over Parameter Sets */
+ /* ---- End of Processing Loop ---- */
+
+ /*
+ * Update hybridInReal/Imag buffer and do the same for arbDmx
+ * this means to move the hybrid data of the current frame to the beginning
+ * of the 2*nFrameLength-long buffer
+ */
+ if (!(hMp4SpaceEnc->encMode == SACENC_212 &&
+ hMp4SpaceEnc->bEncMode_212_only)) {
+ for (ch = 0; ch < nChIn; ch++) { /* for automatic downmix */
+ for (slot = 0;
+ slot < (int)(hMp4SpaceEnc->nUpdateHybridPositionTimeSlots +
+ nFrameTimeSlots - nFrameTimeSlotsReduction);
+ slot++) {
+ copyCplxVec(
+ hMp4SpaceEnc->pppHybridIn__FDK[ch][slot],
+ hMp4SpaceEnc->pppHybridIn__FDK[ch][nFrameTimeSlots + slot],
+ hMp4SpaceEnc->nHybridBands);
+ }
+ for (slot = 0; slot < nFrameTimeSlots; slot++) {
+ setCplxVec(
+ hMp4SpaceEnc->pppHybridIn__FDK
+ [ch][hMp4SpaceEnc->nUpdateHybridPositionTimeSlots +
+ nFrameTimeSlots - nFrameTimeSlotsReduction + slot],
+ (FIXP_DBL)0, hMp4SpaceEnc->nHybridBands);
+ }
+ }
+ }
+ /*
+ * Spatial Tonality:
+ */
+ {
+ /* Smooth config off. */
+ FDKmemclear(&pFrameData->smgData, sizeof(pFrameData->smgData));
+ }
+
+ /*
+ * Create bitstream
+ * - control independecy flag
+ * - write spatial frame
+ * - return bitstream
+ */
+ UCHAR *pBitstreamDelayBuffer;
+
+ if (hMp4SpaceEnc->encMode == SACENC_212) {
+ /* no bitstream delay buffer for SACENC_212 mode, write bitstream directly
+ * into the sacOutBuffer buffer which is provided by the core routine */
+ pBitstreamDelayBuffer = (UCHAR *)outBufDesc->ppBase[1];
+ } else {
+ /* bitstream delay is handled in ppBitstreamDelayBuffer buffer */
+ pBitstreamDelayBuffer =
+ hMp4SpaceEnc
+ ->ppBitstreamDelayBuffer[hMp4SpaceEnc->nBitstreamBufferWrite];
+ }
+ if (pBitstreamDelayBuffer == NULL) {
+ error = SACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ pFrameData->bsIndependencyFlag = hMp4SpaceEnc->independencyFlag;
+
+ if (SACENC_OK !=
+ (error = fdk_sacenc_writeSpatialFrame(
+ pBitstreamDelayBuffer, MAX_MPEGS_BYTES,
+ &hMp4SpaceEnc->pnOutputBits[hMp4SpaceEnc->nBitstreamBufferWrite],
+ hMp4SpaceEnc->hBitstreamFormatter))) {
+ goto bail;
+ }
+
+ /* return bitstream info */
+ if ((hMp4SpaceEnc->nDiscardOutFrames == 0) &&
+ (getBufDescIdx(outBufDesc,
+ (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_BS_DATA)) != -1)) {
+ const INT idx = getBufDescIdx(
+ outBufDesc, (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_BS_DATA));
+ const INT outBits =
+ hMp4SpaceEnc->pnOutputBits[hMp4SpaceEnc->nBitstreamBufferRead];
+
+ if (((outBits + 7) / 8) >
+ (INT)(outBufDesc->pBufSize[idx] / outBufDesc->pEleSize[idx])) {
+ outargs->nOutputBits = 0;
+ error = SACENC_ENCODE_ERROR;
+ goto bail;
+ }
+
+ /* return bitstream buffer, copy delayed bitstream for all configurations
+ * except for the SACENC_212 mode */
+ if (hMp4SpaceEnc->encMode != SACENC_212) {
+ FDKmemcpy(
+ outBufDesc->ppBase[idx],
+ hMp4SpaceEnc
+ ->ppBitstreamDelayBuffer[hMp4SpaceEnc->nBitstreamBufferRead],
+ (outBits + 7) / 8);
+ }
+
+ /* return number of valid bits */
+ outargs->nOutputBits = outBits;
+ } else { /* No spatial data should be returned if the current frame is to be
+ discarded. */
+ outargs->nOutputBits = 0;
+ }
+
+ /* update pointers */
+ hMp4SpaceEnc->nBitstreamBufferRead =
+ (hMp4SpaceEnc->nBitstreamBufferRead + 1) %
+ hMp4SpaceEnc->nBitstreamDelayBuffer;
+ hMp4SpaceEnc->nBitstreamBufferWrite =
+ (hMp4SpaceEnc->nBitstreamBufferWrite + 1) %
+ hMp4SpaceEnc->nBitstreamDelayBuffer;
+
+ /* Set Output Parameters */
+ nOutputSamples =
+ (hMp4SpaceEnc->nDiscardOutFrames == 0)
+ ? (nOutputSamplesMax)
+ : 0; /* don't output samples in case frames to be discarded */
+ if (nOutputSamples > nOutputSamplesBufferSize) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+ outargs->nOutputSamples = nOutputSamples;
+
+ { /* !bQmfOutput */
+
+ if (hMp4SpaceEnc->encMode != SACENC_212) {
+ /* delay output samples and interleave them */
+ /* note: in case of arbitrary downmix this will always be processed,
+ * because nOutputSamples != 0, even if bDMXAlign is switched on */
+ /* always run copy-func, so nOutputSamplesMax instead of nOutputSamples
+ */
+ for (ch = 0; ch < nChOut; ch++) {
+ FDKmemcpy_flex(
+ &hMp4SpaceEnc->pOutputDelayBuffer__FDK
+ [ch + (hMp4SpaceEnc->nOutputBufferDelay) * nChOut],
+ nChOut, hMp4SpaceEnc->ppTimeSigOut__FDK[ch], 1,
+ nOutputSamplesMax / nChOut);
+ }
+
+ /* write delayed data in output pcm stream */
+ /* always calculate, limiter must have a lookahead!!! */
+ FDKmemcpy(pOutputSamples, hMp4SpaceEnc->pOutputDelayBuffer__FDK,
+ nOutputSamplesMax * sizeof(INT_PCM));
+
+ /* update delay buffer (move back end to the beginning of the buffer) */
+ FDKmemmove(
+ hMp4SpaceEnc->pOutputDelayBuffer__FDK,
+ &hMp4SpaceEnc->pOutputDelayBuffer__FDK[nOutputSamplesMax],
+ nChOut * (hMp4SpaceEnc->nOutputBufferDelay) * sizeof(INT_PCM));
+ }
+
+ if (hMp4SpaceEnc->useTimeDomDownmix <= 0) {
+ if (SACENC_OK != (error = fdk_sacenc_staticPostGain_ApplyFDK(
+ hMp4SpaceEnc->hStaticGain, pOutputSamples,
+ nOutputSamplesMax, 0))) {
+ goto bail;
+ }
+ }
+
+ } /* !bQmfOutput */
+
+ if (hMp4SpaceEnc->nDiscardOutFrames > 0) {
+ hMp4SpaceEnc->nDiscardOutFrames--;
+ }
+
+ /* Invalidate Input Buffer */
+ hMp4SpaceEnc->nSamplesValid = 0;
+
+ } /* valid handle */
+bail:
+ return error;
+}
+
+FDK_SACENC_ERROR FDK_sacenc_close(HANDLE_MP4SPACE_ENCODER *phMp4SpaceEnc) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL != phMp4SpaceEnc) {
+ if (NULL != *phMp4SpaceEnc) {
+ int ch, i;
+ HANDLE_MP4SPACE_ENCODER const hEnc = *phMp4SpaceEnc;
+
+ if (hEnc->pParameterBand2HybridBandOffset != NULL) {
+ FDK_FREE_MEMORY_1D(hEnc->pParameterBand2HybridBandOffset);
+ }
+ /* Free Analysis Filterbank Structs */
+ if (hEnc->pEncoderInputChScale != NULL) {
+ FDK_FREE_MEMORY_1D(hEnc->pEncoderInputChScale);
+ }
+ if (hEnc->staticTimeDomainDmxInScale != NULL) {
+ FDK_FREE_MEMORY_1D(hEnc->staticTimeDomainDmxInScale);
+ }
+ if (hEnc->phQmfFiltIn__FDK != NULL) {
+ for (ch = 0; ch < hEnc->setup.maxChIn; ch++) {
+ if (hEnc->phQmfFiltIn__FDK[ch] != NULL) {
+ if (hEnc->phQmfFiltIn__FDK[ch]->FilterStates != NULL) {
+ FDK_FREE_MEMORY_1D(hEnc->phQmfFiltIn__FDK[ch]->FilterStates);
+ }
+ FDK_FREE_MEMORY_1D(hEnc->phQmfFiltIn__FDK[ch]);
+ }
+ }
+ FDK_FREE_MEMORY_1D(hEnc->phQmfFiltIn__FDK);
+ }
+ for (ch = 0; ch < hEnc->setup.maxChIn; ch++) {
+ if (NULL != hEnc->phDCFilterSigIn[ch]) {
+ fdk_sacenc_destroyDCFilter(&hEnc->phDCFilterSigIn[ch]);
+ }
+ }
+ /* Close Onset Detection */
+ for (ch = 0; ch < hEnc->setup.maxChIn; ch++) {
+ if (NULL != hEnc->phOnset[ch]) {
+ fdk_sacenc_onsetDetect_Close(&hEnc->phOnset[ch]);
+ }
+ }
+ if (hEnc->ppTrCurrPos) {
+ FDK_FREE_MEMORY_2D(hEnc->ppTrCurrPos);
+ }
+ if (hEnc->hFrameWindow) {
+ fdk_sacenc_frameWindow_Destroy(&hEnc->hFrameWindow);
+ }
+ /* Close Space Tree */
+ if (NULL != hEnc->hSpaceTree) {
+ fdk_sacenc_spaceTree_Close(&hEnc->hSpaceTree);
+ }
+ if (NULL != hEnc->hEnhancedTimeDmx) {
+ fdk_sacenc_close_enhancedTimeDomainDmx(&hEnc->hEnhancedTimeDmx);
+ }
+ /* Close Static Gain */
+ if (NULL != hEnc->hStaticGain) {
+ fdk_sacenc_staticGain_Close(&hEnc->hStaticGain);
+ }
+ if (NULL != hEnc->hStaticGainConfig) {
+ fdk_sacenc_staticGain_CloseConfig(&hEnc->hStaticGainConfig);
+ }
+ /* Close Delay*/
+ if (NULL != hEnc->hDelay) {
+ fdk_sacenc_delay_Close(&hEnc->hDelay);
+ }
+ /* Delete Bitstream Stuff */
+ if (NULL != hEnc->hBitstreamFormatter) {
+ fdk_sacenc_destroySpatialBitstreamEncoder(&(hEnc->hBitstreamFormatter));
+ }
+ if (hEnc->pppHybridIn__FDK != NULL) {
+ if (hEnc->setup.bEncMode_212 == 1) {
+ FDK_FREE_MEMORY_3D(hEnc->pppHybridIn__FDK);
+ FDK_FREE_MEMORY_3D(hEnc->pppHybridInStatic__FDK);
+ } else {
+ FDK_FREE_MEMORY_3D(hEnc->pppHybridIn__FDK);
+ }
+ }
+ if (hEnc->pppProcDataIn__FDK != NULL) {
+ FDK_FREE_MEMORY_3D(hEnc->pppProcDataIn__FDK);
+ }
+ if (hEnc->pOutputDelayBuffer__FDK != NULL) {
+ FDK_FREE_MEMORY_1D(hEnc->pOutputDelayBuffer__FDK);
+ }
+ if (hEnc->ppTimeSigIn__FDK != NULL) {
+ { FDK_FREE_MEMORY_2D(hEnc->ppTimeSigIn__FDK); }
+ }
+ if (hEnc->ppTimeSigDelayIn__FDK != NULL) {
+ FDK_FREE_MEMORY_2D(hEnc->ppTimeSigDelayIn__FDK);
+ }
+ if (hEnc->ppTimeSigOut__FDK != NULL) {
+ FDK_FREE_MEMORY_2D(hEnc->ppTimeSigOut__FDK);
+ }
+ for (i = 0; i < MAX_NUM_PARAMS; i++) {
+ if (hEnc->pFrameWindowAna__FDK[i] != NULL) {
+ FDK_FREE_MEMORY_1D(hEnc->pFrameWindowAna__FDK[i]);
+ }
+ }
+ if (hEnc->pnOutputBits != NULL) {
+ FDK_FREE_MEMORY_1D(hEnc->pnOutputBits);
+ }
+ if (hEnc->ppBitstreamDelayBuffer != NULL) {
+ FDK_FREE_MEMORY_2D(hEnc->ppBitstreamDelayBuffer);
+ }
+ if (hEnc->sscBuf.pSsc != NULL) {
+ FDK_FREE_MEMORY_1D(hEnc->sscBuf.pSsc);
+ }
+ FDK_FREE_MEMORY_1D(*phMp4SpaceEnc);
+ }
+ }
+
+ return error;
+}
+
+/*-----------------------------------------------------------------------------
+ functionname: mp4SpaceEnc_InitDelayCompensation()
+ description: initialzes delay compensation
+ returns: noError on success, an apropriate error code else
+ -----------------------------------------------------------------------------*/
+static FDK_SACENC_ERROR mp4SpaceEnc_InitDelayCompensation(
+ HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc, const INT coreCoderDelay) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ /* Sanity Check */
+ if (hMp4SpaceEnc == NULL) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ hMp4SpaceEnc->coreCoderDelay = coreCoderDelay;
+
+ if (SACENC_OK != (error = fdk_sacenc_delay_Init(
+ hMp4SpaceEnc->hDelay, hMp4SpaceEnc->nQmfBands,
+ hMp4SpaceEnc->nFrameLength, coreCoderDelay,
+ hMp4SpaceEnc->timeAlignment))) {
+ goto bail;
+ }
+
+ fdk_sacenc_delay_SetDmxAlign(hMp4SpaceEnc->hDelay, 0);
+ fdk_sacenc_delay_SetTimeDomDmx(
+ hMp4SpaceEnc->hDelay, (hMp4SpaceEnc->useTimeDomDownmix >= 1) ? 1 : 0);
+ fdk_sacenc_delay_SetMinimizeDelay(hMp4SpaceEnc->hDelay, 1);
+
+ if (SACENC_OK != (error = fdk_sacenc_delay_SubCalulateBufferDelays(
+ hMp4SpaceEnc->hDelay))) {
+ goto bail;
+ }
+
+ /* init output delay compensation */
+ hMp4SpaceEnc->nBitstreamDelayBuffer =
+ fdk_sacenc_delay_GetBitstreamFrameBufferSize(hMp4SpaceEnc->hDelay);
+ hMp4SpaceEnc->nOutputBufferDelay =
+ fdk_sacenc_delay_GetOutputAudioBufferDelay(hMp4SpaceEnc->hDelay);
+ hMp4SpaceEnc->nSurroundAnalysisBufferDelay =
+ fdk_sacenc_delay_GetSurroundAnalysisBufferDelay(hMp4SpaceEnc->hDelay);
+ hMp4SpaceEnc->nBitstreamBufferRead = 0;
+ hMp4SpaceEnc->nBitstreamBufferWrite =
+ hMp4SpaceEnc->nBitstreamDelayBuffer - 1;
+
+ if (hMp4SpaceEnc->encMode == SACENC_212) {
+ /* mode 212 expects no bitstream delay */
+ if (hMp4SpaceEnc->nBitstreamBufferWrite !=
+ hMp4SpaceEnc->nBitstreamBufferRead) {
+ error = SACENC_PARAM_ERROR;
+ goto bail;
+ }
+
+ /* mode 212 expects no output buffer delay */
+ if (hMp4SpaceEnc->nOutputBufferDelay != 0) {
+ error = SACENC_PARAM_ERROR;
+ goto bail;
+ }
+ }
+
+ /*** Input delay to obtain a net encoder delay that is a multiple
+ of the used framelength to ensure synchronization of framing
+ in artistic down-mix with the corresponding spatial data. ***/
+ hMp4SpaceEnc->nDiscardOutFrames =
+ fdk_sacenc_delay_GetDiscardOutFrames(hMp4SpaceEnc->hDelay);
+ hMp4SpaceEnc->nInputDelay =
+ fdk_sacenc_delay_GetDmxAlignBufferDelay(hMp4SpaceEnc->hDelay);
+
+ /* reset independency Flag counter */
+ hMp4SpaceEnc->independencyCount = 0;
+ hMp4SpaceEnc->independencyFlag = 1;
+
+ int i;
+
+ /* write some parameters to bitstream */
+ for (i = 0; i < hMp4SpaceEnc->nBitstreamDelayBuffer - 1; i++) {
+ SPATIALFRAME *pFrameData = NULL;
+
+ if (NULL == (pFrameData = fdk_sacenc_getSpatialFrame(
+ hMp4SpaceEnc->hBitstreamFormatter, READ_SPATIALFRAME))) {
+ error = SACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ pFrameData->bsIndependencyFlag = 1;
+ pFrameData->framingInfo.numParamSets = 1;
+ pFrameData->framingInfo.bsFramingType = 0;
+
+ fdk_sacenc_writeSpatialFrame(
+ hMp4SpaceEnc->ppBitstreamDelayBuffer[i], MAX_MPEGS_BYTES,
+ &hMp4SpaceEnc->pnOutputBits[i], hMp4SpaceEnc->hBitstreamFormatter);
+ }
+
+ if ((hMp4SpaceEnc->nInputDelay > MAX_DELAY_INPUT) ||
+ (hMp4SpaceEnc->nOutputBufferDelay > MAX_DELAY_OUTPUT) ||
+ (hMp4SpaceEnc->nSurroundAnalysisBufferDelay >
+ MAX_DELAY_SURROUND_ANALYSIS) ||
+ (hMp4SpaceEnc->nBitstreamDelayBuffer > MAX_BITSTREAM_DELAY)) {
+ error = SACENC_INIT_ERROR;
+ goto bail;
+ }
+ }
+
+bail:
+
+ return error;
+}
+
+static QUANTMODE __mapQuantMode(const MP4SPACEENC_QUANTMODE quantMode) {
+ QUANTMODE bsQuantMode = QUANTMODE_INVALID;
+
+ switch (quantMode) {
+ case SACENC_QUANTMODE_FINE:
+ bsQuantMode = QUANTMODE_FINE;
+ break;
+ case SACENC_QUANTMODE_EBQ1:
+ bsQuantMode = QUANTMODE_EBQ1;
+ break;
+ case SACENC_QUANTMODE_EBQ2:
+ bsQuantMode = QUANTMODE_EBQ2;
+ break;
+ case SACENC_QUANTMODE_RSVD3:
+ case SACENC_QUANTMODE_INVALID:
+ default:
+ bsQuantMode = QUANTMODE_INVALID;
+ } /* switch hEnc->quantMode */
+
+ return bsQuantMode;
+}
+
+static FDK_SACENC_ERROR FillSpatialSpecificConfig(
+ const HANDLE_MP4SPACE_ENCODER hEnc, SPATIALSPECIFICCONFIG *const hSsc) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((NULL == hEnc) || (NULL == hSsc)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ SPACE_TREE_DESCRIPTION spaceTreeDescription;
+ int i;
+
+ /* Get tree description */
+ if (SACENC_OK != (error = fdk_sacenc_spaceTree_GetDescription(
+ hEnc->hSpaceTree, &spaceTreeDescription))) {
+ goto bail;
+ }
+
+ /* Fill SSC */
+ FDKmemclear(hSsc, sizeof(SPATIALSPECIFICCONFIG)); /* reset */
+
+ hSsc->numBands = hEnc->spaceTreeSetup.nParamBands; /* for bsFreqRes */
+
+ /* Fill tree configuration */
+ hSsc->treeDescription.numOttBoxes = spaceTreeDescription.nOttBoxes;
+ hSsc->treeDescription.numInChan = spaceTreeDescription.nInChannels;
+ hSsc->treeDescription.numOutChan = spaceTreeDescription.nOutChannels;
+
+ for (i = 0; i < SACENC_MAX_NUM_BOXES; i++) {
+ hSsc->ottConfig[i].bsOttBands = hSsc->numBands;
+ }
+
+ switch (hEnc->encMode) {
+ case SACENC_212:
+ hSsc->bsTreeConfig = TREE_212;
+ break;
+ case SACENC_INVALID_MODE:
+ default:
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ hSsc->bsSamplingFrequency =
+ hEnc->nSampleRate; /* for bsSamplingFrequencyIndex */
+ hSsc->bsFrameLength = hEnc->nFrameTimeSlots - 1;
+
+ /* map decorr type */
+ if (DECORR_INVALID ==
+ (hSsc->bsDecorrConfig = mp4SpaceEnc_GetDecorrConfig(hEnc->encMode))) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ /* map quantMode */
+ if (QUANTMODE_INVALID ==
+ (hSsc->bsQuantMode = __mapQuantMode(hEnc->quantMode))) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ /* Configure Gains*/
+ hSsc->bsFixedGainDMX = fdk_sacenc_staticGain_GetDmxGain(hEnc->hStaticGain);
+ hSsc->bsEnvQuantMode = 0;
+
+ } /* valid handle */
+
+bail:
+ return error;
+}
+
+static FDK_SACENC_ERROR mp4SpaceEnc_FillSpaceTreeSetup(
+ const HANDLE_MP4SPACE_ENCODER hEnc,
+ SPACE_TREE_SETUP *const hSpaceTreeSetup) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ /* Sanity Check */
+ if (NULL == hEnc || NULL == hSpaceTreeSetup) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ QUANTMODE tmpQuantmode = QUANTMODE_INVALID;
+
+ /* map quantMode */
+ if (QUANTMODE_INVALID == (tmpQuantmode = __mapQuantMode(hEnc->quantMode))) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ hSpaceTreeSetup->nParamBands = hEnc->nParamBands;
+ hSpaceTreeSetup->bUseCoarseQuantTtoCld = hEnc->useCoarseQuantCld;
+ hSpaceTreeSetup->bUseCoarseQuantTtoIcc = hEnc->useCoarseQuantIcc;
+ hSpaceTreeSetup->quantMode = tmpQuantmode;
+ hSpaceTreeSetup->nHybridBandsMax = hEnc->nHybridBands;
+
+ switch (hEnc->encMode) {
+ case SACENC_212:
+ hSpaceTreeSetup->mode = SPACETREE_212;
+ hSpaceTreeSetup->nChannelsInMax = 2;
+ break;
+ case SACENC_INVALID_MODE:
+ default:
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ } /* switch hEnc->encMode */
+
+ } /* valid handle */
+bail:
+ return error;
+}
+
+FDK_SACENC_ERROR FDK_sacenc_getInfo(const HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc,
+ MP4SPACEENC_INFO *const pInfo) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((NULL == hMp4SpaceEnc) || (NULL == pInfo)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ pInfo->nSampleRate = hMp4SpaceEnc->nSampleRate;
+ pInfo->nSamplesFrame = hMp4SpaceEnc->nFrameLength;
+ pInfo->nTotalInputChannels = hMp4SpaceEnc->nInputChannels;
+ pInfo->nDmxDelay = fdk_sacenc_delay_GetInfoDmxDelay(hMp4SpaceEnc->hDelay);
+ pInfo->nCodecDelay =
+ fdk_sacenc_delay_GetInfoCodecDelay(hMp4SpaceEnc->hDelay);
+ pInfo->nDecoderDelay =
+ fdk_sacenc_delay_GetInfoDecoderDelay(hMp4SpaceEnc->hDelay);
+ pInfo->nPayloadDelay =
+ fdk_sacenc_delay_GetBitstreamFrameBufferSize(hMp4SpaceEnc->hDelay) - 1;
+ pInfo->nDiscardOutFrames = hMp4SpaceEnc->nDiscardOutFrames;
+
+ pInfo->pSscBuf = &hMp4SpaceEnc->sscBuf;
+ }
+ return error;
+}
+
+FDK_SACENC_ERROR FDK_sacenc_setParam(HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc,
+ const SPACEENC_PARAM param,
+ const UINT value) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ /* check encoder handle */
+ if (hMp4SpaceEnc == NULL) {
+ error = SACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ /* apply param value */
+ switch (param) {
+ case SACENC_LOWDELAY:
+ if (!((value == 0) || (value == 1) || (value == 2))) {
+ error = SACENC_INVALID_CONFIG;
+ break;
+ }
+ hMp4SpaceEnc->user.bLdMode = value;
+ break;
+
+ case SACENC_ENC_MODE:
+ switch ((MP4SPACEENC_MODE)value) {
+ case SACENC_212:
+ hMp4SpaceEnc->user.encMode = (MP4SPACEENC_MODE)value;
+ break;
+ default:
+ error = SACENC_INVALID_CONFIG;
+ }
+ break;
+
+ case SACENC_SAMPLERATE:
+ if (((int)value < 0) ||
+ ((int)value > hMp4SpaceEnc->setup.maxSamplingrate)) {
+ error = SACENC_INVALID_CONFIG;
+ break;
+ }
+ hMp4SpaceEnc->user.sampleRate = value;
+ break;
+
+ case SACENC_FRAME_TIME_SLOTS:
+ if (((int)value < 0) ||
+ ((int)value > hMp4SpaceEnc->setup.maxFrameTimeSlots)) {
+ error = SACENC_INVALID_CONFIG;
+ break;
+ }
+ hMp4SpaceEnc->user.frameTimeSlots = value;
+ break;
+
+ case SACENC_PARAM_BANDS:
+ switch ((MP4SPACEENC_BANDS_CONFIG)value) {
+ case SACENC_BANDS_4:
+ case SACENC_BANDS_5:
+ case SACENC_BANDS_7:
+ case SACENC_BANDS_9:
+ case SACENC_BANDS_12:
+ case SACENC_BANDS_15:
+ case SACENC_BANDS_23:
+ hMp4SpaceEnc->user.nParamBands = (MP4SPACEENC_BANDS_CONFIG)value;
+ break;
+ default:
+ error = SACENC_INVALID_CONFIG;
+ }
+ break;
+
+ case SACENC_TIME_DOM_DMX:
+ if (!((value == 0) || (value == 2))) {
+ error = SACENC_INVALID_CONFIG;
+ break;
+ }
+ hMp4SpaceEnc->user.bTimeDomainDmx = value;
+ break;
+
+ case SACENC_DMX_GAIN:
+ if (!((value == 0) || (value == 1) || (value == 2) || (value == 3) ||
+ (value == 4) || (value == 5) || (value == 6) || (value == 7))) {
+ error = SACENC_INVALID_CONFIG;
+ break;
+ }
+ error = fdk_sacenc_staticGain_SetDmxGain(hMp4SpaceEnc->hStaticGainConfig,
+ (MP4SPACEENC_DMX_GAIN)value);
+ break;
+
+ case SACENC_COARSE_QUANT:
+ if (!((value == 0) || (value == 1))) {
+ error = SACENC_INVALID_CONFIG;
+ break;
+ }
+ hMp4SpaceEnc->user.bUseCoarseQuant = value;
+ break;
+
+ case SACENC_QUANT_MODE:
+ switch ((MP4SPACEENC_QUANTMODE)value) {
+ case SACENC_QUANTMODE_FINE:
+ case SACENC_QUANTMODE_EBQ1:
+ case SACENC_QUANTMODE_EBQ2:
+ hMp4SpaceEnc->user.quantMode = (MP4SPACEENC_QUANTMODE)value;
+ break;
+ default:
+ error = SACENC_INVALID_CONFIG;
+ }
+ break;
+
+ case SACENC_TIME_ALIGNMENT:
+ if ((INT)value < -32768 || (INT)value > 32767) {
+ error = SACENC_INVALID_CONFIG;
+ break;
+ }
+ hMp4SpaceEnc->user.timeAlignment = value;
+ break;
+
+ case SACENC_INDEPENDENCY_COUNT:
+ hMp4SpaceEnc->independencyCount = value;
+ break;
+
+ case SACENC_INDEPENDENCY_FACTOR:
+ hMp4SpaceEnc->user.independencyFactor = value;
+ break;
+
+ default:
+ error = SACENC_UNSUPPORTED_PARAMETER;
+ break;
+ } /* switch(param) */
+bail:
+ return error;
+}
+
+FDK_SACENC_ERROR FDK_sacenc_getLibInfo(LIB_INFO *info) {
+ int i = 0;
+
+ if (info == NULL) {
+ return SACENC_INVALID_HANDLE;
+ }
+
+ FDK_toolsGetLibInfo(info);
+
+ /* search for next free tab */
+ for (i = 0; i < FDK_MODULE_LAST; i++) {
+ if (info[i].module_id == FDK_NONE) break;
+ }
+ if (i == FDK_MODULE_LAST) {
+ return SACENC_INIT_ERROR;
+ }
+
+ info[i].module_id = FDK_MPSENC;
+ info[i].build_date = SACENC_LIB_BUILD_DATE;
+ info[i].build_time = SACENC_LIB_BUILD_TIME;
+ info[i].title = SACENC_LIB_TITLE;
+ info[i].version = LIB_VERSION(SACENC_LIB_VL0, SACENC_LIB_VL1, SACENC_LIB_VL2);
+ LIB_VERSION_STRING(&info[i]);
+
+ /* Capability flags */
+ info[i].flags = 0;
+ /* End of flags */
+
+ return SACENC_OK;
+}
+
+static DECORRCONFIG mp4SpaceEnc_GetDecorrConfig(
+ const MP4SPACEENC_MODE encMode) {
+ DECORRCONFIG decorrConfig = DECORR_INVALID;
+
+ /* set decorrConfig dependent on tree mode */
+ switch (encMode) {
+ case SACENC_212:
+ decorrConfig = DECORR_QMFSPLIT0;
+ break;
+ case SACENC_INVALID_MODE:
+ default:
+ decorrConfig = DECORR_INVALID;
+ }
+ return decorrConfig;
+}
+
+static FDK_SACENC_ERROR mp4SpaceEnc_InitNumParamBands(
+ HANDLE_MP4SPACE_ENCODER hEnc, const MP4SPACEENC_BANDS_CONFIG nParamBands) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ /* Set/Check nParamBands */
+ int k = 0;
+ const int n = sizeof(pValidBands_Ld) / sizeof(UCHAR);
+ const UCHAR *pBands = pValidBands_Ld;
+
+ while (k < n && pBands[k] != (UCHAR)nParamBands) ++k;
+ if (k == n) {
+ hEnc->nParamBands = SACENC_BANDS_INVALID;
+ } else {
+ hEnc->nParamBands = nParamBands;
+ }
+ return error;
+}
diff --git a/libSACenc/src/sacenc_nlc_enc.cpp b/libSACenc/src/sacenc_nlc_enc.cpp
new file mode 100644
index 0000000..ecb89b7
--- /dev/null
+++ b/libSACenc/src/sacenc_nlc_enc.cpp
@@ -0,0 +1,1436 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): Karsten Linzmeier
+
+ Description: Noiseless Coding
+ Huffman encoder
+
+*******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_nlc_enc.h"
+
+#include "genericStds.h"
+#include "fixpoint_math.h"
+
+#include "sacenc_const.h"
+#include "sacenc_huff_tab.h"
+#include "sacenc_paramextract.h"
+
+/* Defines *******************************************************************/
+#define PAIR_SHIFT 4
+#define PAIR_MASK 0xf
+
+#define PBC_MIN_BANDS 5
+
+typedef enum {
+ BACKWARDS = 0x0,
+ FORWARDS = 0x1
+
+} DIRECTION;
+
+typedef enum {
+ DIFF_FREQ = 0x0,
+ DIFF_TIME = 0x1
+
+} DIFF_TYPE;
+
+typedef enum {
+ HUFF_1D = 0x0,
+ HUFF_2D = 0x1
+
+} CODING_SCHEME;
+
+typedef enum {
+ FREQ_PAIR = 0x0,
+ TIME_PAIR = 0x1
+
+} PAIRING;
+
+/* Data Types ****************************************************************/
+
+/* Constants *****************************************************************/
+static const UCHAR lavHuffVal[4] = {0, 2, 6, 7};
+static const UCHAR lavHuffLen[4] = {1, 2, 3, 3};
+
+static const UCHAR lav_step_CLD[] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3};
+static const UCHAR lav_step_ICC[] = {0, 0, 1, 1, 2, 2, 3, 3};
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+static void split_lsb(const SHORT *const in_data, SHORT offset,
+ const INT num_val, SHORT *const out_data_lsb,
+ SHORT *const out_data_msb) {
+ int i;
+
+ for (i = 0; i < num_val; i++) {
+ SHORT val = in_data[i] + offset;
+ if (out_data_lsb != NULL) out_data_lsb[i] = val & 0x0001;
+ if (out_data_msb != NULL) out_data_msb[i] = val >> 1;
+ }
+}
+
+static void apply_lsb_coding(HANDLE_FDK_BITSTREAM strm,
+ const SHORT *const in_data_lsb, const UINT num_lsb,
+ const INT num_val) {
+ int i;
+
+ for (i = 0; i < num_val; i++) {
+ FDKwriteBits(strm, in_data_lsb[i], num_lsb);
+ }
+}
+
+static void calc_diff_freq(const SHORT *const in_data, SHORT *const out_data,
+ const INT num_val) {
+ int i;
+ out_data[0] = in_data[0];
+
+ for (i = 1; i < num_val; i++) {
+ out_data[i] = in_data[i] - in_data[i - 1];
+ }
+}
+
+static void calc_diff_time(const SHORT *const in_data,
+ const SHORT *const prev_data, SHORT *const out_data,
+ const INT num_val) {
+ int i;
+ out_data[0] = in_data[0];
+ out_data[1] = prev_data[0];
+
+ for (i = 0; i < num_val; i++) {
+ out_data[i + 2] = in_data[i] - prev_data[i];
+ }
+}
+
+static INT sym_check(SHORT data[2], const INT lav, SHORT *const pSym_bits) {
+ UCHAR symBits = 0;
+ int sum_val = data[0] + data[1];
+ int diff_val = data[0] - data[1];
+ int num_sbits = 0;
+
+ if (sum_val != 0) {
+ int sum_neg = (sum_val < 0) ? 1 : 0;
+ if (sum_neg) {
+ sum_val = -sum_val;
+ diff_val = -diff_val;
+ }
+ symBits = (symBits << 1) | sum_neg;
+ num_sbits++;
+ }
+
+ if (diff_val != 0) {
+ int diff_neg = (diff_val < 0) ? 1 : 0;
+ if (diff_neg) {
+ diff_val = -diff_val;
+ }
+ symBits = (symBits << 1) | diff_neg;
+ num_sbits++;
+ }
+
+ if (pSym_bits != NULL) {
+ *pSym_bits = symBits;
+ }
+
+ if (sum_val % 2) {
+ data[0] = lav - sum_val / 2;
+ data[1] = lav - diff_val / 2;
+ } else {
+ data[0] = sum_val / 2;
+ data[1] = diff_val / 2;
+ }
+
+ return num_sbits;
+}
+
+static INT ilog2(UINT i) {
+ int l = 0;
+
+ if (i) i--;
+ while (i > 0) {
+ i >>= 1;
+ l++;
+ }
+
+ return l;
+}
+
+static SHORT calc_pcm_bits(const SHORT num_val, const SHORT num_levels) {
+ SHORT num_complete_chunks = 0, rest_chunk_size = 0;
+ SHORT max_grp_len = 0, bits_pcm = 0;
+ int chunk_levels, i;
+
+ switch (num_levels) {
+ case 3:
+ max_grp_len = 5;
+ break;
+ case 6:
+ max_grp_len = 5;
+ break;
+ case 7:
+ max_grp_len = 6;
+ break;
+ case 11:
+ max_grp_len = 2;
+ break;
+ case 13:
+ max_grp_len = 4;
+ break;
+ case 19:
+ max_grp_len = 4;
+ break;
+ case 25:
+ max_grp_len = 3;
+ break;
+ case 51:
+ max_grp_len = 4;
+ break;
+ default:
+ max_grp_len = 1;
+ }
+
+ num_complete_chunks = num_val / max_grp_len;
+ rest_chunk_size = num_val % max_grp_len;
+
+ chunk_levels = 1;
+ for (i = 1; i <= max_grp_len; i++) {
+ chunk_levels *= num_levels;
+ }
+
+ bits_pcm = (SHORT)(ilog2(chunk_levels) * num_complete_chunks);
+ bits_pcm += (SHORT)(ilog2(num_levels) * rest_chunk_size);
+
+ return bits_pcm;
+}
+
+static void apply_pcm_coding(HANDLE_FDK_BITSTREAM strm,
+ const SHORT *const in_data_1,
+ const SHORT *const in_data_2, const SHORT offset,
+ const SHORT num_val, const SHORT num_levels) {
+ SHORT i = 0, j = 0, idx = 0;
+ SHORT max_grp_len = 0, grp_len = 0, next_val = 0;
+ int grp_val = 0, chunk_levels = 0;
+
+ SHORT pcm_chunk_size[7] = {0};
+
+ switch (num_levels) {
+ case 3:
+ max_grp_len = 5;
+ break;
+ case 5:
+ max_grp_len = 3;
+ break;
+ case 6:
+ max_grp_len = 5;
+ break;
+ case 7:
+ max_grp_len = 6;
+ break;
+ case 9:
+ max_grp_len = 5;
+ break;
+ case 11:
+ max_grp_len = 2;
+ break;
+ case 13:
+ max_grp_len = 4;
+ break;
+ case 19:
+ max_grp_len = 4;
+ break;
+ case 25:
+ max_grp_len = 3;
+ break;
+ case 51:
+ max_grp_len = 4;
+ break;
+ default:
+ max_grp_len = 1;
+ }
+
+ chunk_levels = 1;
+ for (i = 1; i <= max_grp_len; i++) {
+ chunk_levels *= num_levels;
+ pcm_chunk_size[i] = ilog2(chunk_levels);
+ }
+
+ for (i = 0; i < num_val; i += max_grp_len) {
+ grp_len = FDKmin(max_grp_len, num_val - i);
+ grp_val = 0;
+ for (j = 0; j < grp_len; j++) {
+ idx = i + j;
+ if (in_data_2 == NULL) {
+ next_val = in_data_1[idx];
+ } else if (in_data_1 == NULL) {
+ next_val = in_data_2[idx];
+ } else {
+ next_val = ((idx % 2) ? in_data_2[idx / 2] : in_data_1[idx / 2]);
+ }
+ next_val += offset;
+ grp_val = grp_val * num_levels + next_val;
+ }
+
+ FDKwriteBits(strm, grp_val, pcm_chunk_size[grp_len]);
+ }
+}
+
+static UINT huff_enc_1D(HANDLE_FDK_BITSTREAM strm, const DATA_TYPE data_type,
+ const INT dim1, SHORT *const in_data,
+ const SHORT num_val, const SHORT p0_flag) {
+ int i, offset = 0;
+ UINT huffBits = 0;
+
+ HUFF_ENTRY part0 = {0};
+ const HUFF_ENTRY *pHuffTab = NULL;
+
+ switch (data_type) {
+ case t_CLD:
+ part0 = fdk_sacenc_huffPart0Tab.cld[in_data[0]];
+ pHuffTab = fdk_sacenc_huffCLDTab.h1D[dim1];
+ break;
+ case t_ICC:
+ part0 = fdk_sacenc_huffPart0Tab.icc[in_data[0]];
+ pHuffTab = fdk_sacenc_huffICCTab.h1D[dim1];
+ break;
+ }
+
+ if (p0_flag) {
+ huffBits += FDKwriteBits(strm, HUFF_VALUE(part0), HUFF_LENGTH(part0));
+ offset = 1;
+ }
+
+ for (i = offset; i < num_val; i++) {
+ int id_sign = 0;
+ int id = in_data[i];
+
+ if (id != 0) {
+ id_sign = 0;
+ if (id < 0) {
+ id = -id;
+ id_sign = 1;
+ }
+ }
+
+ huffBits +=
+ FDKwriteBits(strm, HUFF_VALUE(pHuffTab[id]), HUFF_LENGTH(pHuffTab[id]));
+
+ if (id != 0) {
+ huffBits += FDKwriteBits(strm, id_sign, 1);
+ }
+ } /* for i */
+
+ return huffBits;
+}
+
+static void getHuffEntry(const INT lav, const DATA_TYPE data_type, const INT i,
+ const SHORT tab_idx_2D[2], const SHORT in_data[][2],
+ HUFF_ENTRY *const pEntry, HUFF_ENTRY *const pEscape) {
+ const HUFF_CLD_TAB_2D *pCLD2dTab =
+ &fdk_sacenc_huffCLDTab.h2D[tab_idx_2D[0]][tab_idx_2D[1]];
+ const HUFF_ICC_TAB_2D *pICC2dTab =
+ &fdk_sacenc_huffICCTab.h2D[tab_idx_2D[0]][tab_idx_2D[1]];
+
+ switch (lav) {
+ case 1: {
+ const LAV1_2D *pLav1 = NULL;
+ switch (data_type) {
+ case t_CLD:
+ pLav1 = NULL;
+ break;
+ case t_ICC:
+ pLav1 = &pICC2dTab->lav1;
+ break;
+ }
+ if (pLav1 != NULL) {
+ *pEntry = pLav1->entry[in_data[i][0]][in_data[i][1]];
+ *pEscape = pLav1->escape;
+ }
+ } break;
+ case 3: {
+ const LAV3_2D *pLav3 = NULL;
+ switch (data_type) {
+ case t_CLD:
+ pLav3 = &pCLD2dTab->lav3;
+ break;
+ case t_ICC:
+ pLav3 = &pICC2dTab->lav3;
+ break;
+ }
+ if (pLav3 != NULL) {
+ *pEntry = pLav3->entry[in_data[i][0]][in_data[i][1]];
+ *pEscape = pLav3->escape;
+ }
+ } break;
+ case 5: {
+ const LAV5_2D *pLav5 = NULL;
+ switch (data_type) {
+ case t_CLD:
+ pLav5 = &pCLD2dTab->lav5;
+ break;
+ case t_ICC:
+ pLav5 = &pICC2dTab->lav5;
+ break;
+ }
+ if (pLav5 != NULL) {
+ *pEntry = pLav5->entry[in_data[i][0]][in_data[i][1]];
+ *pEscape = pLav5->escape;
+ }
+ } break;
+ case 7: {
+ const LAV7_2D *pLav7 = NULL;
+ switch (data_type) {
+ case t_CLD:
+ pLav7 = &pCLD2dTab->lav7;
+ break;
+ case t_ICC:
+ pLav7 = &pICC2dTab->lav7;
+ break;
+ }
+ if (pLav7 != NULL) {
+ *pEntry = pLav7->entry[in_data[i][0]][in_data[i][1]];
+ *pEscape = pLav7->escape;
+ }
+ } break;
+ case 9: {
+ const LAV9_2D *pLav9 = NULL;
+ switch (data_type) {
+ case t_CLD:
+ pLav9 = &pCLD2dTab->lav9;
+ break;
+ case t_ICC:
+ pLav9 = NULL;
+ break;
+ }
+ if (pLav9 != NULL) {
+ *pEntry = pLav9->entry[in_data[i][0]][in_data[i][1]];
+ *pEscape = pLav9->escape;
+ }
+ } break;
+ }
+}
+
+static UINT huff_enc_2D(HANDLE_FDK_BITSTREAM strm, const DATA_TYPE data_type,
+ SHORT tab_idx_2D[2], SHORT lav_idx, SHORT in_data[][2],
+ SHORT num_val, SHORT stride, SHORT *p0_data[2]) {
+ SHORT i = 0, lav = 0, num_sbits = 0, sym_bits = 0, escIdx = 0;
+ SHORT esc_data[2][MAXBANDS] = {{0}};
+
+ UINT huffBits = 0;
+
+ const HUFF_ENTRY *pHuffEntry = NULL;
+
+ switch (data_type) {
+ case t_CLD:
+ lav = 2 * lav_idx + 3; /* LAV */
+ pHuffEntry = fdk_sacenc_huffPart0Tab.cld;
+ break;
+ case t_ICC:
+ lav = 2 * lav_idx + 1; /* LAV */
+ pHuffEntry = fdk_sacenc_huffPart0Tab.icc;
+ break;
+ }
+
+ /* Partition 0 */
+ if (p0_data[0] != NULL) {
+ HUFF_ENTRY entry = pHuffEntry[*p0_data[0]];
+ huffBits += FDKwriteBits(strm, HUFF_VALUE(entry), HUFF_LENGTH(entry));
+ }
+ if (p0_data[1] != NULL) {
+ HUFF_ENTRY entry = pHuffEntry[*p0_data[1]];
+ huffBits += FDKwriteBits(strm, HUFF_VALUE(entry), HUFF_LENGTH(entry));
+ }
+
+ for (i = 0; i < num_val; i += stride) {
+ HUFF_ENTRY entry = {0};
+ HUFF_ENTRY escape = {0};
+
+ esc_data[0][escIdx] = in_data[i][0] + lav;
+ esc_data[1][escIdx] = in_data[i][1] + lav;
+
+ num_sbits = sym_check(in_data[i], lav, &sym_bits);
+
+ getHuffEntry(lav, data_type, i, tab_idx_2D, in_data, &entry, &escape);
+
+ huffBits += FDKwriteBits(strm, HUFF_VALUE(entry), HUFF_LENGTH(entry));
+
+ if ((HUFF_VALUE(entry) == HUFF_VALUE(escape)) &&
+ (HUFF_LENGTH(entry) == HUFF_LENGTH(escape))) {
+ escIdx++;
+ } else {
+ huffBits += FDKwriteBits(strm, sym_bits, num_sbits);
+ }
+ } /* for i */
+
+ if (escIdx > 0) {
+ huffBits += calc_pcm_bits(2 * escIdx, (2 * lav + 1));
+ if (strm != NULL) {
+ apply_pcm_coding(strm, esc_data[0], esc_data[1], 0 /*offset*/, 2 * escIdx,
+ (2 * lav + 1));
+ }
+ }
+
+ return huffBits;
+}
+
+static SCHAR get_next_lav_step(const INT lav, const DATA_TYPE data_type) {
+ SCHAR lav_step = 0;
+
+ switch (data_type) {
+ case t_CLD:
+ lav_step = (lav > 9) ? -1 : lav_step_CLD[lav];
+ break;
+ case t_ICC:
+ lav_step = (lav > 7) ? -1 : lav_step_ICC[lav];
+ break;
+ }
+
+ return lav_step;
+}
+
+static INT diff_type_offset(const DIFF_TYPE diff_type) {
+ int offset = 0;
+ switch (diff_type) {
+ case DIFF_FREQ:
+ offset = 0;
+ break;
+ case DIFF_TIME:
+ offset = 2;
+ break;
+ }
+ return offset;
+}
+
+static SHORT calc_huff_bits(SHORT *in_data_1, SHORT *in_data_2,
+ const DATA_TYPE data_type,
+ const DIFF_TYPE diff_type_1,
+ const DIFF_TYPE diff_type_2, const SHORT num_val,
+ SHORT *const lav_idx, SHORT *const cdg_scheme) {
+ SHORT tab_idx_2D[2][2] = {{0}};
+ SHORT tab_idx_1D[2] = {0};
+ SHORT df_rest_flag[2] = {0};
+ SHORT p0_flag[2] = {0};
+
+ SHORT pair_vec[MAXBANDS][2] = {{0}};
+
+ SHORT *p0_data_1[2] = {NULL};
+ SHORT *p0_data_2[2] = {NULL};
+
+ SHORT i = 0;
+ SHORT lav_fp[2] = {0};
+
+ SHORT bit_count_1D = 0;
+ SHORT bit_count_2D_freq = 0;
+ SHORT bit_count_min = 0;
+
+ SHORT num_val_1_short = 0;
+ SHORT num_val_2_short = 0;
+
+ SHORT *in_data_1_short = NULL;
+ SHORT *in_data_2_short = NULL;
+
+ /* 1D Huffman coding */
+ bit_count_1D = 1; /* HUFF_1D */
+
+ num_val_1_short = num_val;
+ num_val_2_short = num_val;
+
+ if (in_data_1 != NULL) {
+ in_data_1_short = in_data_1 + diff_type_offset(diff_type_1);
+ }
+ if (in_data_2 != NULL) {
+ in_data_2_short = in_data_2 + diff_type_offset(diff_type_2);
+ }
+
+ p0_flag[0] = (diff_type_1 == DIFF_FREQ);
+ p0_flag[1] = (diff_type_2 == DIFF_FREQ);
+
+ tab_idx_1D[0] = (diff_type_1 == DIFF_FREQ) ? 0 : 1;
+ tab_idx_1D[1] = (diff_type_2 == DIFF_FREQ) ? 0 : 1;
+
+ if (in_data_1 != NULL) {
+ bit_count_1D += huff_enc_1D(NULL, data_type, tab_idx_1D[0], in_data_1_short,
+ num_val_1_short, p0_flag[0]);
+ }
+ if (in_data_2 != NULL) {
+ bit_count_1D += huff_enc_1D(NULL, data_type, tab_idx_1D[1], in_data_2_short,
+ num_val_2_short, p0_flag[1]);
+ }
+
+ bit_count_min = bit_count_1D;
+ *cdg_scheme = HUFF_1D << PAIR_SHIFT;
+ lav_idx[0] = lav_idx[1] = -1;
+
+ /* Huffman 2D frequency pairs */
+ bit_count_2D_freq = 1; /* HUFF_2D */
+
+ num_val_1_short = num_val;
+ num_val_2_short = num_val;
+
+ if (in_data_1 != NULL) {
+ in_data_1_short = in_data_1 + diff_type_offset(diff_type_1);
+ }
+ if (in_data_2 != NULL) {
+ in_data_2_short = in_data_2 + diff_type_offset(diff_type_2);
+ }
+
+ lav_fp[0] = lav_fp[1] = 0;
+
+ p0_data_1[0] = NULL;
+ p0_data_1[1] = NULL;
+ p0_data_2[0] = NULL;
+ p0_data_2[1] = NULL;
+
+ if (in_data_1 != NULL) {
+ if (diff_type_1 == DIFF_FREQ) {
+ p0_data_1[0] = &in_data_1[0];
+ p0_data_1[1] = NULL;
+
+ num_val_1_short -= 1;
+ in_data_1_short += 1;
+ }
+
+ df_rest_flag[0] = num_val_1_short % 2;
+
+ if (df_rest_flag[0]) num_val_1_short -= 1;
+
+ for (i = 0; i < num_val_1_short - 1; i += 2) {
+ pair_vec[i][0] = in_data_1_short[i];
+ pair_vec[i][1] = in_data_1_short[i + 1];
+
+ lav_fp[0] = FDKmax(lav_fp[0], fAbs(pair_vec[i][0]));
+ lav_fp[0] = FDKmax(lav_fp[0], fAbs(pair_vec[i][1]));
+ }
+
+ tab_idx_2D[0][0] = (diff_type_1 == DIFF_TIME) ? 1 : 0;
+ tab_idx_2D[0][1] = 0;
+
+ tab_idx_1D[0] = (diff_type_1 == DIFF_FREQ) ? 0 : 1;
+
+ lav_fp[0] = get_next_lav_step(lav_fp[0], data_type);
+
+ if (lav_fp[0] != -1) bit_count_2D_freq += lavHuffLen[lav_fp[0]];
+ }
+
+ if (in_data_2 != NULL) {
+ if (diff_type_2 == DIFF_FREQ) {
+ p0_data_2[0] = NULL;
+ p0_data_2[1] = &in_data_2[0];
+
+ num_val_2_short -= 1;
+ in_data_2_short += 1;
+ }
+
+ df_rest_flag[1] = num_val_2_short % 2;
+
+ if (df_rest_flag[1]) num_val_2_short -= 1;
+
+ for (i = 0; i < num_val_2_short - 1; i += 2) {
+ pair_vec[i + 1][0] = in_data_2_short[i];
+ pair_vec[i + 1][1] = in_data_2_short[i + 1];
+
+ lav_fp[1] = FDKmax(lav_fp[1], fAbs(pair_vec[i + 1][0]));
+ lav_fp[1] = FDKmax(lav_fp[1], fAbs(pair_vec[i + 1][1]));
+ }
+
+ tab_idx_2D[1][0] = (diff_type_2 == DIFF_TIME) ? 1 : 0;
+ tab_idx_2D[1][1] = 0;
+
+ tab_idx_1D[1] = (diff_type_2 == DIFF_FREQ) ? 0 : 1;
+
+ lav_fp[1] = get_next_lav_step(lav_fp[1], data_type);
+
+ if (lav_fp[1] != -1) bit_count_2D_freq += lavHuffLen[lav_fp[1]];
+ }
+
+ if ((lav_fp[0] != -1) && (lav_fp[1] != -1)) {
+ if (in_data_1 != NULL) {
+ bit_count_2D_freq +=
+ huff_enc_2D(NULL, data_type, tab_idx_2D[0], lav_fp[0], pair_vec,
+ num_val_1_short, 2, p0_data_1);
+ }
+ if (in_data_2 != NULL) {
+ bit_count_2D_freq +=
+ huff_enc_2D(NULL, data_type, tab_idx_2D[1], lav_fp[1], pair_vec + 1,
+ num_val_2_short, 2, p0_data_2);
+ }
+ if (in_data_1 != NULL) {
+ if (df_rest_flag[0])
+ bit_count_2D_freq +=
+ huff_enc_1D(NULL, data_type, tab_idx_1D[0],
+ in_data_1_short + num_val_1_short, 1, 0);
+ }
+ if (in_data_2 != NULL) {
+ if (df_rest_flag[1])
+ bit_count_2D_freq +=
+ huff_enc_1D(NULL, data_type, tab_idx_1D[1],
+ in_data_2_short + num_val_2_short, 1, 0);
+ }
+
+ if (bit_count_2D_freq < bit_count_min) {
+ bit_count_min = bit_count_2D_freq;
+ *cdg_scheme = HUFF_2D << PAIR_SHIFT | FREQ_PAIR;
+ lav_idx[0] = lav_fp[0];
+ lav_idx[1] = lav_fp[1];
+ }
+ }
+
+ return bit_count_min;
+}
+
+static void apply_huff_coding(HANDLE_FDK_BITSTREAM strm, SHORT *const in_data_1,
+ SHORT *const in_data_2, const DATA_TYPE data_type,
+ const DIFF_TYPE diff_type_1,
+ const DIFF_TYPE diff_type_2, const SHORT num_val,
+ const SHORT *const lav_idx,
+ const SHORT cdg_scheme) {
+ SHORT tab_idx_2D[2][2] = {{0}};
+ SHORT tab_idx_1D[2] = {0};
+ SHORT df_rest_flag[2] = {0};
+ SHORT p0_flag[2] = {0};
+
+ SHORT pair_vec[MAXBANDS][2] = {{0}};
+
+ SHORT *p0_data_1[2] = {NULL};
+ SHORT *p0_data_2[2] = {NULL};
+
+ SHORT i = 0;
+
+ SHORT num_val_1_short = num_val;
+ SHORT num_val_2_short = num_val;
+
+ SHORT *in_data_1_short = NULL;
+ SHORT *in_data_2_short = NULL;
+
+ /* Offset */
+ if (in_data_1 != NULL) {
+ in_data_1_short = in_data_1 + diff_type_offset(diff_type_1);
+ }
+ if (in_data_2 != NULL) {
+ in_data_2_short = in_data_2 + diff_type_offset(diff_type_2);
+ }
+
+ /* Signalize coding scheme */
+ FDKwriteBits(strm, cdg_scheme >> PAIR_SHIFT, 1);
+
+ switch (cdg_scheme >> PAIR_SHIFT) {
+ case HUFF_1D:
+
+ p0_flag[0] = (diff_type_1 == DIFF_FREQ);
+ p0_flag[1] = (diff_type_2 == DIFF_FREQ);
+
+ tab_idx_1D[0] = (diff_type_1 == DIFF_FREQ) ? 0 : 1;
+ tab_idx_1D[1] = (diff_type_2 == DIFF_FREQ) ? 0 : 1;
+
+ if (in_data_1 != NULL) {
+ huff_enc_1D(strm, data_type, tab_idx_1D[0], in_data_1_short,
+ num_val_1_short, p0_flag[0]);
+ }
+ if (in_data_2 != NULL) {
+ huff_enc_1D(strm, data_type, tab_idx_1D[1], in_data_2_short,
+ num_val_2_short, p0_flag[1]);
+ }
+ break; /* HUFF_1D */
+
+ case HUFF_2D:
+
+ switch (cdg_scheme & PAIR_MASK) {
+ case FREQ_PAIR:
+
+ if (in_data_1 != NULL) {
+ if (diff_type_1 == DIFF_FREQ) {
+ p0_data_1[0] = &in_data_1[0];
+ p0_data_1[1] = NULL;
+
+ num_val_1_short -= 1;
+ in_data_1_short += 1;
+ }
+
+ df_rest_flag[0] = num_val_1_short % 2;
+
+ if (df_rest_flag[0]) num_val_1_short -= 1;
+
+ for (i = 0; i < num_val_1_short - 1; i += 2) {
+ pair_vec[i][0] = in_data_1_short[i];
+ pair_vec[i][1] = in_data_1_short[i + 1];
+ }
+
+ tab_idx_2D[0][0] = (diff_type_1 == DIFF_TIME) ? 1 : 0;
+ tab_idx_2D[0][1] = 0;
+
+ tab_idx_1D[0] = (diff_type_1 == DIFF_FREQ) ? 0 : 1;
+ } /* if( in_data_1 != NULL ) */
+
+ if (in_data_2 != NULL) {
+ if (diff_type_2 == DIFF_FREQ) {
+ p0_data_2[0] = NULL;
+ p0_data_2[1] = &in_data_2[0];
+
+ num_val_2_short -= 1;
+ in_data_2_short += 1;
+ }
+
+ df_rest_flag[1] = num_val_2_short % 2;
+
+ if (df_rest_flag[1]) num_val_2_short -= 1;
+
+ for (i = 0; i < num_val_2_short - 1; i += 2) {
+ pair_vec[i + 1][0] = in_data_2_short[i];
+ pair_vec[i + 1][1] = in_data_2_short[i + 1];
+ }
+
+ tab_idx_2D[1][0] = (diff_type_2 == DIFF_TIME) ? 1 : 0;
+ tab_idx_2D[1][1] = 0;
+
+ tab_idx_1D[1] = (diff_type_2 == DIFF_FREQ) ? 0 : 1;
+ } /* if( in_data_2 != NULL ) */
+
+ if (in_data_1 != NULL) {
+ FDKwriteBits(strm, lavHuffVal[lav_idx[0]], lavHuffLen[lav_idx[0]]);
+ huff_enc_2D(strm, data_type, tab_idx_2D[0], lav_idx[0], pair_vec,
+ num_val_1_short, 2, p0_data_1);
+ if (df_rest_flag[0]) {
+ huff_enc_1D(strm, data_type, tab_idx_1D[0],
+ in_data_1_short + num_val_1_short, 1, 0);
+ }
+ }
+ if (in_data_2 != NULL) {
+ FDKwriteBits(strm, lavHuffVal[lav_idx[1]], lavHuffLen[lav_idx[1]]);
+ huff_enc_2D(strm, data_type, tab_idx_2D[1], lav_idx[1],
+ pair_vec + 1, num_val_2_short, 2, p0_data_2);
+ if (df_rest_flag[1]) {
+ huff_enc_1D(strm, data_type, tab_idx_1D[1],
+ in_data_2_short + num_val_2_short, 1, 0);
+ }
+ }
+ break; /* FREQ_PAIR */
+
+ case TIME_PAIR:
+
+ if ((diff_type_1 == DIFF_FREQ) || (diff_type_2 == DIFF_FREQ)) {
+ p0_data_1[0] = &in_data_1[0];
+ p0_data_1[1] = &in_data_2[0];
+
+ in_data_1_short += 1;
+ in_data_2_short += 1;
+
+ num_val_1_short -= 1;
+ }
+
+ for (i = 0; i < num_val_1_short; i++) {
+ pair_vec[i][0] = in_data_1_short[i];
+ pair_vec[i][1] = in_data_2_short[i];
+ }
+
+ tab_idx_2D[0][0] =
+ ((diff_type_1 == DIFF_TIME) || (diff_type_2 == DIFF_TIME)) ? 1
+ : 0;
+ tab_idx_2D[0][1] = 1;
+
+ FDKwriteBits(strm, lavHuffVal[lav_idx[0]], lavHuffLen[lav_idx[0]]);
+
+ huff_enc_2D(strm, data_type, tab_idx_2D[0], lav_idx[0], pair_vec,
+ num_val_1_short, 1, p0_data_1);
+
+ break; /* TIME_PAIR */
+ } /* switch( cdg_scheme & PAIR_MASK ) */
+
+ break; /* HUFF_2D */
+
+ default:
+ break;
+ } /* switch( cdg_scheme >> PAIR_SHIFT ) */
+}
+
+INT fdk_sacenc_ecDataPairEnc(HANDLE_FDK_BITSTREAM strm,
+ SHORT aaInData[][MAXBANDS],
+ SHORT aHistory[MAXBANDS],
+ const DATA_TYPE data_type, const INT setIdx,
+ const INT startBand, const INT dataBands,
+ const INT coarse_flag,
+ const INT independency_flag) {
+ SHORT reset = 0, pb = 0;
+ SHORT quant_levels = 0, quant_offset = 0, num_pcm_val = 0;
+
+ SHORT splitLsb_flag = 0;
+ SHORT pcmCoding_flag = 0;
+
+ SHORT allowDiffTimeBack_flag = !independency_flag || (setIdx > 0);
+
+ SHORT num_lsb_bits = -1;
+ SHORT num_pcm_bits = -1;
+
+ SHORT quant_data_lsb[2][MAXBANDS];
+ SHORT quant_data_msb[2][MAXBANDS];
+
+ SHORT quant_data_hist_lsb[MAXBANDS];
+ SHORT quant_data_hist_msb[MAXBANDS];
+
+ SHORT data_diff_freq[2][MAXBANDS];
+ SHORT data_diff_time[2][MAXBANDS + 2];
+
+ SHORT *p_quant_data_msb[2];
+ SHORT *p_quant_data_hist_msb = NULL;
+
+ SHORT min_bits_all = 0;
+ SHORT min_found = 0;
+
+ SHORT min_bits_df_df = -1;
+ SHORT min_bits_df_dt = -1;
+ SHORT min_bits_dtbw_df = -1;
+ SHORT min_bits_dt_dt = -1;
+
+ SHORT lav_df_df[2] = {-1, -1};
+ SHORT lav_df_dt[2] = {-1, -1};
+ SHORT lav_dtbw_df[2] = {-1, -1};
+ SHORT lav_dt_dt[2] = {-1, -1};
+
+ SHORT coding_scheme_df_df = 0;
+ SHORT coding_scheme_df_dt = 0;
+ SHORT coding_scheme_dtbw_df = 0;
+ SHORT coding_scheme_dt_dt = 0;
+
+ switch (data_type) {
+ case t_CLD:
+ if (coarse_flag) {
+ splitLsb_flag = 0;
+ quant_levels = 15;
+ quant_offset = 7;
+ } else {
+ splitLsb_flag = 0;
+ quant_levels = 31;
+ quant_offset = 15;
+ }
+ break;
+ case t_ICC:
+ if (coarse_flag) {
+ splitLsb_flag = 0;
+ quant_levels = 4;
+ quant_offset = 0;
+ } else {
+ splitLsb_flag = 0;
+ quant_levels = 8;
+ quant_offset = 0;
+ }
+ break;
+ } /* switch( data_type ) */
+
+ /* Split off LSB */
+ if (splitLsb_flag) {
+ split_lsb(aaInData[setIdx] + startBand, quant_offset, dataBands,
+ quant_data_lsb[0], quant_data_msb[0]);
+
+ split_lsb(aaInData[setIdx + 1] + startBand, quant_offset, dataBands,
+ quant_data_lsb[1], quant_data_msb[1]);
+
+ p_quant_data_msb[0] = quant_data_msb[0];
+ p_quant_data_msb[1] = quant_data_msb[1];
+
+ num_lsb_bits = 2 * dataBands;
+ } else if (quant_offset != 0) {
+ for (pb = 0; pb < dataBands; pb++) {
+ quant_data_msb[0][pb] = aaInData[setIdx][startBand + pb] + quant_offset;
+ quant_data_msb[1][pb] =
+ aaInData[setIdx + 1][startBand + pb] + quant_offset;
+ }
+
+ p_quant_data_msb[0] = quant_data_msb[0];
+ p_quant_data_msb[1] = quant_data_msb[1];
+
+ num_lsb_bits = 0;
+ } else {
+ p_quant_data_msb[0] = aaInData[setIdx] + startBand;
+ p_quant_data_msb[1] = aaInData[setIdx + 1] + startBand;
+
+ num_lsb_bits = 0;
+ }
+
+ if (allowDiffTimeBack_flag) {
+ if (splitLsb_flag) {
+ split_lsb(aHistory + startBand, quant_offset, dataBands,
+ quant_data_hist_lsb, quant_data_hist_msb);
+
+ p_quant_data_hist_msb = quant_data_hist_msb;
+ } else if (quant_offset != 0) {
+ for (pb = 0; pb < dataBands; pb++) {
+ quant_data_hist_msb[pb] = aHistory[startBand + pb] + quant_offset;
+ }
+ p_quant_data_hist_msb = quant_data_hist_msb;
+ } else {
+ p_quant_data_hist_msb = aHistory + startBand;
+ }
+ }
+
+ /* Calculate frequency differences */
+ calc_diff_freq(p_quant_data_msb[0], data_diff_freq[0], dataBands);
+
+ calc_diff_freq(p_quant_data_msb[1], data_diff_freq[1], dataBands);
+
+ /* Calculate time differences */
+ if (allowDiffTimeBack_flag) {
+ calc_diff_time(p_quant_data_msb[0], p_quant_data_hist_msb,
+ data_diff_time[0], dataBands);
+ }
+
+ calc_diff_time(p_quant_data_msb[1], p_quant_data_msb[0], data_diff_time[1],
+ dataBands);
+
+ /* Calculate coding scheme with minumum bit consumption */
+
+ /**********************************************************/
+ num_pcm_bits = calc_pcm_bits(2 * dataBands, quant_levels);
+ num_pcm_val = 2 * dataBands;
+
+ /**********************************************************/
+
+ min_bits_all = num_pcm_bits;
+
+ /**********************************************************/
+ /**********************************************************/
+
+ /**********************************************************/
+ min_bits_df_df =
+ calc_huff_bits(data_diff_freq[0], data_diff_freq[1], data_type, DIFF_FREQ,
+ DIFF_FREQ, dataBands, lav_df_df, &coding_scheme_df_df);
+
+ min_bits_df_df += 2;
+
+ min_bits_df_df += num_lsb_bits;
+
+ if (min_bits_df_df < min_bits_all) {
+ min_bits_all = min_bits_df_df;
+ }
+ /**********************************************************/
+
+ /**********************************************************/
+ min_bits_df_dt =
+ calc_huff_bits(data_diff_freq[0], data_diff_time[1], data_type, DIFF_FREQ,
+ DIFF_TIME, dataBands, lav_df_dt, &coding_scheme_df_dt);
+
+ min_bits_df_dt += 2;
+
+ min_bits_df_dt += num_lsb_bits;
+
+ if (min_bits_df_dt < min_bits_all) {
+ min_bits_all = min_bits_df_dt;
+ }
+ /**********************************************************/
+
+ /**********************************************************/
+ /**********************************************************/
+
+ if (allowDiffTimeBack_flag) {
+ /**********************************************************/
+ min_bits_dtbw_df = calc_huff_bits(
+ data_diff_time[0], data_diff_freq[1], data_type, DIFF_TIME, DIFF_FREQ,
+ dataBands, lav_dtbw_df, &coding_scheme_dtbw_df);
+
+ min_bits_dtbw_df += 2;
+
+ min_bits_dtbw_df += num_lsb_bits;
+
+ if (min_bits_dtbw_df < min_bits_all) {
+ min_bits_all = min_bits_dtbw_df;
+ }
+ /**********************************************************/
+
+ /**********************************************************/
+ min_bits_dt_dt = calc_huff_bits(data_diff_time[0], data_diff_time[1],
+ data_type, DIFF_TIME, DIFF_TIME, dataBands,
+ lav_dt_dt, &coding_scheme_dt_dt);
+
+ min_bits_dt_dt += 2;
+
+ min_bits_dt_dt += num_lsb_bits;
+
+ if (min_bits_dt_dt < min_bits_all) {
+ min_bits_all = min_bits_dt_dt;
+ }
+ /**********************************************************/
+
+ } /* if( allowDiffTimeBack_flag ) */
+
+ /***************************/
+ /* Start actual coding now */
+ /***************************/
+
+ /* PCM or Diff/Huff Coding? */
+ pcmCoding_flag = (min_bits_all == num_pcm_bits);
+
+ FDKwriteBits(strm, pcmCoding_flag, 1);
+
+ if (pcmCoding_flag) {
+ /* Grouped PCM Coding */
+ apply_pcm_coding(strm, aaInData[setIdx] + startBand,
+ aaInData[setIdx + 1] + startBand, quant_offset,
+ num_pcm_val, quant_levels);
+ } else {
+ /* Diff/Huff Coding */
+
+ min_found = 0;
+
+ /*******************************************/
+ if (min_bits_all == min_bits_df_df) {
+ FDKwriteBits(strm, DIFF_FREQ, 1);
+ FDKwriteBits(strm, DIFF_FREQ, 1);
+
+ apply_huff_coding(strm, data_diff_freq[0], data_diff_freq[1], data_type,
+ DIFF_FREQ, DIFF_FREQ, dataBands, lav_df_df,
+ coding_scheme_df_df);
+
+ min_found = 1;
+ }
+ /*******************************************/
+
+ /*******************************************/
+ if (!min_found && (min_bits_all == min_bits_df_dt)) {
+ FDKwriteBits(strm, DIFF_FREQ, 1);
+ FDKwriteBits(strm, DIFF_TIME, 1);
+
+ apply_huff_coding(strm, data_diff_freq[0], data_diff_time[1], data_type,
+ DIFF_FREQ, DIFF_TIME, dataBands, lav_df_dt,
+ coding_scheme_df_dt);
+
+ min_found = 1;
+ }
+ /*******************************************/
+
+ /*******************************************/
+ /*******************************************/
+
+ if (allowDiffTimeBack_flag) {
+ /*******************************************/
+ if (!min_found && (min_bits_all == min_bits_dtbw_df)) {
+ FDKwriteBits(strm, DIFF_TIME, 1);
+ FDKwriteBits(strm, DIFF_FREQ, 1);
+
+ apply_huff_coding(strm, data_diff_time[0], data_diff_freq[1], data_type,
+ DIFF_TIME, DIFF_FREQ, dataBands, lav_dtbw_df,
+ coding_scheme_dtbw_df);
+
+ min_found = 1;
+ }
+ /*******************************************/
+
+ /*******************************************/
+ if (!min_found && (min_bits_all == min_bits_dt_dt)) {
+ FDKwriteBits(strm, DIFF_TIME, 1);
+ FDKwriteBits(strm, DIFF_TIME, 1);
+
+ apply_huff_coding(strm, data_diff_time[0], data_diff_time[1], data_type,
+ DIFF_TIME, DIFF_TIME, dataBands, lav_dt_dt,
+ coding_scheme_dt_dt);
+ }
+ /*******************************************/
+
+ } /* if( allowDiffTimeBack_flag ) */
+
+ /* LSB coding */
+ if (splitLsb_flag) {
+ apply_lsb_coding(strm, quant_data_lsb[0], 1, dataBands);
+
+ apply_lsb_coding(strm, quant_data_lsb[1], 1, dataBands);
+ }
+
+ } /* Diff/Huff/LSB coding */
+
+ return reset;
+}
+
+INT fdk_sacenc_ecDataSingleEnc(HANDLE_FDK_BITSTREAM strm,
+ SHORT aaInData[][MAXBANDS],
+ SHORT aHistory[MAXBANDS],
+ const DATA_TYPE data_type, const INT setIdx,
+ const INT startBand, const INT dataBands,
+ const INT coarse_flag,
+ const INT independency_flag) {
+ SHORT reset = 0, pb = 0;
+ SHORT quant_levels = 0, quant_offset = 0, num_pcm_val = 0;
+
+ SHORT splitLsb_flag = 0;
+ SHORT pcmCoding_flag = 0;
+
+ SHORT allowDiffTimeBack_flag = !independency_flag || (setIdx > 0);
+
+ SHORT num_lsb_bits = -1;
+ SHORT num_pcm_bits = -1;
+
+ SHORT quant_data_lsb[MAXBANDS];
+ SHORT quant_data_msb[MAXBANDS];
+
+ SHORT quant_data_hist_lsb[MAXBANDS];
+ SHORT quant_data_hist_msb[MAXBANDS];
+
+ SHORT data_diff_freq[MAXBANDS];
+ SHORT data_diff_time[MAXBANDS + 2];
+
+ SHORT *p_quant_data_msb;
+ SHORT *p_quant_data_hist_msb = NULL;
+
+ SHORT min_bits_all = 0;
+ SHORT min_found = 0;
+
+ SHORT min_bits_df = -1;
+ SHORT min_bits_dt = -1;
+
+ SHORT lav_df[2] = {-1, -1};
+ SHORT lav_dt[2] = {-1, -1};
+
+ SHORT coding_scheme_df = 0;
+ SHORT coding_scheme_dt = 0;
+
+ switch (data_type) {
+ case t_CLD:
+ if (coarse_flag) {
+ splitLsb_flag = 0;
+ quant_levels = 15;
+ quant_offset = 7;
+ } else {
+ splitLsb_flag = 0;
+ quant_levels = 31;
+ quant_offset = 15;
+ }
+ break;
+ case t_ICC:
+ if (coarse_flag) {
+ splitLsb_flag = 0;
+ quant_levels = 4;
+ quant_offset = 0;
+ } else {
+ splitLsb_flag = 0;
+ quant_levels = 8;
+ quant_offset = 0;
+ }
+ break;
+ } /* switch( data_type ) */
+
+ /* Split off LSB */
+ if (splitLsb_flag) {
+ split_lsb(aaInData[setIdx] + startBand, quant_offset, dataBands,
+ quant_data_lsb, quant_data_msb);
+
+ p_quant_data_msb = quant_data_msb;
+ num_lsb_bits = dataBands;
+ } else if (quant_offset != 0) {
+ for (pb = 0; pb < dataBands; pb++) {
+ quant_data_msb[pb] = aaInData[setIdx][startBand + pb] + quant_offset;
+ }
+
+ p_quant_data_msb = quant_data_msb;
+ num_lsb_bits = 0;
+ } else {
+ p_quant_data_msb = aaInData[setIdx] + startBand;
+ num_lsb_bits = 0;
+ }
+
+ if (allowDiffTimeBack_flag) {
+ if (splitLsb_flag) {
+ split_lsb(aHistory + startBand, quant_offset, dataBands,
+ quant_data_hist_lsb, quant_data_hist_msb);
+
+ p_quant_data_hist_msb = quant_data_hist_msb;
+ } else if (quant_offset != 0) {
+ for (pb = 0; pb < dataBands; pb++) {
+ quant_data_hist_msb[pb] = aHistory[startBand + pb] + quant_offset;
+ }
+ p_quant_data_hist_msb = quant_data_hist_msb;
+ } else {
+ p_quant_data_hist_msb = aHistory + startBand;
+ }
+ }
+
+ /* Calculate frequency differences */
+ calc_diff_freq(p_quant_data_msb, data_diff_freq, dataBands);
+
+ /* Calculate time differences */
+ if (allowDiffTimeBack_flag) {
+ calc_diff_time(p_quant_data_msb, p_quant_data_hist_msb, data_diff_time,
+ dataBands);
+ }
+
+ /* Calculate coding scheme with minumum bit consumption */
+
+ /**********************************************************/
+ num_pcm_bits = calc_pcm_bits(dataBands, quant_levels);
+ num_pcm_val = dataBands;
+
+ /**********************************************************/
+
+ min_bits_all = num_pcm_bits;
+
+ /**********************************************************/
+ /**********************************************************/
+
+ /**********************************************************/
+ min_bits_df = calc_huff_bits(data_diff_freq, NULL, data_type, DIFF_FREQ,
+ DIFF_FREQ, dataBands, lav_df, &coding_scheme_df);
+
+ if (allowDiffTimeBack_flag) min_bits_df += 1;
+
+ min_bits_df += num_lsb_bits;
+
+ if (min_bits_df < min_bits_all) {
+ min_bits_all = min_bits_df;
+ }
+ /**********************************************************/
+
+ /**********************************************************/
+ if (allowDiffTimeBack_flag) {
+ min_bits_dt =
+ calc_huff_bits(data_diff_time, NULL, data_type, DIFF_TIME, DIFF_TIME,
+ dataBands, lav_dt, &coding_scheme_dt);
+
+ min_bits_dt += 1;
+ min_bits_dt += num_lsb_bits;
+
+ if (min_bits_dt < min_bits_all) {
+ min_bits_all = min_bits_dt;
+ }
+ } /* if( allowDiffTimeBack_flag ) */
+
+ /***************************/
+ /* Start actual coding now */
+ /***************************/
+
+ /* PCM or Diff/Huff Coding? */
+ pcmCoding_flag = (min_bits_all == num_pcm_bits);
+
+ FDKwriteBits(strm, pcmCoding_flag, 1);
+
+ if (pcmCoding_flag) {
+ /* Grouped PCM Coding */
+ apply_pcm_coding(strm, aaInData[setIdx] + startBand, NULL, quant_offset,
+ num_pcm_val, quant_levels);
+ } else {
+ /* Diff/Huff Coding */
+
+ min_found = 0;
+
+ /*******************************************/
+ if (min_bits_all == min_bits_df) {
+ if (allowDiffTimeBack_flag) {
+ FDKwriteBits(strm, DIFF_FREQ, 1);
+ }
+
+ apply_huff_coding(strm, data_diff_freq, NULL, data_type, DIFF_FREQ,
+ DIFF_FREQ, dataBands, lav_df, coding_scheme_df);
+
+ min_found = 1;
+ } /* if( min_bits_all == min_bits_df ) */
+ /*******************************************/
+
+ /*******************************************/
+ if (allowDiffTimeBack_flag) {
+ /*******************************************/
+ if (!min_found && (min_bits_all == min_bits_dt)) {
+ FDKwriteBits(strm, DIFF_TIME, 1);
+
+ apply_huff_coding(strm, data_diff_time, NULL, data_type, DIFF_TIME,
+ DIFF_TIME, dataBands, lav_dt, coding_scheme_dt);
+ }
+ /*******************************************/
+
+ } /* if( allowDiffTimeBack_flag ) */
+
+ /* LSB coding */
+ if (splitLsb_flag) {
+ apply_lsb_coding(strm, quant_data_lsb, 1, dataBands);
+ }
+
+ } /* Diff/Huff/LSB coding */
+
+ return reset;
+}
diff --git a/libSACenc/src/sacenc_nlc_enc.h b/libSACenc/src/sacenc_nlc_enc.h
new file mode 100644
index 0000000..506b308
--- /dev/null
+++ b/libSACenc/src/sacenc_nlc_enc.h
@@ -0,0 +1,141 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): Karsten Linzmeier
+
+ Description: Noiseless Coding
+ Huffman encoder
+
+*******************************************************************************/
+
+#ifndef SACENC_NLC_ENC_H
+#define SACENC_NLC_ENC_H
+
+/* Includes ******************************************************************/
+#include "sacenc_const.h"
+#include "FDK_bitstream.h"
+#include "sacenc_bitstream.h"
+
+/* Defines *******************************************************************/
+#define MAXBANDS MAX_NUM_BINS /* maximum number of frequency bands */
+
+/* Data Types ****************************************************************/
+typedef enum {
+ t_CLD,
+ t_ICC
+
+} DATA_TYPE;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+INT fdk_sacenc_ecDataPairEnc(HANDLE_FDK_BITSTREAM strm,
+ SHORT aaInData[][MAXBANDS],
+ SHORT aHistory[MAXBANDS],
+ const DATA_TYPE data_type, const INT setIdx,
+ const INT startBand, const INT dataBands,
+ const INT coarse_flag,
+ const INT independency_flag);
+
+INT fdk_sacenc_ecDataSingleEnc(HANDLE_FDK_BITSTREAM strm,
+ SHORT aaInData[][MAXBANDS],
+ SHORT aHistory[MAXBANDS],
+ const DATA_TYPE data_type, const INT setIdx,
+ const INT startBand, const INT dataBands,
+ const INT coarse_flag,
+ const INT independency_flag);
+
+#endif /* SACENC_NLC_ENC_H */
diff --git a/libSACenc/src/sacenc_onsetdetect.cpp b/libSACenc/src/sacenc_onsetdetect.cpp
new file mode 100644
index 0000000..7e9aee1
--- /dev/null
+++ b/libSACenc/src/sacenc_onsetdetect.cpp
@@ -0,0 +1,381 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): Max Neuendorf
+
+ Description: Encoder Library Interface
+ Detect Onset in current frame
+
+*******************************************************************************/
+
+/**************************************************************************/ /**
+ \file
+ Description of file contents
+ ******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_onsetdetect.h"
+#include "genericStds.h"
+#include "sacenc_vectorfunctions.h"
+
+/* Defines *******************************************************************/
+#define SPACE_ONSET_THRESHOLD (3.0)
+#define SPACE_ONSET_THRESHOLD_SF (3)
+#define SPACE_ONSET_THRESHOLD_SQUARE \
+ (FL2FXCONST_DBL((1.0 / (SPACE_ONSET_THRESHOLD * SPACE_ONSET_THRESHOLD)) * \
+ (float)(1 << SPACE_ONSET_THRESHOLD_SF)))
+
+/* Data Types ****************************************************************/
+struct ONSET_DETECT {
+ INT maxTimeSlots;
+ INT minTransientDistance;
+ INT avgEnergyDistance;
+ INT lowerBoundOnsetDetection;
+ INT upperBoundOnsetDetection;
+ FIXP_DBL *pEnergyHist__FDK;
+ SCHAR *pEnergyHistScale;
+ SCHAR avgEnergyDistanceScale;
+};
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+FDK_SACENC_ERROR fdk_sacenc_onsetDetect_Open(HANDLE_ONSET_DETECT *phOnset,
+ const UINT maxTimeSlots) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+ HANDLE_ONSET_DETECT hOnset = NULL;
+
+ if (NULL == phOnset) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ /* Memory Allocation */
+ FDK_ALLOCATE_MEMORY_1D(hOnset, 1, struct ONSET_DETECT);
+ FDK_ALLOCATE_MEMORY_1D(hOnset->pEnergyHist__FDK, 16 + maxTimeSlots,
+ FIXP_DBL);
+ FDK_ALLOCATE_MEMORY_1D(hOnset->pEnergyHistScale, 16 + maxTimeSlots, SCHAR);
+
+ hOnset->maxTimeSlots = maxTimeSlots;
+ hOnset->minTransientDistance =
+ 8; /* minimum distance between detected transients */
+ hOnset->avgEnergyDistance = 16; /* average energy distance */
+
+ hOnset->avgEnergyDistanceScale = 4;
+ *phOnset = hOnset;
+ }
+ return error;
+
+bail:
+ fdk_sacenc_onsetDetect_Close(&hOnset);
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+FDK_SACENC_ERROR fdk_sacenc_onsetDetect_Init(
+ HANDLE_ONSET_DETECT hOnset,
+ const ONSET_DETECT_CONFIG *const pOnsetDetectConfig, const UINT initFlags) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((NULL == hOnset) || (pOnsetDetectConfig == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ if ((pOnsetDetectConfig->maxTimeSlots > hOnset->maxTimeSlots) ||
+ (pOnsetDetectConfig->upperBoundOnsetDetection <
+ hOnset->lowerBoundOnsetDetection)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ hOnset->maxTimeSlots = pOnsetDetectConfig->maxTimeSlots;
+ hOnset->lowerBoundOnsetDetection =
+ pOnsetDetectConfig->lowerBoundOnsetDetection;
+ hOnset->upperBoundOnsetDetection =
+ pOnsetDetectConfig->upperBoundOnsetDetection;
+
+ hOnset->minTransientDistance =
+ 8; /* minimum distance between detected transients */
+ hOnset->avgEnergyDistance = 16; /* average energy distance */
+
+ hOnset->avgEnergyDistanceScale = 4;
+
+ /* Init / Reset */
+ if (initFlags) {
+ int i;
+ for (i = 0; i < hOnset->avgEnergyDistance + hOnset->maxTimeSlots; i++)
+ hOnset->pEnergyHistScale[i] = -(DFRACT_BITS - 3);
+
+ FDKmemset_flex(
+ hOnset->pEnergyHist__FDK,
+ FL2FXCONST_DBL(SACENC_FLOAT_EPSILON * (1 << (DFRACT_BITS - 3))),
+ hOnset->avgEnergyDistance + hOnset->maxTimeSlots);
+ }
+ }
+
+bail:
+ return error;
+}
+
+/**************************************************************************/
+
+FDK_SACENC_ERROR fdk_sacenc_onsetDetect_Close(HANDLE_ONSET_DETECT *phOnset) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((NULL != phOnset) && (NULL != *phOnset)) {
+ if (NULL != (*phOnset)->pEnergyHist__FDK) {
+ FDKfree((*phOnset)->pEnergyHist__FDK);
+ }
+ (*phOnset)->pEnergyHist__FDK = NULL;
+
+ if (NULL != (*phOnset)->pEnergyHistScale) {
+ FDKfree((*phOnset)->pEnergyHistScale);
+ }
+ (*phOnset)->pEnergyHistScale = NULL;
+ FDKfree(*phOnset);
+ *phOnset = NULL;
+ }
+ return error;
+}
+
+/**************************************************************************/
+
+FDK_SACENC_ERROR fdk_sacenc_onsetDetect_Update(HANDLE_ONSET_DETECT hOnset,
+ const INT timeSlots) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == hOnset) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ if (timeSlots > hOnset->maxTimeSlots) {
+ error = SACENC_INVALID_CONFIG;
+ } else {
+ int i;
+ /* Shift old data */
+ for (i = 0; i < hOnset->avgEnergyDistance; i++) {
+ hOnset->pEnergyHist__FDK[i] = hOnset->pEnergyHist__FDK[i + timeSlots];
+ hOnset->pEnergyHistScale[i] = hOnset->pEnergyHistScale[i + timeSlots];
+ }
+
+ /* Clear for new data */
+ FDKmemset_flex(&hOnset->pEnergyHist__FDK[hOnset->avgEnergyDistance],
+ FL2FXCONST_DBL(SACENC_FLOAT_EPSILON), timeSlots);
+ }
+ }
+ return error;
+}
+
+/**************************************************************************/
+
+FDK_SACENC_ERROR fdk_sacenc_onsetDetect_Apply(
+ HANDLE_ONSET_DETECT hOnset, const INT nTimeSlots, const INT nHybridBands,
+ FIXP_DPK *const *const ppHybridData__FDK, const INT hybridDataScale,
+ const INT prevPos, INT pTransientPos[MAX_NUM_TRANS]) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ C_ALLOC_SCRATCH_START(envs, FIXP_DBL, (16 + MAX_TIME_SLOTS))
+ FDKmemclear(envs, (16 + MAX_TIME_SLOTS) * sizeof(FIXP_DBL));
+
+ if ((hOnset == NULL) || (pTransientPos == NULL) ||
+ (ppHybridData__FDK == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int i, ts, trCnt, currPos;
+
+ if ((nTimeSlots < 0) || (nTimeSlots > hOnset->maxTimeSlots) ||
+ (hOnset->lowerBoundOnsetDetection < -1) ||
+ (hOnset->upperBoundOnsetDetection > nHybridBands)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ const int lowerBoundOnsetDetection = hOnset->lowerBoundOnsetDetection;
+ const int upperBoundOnsetDetection = hOnset->upperBoundOnsetDetection;
+ const int M = hOnset->avgEnergyDistance;
+
+ {
+ SCHAR *envScale = hOnset->pEnergyHistScale;
+ FIXP_DBL *env = hOnset->pEnergyHist__FDK;
+ const FIXP_DBL threshold_square = SPACE_ONSET_THRESHOLD_SQUARE;
+
+ trCnt = 0;
+
+ /* reset transient array */
+ FDKmemset_flex(pTransientPos, -1, MAX_NUM_TRANS);
+
+ /* minimum transient distance of minTransDist QMF samples */
+ if (prevPos > 0) {
+ currPos = FDKmax(nTimeSlots,
+ prevPos - nTimeSlots + hOnset->minTransientDistance);
+ } else {
+ currPos = nTimeSlots;
+ }
+
+ /* get energy and scalefactor for each time slot */
+ int outScale;
+ int inScale = 3; /* scale factor determined empirically */
+ for (ts = 0; ts < nTimeSlots; ts++) {
+ env[M + ts] = sumUpCplxPow2(
+ &ppHybridData__FDK[ts][lowerBoundOnsetDetection + 1],
+ SUM_UP_DYNAMIC_SCALE, inScale, &outScale,
+ upperBoundOnsetDetection - lowerBoundOnsetDetection - 1);
+ envScale[M + ts] = outScale + (hybridDataScale << 1);
+ }
+
+ /* calculate common scale for all time slots */
+ SCHAR maxScale = -(DFRACT_BITS - 1);
+ for (i = 0; i < (nTimeSlots + M); i++) {
+ maxScale = fixMax(maxScale, envScale[i]);
+ }
+
+ /* apply common scale and store energy in temporary buffer */
+ for (i = 0; i < (nTimeSlots + M); i++) {
+ envs[i] = env[i] >> fixMin((maxScale - envScale[i]), (DFRACT_BITS - 1));
+ }
+
+ FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
+ for (i = 0; i < (nTimeSlots + M); i++) {
+ maxVal |= fAbs(envs[i]);
+ }
+
+ int s = fixMax(0, CntLeadingZeros(maxVal) - 1);
+
+ for (i = 0; i < (nTimeSlots + M); i++) {
+ envs[i] = envs[i] << s;
+ }
+
+ int currPosPrev = currPos;
+ FIXP_DBL p1, p2;
+ p2 = FL2FXCONST_DBL(0.0f);
+ for (; (currPos < (nTimeSlots << 1)) && (trCnt < MAX_NUM_TRANS);
+ currPos++) {
+ p1 = fMultDiv2(envs[currPos - nTimeSlots + M], threshold_square) >>
+ (SPACE_ONSET_THRESHOLD_SF - 1);
+
+ /* Calculate average of past M energy values */
+ if (currPosPrev == (currPos - 1)) {
+ /* remove last and add new element */
+ p2 -= (envs[currPosPrev - nTimeSlots] >>
+ (int)hOnset->avgEnergyDistanceScale);
+ p2 += (envs[currPos - nTimeSlots + M - 1] >>
+ (int)hOnset->avgEnergyDistanceScale);
+ } else {
+ /* calculate complete vector */
+ p2 = FL2FXCONST_DBL(0.0f);
+ for (ts = 0; ts < M; ts++) {
+ p2 += (envs[currPos - nTimeSlots + ts] >>
+ (int)hOnset->avgEnergyDistanceScale);
+ }
+ }
+ currPosPrev = currPos;
+
+ {
+ /* save position if transient found */
+ if (p1 > p2) {
+ pTransientPos[trCnt++] = currPos;
+ currPos += hOnset->minTransientDistance;
+ }
+ }
+ } /* for currPos */
+ }
+
+ } /* valid handle*/
+bail:
+
+ C_ALLOC_SCRATCH_END(envs, FIXP_DBL, (16 + MAX_TIME_SLOTS))
+
+ return error;
+}
+
+/**************************************************************************/
diff --git a/libSACenc/src/sacenc_onsetdetect.h b/libSACenc/src/sacenc_onsetdetect.h
new file mode 100644
index 0000000..5f3f0bd
--- /dev/null
+++ b/libSACenc/src/sacenc_onsetdetect.h
@@ -0,0 +1,154 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): Max Neuendorf
+
+ Description: Encoder Library Interface
+ Determine TES flags
+
+*******************************************************************************/
+
+#ifndef SACENC_ONSETDETECT_H
+#define SACENC_ONSETDETECT_H
+
+/**************************************************************************/ /**
+ \file
+ Description of file contents
+ ******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "common_fix.h"
+#include "FDK_matrixCalloc.h"
+#include "sacenc_lib.h"
+#include "sacenc_bitstream.h" /* for def. of MAX_NUM_PARAMS */
+
+/* Defines *******************************************************************/
+#define MAX_NUM_TRANS (MAX_NUM_PARAMS / 2)
+
+/* Data Types ****************************************************************/
+typedef struct T_ONSET_DETECT_CONFIG {
+ INT maxTimeSlots;
+
+ /* calc transien detection in ]lowerBoundOnsetDetection;
+ * upperBoundOnsetDetection[ */
+ INT lowerBoundOnsetDetection;
+ INT upperBoundOnsetDetection;
+
+} ONSET_DETECT_CONFIG;
+
+typedef struct ONSET_DETECT *HANDLE_ONSET_DETECT;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+FDK_SACENC_ERROR fdk_sacenc_onsetDetect_Open(HANDLE_ONSET_DETECT *phOnset,
+ const UINT maxTimeSlots);
+
+FDK_SACENC_ERROR fdk_sacenc_onsetDetect_Init(
+ HANDLE_ONSET_DETECT hOnset,
+ const ONSET_DETECT_CONFIG *const pOnsetDetectConfig, const UINT initFlags);
+
+FDK_SACENC_ERROR fdk_sacenc_onsetDetect_Close(HANDLE_ONSET_DETECT *phOnset);
+
+FDK_SACENC_ERROR fdk_sacenc_onsetDetect_Update(HANDLE_ONSET_DETECT hOnset,
+ const INT timeSlots);
+
+FDK_SACENC_ERROR fdk_sacenc_onsetDetect_Apply(
+ HANDLE_ONSET_DETECT hOnset, const INT nTimeSlots, const INT nHybridBands,
+ FIXP_DPK *const *const ppHybridData__FDK, const INT hybridDataScale,
+ const INT prevPos, INT pTransientPos[MAX_NUM_TRANS]);
+
+#endif /* SACENC_ONSETDETECT_H */
diff --git a/libSACenc/src/sacenc_paramextract.cpp b/libSACenc/src/sacenc_paramextract.cpp
new file mode 100644
index 0000000..dcbce1e
--- /dev/null
+++ b/libSACenc/src/sacenc_paramextract.cpp
@@ -0,0 +1,725 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): M. Multrus
+
+ Description: Parameter Extraction
+
+*******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_paramextract.h"
+#include "sacenc_tree.h"
+#include "sacenc_vectorfunctions.h"
+
+/* Defines *******************************************************************/
+#define LOG10_2_10 (3.01029995664f) /* 10.0f*log10(2.f) */
+#define SCALE_CLDE_SF (7) /* maxVal in Quant tab is +/- 50 */
+#define SCALE_CLDD_SF (8) /* maxVal in Quant tab is +/- 150 */
+
+/* Data Types ****************************************************************/
+typedef struct T_TTO_BOX {
+ FIXP_DBL pCld__FDK[MAX_NUM_PARAM_BANDS];
+ FIXP_DBL pIcc__FDK[MAX_NUM_PARAM_BANDS];
+ FIXP_DBL pCldQuant__FDK[MAX_NUM_PARAM_BANDS];
+
+ const FIXP_DBL *pIccQuantTable__FDK;
+ const FIXP_DBL *pCldQuantTableDec__FDK;
+ const FIXP_DBL *pCldQuantTableEnc__FDK;
+
+ SCHAR pCldEbQIdx[MAX_NUM_PARAM_BANDS];
+ SCHAR pIccDownmixIdx[MAX_NUM_PARAM_BANDS];
+
+ UCHAR *pParameterBand2HybridBandOffset;
+ const INT *pSubbandImagSign;
+ UCHAR nHybridBandsMax;
+ UCHAR nParameterBands;
+ UCHAR bFrameKeep;
+
+ UCHAR iccCorrelationCoherenceBorder;
+ BOX_QUANTMODE boxQuantMode;
+
+ UCHAR nIccQuantSteps;
+ UCHAR nIccQuantOffset;
+
+ UCHAR nCldQuantSteps;
+ UCHAR nCldQuantOffset;
+
+ UCHAR bUseCoarseQuantCld;
+ UCHAR bUseCoarseQuantIcc;
+
+} TTO_BOX;
+
+struct BOX_SUBBAND_SETUP {
+ BOX_SUBBAND_CONFIG subbandConfig;
+ UCHAR nParameterBands;
+ const UCHAR *pSubband2ParameterIndexLd;
+ UCHAR iccCorrelationCoherenceBorder;
+};
+
+/* Constants *****************************************************************/
+static const UCHAR subband2Parameter4_Ld[NUM_QMF_BANDS] = {
+ 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3};
+
+static const UCHAR subband2Parameter5_Ld[NUM_QMF_BANDS] = {
+ 0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4};
+
+static const UCHAR subband2Parameter7_Ld[NUM_QMF_BANDS] = {
+ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
+
+static const UCHAR subband2Parameter9_Ld[NUM_QMF_BANDS] = {
+ 0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
+
+static const UCHAR subband2Parameter12_Ld[NUM_QMF_BANDS] = {
+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8,
+ 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11};
+
+static const UCHAR subband2Parameter15_Ld[NUM_QMF_BANDS] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 10, 10, 11, 11,
+ 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14};
+
+static const UCHAR subband2Parameter23_Ld[NUM_QMF_BANDS] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 13,
+ 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 18, 19, 19,
+ 19, 19, 19, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22};
+
+static const INT subbandImagSign_Ld[NUM_QMF_BANDS] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+};
+
+#define SCALE_CLDE(a) (FL2FXCONST_DBL(a / (float)(1 << SCALE_CLDE_SF)))
+static const FIXP_DBL cldQuantTableFineEnc__FDK[MAX_CLD_QUANT_FINE] = {
+ SCALE_CLDE(-50.0), SCALE_CLDE(-45.0), SCALE_CLDE(-40.0), SCALE_CLDE(-35.0),
+ SCALE_CLDE(-30.0), SCALE_CLDE(-25.0), SCALE_CLDE(-22.0), SCALE_CLDE(-19.0),
+ SCALE_CLDE(-16.0), SCALE_CLDE(-13.0), SCALE_CLDE(-10.0), SCALE_CLDE(-8.0),
+ SCALE_CLDE(-6.0), SCALE_CLDE(-4.0), SCALE_CLDE(-2.0), SCALE_CLDE(0.0),
+ SCALE_CLDE(2.0), SCALE_CLDE(4.0), SCALE_CLDE(6.0), SCALE_CLDE(8.0),
+ SCALE_CLDE(10.0), SCALE_CLDE(13.0), SCALE_CLDE(16.0), SCALE_CLDE(19.0),
+ SCALE_CLDE(22.0), SCALE_CLDE(25.0), SCALE_CLDE(30.0), SCALE_CLDE(35.0),
+ SCALE_CLDE(40.0), SCALE_CLDE(45.0), SCALE_CLDE(50.0)};
+
+static const FIXP_DBL cldQuantTableCoarseEnc__FDK[MAX_CLD_QUANT_COARSE] = {
+ SCALE_CLDE(-50.0), SCALE_CLDE(-35.0), SCALE_CLDE(-25.0), SCALE_CLDE(-19.0),
+ SCALE_CLDE(-13.0), SCALE_CLDE(-8.0), SCALE_CLDE(-4.0), SCALE_CLDE(0.0),
+ SCALE_CLDE(4.0), SCALE_CLDE(8.0), SCALE_CLDE(13.0), SCALE_CLDE(19.0),
+ SCALE_CLDE(25.0), SCALE_CLDE(35.0), SCALE_CLDE(50.0)};
+
+#define SCALE_CLDD(a) (FL2FXCONST_DBL(a / (float)(1 << SCALE_CLDD_SF)))
+static const FIXP_DBL cldQuantTableFineDec__FDK[MAX_CLD_QUANT_FINE] = {
+ SCALE_CLDD(-150.0), SCALE_CLDD(-45.0), SCALE_CLDD(-40.0), SCALE_CLDD(-35.0),
+ SCALE_CLDD(-30.0), SCALE_CLDD(-25.0), SCALE_CLDD(-22.0), SCALE_CLDD(-19.0),
+ SCALE_CLDD(-16.0), SCALE_CLDD(-13.0), SCALE_CLDD(-10.0), SCALE_CLDD(-8.0),
+ SCALE_CLDD(-6.0), SCALE_CLDD(-4.0), SCALE_CLDD(-2.0), SCALE_CLDD(0.0),
+ SCALE_CLDD(2.0), SCALE_CLDD(4.0), SCALE_CLDD(6.0), SCALE_CLDD(8.0),
+ SCALE_CLDD(10.0), SCALE_CLDD(13.0), SCALE_CLDD(16.0), SCALE_CLDD(19.0),
+ SCALE_CLDD(22.0), SCALE_CLDD(25.0), SCALE_CLDD(30.0), SCALE_CLDD(35.0),
+ SCALE_CLDD(40.0), SCALE_CLDD(45.0), SCALE_CLDD(150.0)};
+
+static const FIXP_DBL cldQuantTableCoarseDec__FDK[MAX_CLD_QUANT_COARSE] = {
+ SCALE_CLDD(-150.0), SCALE_CLDD(-35.0), SCALE_CLDD(-25.0), SCALE_CLDD(-19.0),
+ SCALE_CLDD(-13.0), SCALE_CLDD(-8.0), SCALE_CLDD(-4.0), SCALE_CLDD(0.0),
+ SCALE_CLDD(4.0), SCALE_CLDD(8.0), SCALE_CLDD(13.0), SCALE_CLDD(19.0),
+ SCALE_CLDD(25.0), SCALE_CLDD(35.0), SCALE_CLDD(150.0)};
+
+#define SCALE_ICC(a) (FL2FXCONST_DBL(a))
+static const FIXP_DBL iccQuantTableFine__FDK[MAX_ICC_QUANT_FINE] = {
+ SCALE_ICC(0.99999999953), SCALE_ICC(0.937f), SCALE_ICC(0.84118f),
+ SCALE_ICC(0.60092f), SCALE_ICC(0.36764f), SCALE_ICC(0.0f),
+ SCALE_ICC(-0.589f), SCALE_ICC(-0.99f)};
+
+static const FIXP_DBL iccQuantTableCoarse__FDK[MAX_ICC_QUANT_COARSE] = {
+ SCALE_ICC(0.99999999953), SCALE_ICC(0.84118f), SCALE_ICC(0.36764f),
+ SCALE_ICC(-0.5890f)};
+
+static const BOX_SUBBAND_SETUP boxSubbandSetup[] = {
+ {BOX_SUBBANDS_4, 4, subband2Parameter4_Ld, 1},
+ {BOX_SUBBANDS_5, 5, subband2Parameter5_Ld, 2},
+ {BOX_SUBBANDS_7, 7, subband2Parameter7_Ld, 3},
+ {BOX_SUBBANDS_9, 9, subband2Parameter9_Ld, 4},
+ {BOX_SUBBANDS_12, 12, subband2Parameter12_Ld, 4},
+ {BOX_SUBBANDS_15, 15, subband2Parameter15_Ld, 5},
+ {BOX_SUBBANDS_23, 23, subband2Parameter23_Ld, 8}};
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+static const BOX_SUBBAND_SETUP *getBoxSubbandSetup(
+ const BOX_SUBBAND_CONFIG subbandConfig) {
+ int i;
+ const BOX_SUBBAND_SETUP *setup = NULL;
+
+ for (i = 0; i < (int)(sizeof(boxSubbandSetup) / sizeof(BOX_SUBBAND_SETUP));
+ i++) {
+ if (boxSubbandSetup[i].subbandConfig == subbandConfig) {
+ setup = &boxSubbandSetup[i];
+ break;
+ }
+ }
+ return setup;
+}
+
+static inline void ApplyBBCuesFDK(FIXP_DBL *const pData,
+ const INT nParamBands) {
+ int i, s;
+ FIXP_DBL tmp, invParamBands;
+
+ invParamBands = fDivNormHighPrec((FIXP_DBL)1, (FIXP_DBL)nParamBands, &s);
+ s = -s;
+
+ tmp = fMult(pData[0], invParamBands) >> s;
+ for (i = 1; i < nParamBands; i++) {
+ tmp += fMult(pData[i], invParamBands) >> s;
+ }
+
+ for (i = 0; i < nParamBands; i++) {
+ pData[i] = tmp;
+ }
+}
+
+static INT getNumberParameterBands(const BOX_SUBBAND_CONFIG subbandConfig) {
+ const BOX_SUBBAND_SETUP *setup = getBoxSubbandSetup(subbandConfig);
+ return ((setup == NULL) ? 0 : setup->nParameterBands);
+}
+
+static const UCHAR *getSubband2ParameterIndex(
+ const BOX_SUBBAND_CONFIG subbandConfig) {
+ const BOX_SUBBAND_SETUP *setup = getBoxSubbandSetup(subbandConfig);
+
+ return ((setup == NULL) ? NULL : (setup->pSubband2ParameterIndexLd));
+}
+
+void fdk_sacenc_calcParameterBand2HybridBandOffset(
+ const BOX_SUBBAND_CONFIG subbandConfig, const INT nHybridBands,
+ UCHAR *pParameterBand2HybridBandOffset) {
+ const BOX_SUBBAND_SETUP *setup = getBoxSubbandSetup(subbandConfig);
+ const UCHAR *pSubband2ParameterIndex;
+
+ int i, pb;
+
+ pSubband2ParameterIndex = setup->pSubband2ParameterIndexLd;
+
+ for (pb = 0, i = 0; i < nHybridBands - 1; i++) {
+ if (pSubband2ParameterIndex[i + 1] - pSubband2ParameterIndex[i]) {
+ pParameterBand2HybridBandOffset[pb++] = (i + 1);
+ }
+ }
+ pParameterBand2HybridBandOffset[pb++] = (i + 1);
+}
+
+const INT *fdk_sacenc_getSubbandImagSign() {
+ const INT *pImagSign = NULL;
+
+ pImagSign = subbandImagSign_Ld;
+
+ return (pImagSign);
+}
+
+static INT getIccCorrelationCoherenceBorder(
+ const BOX_SUBBAND_CONFIG subbandConfig, const INT bUseCoherenceOnly) {
+ const BOX_SUBBAND_SETUP *setup = getBoxSubbandSetup(subbandConfig);
+ return (
+ (setup == NULL)
+ ? 0
+ : ((bUseCoherenceOnly) ? 0 : setup->iccCorrelationCoherenceBorder));
+}
+
+FDK_SACENC_ERROR fdk_sacenc_createTtoBox(HANDLE_TTO_BOX *hTtoBox) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == hTtoBox) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ FDK_ALLOCATE_MEMORY_1D(*hTtoBox, 1, TTO_BOX);
+ }
+ return error;
+
+bail:
+ fdk_sacenc_destroyTtoBox(hTtoBox);
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+FDK_SACENC_ERROR fdk_sacenc_initTtoBox(HANDLE_TTO_BOX hTtoBox,
+ const TTO_BOX_CONFIG *const ttoBoxConfig,
+ UCHAR *pParameterBand2HybridBandOffset) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hTtoBox == NULL) || (ttoBoxConfig == NULL) ||
+ (pParameterBand2HybridBandOffset == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ FDKmemclear(hTtoBox, sizeof(TTO_BOX));
+
+ hTtoBox->bUseCoarseQuantCld = ttoBoxConfig->bUseCoarseQuantCld;
+ hTtoBox->bUseCoarseQuantIcc = ttoBoxConfig->bUseCoarseQuantIcc;
+ hTtoBox->boxQuantMode = ttoBoxConfig->boxQuantMode;
+ hTtoBox->iccCorrelationCoherenceBorder = getIccCorrelationCoherenceBorder(
+ ttoBoxConfig->subbandConfig, ttoBoxConfig->bUseCoherenceIccOnly);
+ hTtoBox->nHybridBandsMax = ttoBoxConfig->nHybridBandsMax;
+ hTtoBox->nParameterBands =
+ getNumberParameterBands(ttoBoxConfig->subbandConfig);
+ hTtoBox->bFrameKeep = ttoBoxConfig->bFrameKeep;
+
+ hTtoBox->nIccQuantSteps =
+ fdk_sacenc_getNumberIccQuantLevels(hTtoBox->bUseCoarseQuantIcc);
+ hTtoBox->nIccQuantOffset =
+ fdk_sacenc_getIccQuantOffset(hTtoBox->bUseCoarseQuantIcc);
+
+ hTtoBox->pIccQuantTable__FDK = hTtoBox->bUseCoarseQuantIcc
+ ? iccQuantTableCoarse__FDK
+ : iccQuantTableFine__FDK;
+ hTtoBox->pCldQuantTableDec__FDK = hTtoBox->bUseCoarseQuantCld
+ ? cldQuantTableCoarseDec__FDK
+ : cldQuantTableFineDec__FDK;
+ hTtoBox->pCldQuantTableEnc__FDK = hTtoBox->bUseCoarseQuantCld
+ ? cldQuantTableCoarseEnc__FDK
+ : cldQuantTableFineEnc__FDK;
+
+ hTtoBox->nCldQuantSteps =
+ fdk_sacenc_getNumberCldQuantLevels(hTtoBox->bUseCoarseQuantCld);
+ hTtoBox->nCldQuantOffset =
+ fdk_sacenc_getCldQuantOffset(hTtoBox->bUseCoarseQuantCld);
+
+ /* sanity */
+ if (NULL == (hTtoBox->pParameterBand2HybridBandOffset =
+ pParameterBand2HybridBandOffset)) {
+ error = SACENC_INIT_ERROR;
+ goto bail;
+ }
+
+ if (NULL == (hTtoBox->pSubbandImagSign = fdk_sacenc_getSubbandImagSign())) {
+ error = SACENC_INIT_ERROR;
+ }
+
+ if ((hTtoBox->boxQuantMode != BOX_QUANTMODE_FINE) &&
+ (hTtoBox->boxQuantMode != BOX_QUANTMODE_EBQ1) &&
+ (hTtoBox->boxQuantMode != BOX_QUANTMODE_EBQ2)) {
+ error = SACENC_INIT_ERROR;
+ goto bail;
+ }
+ }
+bail:
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_destroyTtoBox(HANDLE_TTO_BOX *hTtoBox) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (*hTtoBox != NULL) {
+ FDKfree(*hTtoBox);
+ *hTtoBox = NULL;
+ }
+
+ return error;
+}
+
+static FDK_SACENC_ERROR calculateIccFDK(const INT nParamBand,
+ const INT correlationCoherenceBorder,
+ const FIXP_DBL *const pPwr1,
+ const FIXP_DBL *const pPwr2,
+ const FIXP_DBL *const pProdReal,
+ FIXP_DBL const *const pProdImag,
+ FIXP_DBL *const pIcc) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((pPwr1 == NULL) || (pPwr2 == NULL) || (pProdReal == NULL) ||
+ (pProdImag == NULL) || (pIcc == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ /* sanity check border */
+ if (correlationCoherenceBorder > nParamBand) {
+ error = SACENC_INVALID_CONFIG;
+ } else {
+ /* correlation */
+ FDKcalcCorrelationVec(pIcc, pProdReal, pPwr1, pPwr2,
+ correlationCoherenceBorder);
+
+ /* coherence */
+ calcCoherenceVec(&pIcc[correlationCoherenceBorder],
+ &pProdReal[correlationCoherenceBorder],
+ &pProdImag[correlationCoherenceBorder],
+ &pPwr1[correlationCoherenceBorder],
+ &pPwr2[correlationCoherenceBorder], 0, 0,
+ nParamBand - correlationCoherenceBorder);
+
+ } /* valid configuration */
+ } /* valid handle */
+
+ return error;
+}
+
+static void QuantizeCoefFDK(const FIXP_DBL *const input, const INT nBands,
+ const FIXP_DBL *const quantTable,
+ const INT idxOffset, const INT nQuantSteps,
+ SCHAR *const quantOut) {
+ int band;
+ const int reverse = (quantTable[0] > quantTable[1]);
+
+ for (band = 0; band < nBands; band++) {
+ FIXP_DBL qVal;
+ FIXP_DBL curVal = input[band];
+
+ int lower = 0;
+ int upper = nQuantSteps - 1;
+
+ if (reverse) {
+ while (upper - lower > 1) {
+ int idx = (lower + upper) >> 1;
+ qVal = quantTable[idx];
+ if (curVal >= qVal) {
+ upper = idx;
+ } else {
+ lower = idx;
+ }
+ } /* while */
+
+ if ((curVal - quantTable[lower]) >= (quantTable[upper] - curVal)) {
+ quantOut[band] = lower - idxOffset;
+ } else {
+ quantOut[band] = upper - idxOffset;
+ }
+ } /* if reverse */
+ else {
+ while (upper - lower > 1) {
+ int idx = (lower + upper) >> 1;
+ qVal = quantTable[idx];
+ if (curVal <= qVal) {
+ upper = idx;
+ } else {
+ lower = idx;
+ }
+ } /* while */
+
+ if ((curVal - quantTable[lower]) <= (quantTable[upper] - curVal)) {
+ quantOut[band] = lower - idxOffset;
+ } else {
+ quantOut[band] = upper - idxOffset;
+ }
+ } /* else reverse */
+ } /* for band */
+}
+
+static void deQuantizeCoefFDK(const SCHAR *const input, const INT nBands,
+ const FIXP_DBL *const quantTable,
+ const INT idxOffset, FIXP_DBL *const dequantOut) {
+ int band;
+
+ for (band = 0; band < nBands; band++) {
+ dequantOut[band] = quantTable[input[band] + idxOffset];
+ }
+}
+
+static void CalculateCldFDK(FIXP_DBL *const pCld, const FIXP_DBL *const pPwr1,
+ const FIXP_DBL *const pPwr2, const INT scaleCh1,
+ const INT *const pbScaleCh1, const INT scaleCh2,
+ const INT *const pbScaleCh2, const int nParamBand) {
+ INT i;
+ FIXP_DBL ldPwr1, ldPwr2, cld;
+ FIXP_DBL maxPwr = FL2FXCONST_DBL(
+ 30.0f /
+ (1 << (LD_DATA_SHIFT +
+ 1))); /* consider SACENC_FLOAT_EPSILON in power calculation */
+
+ for (i = 0; i < nParamBand; i++) {
+ ldPwr1 =
+ (CalcLdData(pPwr1[i]) >> 1) + ((FIXP_DBL)(scaleCh1 + pbScaleCh1[i])
+ << (DFRACT_BITS - 1 - LD_DATA_SHIFT));
+ ldPwr2 =
+ (CalcLdData(pPwr2[i]) >> 1) + ((FIXP_DBL)(scaleCh2 + pbScaleCh2[i])
+ << (DFRACT_BITS - 1 - LD_DATA_SHIFT));
+
+ ldPwr1 = fixMax(fixMin(ldPwr1, maxPwr), -maxPwr);
+ ldPwr2 = fixMax(fixMin(ldPwr2, maxPwr), -maxPwr);
+
+ /* ldPwr1 and ldPwr2 are scaled by LD_DATA_SHIFT and additional 1 bit; 1 bit
+ * scale by fMultDiv2() */
+ cld = fMultDiv2(FL2FXCONST_DBL(LOG10_2_10 / (1 << SCALE_CLDE_SF)),
+ ldPwr1 - ldPwr2);
+
+ cld =
+ fixMin(cld, (FIXP_DBL)(((FIXP_DBL)MAXVAL_DBL) >> (LD_DATA_SHIFT + 2)));
+ cld =
+ fixMax(cld, (FIXP_DBL)(((FIXP_DBL)MINVAL_DBL) >> (LD_DATA_SHIFT + 2)));
+ pCld[i] = cld << (LD_DATA_SHIFT + 2);
+ }
+}
+
+FDK_SACENC_ERROR fdk_sacenc_applyTtoBox(
+ HANDLE_TTO_BOX hTtoBox, const INT nTimeSlots, const INT startTimeSlot,
+ const INT nHybridBands, const FIXP_DPK *const *const ppHybridData1__FDK,
+ const FIXP_DPK *const *const ppHybridData2__FDK, SCHAR *const pIccIdx,
+ UCHAR *const pbIccQuantCoarse, SCHAR *const pCldIdx,
+ UCHAR *const pbCldQuantCoarse, const INT bUseBBCues, INT *scaleCh1,
+ INT *scaleCh2) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ C_ALLOC_SCRATCH_START(powerHybridData1__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_START(powerHybridData2__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_START(prodHybridDataReal__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_START(prodHybridDataImag__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+
+ C_ALLOC_SCRATCH_START(IccDownmix__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_START(IccDownmixQuant__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_START(pbScaleCh1, INT, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_START(pbScaleCh2, INT, MAX_NUM_PARAM_BANDS)
+
+ if ((hTtoBox == NULL) || (pCldIdx == NULL) || (pbCldQuantCoarse == NULL) ||
+ (ppHybridData1__FDK == NULL) || (ppHybridData2__FDK == NULL) ||
+ (pIccIdx == NULL) || (pbIccQuantCoarse == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int j, pb;
+ const int nParamBands = hTtoBox->nParameterBands;
+ const int bUseEbQ = (hTtoBox->boxQuantMode == BOX_QUANTMODE_EBQ1) ||
+ (hTtoBox->boxQuantMode == BOX_QUANTMODE_EBQ2);
+
+ /* sanity check */
+ if ((nHybridBands < 0) || (nHybridBands > hTtoBox->nHybridBandsMax)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ int outScale; /* scalefactor will not be evaluated */
+ int inScale = 5; /* scale factor determined empirically */
+
+ /* calculate the headroom of the hybrid data for each parameter band */
+ FDKcalcPbScaleFactor(ppHybridData1__FDK,
+ hTtoBox->pParameterBand2HybridBandOffset, pbScaleCh1,
+ startTimeSlot, nTimeSlots, nParamBands);
+ FDKcalcPbScaleFactor(ppHybridData2__FDK,
+ hTtoBox->pParameterBand2HybridBandOffset, pbScaleCh2,
+ startTimeSlot, nTimeSlots, nParamBands);
+
+ for (j = 0, pb = 0; pb < nParamBands; pb++) {
+ FIXP_DBL data1, data2;
+ data1 = data2 = (FIXP_DBL)0;
+ for (; j < hTtoBox->pParameterBand2HybridBandOffset[pb]; j++) {
+ data1 += sumUpCplxPow2Dim2(ppHybridData1__FDK, SUM_UP_STATIC_SCALE,
+ inScale + pbScaleCh1[pb], &outScale,
+ startTimeSlot, nTimeSlots, j, j + 1);
+ data2 += sumUpCplxPow2Dim2(ppHybridData2__FDK, SUM_UP_STATIC_SCALE,
+ inScale + pbScaleCh2[pb], &outScale,
+ startTimeSlot, nTimeSlots, j, j + 1);
+ } /* for j */
+ powerHybridData1__FDK[pb] = data1;
+ powerHybridData2__FDK[pb] = data2;
+ } /* pb */
+
+ {
+ for (j = 0, pb = 0; pb < nParamBands; pb++) {
+ FIXP_DBL dataReal, dataImag;
+ dataReal = dataImag = (FIXP_DBL)0;
+ for (; j < hTtoBox->pParameterBand2HybridBandOffset[pb]; j++) {
+ FIXP_DPK scalarProd;
+ cplx_cplxScalarProduct(&scalarProd, ppHybridData1__FDK,
+ ppHybridData2__FDK, inScale + pbScaleCh1[pb],
+ inScale + pbScaleCh2[pb], &outScale,
+ startTimeSlot, nTimeSlots, j, j + 1);
+ dataReal += scalarProd.v.re;
+ if (hTtoBox->pSubbandImagSign[j] < 0) {
+ dataImag -= scalarProd.v.im;
+ } else {
+ dataImag += scalarProd.v.im;
+ }
+ } /* for j */
+ prodHybridDataReal__FDK[pb] = dataReal;
+ prodHybridDataImag__FDK[pb] = dataImag;
+ } /* pb */
+
+ if (SACENC_OK != (error = calculateIccFDK(
+ nParamBands, hTtoBox->iccCorrelationCoherenceBorder,
+ powerHybridData1__FDK, powerHybridData2__FDK,
+ prodHybridDataReal__FDK, prodHybridDataImag__FDK,
+ hTtoBox->pIcc__FDK))) {
+ goto bail;
+ }
+
+ /* calculate correlation based Icc for downmix */
+ if (SACENC_OK != (error = calculateIccFDK(
+ nParamBands, nParamBands, powerHybridData1__FDK,
+ powerHybridData2__FDK, prodHybridDataReal__FDK,
+ prodHybridDataImag__FDK, IccDownmix__FDK))) {
+ goto bail;
+ }
+ }
+
+ if (!bUseEbQ) {
+ CalculateCldFDK(hTtoBox->pCld__FDK, powerHybridData1__FDK,
+ powerHybridData2__FDK, *scaleCh1 + inScale + 1,
+ pbScaleCh1, *scaleCh2 + inScale + 1, pbScaleCh2,
+ nParamBands);
+ }
+
+ if (bUseBBCues) {
+ ApplyBBCuesFDK(&hTtoBox->pCld__FDK[0], nParamBands);
+
+ { ApplyBBCuesFDK(&hTtoBox->pIcc__FDK[0], nParamBands); }
+
+ } /* bUseBBCues */
+
+ /* quantize/de-quantize icc */
+ {
+ QuantizeCoefFDK(hTtoBox->pIcc__FDK, nParamBands,
+ hTtoBox->pIccQuantTable__FDK, hTtoBox->nIccQuantOffset,
+ hTtoBox->nIccQuantSteps, pIccIdx);
+ QuantizeCoefFDK(IccDownmix__FDK, nParamBands,
+ hTtoBox->pIccQuantTable__FDK, hTtoBox->nIccQuantOffset,
+ hTtoBox->nIccQuantSteps, hTtoBox->pIccDownmixIdx);
+ deQuantizeCoefFDK(hTtoBox->pIccDownmixIdx, nParamBands,
+ hTtoBox->pIccQuantTable__FDK, hTtoBox->nIccQuantOffset,
+ IccDownmixQuant__FDK);
+
+ *pbIccQuantCoarse = hTtoBox->bUseCoarseQuantIcc;
+ }
+
+ /* quantize/de-quantize cld */
+ if (!bUseEbQ) {
+ QuantizeCoefFDK(hTtoBox->pCld__FDK, nParamBands,
+ hTtoBox->pCldQuantTableEnc__FDK, hTtoBox->nCldQuantOffset,
+ hTtoBox->nCldQuantSteps, pCldIdx);
+ deQuantizeCoefFDK(pCldIdx, nParamBands, hTtoBox->pCldQuantTableDec__FDK,
+ hTtoBox->nCldQuantOffset, hTtoBox->pCldQuant__FDK);
+ } else {
+ FDKmemcpy(pCldIdx, hTtoBox->pCldEbQIdx, nParamBands * sizeof(SCHAR));
+ }
+ *pbCldQuantCoarse = hTtoBox->bUseCoarseQuantCld;
+
+ } /* valid handle */
+
+bail:
+ C_ALLOC_SCRATCH_END(pbScaleCh2, INT, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_END(pbScaleCh1, INT, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_END(IccDownmixQuant__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_END(IccDownmix__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+
+ C_ALLOC_SCRATCH_END(prodHybridDataImag__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_END(prodHybridDataReal__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_END(powerHybridData2__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_END(powerHybridData1__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+
+ return error;
+}
+
+INT fdk_sacenc_subband2ParamBand(const BOX_SUBBAND_CONFIG boxSubbandConfig,
+ const INT nSubband) {
+ INT nParamBand = -1;
+ const UCHAR *pSubband2ParameterIndex =
+ getSubband2ParameterIndex(boxSubbandConfig);
+
+ if (pSubband2ParameterIndex != NULL) {
+ const int hybrid_resolution = 64;
+
+ if ((nSubband > -1) && (nSubband < hybrid_resolution)) {
+ nParamBand = pSubband2ParameterIndex[nSubband];
+ }
+ }
+
+ return nParamBand;
+}
diff --git a/libSACenc/src/sacenc_paramextract.h b/libSACenc/src/sacenc_paramextract.h
new file mode 100644
index 0000000..9ebb902
--- /dev/null
+++ b/libSACenc/src/sacenc_paramextract.h
@@ -0,0 +1,214 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): M. Multrus
+
+ Description: Parameter Extraction
+
+*******************************************************************************/
+
+#ifndef SACENC_PARAMEXTRACT_H
+#define SACENC_PARAMEXTRACT_H
+
+/* Includes ******************************************************************/
+#include "common_fix.h"
+#include "sacenc_lib.h"
+#include "sacenc_const.h"
+#include "sacenc_bitstream.h"
+
+/* Defines *******************************************************************/
+#define MAX_CLD_QUANT_FINE (31)
+#define MAX_CLD_QUANT_COARSE (15)
+#define OFFSET_CLD_QUANT_COARSE (7)
+#define OFFSET_CLD_QUANT_FINE (15)
+
+#define MAX_ICC_QUANT_COARSE (4)
+#define MAX_ICC_QUANT_FINE (8)
+#define OFFSET_ICC_QUANT_COARSE (0)
+#define OFFSET_ICC_QUANT_FINE (0)
+
+#define MAX_NUM_PARAM_BANDS (28)
+
+#define NUM_MAPPED_HYBRID_BANDS (16)
+
+/* Data Types ****************************************************************/
+typedef struct T_TTO_BOX *HANDLE_TTO_BOX;
+
+typedef enum {
+ BOX_SUBBANDS_INVALID = 0,
+ BOX_SUBBANDS_4 = 4,
+ BOX_SUBBANDS_5 = 5,
+ BOX_SUBBANDS_7 = 7,
+ BOX_SUBBANDS_9 = 9,
+ BOX_SUBBANDS_12 = 12,
+ BOX_SUBBANDS_15 = 15,
+ BOX_SUBBANDS_23 = 23
+
+} BOX_SUBBAND_CONFIG;
+
+typedef enum {
+ BOX_QUANTMODE_INVALID = -1,
+ BOX_QUANTMODE_FINE = 0,
+ BOX_QUANTMODE_EBQ1 = 1,
+ BOX_QUANTMODE_EBQ2 = 2,
+ BOX_QUANTMODE_RESERVED3 = 3,
+ BOX_QUANTMODE_RESERVED4 = 4,
+ BOX_QUANTMODE_RESERVED5 = 5,
+ BOX_QUANTMODE_RESERVED6 = 6,
+ BOX_QUANTMODE_RESERVED7 = 7
+
+} BOX_QUANTMODE;
+
+typedef struct T_TTO_BOX_CONFIG {
+ UCHAR bUseCoarseQuantCld;
+ UCHAR bUseCoarseQuantIcc;
+ UCHAR bUseCoherenceIccOnly;
+
+ BOX_SUBBAND_CONFIG subbandConfig;
+ BOX_QUANTMODE boxQuantMode;
+
+ UCHAR nHybridBandsMax;
+
+ UCHAR bFrameKeep;
+
+} TTO_BOX_CONFIG;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+FDK_SACENC_ERROR fdk_sacenc_createTtoBox(HANDLE_TTO_BOX *hTtoBox);
+
+FDK_SACENC_ERROR fdk_sacenc_initTtoBox(HANDLE_TTO_BOX hTtoBox,
+ const TTO_BOX_CONFIG *const ttoBoxConfig,
+ UCHAR *pParameterBand2HybridBandOffset);
+
+FDK_SACENC_ERROR fdk_sacenc_destroyTtoBox(HANDLE_TTO_BOX *hTtoBox);
+
+FDK_SACENC_ERROR fdk_sacenc_applyTtoBox(
+ HANDLE_TTO_BOX hTtoBox, const INT nTimeSlots, const INT startTimeSlot,
+ const INT nHybridBands, const FIXP_DPK *const *const ppHybridData1__FDK,
+ const FIXP_DPK *const *const ppHybridData2__FDK, SCHAR *const pIccIdx,
+ UCHAR *const pbIccQuantCoarse, SCHAR *const pCldIdx,
+ UCHAR *const pbCldQuantCoarse, const INT bUseBBCues, INT *scaleCh0,
+ INT *scaleCh1);
+
+INT fdk_sacenc_subband2ParamBand(const BOX_SUBBAND_CONFIG boxSubbandConfig,
+ const INT nSubband);
+
+const INT *fdk_sacenc_getSubbandImagSign();
+
+void fdk_sacenc_calcParameterBand2HybridBandOffset(
+ const BOX_SUBBAND_CONFIG subbandConfig, const INT nHybridBands,
+ UCHAR *pParameterBand2HybridBandOffset);
+
+/* Function / Class Definition ***********************************************/
+static inline UCHAR fdk_sacenc_getCldQuantOffset(const INT bUseCoarseQuant) {
+ return ((bUseCoarseQuant) ? OFFSET_CLD_QUANT_COARSE : OFFSET_CLD_QUANT_FINE);
+}
+static inline UCHAR fdk_sacenc_getIccQuantOffset(const INT bUseCoarseQuant) {
+ return ((bUseCoarseQuant) ? OFFSET_ICC_QUANT_COARSE : OFFSET_ICC_QUANT_FINE);
+}
+
+static inline UCHAR fdk_sacenc_getNumberCldQuantLevels(
+ const INT bUseCoarseQuant) {
+ return ((bUseCoarseQuant) ? MAX_CLD_QUANT_COARSE : MAX_CLD_QUANT_FINE);
+}
+static inline UCHAR fdk_sacenc_getNumberIccQuantLevels(
+ const INT bUseCoarseQuant) {
+ return ((bUseCoarseQuant) ? MAX_ICC_QUANT_COARSE : MAX_ICC_QUANT_FINE);
+}
+
+#endif /* SACENC_PARAMEXTRACT_H */
diff --git a/libSACenc/src/sacenc_staticgain.cpp b/libSACenc/src/sacenc_staticgain.cpp
new file mode 100644
index 0000000..fef9f8d
--- /dev/null
+++ b/libSACenc/src/sacenc_staticgain.cpp
@@ -0,0 +1,446 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): Christian Goettlinger
+
+ Description: Encoder Library Interface
+ gain management of the encoder
+
+*******************************************************************************/
+
+/*****************************************************************************
+\file
+This file contains all static gain infrastructure
+******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_staticgain.h"
+
+/* Defines *******************************************************************/
+#define MP4SPACEENC_DMX_GAIN_DEFAULT SACENC_DMXGAIN_3_dB
+#define GAINCF_SF (4)
+#define GAINCT1(x) FL2FXCONST_DBL(x)
+#define GAINCF(x) FL2FXCONST_DBL(x)
+
+#define GAINCT2(x) FL2FXCONST_DBL(x)
+#define FX_DBL2FX_GAIN(x) (x)
+
+/* Data Types ****************************************************************/
+struct STATIC_GAIN {
+ /* External Config Values */
+ MP4SPACEENC_MODE encMode;
+ MP4SPACEENC_DMX_GAIN fixedGainDMX;
+ INT preGainFactorDb;
+
+ /* Internal Values */
+ FIXP_GAIN PostGain__FDK;
+ FIXP_GAIN pPreGain__FDK[SACENC_MAX_INPUT_CHANNELS];
+};
+
+/* Constants *****************************************************************/
+/*
+ preGainFactorTable:
+
+ pre calculation: (float)pow(10.f,(((float) x)/20.f))/(float)(1<<GAINCF_SF), x
+ = -20 ... +20
+*/
+static const FIXP_DBL preGainFactorTable__FDK[41] = {
+ GAINCF(6.2500000931e-003), GAINCF(7.0126154460e-003),
+ GAINCF(7.8682834283e-003), GAINCF(8.8283596560e-003),
+ GAINCF(9.9055822939e-003), GAINCF(1.1114246212e-002),
+ GAINCF(1.2470389716e-002), GAINCF(1.3992006890e-002),
+ GAINCF(1.5699289739e-002), GAINCF(1.7614893615e-002),
+ GAINCF(1.9764235243e-002), GAINCF(2.2175837308e-002),
+ GAINCF(2.4881698191e-002), GAINCF(2.7917724103e-002),
+ GAINCF(3.1324200332e-002), GAINCF(3.5146333277e-002),
+ GAINCF(3.9434835315e-002), GAINCF(4.4246610254e-002),
+ GAINCF(4.9645513296e-002), GAINCF(5.5703181773e-002),
+ GAINCF(6.2500000000e-002), GAINCF(7.0126153529e-002),
+ GAINCF(7.8682839870e-002), GAINCF(8.8283598423e-002),
+ GAINCF(9.9055826664e-002), GAINCF(1.1114246398e-001),
+ GAINCF(1.2470389158e-001), GAINCF(1.3992007077e-001),
+ GAINCF(1.5699289739e-001), GAINCF(1.7614893615e-001),
+ GAINCF(1.9764235616e-001), GAINCF(2.2175836563e-001),
+ GAINCF(2.4881698191e-001), GAINCF(2.7917724848e-001),
+ GAINCF(3.1324201822e-001), GAINCF(3.5146331787e-001),
+ GAINCF(3.9434835315e-001), GAINCF(4.4246610999e-001),
+ GAINCF(4.9645513296e-001), GAINCF(5.5703181028e-001),
+ GAINCF(6.2500000000e-001)};
+
+static const FIXP_GAIN dmxGainTable__FDK[] = {
+ /* GAINCT2(1.0), */ GAINCT2(0.84089650f),
+ GAINCT2(0.70710706f),
+ GAINCT2(0.59460385f),
+ GAINCT2(0.50000000f),
+ GAINCT2(0.42044825f),
+ GAINCT2(0.35355341f),
+ GAINCT2(0.25000000f)};
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+
+/*-----------------------------------------------------------------------------
+functionname: fdk_sacenc_staticGain_OpenConfig()
+description: opens and sets ConfigStruct to Default Values
+returns: noError on success, an apropriate error code else
+-----------------------------------------------------------------------------*/
+FDK_SACENC_ERROR fdk_sacenc_staticGain_OpenConfig(
+ HANDLE_STATIC_GAIN_CONFIG *phStaticGainConfig) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == phStaticGainConfig) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ /* Allocate Instance */
+ FDK_ALLOCATE_MEMORY_1D(*phStaticGainConfig, 1, struct STATIC_GAIN_CONFIG);
+ }
+ return error;
+
+bail:
+ fdk_sacenc_staticGain_CloseConfig(phStaticGainConfig);
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+FDK_SACENC_ERROR fdk_sacenc_staticGain_InitDefaultConfig(
+ HANDLE_STATIC_GAIN_CONFIG hStaticGainConfig) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == hStaticGainConfig) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ /* Necessary Input Variables */
+ hStaticGainConfig->encMode = SACENC_INVALID_MODE;
+
+ /* Optional Configs Set to Default Values */
+ hStaticGainConfig->fixedGainDMX = MP4SPACEENC_DMX_GAIN_DEFAULT;
+ hStaticGainConfig->preGainFactorDb = 0;
+ }
+ return error;
+}
+
+/*-----------------------------------------------------------------------------
+functionname: fdk_sacenc_staticGain_CloseConfig()
+description: destructs Static Gain Config Structure
+returns: noError on success, an apropriate error code else
+-----------------------------------------------------------------------------*/
+FDK_SACENC_ERROR fdk_sacenc_staticGain_CloseConfig(
+ HANDLE_STATIC_GAIN_CONFIG *phStaticGainConfig) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((phStaticGainConfig == NULL) || (*phStaticGainConfig == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ FDKfree(*phStaticGainConfig);
+ *phStaticGainConfig = NULL;
+ }
+ return error;
+}
+
+/*-----------------------------------------------------------------------------
+functionname: fdk_sacenc_staticGain_Open()
+description: initializes Static Gains
+returns: noError on success, an apropriate error code else
+-----------------------------------------------------------------------------*/
+FDK_SACENC_ERROR fdk_sacenc_staticGain_Open(HANDLE_STATIC_GAIN *phStaticGain) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == phStaticGain) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ /* Allocate Instance */
+ FDK_ALLOCATE_MEMORY_1D(*phStaticGain, 1, struct STATIC_GAIN);
+ }
+ return error;
+
+bail:
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+FDK_SACENC_ERROR fdk_sacenc_staticGain_Init(
+ HANDLE_STATIC_GAIN hStaticGain,
+ const HANDLE_STATIC_GAIN_CONFIG hStaticGainConfig, INT *const scale) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hStaticGain == NULL) || (hStaticGainConfig == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ hStaticGain->encMode = hStaticGainConfig->encMode;
+ hStaticGain->fixedGainDMX = hStaticGainConfig->fixedGainDMX;
+ hStaticGain->preGainFactorDb = hStaticGainConfig->preGainFactorDb;
+
+ if ((hStaticGain->preGainFactorDb < -20) ||
+ (hStaticGain->preGainFactorDb > 20)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ FIXP_DBL fPreGainFactor__FDK;
+
+ if (hStaticGain->preGainFactorDb == 0) {
+ fPreGainFactor__FDK = (FIXP_DBL)MAXVAL_DBL;
+ *scale = 0;
+ } else {
+ int s;
+ fPreGainFactor__FDK =
+ preGainFactorTable__FDK[hStaticGain->preGainFactorDb + 20];
+ s = fixMax(0, CntLeadingZeros(fPreGainFactor__FDK) - 1);
+ fPreGainFactor__FDK = fPreGainFactor__FDK << (s);
+ *scale = GAINCF_SF - s;
+ }
+
+ if (hStaticGain->fixedGainDMX == 0)
+ hStaticGain->PostGain__FDK = MAXVAL_GAIN;
+ else
+ hStaticGain->PostGain__FDK =
+ dmxGainTable__FDK[hStaticGain->fixedGainDMX - 1];
+
+ FDKmemclear(
+ hStaticGain->pPreGain__FDK,
+ sizeof(hStaticGain->pPreGain__FDK)); /* zero all input channels */
+
+ /* Configure PreGain-Vector */
+ if (hStaticGain->encMode == SACENC_212) {
+ hStaticGain->pPreGain__FDK[0] =
+ FX_DBL2FX_GAIN(fPreGainFactor__FDK); /* L */
+ hStaticGain->pPreGain__FDK[1] =
+ FX_DBL2FX_GAIN(fPreGainFactor__FDK); /* R */
+ } else {
+ error = SACENC_INVALID_CONFIG;
+ }
+
+ } /* valid handle */
+
+bail:
+
+ return error;
+}
+
+/*-----------------------------------------------------------------------------
+functionname: fdk_sacenc_staticGain_Close()
+description: destructs Static Gains
+returns: noError on success, an apropriate error code else
+-----------------------------------------------------------------------------*/
+FDK_SACENC_ERROR fdk_sacenc_staticGain_Close(HANDLE_STATIC_GAIN *phStaticGain) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((phStaticGain == NULL) || (*phStaticGain == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ FDKfree(*phStaticGain);
+ *phStaticGain = NULL;
+ }
+ return error;
+}
+
+/*-----------------------------------------------------------------------------
+functionname: fdk_sacenc_staticPostGain_Apply
+description: multiply the Output samples with the PostGain
+returns: noError on success, an apropriate error code else
+-----------------------------------------------------------------------------*/
+FDK_SACENC_ERROR fdk_sacenc_staticPostGain_ApplyFDK(
+ const HANDLE_STATIC_GAIN hStaticGain, INT_PCM *const pOutputSamples,
+ const INT nOutputSamples, const INT scale) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == hStaticGain) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int i;
+ FIXP_GAIN postGain = hStaticGain->PostGain__FDK;
+
+ if (scale < 0) {
+ if (postGain == MAXVAL_GAIN) {
+ for (i = 0; i < nOutputSamples; i++) {
+ pOutputSamples[i] = pOutputSamples[i] >> (-scale);
+ }
+ } else {
+ for (i = 0; i < nOutputSamples; i++) {
+ pOutputSamples[i] = FX_DBL2FX_PCM(
+ fMult(postGain, FX_PCM2FX_DBL(pOutputSamples[i])) >> (-scale));
+ }
+ }
+ } else {
+ if (postGain == MAXVAL_GAIN) {
+ for (i = 0; i < nOutputSamples; i++) {
+ pOutputSamples[i] = FX_DBL2FX_PCM(SATURATE_LEFT_SHIFT(
+ FX_PCM2FX_DBL(pOutputSamples[i]), scale, DFRACT_BITS));
+ }
+ } else {
+ for (i = 0; i < nOutputSamples; i++) {
+ pOutputSamples[i] = FX_DBL2FX_PCM(SATURATE_LEFT_SHIFT(
+ fMult(postGain, FX_PCM2FX_DBL(pOutputSamples[i])), scale,
+ DFRACT_BITS));
+ }
+ }
+ }
+ }
+ return error;
+}
+
+/*-----------------------------------------------------------------------------
+functionname: fdk_sacenc_getPreGainPtr()/ fdk_sacenc_getPostGain()
+description: get Gain-Pointers from struct
+returns: Pointer to PreGain or postGain
+-----------------------------------------------------------------------------*/
+FIXP_GAIN *fdk_sacenc_getPreGainPtrFDK(HANDLE_STATIC_GAIN hStaticGain) {
+ return ((hStaticGain == NULL) ? NULL : hStaticGain->pPreGain__FDK);
+}
+
+FIXP_GAIN fdk_sacenc_getPostGainFDK(HANDLE_STATIC_GAIN hStaticGain) {
+ return (hStaticGain->PostGain__FDK);
+}
+
+/* get fixed downmix gain and map it to bitstream enum */
+FIXEDGAINDMXCONFIG fdk_sacenc_staticGain_GetDmxGain(
+ const HANDLE_STATIC_GAIN hStaticGain) {
+ FIXEDGAINDMXCONFIG dmxGain = FIXEDGAINDMX_INVALID;
+
+ switch (hStaticGain->fixedGainDMX) {
+ case 0:
+ dmxGain = FIXEDGAINDMX_0;
+ break;
+ case 1:
+ dmxGain = FIXEDGAINDMX_1;
+ break;
+ case 2:
+ dmxGain = FIXEDGAINDMX_2;
+ break;
+ case 3:
+ dmxGain = FIXEDGAINDMX_3;
+ break;
+ case 4:
+ dmxGain = FIXEDGAINDMX_4;
+ break;
+ case 5:
+ dmxGain = FIXEDGAINDMX_5;
+ break;
+ case 6:
+ dmxGain = FIXEDGAINDMX_6;
+ break;
+ case 7:
+ dmxGain = FIXEDGAINDMX_7;
+ break;
+ default:
+ dmxGain = FIXEDGAINDMX_INVALID;
+ }
+ return dmxGain;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_staticGain_SetDmxGain(
+ HANDLE_STATIC_GAIN_CONFIG hStaticGainCfg,
+ const MP4SPACEENC_DMX_GAIN dmxGain) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == hStaticGainCfg) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ hStaticGainCfg->fixedGainDMX = dmxGain;
+ }
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_staticGain_SetEncMode(
+ HANDLE_STATIC_GAIN_CONFIG hStaticGainCfg, const MP4SPACEENC_MODE encMode) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == hStaticGainCfg) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ hStaticGainCfg->encMode = encMode;
+ }
+ return error;
+}
diff --git a/libSACenc/src/sacenc_staticgain.h b/libSACenc/src/sacenc_staticgain.h
new file mode 100644
index 0000000..5db3bec
--- /dev/null
+++ b/libSACenc/src/sacenc_staticgain.h
@@ -0,0 +1,177 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): Christian Goettlinger
+
+ Description: Encoder Library Interfac
+ gain management of the encoder
+
+*******************************************************************************/
+
+/**************************************************************************/ /**
+ \file
+ ******************************************************************************/
+
+#ifndef SACENC_STATICGAIN_H
+#define SACENC_STATICGAIN_H
+
+/* Includes ******************************************************************/
+#include "common_fix.h"
+#include "sacenc_lib.h"
+#include "sacenc_const.h"
+#include "sacenc_bitstream.h"
+
+/* Defines *******************************************************************/
+#define FIXP_GAIN FIXP_DBL
+#define MAXVAL_GAIN ((FIXP_DBL)MAXVAL_DBL)
+
+/* Data Types ****************************************************************/
+struct STATIC_GAIN_CONFIG {
+ MP4SPACEENC_MODE encMode;
+ MP4SPACEENC_DMX_GAIN fixedGainDMX;
+ INT preGainFactorDb;
+};
+
+typedef struct STATIC_GAIN_CONFIG *HANDLE_STATIC_GAIN_CONFIG;
+typedef struct STATIC_GAIN *HANDLE_STATIC_GAIN;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+
+/* Initializes Static Gain Computation Config */
+FDK_SACENC_ERROR fdk_sacenc_staticGain_OpenConfig(
+ HANDLE_STATIC_GAIN_CONFIG *phStaticGainConfig);
+
+FDK_SACENC_ERROR fdk_sacenc_staticGain_InitDefaultConfig(
+ HANDLE_STATIC_GAIN_CONFIG hStaticGainConfig);
+
+/* Deletes Static Gain Computation Config ~Destructor */
+FDK_SACENC_ERROR fdk_sacenc_staticGain_CloseConfig(
+ HANDLE_STATIC_GAIN_CONFIG *phStaticGainConfig);
+
+/* Initializes Static Gain Computation ~Constructor */
+FDK_SACENC_ERROR fdk_sacenc_staticGain_Open(HANDLE_STATIC_GAIN *phStaticGain);
+
+FDK_SACENC_ERROR fdk_sacenc_staticGain_Init(
+ HANDLE_STATIC_GAIN hStaticGain,
+ const HANDLE_STATIC_GAIN_CONFIG hStaticGainConfig, INT *const scale);
+
+/* Deletes Static Gain Computation Infrastucture ~Destructor */
+FDK_SACENC_ERROR fdk_sacenc_staticGain_Close(HANDLE_STATIC_GAIN *phStaticGain);
+
+/* Apply PostGain to the output PCM Downmix-Signal */
+FDK_SACENC_ERROR fdk_sacenc_staticPostGain_ApplyFDK(
+ const HANDLE_STATIC_GAIN hStaticGain, INT_PCM *const pOutputSamples,
+ const INT nOutputSamples, const INT scale);
+
+/* Get Pointer to PreGain-vector */
+FIXP_GAIN *fdk_sacenc_getPreGainPtrFDK(HANDLE_STATIC_GAIN hStaticGain);
+
+/* Get Pointer to PostGain-coef */
+FIXP_GAIN fdk_sacenc_getPostGainFDK(HANDLE_STATIC_GAIN hStaticGain);
+
+FIXEDGAINDMXCONFIG fdk_sacenc_staticGain_GetDmxGain(
+ const HANDLE_STATIC_GAIN hStaticGain);
+
+FDK_SACENC_ERROR fdk_sacenc_staticGain_SetDmxGain(
+ HANDLE_STATIC_GAIN_CONFIG hStaticGainCfg,
+ const MP4SPACEENC_DMX_GAIN dmxGain);
+
+FDK_SACENC_ERROR fdk_sacenc_staticGain_SetEncMode(
+ HANDLE_STATIC_GAIN_CONFIG hStaticGainCfg, const MP4SPACEENC_MODE encMode);
+
+#endif /* SACENC_STATICGAIN_H */
diff --git a/libSACenc/src/sacenc_tree.cpp b/libSACenc/src/sacenc_tree.cpp
new file mode 100644
index 0000000..c7d3128
--- /dev/null
+++ b/libSACenc/src/sacenc_tree.cpp
@@ -0,0 +1,488 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): Max Neuendorf
+
+ Description: Encoder Library Interface
+ Tree Structure for Space Encoder
+
+*******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_tree.h"
+#include "genericStds.h"
+#include "sacenc_const.h"
+#include "sacenc_paramextract.h"
+#include "sacenc_framewindowing.h"
+#include "FDK_matrixCalloc.h"
+
+/* Defines *******************************************************************/
+enum { BOX_0 = 0, BOX_1 = 1 };
+
+enum { CH_L = 0, CH_R = 1 };
+
+enum { TTO_CH_0 = 0, TTO_CH_1 = 1 };
+
+enum { WIN_INACTIV = 0, WIN_ACTIV = 1 };
+
+enum { MAX_KEEP_FRAMECOUNT = 100 };
+
+/* Data Types ****************************************************************/
+struct SPACE_TREE {
+ SPACETREE_MODE mode;
+ SPACE_TREE_DESCRIPTION descr;
+ HANDLE_TTO_BOX ttoBox[SACENC_MAX_NUM_BOXES];
+ UCHAR nParamBands;
+ UCHAR bUseCoarseQuantTtoIcc;
+ UCHAR bUseCoarseQuantTtoCld;
+ QUANTMODE quantMode;
+ INT frameCount;
+ UCHAR bFrameKeep;
+
+ /* Intermediate buffers */
+ UCHAR pCld_prev[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAM_BANDS];
+ UCHAR pIcc_prev[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAM_BANDS];
+
+ UCHAR nChannelsInMax;
+ UCHAR nHybridBandsMax;
+};
+
+typedef struct {
+ UCHAR boxId;
+ UCHAR inCh1;
+ UCHAR inCh2;
+ UCHAR inCh3;
+ UCHAR inCh4;
+ UCHAR wCh1;
+ UCHAR wCh2;
+
+} TTO_DESCRIPTOR;
+
+typedef struct {
+ SPACETREE_MODE mode;
+ SPACE_TREE_DESCRIPTION treeDescription;
+
+} TREE_CONFIG;
+
+typedef struct {
+ SPACETREE_MODE mode;
+ UCHAR nChannelsIn;
+ UCHAR nChannelsOut;
+ UCHAR nTtoBoxes;
+ TTO_DESCRIPTOR tto_descriptor[1];
+
+} TREE_SETUP;
+
+/* Constants *****************************************************************/
+static const TREE_CONFIG treeConfigTable[] = {
+ {SPACETREE_INVALID_MODE, {0, 0, 0}}, {SPACETREE_212, {1, 1, 2}}};
+
+static const TREE_SETUP treeSetupTable[] = {
+ {SPACETREE_INVALID_MODE, 0, 0, 0, {{0, 0, 0, 0, 0, 0, 0}}},
+ {SPACETREE_212,
+ 2,
+ 1,
+ 1,
+ {{BOX_0, CH_L, CH_R, TTO_CH_0, TTO_CH_1, WIN_ACTIV, WIN_ACTIV}}}};
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+static FDK_SACENC_ERROR getTreeConfig(
+ const SPACETREE_MODE mode, SPACE_TREE_DESCRIPTION *pTreeDescription) {
+ FDK_SACENC_ERROR error = SACENC_INIT_ERROR;
+
+ if (pTreeDescription == NULL) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int i;
+ for (i = 0; i < (int)(sizeof(treeConfigTable) / sizeof(TREE_CONFIG)); i++) {
+ if (treeConfigTable[i].mode == mode) {
+ *pTreeDescription = treeConfigTable[i].treeDescription;
+ error = SACENC_OK;
+ break;
+ }
+ }
+ } /* valid handle */
+ return error;
+}
+
+static const TREE_SETUP *getTreeSetup(const SPACETREE_MODE mode) {
+ int i;
+ const TREE_SETUP *setup = NULL;
+
+ for (i = 0; i < (int)(sizeof(treeSetupTable) / sizeof(TREE_SETUP)); i++) {
+ if (treeSetupTable[i].mode == mode) {
+ setup = &treeSetupTable[i];
+ break;
+ }
+ }
+ return setup;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_spaceTree_Open(HANDLE_SPACE_TREE *phSpaceTree) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+ HANDLE_SPACE_TREE hSpaceTree = NULL;
+
+ if (NULL == phSpaceTree) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int box;
+
+ FDK_ALLOCATE_MEMORY_1D(hSpaceTree, 1, struct SPACE_TREE);
+
+ for (box = 0; box < SACENC_MAX_NUM_BOXES; box++) {
+ HANDLE_TTO_BOX ttoBox = NULL;
+ if (SACENC_OK != (error = fdk_sacenc_createTtoBox(&ttoBox))) {
+ goto bail;
+ }
+ if (NULL != hSpaceTree) {
+ hSpaceTree->ttoBox[box] = ttoBox;
+ }
+ }
+ *phSpaceTree = hSpaceTree;
+ }
+ return error;
+
+bail:
+ fdk_sacenc_spaceTree_Close(&hSpaceTree);
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+FDK_SACENC_ERROR fdk_sacenc_spaceTree_Init(
+ HANDLE_SPACE_TREE hST, const SPACE_TREE_SETUP *const hSetup,
+ UCHAR *pParameterBand2HybridBandOffset, const INT bFrameKeep) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hST == NULL) || (hSetup == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int bTtoBoxFrontBackCombin[SACENC_MAX_NUM_BOXES] = {0};
+ int box = 0;
+
+ hST->frameCount = 0;
+ hST->bFrameKeep = bFrameKeep;
+
+ /* Init */
+ hST->mode = hSetup->mode;
+ hST->nParamBands = hSetup->nParamBands;
+ hST->bUseCoarseQuantTtoIcc = hSetup->bUseCoarseQuantTtoIcc;
+ hST->bUseCoarseQuantTtoCld = hSetup->bUseCoarseQuantTtoCld;
+ hST->quantMode = hSetup->quantMode;
+ hST->nChannelsInMax = hSetup->nChannelsInMax;
+ hST->nHybridBandsMax = hSetup->nHybridBandsMax;
+
+ if (SACENC_OK != (error = getTreeConfig(hST->mode, &hST->descr))) {
+ goto bail;
+ }
+
+ switch (hST->mode) {
+ case SPACETREE_212:
+ bTtoBoxFrontBackCombin[BOX_0] = 0;
+ break;
+ case SPACETREE_INVALID_MODE:
+ default:
+ error = SACENC_INIT_ERROR;
+ goto bail;
+ } /* switch (hST->mode) */
+
+ if (hST->descr.nOttBoxes > SACENC_MAX_NUM_BOXES) {
+ error = SACENC_INIT_ERROR;
+ goto bail;
+ }
+
+ for (box = 0; box < hST->descr.nOttBoxes; box++) {
+ TTO_BOX_CONFIG boxConfig;
+ boxConfig.subbandConfig = (BOX_SUBBAND_CONFIG)hST->nParamBands;
+ boxConfig.bUseCoarseQuantCld = hST->bUseCoarseQuantTtoCld;
+ boxConfig.bUseCoarseQuantIcc = hST->bUseCoarseQuantTtoIcc;
+ boxConfig.bUseCoherenceIccOnly = bTtoBoxFrontBackCombin[box];
+ boxConfig.boxQuantMode = (BOX_QUANTMODE)hST->quantMode;
+ boxConfig.nHybridBandsMax = hST->nHybridBandsMax;
+ boxConfig.bFrameKeep = hST->bFrameKeep;
+
+ if (SACENC_OK !=
+ (error = fdk_sacenc_initTtoBox(hST->ttoBox[box], &boxConfig,
+ pParameterBand2HybridBandOffset))) {
+ goto bail;
+ }
+ } /* for box */
+
+ } /* valid handle */
+
+bail:
+ return error;
+}
+
+static void SpaceTree_FrameKeep212(const HANDLE_SPACE_TREE hST,
+ SPATIALFRAME *const hSTOut,
+ const INT avoid_keep) {
+ int pb;
+
+ if (avoid_keep == 0) {
+ if (hST->frameCount % 2 == 0) {
+ for (pb = 0; pb < hST->nParamBands; pb++) {
+ hST->pIcc_prev[BOX_0][pb] = hSTOut->ottData.icc[BOX_0][0][pb];
+ hSTOut->ottData.cld[BOX_0][0][pb] = hST->pCld_prev[BOX_0][pb];
+ }
+ } else {
+ for (pb = 0; pb < hST->nParamBands; pb++) {
+ hSTOut->ottData.icc[BOX_0][0][pb] = hST->pIcc_prev[BOX_0][pb];
+ hST->pCld_prev[BOX_0][pb] = hSTOut->ottData.cld[BOX_0][0][pb];
+ }
+ }
+ } else {
+ for (pb = 0; pb < hST->nParamBands; pb++) {
+ hST->pIcc_prev[BOX_0][pb] = hSTOut->ottData.icc[BOX_0][0][pb];
+ hST->pCld_prev[BOX_0][pb] = hSTOut->ottData.cld[BOX_0][0][pb];
+ }
+ }
+ hST->frameCount++;
+ if (hST->frameCount == MAX_KEEP_FRAMECOUNT) {
+ hST->frameCount = 0;
+ }
+}
+
+static FDK_SACENC_ERROR SpaceTree_FrameKeep(const HANDLE_SPACE_TREE hST,
+ SPATIALFRAME *const hSTOut,
+ const INT avoid_keep) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ switch (hST->mode) {
+ case SPACETREE_212:
+ SpaceTree_FrameKeep212(hST, hSTOut, avoid_keep);
+ break;
+ case SPACETREE_INVALID_MODE:
+ default:
+ error = SACENC_INVALID_CONFIG;
+ break;
+ }
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_spaceTree_Apply(
+ HANDLE_SPACE_TREE hST, const INT paramSet, const INT nChannelsIn,
+ const INT nTimeSlots, const INT startTimeSlot, const INT nHybridBands,
+ FIXP_WIN *pFrameWindowAna__FDK,
+ FIXP_DPK *const *const *const pppHybrid__FDK,
+ FIXP_DPK *const *const *const pppHybridIn__FDK, SPATIALFRAME *const hSTOut,
+ const INT avoid_keep, INT *pEncoderInputChScale) {
+ /** \verbatim
+ =============================================================================================================================
+ TREE_212
+ =============================================================================================================================
+ _______
+ L -- TTO_CH_0 --| |
+ | TTO_0 |-- TTO_CH_0
+ R -- TTO_CH_1 --|_______|
+
+ \endverbatim */
+
+ FDK_SACENC_ERROR error = SACENC_OK;
+ int k;
+ const TREE_SETUP *treeSetup = NULL;
+
+ if ((hST == NULL) || (hSTOut == NULL) || (pppHybrid__FDK == NULL) ||
+ (pppHybridIn__FDK == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ if ((treeSetup = getTreeSetup(hST->mode)) == NULL) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ /* Sanity Checks */
+ if ((nChannelsIn != treeSetup->nChannelsIn) ||
+ (nChannelsIn > hST->nChannelsInMax) ||
+ (nHybridBands > hST->nHybridBandsMax)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ /* Apply all TTO boxes. */
+ for (k = 0; k < treeSetup->nTtoBoxes; k++) {
+ const TTO_DESCRIPTOR *pTTO = &treeSetup->tto_descriptor[k];
+
+ int i, inCh[2], outCh[2], win[2];
+
+ inCh[0] = pTTO->inCh1;
+ outCh[0] = pTTO->inCh3;
+ win[0] = pTTO->wCh1;
+ inCh[1] = pTTO->inCh2;
+ outCh[1] = pTTO->inCh4;
+ win[1] = pTTO->wCh2;
+
+ for (i = 0; i < 2; i++) {
+ if (win[i] == WIN_ACTIV) {
+ fdk_sacenc_analysisWindowing(
+ nTimeSlots, startTimeSlot, pFrameWindowAna__FDK,
+ pppHybrid__FDK[inCh[i]], pppHybridIn__FDK[outCh[i]], nHybridBands,
+ FW_LEAVE_DIM);
+ }
+ }
+
+ /* Calculate output downmix within last TTO box, if no TTT box is applied.
+ */
+ if (SACENC_OK !=
+ (error = fdk_sacenc_applyTtoBox(
+ hST->ttoBox[pTTO->boxId], nTimeSlots, startTimeSlot, nHybridBands,
+ pppHybridIn__FDK[pTTO->inCh3], pppHybridIn__FDK[pTTO->inCh4],
+ hSTOut->ottData.icc[pTTO->boxId][paramSet],
+ &(hSTOut->ICCLosslessData.bsQuantCoarseXXX[pTTO->boxId][paramSet]),
+ hSTOut->ottData.cld[pTTO->boxId][paramSet],
+ &(hSTOut->CLDLosslessData.bsQuantCoarseXXX[pTTO->boxId][paramSet]),
+ hSTOut->bUseBBCues, &pEncoderInputChScale[inCh[0]],
+ &pEncoderInputChScale[inCh[1]]))) {
+ goto bail;
+ }
+ }
+
+ if (hST->bFrameKeep == 1) {
+ if (SACENC_OK != (error = SpaceTree_FrameKeep(hST, hSTOut, avoid_keep))) {
+ goto bail;
+ }
+ }
+
+bail:
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_spaceTree_Close(HANDLE_SPACE_TREE *phSpaceTree) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((phSpaceTree == NULL) || (*phSpaceTree == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int box;
+ HANDLE_SPACE_TREE const hST = *phSpaceTree;
+
+ /* for (box = 0; box < hST->descr.nOttBoxes; ++box) { */
+ for (box = 0; box < SACENC_MAX_NUM_BOXES; ++box) {
+ if (SACENC_OK != (error = fdk_sacenc_destroyTtoBox(&hST->ttoBox[box]))) {
+ goto bail;
+ }
+ }
+
+ FDKfree(*phSpaceTree);
+ *phSpaceTree = NULL;
+ }
+bail:
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_spaceTree_GetDescription(
+ const HANDLE_SPACE_TREE hSpaceTree,
+ SPACE_TREE_DESCRIPTION *pSpaceTreeDescription) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hSpaceTree == NULL) || (pSpaceTreeDescription == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ *pSpaceTreeDescription = hSpaceTree->descr;
+ }
+ return error;
+}
+
+INT fdk_sacenc_spaceTree_Hybrid2ParamBand(const INT nParamBands,
+ const INT nHybridBand) {
+ return fdk_sacenc_subband2ParamBand((BOX_SUBBAND_CONFIG)nParamBands,
+ nHybridBand);
+}
+
+/*****************************************************************************
+******************************************************************************/
diff --git a/libSACenc/src/sacenc_tree.h b/libSACenc/src/sacenc_tree.h
new file mode 100644
index 0000000..09f5b2b
--- /dev/null
+++ b/libSACenc/src/sacenc_tree.h
@@ -0,0 +1,168 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): Max Neuendorf
+
+ Description: Encoder Library Interface
+ Tree Structure for Space Encoder
+
+*******************************************************************************/
+
+#ifndef SACENC_TREE_H
+#define SACENC_TREE_H
+
+/* Includes ******************************************************************/
+#include "sacenc_framewindowing.h"
+#include "sacenc_lib.h"
+#include "sacenc_bitstream.h"
+
+/* Defines *******************************************************************/
+
+/* Data Types ****************************************************************/
+typedef enum {
+ SPACETREE_INVALID_MODE = 0,
+ SPACETREE_212 = 8
+
+} SPACETREE_MODE;
+
+typedef struct SPACE_TREE *HANDLE_SPACE_TREE;
+
+typedef struct {
+ UCHAR nParamBands;
+ UCHAR bUseCoarseQuantTtoCld;
+ UCHAR bUseCoarseQuantTtoIcc;
+ QUANTMODE quantMode;
+ SPACETREE_MODE mode;
+
+ UCHAR nChannelsInMax;
+ UCHAR nHybridBandsMax;
+
+} SPACE_TREE_SETUP;
+
+typedef struct {
+ UCHAR nOttBoxes;
+ UCHAR nInChannels;
+ UCHAR nOutChannels;
+
+} SPACE_TREE_DESCRIPTION;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+FDK_SACENC_ERROR fdk_sacenc_spaceTree_Open(HANDLE_SPACE_TREE *phSpaceTree);
+
+FDK_SACENC_ERROR fdk_sacenc_spaceTree_Init(
+ HANDLE_SPACE_TREE hST, const SPACE_TREE_SETUP *const hSetup,
+ UCHAR *pParameterBand2HybridBandOffset, const INT bFrameKeep);
+
+FDK_SACENC_ERROR fdk_sacenc_spaceTree_Apply(
+ HANDLE_SPACE_TREE hST, const INT paramSet, const INT nChannelsIn,
+ const INT nTimeSlots, const INT startTimeSlot, const INT nHybridBands,
+ FIXP_WIN *pFrameWindowAna__FDK,
+ FIXP_DPK *const *const *const pppHybrid__FDK,
+ FIXP_DPK *const *const *const pppHybridIn__FDK, SPATIALFRAME *const hSTOut,
+ const INT avoid_keep, INT *pEncoderInputChScale);
+
+FDK_SACENC_ERROR fdk_sacenc_spaceTree_Close(HANDLE_SPACE_TREE *phSpaceTree);
+
+FDK_SACENC_ERROR fdk_sacenc_spaceTree_GetDescription(
+ const HANDLE_SPACE_TREE hSpaceTree,
+ SPACE_TREE_DESCRIPTION *pSpaceTreeDescription);
+
+INT fdk_sacenc_spaceTree_Hybrid2ParamBand(const INT nParamBands,
+ const INT nHybridBand);
+
+#endif /* SACENC_TREE_H */
diff --git a/libSACenc/src/sacenc_vectorfunctions.cpp b/libSACenc/src/sacenc_vectorfunctions.cpp
new file mode 100644
index 0000000..c1e24b7
--- /dev/null
+++ b/libSACenc/src/sacenc_vectorfunctions.cpp
@@ -0,0 +1,450 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): Josef Hoepfl
+
+ Description: Encoder Library Interface
+ vector functions
+
+*******************************************************************************/
+
+/*****************************************************************************
+\file
+This file contains vector functions
+******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_vectorfunctions.h"
+
+/* Defines *******************************************************************/
+
+/* Data Types ****************************************************************/
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+
+FIXP_DBL sumUpCplxPow2(const FIXP_DPK *const x, const INT scaleMode,
+ const INT inScaleFactor, INT *const outScaleFactor,
+ const INT n) {
+ int i, cs;
+
+ if (scaleMode == SUM_UP_DYNAMIC_SCALE) {
+ /* calculate headroom */
+ FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
+ for (i = 0; i < n; i++) {
+ maxVal |= fAbs(x[i].v.re);
+ maxVal |= fAbs(x[i].v.im);
+ }
+ cs = inScaleFactor - fixMax(0, CntLeadingZeros(maxVal) - 1);
+ } else {
+ cs = inScaleFactor;
+ }
+
+ /* consider scaling of energy and scaling in fPow2Div2 and addition */
+ *outScaleFactor = 2 * cs + 2;
+
+ /* make sure that the scalefactor is in the range of -(DFRACT_BITS-1), ... ,
+ * (DFRACT_BITS-1) */
+ cs = fixMax(fixMin(cs, DFRACT_BITS - 1), -(DFRACT_BITS - 1));
+
+ /* sum up complex energy samples */
+ FIXP_DBL re, im, sum;
+
+ re = im = sum = FL2FXCONST_DBL(0.0);
+ if (cs < 0) {
+ cs = -cs;
+ for (i = 0; i < n; i++) {
+ re += fPow2Div2(x[i].v.re << cs);
+ im += fPow2Div2(x[i].v.im << cs);
+ }
+ } else {
+ cs = 2 * cs;
+ for (i = 0; i < n; i++) {
+ re += fPow2Div2(x[i].v.re) >> cs;
+ im += fPow2Div2(x[i].v.im) >> cs;
+ }
+ }
+
+ sum = (re >> 1) + (im >> 1);
+
+ return (sum);
+}
+
+FIXP_DBL sumUpCplxPow2Dim2(const FIXP_DPK *const *const x, const INT scaleMode,
+ const INT inScaleFactor, INT *const outScaleFactor,
+ const INT sDim1, const INT nDim1, const INT sDim2,
+ const INT nDim2) {
+ int i, j, cs;
+
+ if (scaleMode == SUM_UP_DYNAMIC_SCALE) {
+ /* calculate headroom */
+ FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
+ for (i = sDim1; i < nDim1; i++) {
+ for (j = sDim2; j < nDim2; j++) {
+ maxVal |= fAbs(x[i][j].v.re);
+ maxVal |= fAbs(x[i][j].v.im);
+ }
+ }
+ cs = inScaleFactor - fixMax(0, CntLeadingZeros(maxVal) - 1);
+ } else {
+ cs = inScaleFactor;
+ }
+
+ /* consider scaling of energy and scaling in fPow2Div2 and addition */
+ *outScaleFactor = 2 * cs + 2;
+
+ /* make sure that the scalefactor is in the range of -(DFRACT_BITS-1), ... ,
+ * (DFRACT_BITS-1) */
+ cs = fixMax(fixMin(cs, DFRACT_BITS - 1), -(DFRACT_BITS - 1));
+
+ /* sum up complex energy samples */
+ FIXP_DBL re, im, sum;
+
+ re = im = sum = FL2FXCONST_DBL(0.0);
+ if (cs < 0) {
+ cs = -cs;
+ for (i = sDim1; i < nDim1; i++) {
+ for (j = sDim2; j < nDim2; j++) {
+ re += fPow2Div2(x[i][j].v.re << cs);
+ im += fPow2Div2(x[i][j].v.im << cs);
+ }
+ }
+ } else {
+ cs = 2 * cs;
+ for (i = sDim1; i < nDim1; i++) {
+ for (j = sDim2; j < nDim2; j++) {
+ re += fPow2Div2(x[i][j].v.re) >> cs;
+ im += fPow2Div2(x[i][j].v.im) >> cs;
+ }
+ }
+ }
+
+ sum = (re >> 1) + (im >> 1);
+
+ return (sum);
+}
+
+void copyCplxVec(FIXP_DPK *const Z, const FIXP_DPK *const X, const INT n) {
+ FDKmemmove(Z, X, sizeof(FIXP_DPK) * n);
+}
+
+void setCplxVec(FIXP_DPK *const Z, const FIXP_DBL a, const INT n) {
+ int i;
+
+ for (i = 0; i < n; i++) {
+ Z[i].v.re = a;
+ Z[i].v.im = a;
+ }
+}
+
+void cplx_cplxScalarProduct(FIXP_DPK *const Z, const FIXP_DPK *const *const X,
+ const FIXP_DPK *const *const Y, const INT scaleX,
+ const INT scaleY, INT *const scaleZ,
+ const INT sDim1, const INT nDim1, const INT sDim2,
+ const INT nDim2) {
+ int i, j, sx, sy;
+ FIXP_DBL xre, yre, xim, yim, re, im;
+
+ /* make sure that the scalefactor is in the range of -(DFRACT_BITS-1), ... ,
+ * (DFRACT_BITS-1) */
+ sx = fixMax(fixMin(scaleX, DFRACT_BITS - 1), -(DFRACT_BITS - 1));
+ sy = fixMax(fixMin(scaleY, DFRACT_BITS - 1), -(DFRACT_BITS - 1));
+
+ /* consider scaling of energy and scaling in fMultDiv2 and shift of result
+ * values */
+ *scaleZ = sx + sy + 2;
+
+ re = (FIXP_DBL)0;
+ im = (FIXP_DBL)0;
+ if ((sx < 0) && (sy < 0)) {
+ sx = -sx;
+ sy = -sy;
+ for (i = sDim1; i < nDim1; i++) {
+ for (j = sDim2; j < nDim2; j++) {
+ xre = X[i][j].v.re << sx;
+ xim = X[i][j].v.im << sx;
+ yre = Y[i][j].v.re << sy;
+ yim = Y[i][j].v.im << sy;
+ re += fMultDiv2(xre, yre) + fMultDiv2(xim, yim);
+ im += fMultDiv2(xim, yre) - fMultDiv2(xre, yim);
+ }
+ }
+ } else if ((sx >= 0) && (sy >= 0)) {
+ for (i = sDim1; i < nDim1; i++) {
+ for (j = sDim2; j < nDim2; j++) {
+ xre = X[i][j].v.re;
+ xim = X[i][j].v.im;
+ yre = Y[i][j].v.re;
+ yim = Y[i][j].v.im;
+ re += (fMultDiv2(xre, yre) + fMultDiv2(xim, yim)) >> (sx + sy);
+ im += (fMultDiv2(xim, yre) - fMultDiv2(xre, yim)) >> (sx + sy);
+ }
+ }
+ } else if ((sx < 0) && (sy >= 0)) {
+ sx = -sx;
+ for (i = sDim1; i < nDim1; i++) {
+ for (j = sDim2; j < nDim2; j++) {
+ xre = X[i][j].v.re << sx;
+ xim = X[i][j].v.im << sx;
+ yre = Y[i][j].v.re;
+ yim = Y[i][j].v.im;
+ re += (fMultDiv2(xre, yre) + fMultDiv2(xim, yim)) >> sy;
+ im += (fMultDiv2(xim, yre) - fMultDiv2(xre, yim)) >> sy;
+ }
+ }
+ } else {
+ sy = -sy;
+ for (i = sDim1; i < nDim1; i++) {
+ for (j = sDim2; j < nDim2; j++) {
+ xre = X[i][j].v.re;
+ xim = X[i][j].v.im;
+ yre = Y[i][j].v.re << sy;
+ yim = Y[i][j].v.im << sy;
+ re += (fMultDiv2(xre, yre) + fMultDiv2(xim, yim)) >> sx;
+ im += (fMultDiv2(xim, yre) - fMultDiv2(xre, yim)) >> sx;
+ }
+ }
+ }
+
+ Z->v.re = re >> 1;
+ Z->v.im = im >> 1;
+}
+
+void FDKcalcCorrelationVec(FIXP_DBL *const z, const FIXP_DBL *const pr12,
+ const FIXP_DBL *const p1, const FIXP_DBL *const p2,
+ const INT n) {
+ int i, s;
+ FIXP_DBL p12, cor;
+
+ /* correlation */
+ for (i = 0; i < n; i++) {
+ p12 = fMult(p1[i], p2[i]);
+ if (p12 > FL2FXCONST_DBL(0.0f)) {
+ p12 = invSqrtNorm2(p12, &s);
+ cor = fMult(pr12[i], p12);
+ z[i] = SATURATE_LEFT_SHIFT(cor, s, DFRACT_BITS);
+ } else {
+ z[i] = (FIXP_DBL)MAXVAL_DBL;
+ }
+ }
+}
+
+void calcCoherenceVec(FIXP_DBL *const z, const FIXP_DBL *const p12r,
+ const FIXP_DBL *const p12i, const FIXP_DBL *const p1,
+ const FIXP_DBL *const p2, const INT scaleP12,
+ const INT scaleP, const INT n) {
+ int i, s, s1, s2;
+ FIXP_DBL coh, p12, p12ri;
+
+ for (i = 0; i < n; i++) {
+ s2 = fixMin(fixMax(0, CountLeadingBits(p12r[i]) - 1),
+ fixMax(0, CountLeadingBits(p12i[i]) - 1));
+ p12ri = sqrtFixp(fPow2Div2(p12r[i] << s2) + fPow2Div2(p12i[i] << s2));
+ s1 = fixMin(fixMax(0, CountLeadingBits(p1[i]) - 1),
+ fixMax(0, CountLeadingBits(p2[i]) - 1));
+ p12 = fMultDiv2(p1[i] << s1, p2[i] << s1);
+
+ if (p12 > FL2FXCONST_DBL(0.0f)) {
+ p12 = invSqrtNorm2(p12, &s);
+ coh = fMult(p12ri, p12);
+ s = fixMax(fixMin((scaleP12 - scaleP + s + s1 - s2), DFRACT_BITS - 1),
+ -(DFRACT_BITS - 1));
+ if (s < 0) {
+ z[i] = coh >> (-s);
+ } else {
+ z[i] = SATURATE_LEFT_SHIFT(coh, s, DFRACT_BITS);
+ }
+ } else {
+ z[i] = (FIXP_DBL)MAXVAL_DBL;
+ }
+ }
+}
+
+void addWeightedCplxVec(FIXP_DPK *const *const Z, const FIXP_DBL *const a,
+ const FIXP_DPK *const *const X, const FIXP_DBL *const b,
+ const FIXP_DPK *const *const Y, const INT scale,
+ INT *const scaleCh1, const INT scaleCh2,
+ const UCHAR *const pParameterBand2HybridBandOffset,
+ const INT nParameterBands, const INT nTimeSlots,
+ const INT startTimeSlot) {
+ int pb, j, i;
+ int cs, s1, s2;
+
+ /* determine maximum scale of both channels */
+ cs = fixMax(*scaleCh1, scaleCh2);
+ s1 = cs - (*scaleCh1);
+ s2 = cs - scaleCh2;
+
+ /* scalefactor 1 is updated with common scale of channel 1 and channel2 */
+ *scaleCh1 = cs;
+
+ /* scale of a and b; additional scale for fMultDiv2() */
+ for (j = 0, pb = 0; pb < nParameterBands; pb++) {
+ FIXP_DBL aPb, bPb;
+ aPb = a[pb], bPb = b[pb];
+ for (; j < pParameterBand2HybridBandOffset[pb]; j++) {
+ for (i = startTimeSlot; i < nTimeSlots; i++) {
+ Z[j][i].v.re = ((fMultDiv2(aPb, X[j][i].v.re) >> s1) +
+ (fMultDiv2(bPb, Y[j][i].v.re) >> s2))
+ << (scale + 1);
+ Z[j][i].v.im = ((fMultDiv2(aPb, X[j][i].v.im) >> s1) +
+ (fMultDiv2(bPb, Y[j][i].v.im) >> s2))
+ << (scale + 1);
+ }
+ }
+ }
+}
+
+void FDKcalcPbScaleFactor(const FIXP_DPK *const *const x,
+ const UCHAR *const pParameterBand2HybridBandOffset,
+ INT *const outScaleFactor, const INT startTimeSlot,
+ const INT nTimeSlots, const INT nParamBands) {
+ int i, j, pb;
+
+ /* calculate headroom */
+ for (j = 0, pb = 0; pb < nParamBands; pb++) {
+ FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
+ for (; j < pParameterBand2HybridBandOffset[pb]; j++) {
+ for (i = startTimeSlot; i < nTimeSlots; i++) {
+ maxVal |= fAbs(x[i][j].v.re);
+ maxVal |= fAbs(x[i][j].v.im);
+ }
+ }
+ outScaleFactor[pb] = -fixMax(0, CntLeadingZeros(maxVal) - 1);
+ }
+}
+
+INT FDKcalcScaleFactor(const FIXP_DBL *const x, const FIXP_DBL *const y,
+ const INT n) {
+ int i;
+
+ /* calculate headroom */
+ FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
+ if (x != NULL) {
+ for (i = 0; i < n; i++) {
+ maxVal |= fAbs(x[i]);
+ }
+ }
+
+ if (y != NULL) {
+ for (i = 0; i < n; i++) {
+ maxVal |= fAbs(y[i]);
+ }
+ }
+
+ if (maxVal == (FIXP_DBL)0)
+ return (-(DFRACT_BITS - 1));
+ else
+ return (-CountLeadingBits(maxVal));
+}
+
+INT FDKcalcScaleFactorDPK(const FIXP_DPK *RESTRICT x, const INT startBand,
+ const INT bands) {
+ INT qs, clz;
+ FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
+
+ for (qs = startBand; qs < bands; qs++) {
+ maxVal |= fAbs(x[qs].v.re);
+ maxVal |= fAbs(x[qs].v.im);
+ }
+
+ clz = -fixMax(0, CntLeadingZeros(maxVal) - 1);
+
+ return (clz);
+}
diff --git a/libSACenc/src/sacenc_vectorfunctions.h b/libSACenc/src/sacenc_vectorfunctions.h
new file mode 100644
index 0000000..e9c4abd
--- /dev/null
+++ b/libSACenc/src/sacenc_vectorfunctions.h
@@ -0,0 +1,488 @@
+/* -----------------------------------------------------------------------------
+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
+----------------------------------------------------------------------------- */
+
+/*********************** MPEG surround encoder library *************************
+
+ Author(s): Josef Hoepfl
+
+ Description: Encoder Library Interface
+ vector functions
+
+*******************************************************************************/
+
+/*****************************************************************************
+\file
+This file contains vector functions
+******************************************************************************/
+
+#ifndef SACENC_VECTORFUNCTIONS_H
+#define SACENC_VECTORFUNCTIONS_H
+
+/* Includes ******************************************************************/
+#include "common_fix.h"
+
+/* Defines *******************************************************************/
+#define SUM_UP_STATIC_SCALE 0
+#define SUM_UP_DYNAMIC_SCALE 1
+
+/* Data Types ****************************************************************/
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+
+/**
+ * \brief Vector function : Sum up complex power
+ *
+ * Description : ret = sum( re{X[i]} * re{X[i]} + im{X[i]} *
+ * im{X[i]} ), i=0,...,n-1 ret is scaled by outScaleFactor
+ *
+ * \param const FIXP_DPK x[]
+ * Input: complex vector of the length n
+ *
+ * \param int scaleMode
+ * Input: choose static or dynamic scaling
+ * (SUM_UP_DYNAMIC_SCALE/SUM_UP_STATIC_SCALE)
+ *
+ * \param int inScaleFactor
+ * Input: determine headroom bits for the complex input vector
+ *
+ * \param int outScaleFactor
+ * Output: complete scaling in energy calculation
+ *
+ * \return FIXP_DBL ret
+ */
+FIXP_DBL sumUpCplxPow2(const FIXP_DPK *const x, const INT scaleMode,
+ const INT inScaleFactor, INT *const outScaleFactor,
+ const INT n);
+
+/**
+ * \brief Vector function : Sum up complex power
+ *
+ * Description : ret = sum( re{X[i][j]} * re{X[i][]} +
+ * im{X[i][]} * im{X[i][]} ), i=sDim1,...,nDim1-1 i=sDim2,...,nDim2-1 ret is
+ * scaled by outScaleFactor
+ *
+ * \param const FIXP_DPK x[]
+ * Input: complex vector of the length n
+ *
+ * \param int scaleMode
+ * Input: choose static or dynamic scaling
+ * (SUM_UP_DYNAMIC_SCALE/SUM_UP_STATIC_SCALE)
+ *
+ * \param int inScaleFactor
+ * Input: determine headroom bits for the complex input vector
+ *
+ * \param int outScaleFactor
+ * Output: complete scaling in energy calculation
+ *
+ * \param int sDim1
+ * Input: start index for loop counter in dimension 1
+ *
+ * \param int nDim1
+ * Input: loop counter in dimension 1
+ *
+ * \param int sDim2
+ * Input: start index for loop counter in dimension 2
+ *
+ * \param int nDim2
+ * Input: loop counter in dimension 2
+ *
+ * \return FIXP_DBL ret
+ */
+FIXP_DBL sumUpCplxPow2Dim2(const FIXP_DPK *const *const x, const INT scaleMode,
+ const INT inScaleFactor, INT *const outScaleFactor,
+ const INT sDim1, const INT nDim1, const INT sDim2,
+ const INT nDim2);
+
+/**
+ * \brief Vector function : Z[i] = X[i], i=0,...,n-1
+ *
+ * Description : re{Z[i]} = re{X[i]}, i=0,...,n-1
+ * im{Z[i]} = im{X[i]}, i=0,...,n-1
+ *
+ * Copy complex vector X[] to complex vector Z[].
+ * It is allowed to overlay X[] with Z[].
+ *
+ * \param FIXP_DPK Z[]
+ * Output: vector of the length n
+ *
+ * \param const FIXP_DPK X[]
+ * Input: vector of the length n
+ *
+ * \param int n
+ * Input: length of vector Z[] and X[]
+ *
+ * \return void
+ */
+void copyCplxVec(FIXP_DPK *const Z, const FIXP_DPK *const X, const INT n);
+
+/**
+ * \brief Vector function : Z[i] = a, i=0,...,n-1
+ *
+ * Description : re{Z[i]} = a, i=0,...,n-1
+ * im{Z[i]} = a, i=0,...,n-1
+ *
+ * Set real and imaginary part of the complex value Z to a.
+ *
+ * \param FIPX_DPK Z[]
+ * Output: vector of the length n
+ *
+ * \param const FIXP_DBL a
+ * Input: constant value
+ *
+ * \param int n
+ * Input: length of vector Z[]
+ *
+ * \return void
+ */
+void setCplxVec(FIXP_DPK *const Z, const FIXP_DBL a, const INT n);
+
+/**
+ * \brief Vector function : Calculate complex-valued result of complex
+ * scalar product
+ *
+ * Description : re{Z} = sum( re{X[i]} * re{Y[i]} + im{X[i]} *
+ * im{Y[i]}, i=0,...,n-1 ) im{Z} = sum( im{X[i]} * re{Y[i]} - re{X[i]} *
+ * im{Y[i]}, i=0,...,n-1 )
+ *
+ * The function returns the complex-valued result of the complex
+ * scalar product at the address of Z. The result is scaled by scaleZ.
+ *
+ * \param FIXP_DPK *Z
+ * Output: pointer to Z
+ *
+ * \param const FIXP_DPK *const *const X
+ * Input: vector of the length n
+ *
+ * \param const FIXP_DPK *const *const Y
+ * Input: vector of the length n
+ *
+ * \param int scaleX
+ * Input: scalefactor of vector X[]
+ *
+ * \param int scaleY
+ * Input: scalefactor of vector Y[]
+ *
+ * \param int scaleZ
+ * Output: scalefactor of vector Z[]
+ *
+ * \param int sDim1
+ * Input: start index for loop counter in dimension 1
+ *
+ * \param int nDim1
+ * Input: loop counter in dimension 1
+ *
+ * \param int sDim2
+ * Input: start index for loop counter in dimension 2
+ *
+ * \param int nDim2
+ * Input: loop counter in dimension 2
+ *
+ * \return void
+ */
+void cplx_cplxScalarProduct(FIXP_DPK *const Z, const FIXP_DPK *const *const X,
+ const FIXP_DPK *const *const Y, const INT scaleX,
+ const INT scaleY, INT *const scaleZ,
+ const INT sDim1, const INT nDim1, const INT sDim2,
+ const INT nDim2);
+
+/**
+ * \brief Vector function : Calculate correlation
+ *
+ * Description : z[i] = pr12[i] / sqrt(p1[i]*p2[i]) ,
+ * i=0,...,n-1
+ *
+ * \param FIXP_DBL z[]
+ * Output: vector of length n
+ *
+ * \param const FIXP_DBL pr12[]
+ * Input: vector of the length n
+ *
+ * \param const FIXP_DBL p1[]
+ * Input: vector of the length n
+ *
+ * \param const FIXP_DBL p2[]
+ * Input: vector of the length n
+ *
+ * \param int n
+ * Input: length of vector pr12[], p1[] and p2[]
+ *
+ * \return void
+ */
+void FDKcalcCorrelationVec(FIXP_DBL *const z, const FIXP_DBL *const pr12,
+ const FIXP_DBL *const p1, const FIXP_DBL *const p2,
+ const INT n);
+
+/**
+ * \brief Vector function : Calculate coherence
+ *
+ * Description : z[i] = sqrt( (p12r[i]*p12r[i] +
+ * p12i[i]*p12i[i]) / (p1[i]*p2[i]) ), i=0,...,n-1
+ *
+ * \param FIXP_DBL z[]
+ * Output: vector of length n
+ *
+ * \param const FIXP_DBL p12r[]
+ * Input: vector of the length n
+ *
+ * \param const FIXP_DBL p12i[]
+ * Input: vector of the length n
+ *
+ * \param const FIXP_DBL p1[]
+ * Input: vector of the length n
+ *
+ * \param const FIXP_DBL p2[]
+ * Input: vector of the length n
+ *
+ * \param int scaleP12[]
+ * Input: scalefactor of p12r and p12i
+ *
+ * \param int scaleP
+ * Input: scalefactor of p1 and p2
+ *
+ * \param int n
+ * Input: length of vector p12r[], p12i[], p1[] and p2[]
+ *
+ * \return void
+ */
+void calcCoherenceVec(FIXP_DBL *const z, const FIXP_DBL *const p12r,
+ const FIXP_DBL *const p12i, const FIXP_DBL *const p1,
+ const FIXP_DBL *const p2, const INT scaleP12,
+ const INT scaleP, const INT n);
+
+/**
+ * \brief Vector function : Z[j][i] = a[pb] * X[j][i] + b[pb] *
+ * Y[j][i], j=0,...,nHybridBands-1; i=startTimeSlot,...,nTimeSlots-1;
+ * pb=0,...,nParameterBands-1
+ *
+ * Description : re{Z[j][i]} = a[pb] * re{X[j][i]} + b[pb] *
+ * re{Y[j][i]}, j=0,...,nHybridBands-1; i=startTimeSlot,...,nTimeSlots-1;
+ * pb=0,...,nParameterBands-1 im{Z[j][i]} = a[pb] * im{X[j][i]} + b[pb] *
+ * im{Y[j][i]}, j=0,...,nHybridBands-1;
+ * i=startTimeSlot,...,nTimeSlots-1; pb=0,...,nParameterBands-1
+ *
+ * It is allowed to overlay X[] or Y[] with Z[]. The scalefactor
+ * of channel 1 is updated with the common scalefactor of channel 1 and
+ * channel 2.
+ *
+ * \param FIXP_DPK **Z
+ * Output: vector of the length nHybridBands*nTimeSlots
+ *
+ * \param const FIXP_DBL *a
+ * Input: vector of length nParameterBands
+ *
+ * \param const FIXP_DPK **X
+ * Input: vector of the length nHybridBands*nTimeSlots
+ *
+ * \param const FIXP_DBL *b
+ * Input: vector of length nParameterBands
+ *
+ * \param const FIXP_DPK **Y
+ * Input: vector of the length nHybridBands*nTimeSlots
+ *
+ * \param int scale
+ * Input: scale of vector a and b
+ *
+ * \param int *scaleCh1
+ * Input: scale of ch1
+ *
+ * \param int scaleCh2
+ * Input: scale of ch2
+ *
+ * \param UCHAR *pParameterBand2HybridBandOffset
+ * Input: vector of length nParameterBands
+ *
+ * \param int nTimeSlots
+ * Input: number of time slots
+ *
+ * \param int startTimeSlot
+ * Input: start time slot
+ *
+ * \return void
+ */
+void addWeightedCplxVec(FIXP_DPK *const *const Z, const FIXP_DBL *const a,
+ const FIXP_DPK *const *const X, const FIXP_DBL *const b,
+ const FIXP_DPK *const *const Y, const INT scale,
+ INT *const scaleCh1, const INT scaleCh2,
+ const UCHAR *const pParameterBand2HybridBandOffset,
+ const INT nParameterBands, const INT nTimeSlots,
+ const INT startTimeSlot);
+
+/**
+ * \brief Vector function : Calculate the headroom of a complex vector
+ * in a parameter band grid
+ *
+ * \param FIXP_DPK **x
+ * Input: pointer to complex input vector
+ *
+ * \param UCHAR *pParameterBand2HybridBandOffset
+ * Input: pointer to hybrid band offsets
+ *
+ * \param int *outScaleFactor
+ * Input: pointer to ouput scalefactor
+ *
+ * \param int startTimeSlot
+ * Input: start time slot
+ *
+ * \param int nTimeSlots
+ * Input: number of time slot
+ *
+ * \param int nParamBands
+ * Input: number of parameter bands
+ *
+ * \return void
+ */
+void FDKcalcPbScaleFactor(const FIXP_DPK *const *const x,
+ const UCHAR *const pParameterBand2HybridBandOffset,
+ INT *const outScaleFactor, const INT startTimeSlot,
+ const INT nTimeSlots, const INT nParamBands);
+
+/**
+ * \brief Vector function : Calculate the common headroom of two
+ * sparate vectors
+ *
+ * \param FIXP_DBL *x
+ * Input: pointer to first input vector
+ *
+ * \param FIXP_DBL *y
+ * Input: pointer to second input vector
+ *
+ * \param int n
+ * Input: number of samples
+ *
+ * \return int headromm in bits
+ */
+INT FDKcalcScaleFactor(const FIXP_DBL *const x, const FIXP_DBL *const y,
+ const INT n);
+
+/**
+ * \brief Vector function : Calculate the headroom of a complex vector
+ *
+ * \param FIXP_DPK *x
+ * Input: pointer to complex input vector
+ *
+ * \param INT startBand
+ * Input: start band
+ *
+ * \param INT bands
+ * Input: number of bands
+ *
+ * \return int headromm in bits
+ */
+INT FDKcalcScaleFactorDPK(const FIXP_DPK *RESTRICT x, const INT startBand,
+ const INT bands);
+
+/* Function / Class Definition ***********************************************/
+template <class T>
+inline void FDKmemcpy_flex(T *const dst, const INT dstStride,
+ const T *const src, const INT srcStride,
+ const INT nSamples) {
+ int i;
+
+ for (i = 0; i < nSamples; i++) {
+ dst[i * dstStride] = src[i * srcStride];
+ }
+}
+
+template <class T>
+inline void FDKmemset_flex(T *const x, const T c, const INT nSamples) {
+ int i;
+
+ for (i = 0; i < nSamples; i++) {
+ x[i] = c;
+ }
+}
+
+#endif /* SACENC_VECTORFUNCTIONS_H */