aboutsummaryrefslogtreecommitdiffstats
path: root/fdk-aac/libAACenc/src
diff options
context:
space:
mode:
Diffstat (limited to 'fdk-aac/libAACenc/src')
-rw-r--r--fdk-aac/libAACenc/src/aacEnc_ram.cpp208
-rw-r--r--fdk-aac/libAACenc/src/aacEnc_ram.h249
-rw-r--r--fdk-aac/libAACenc/src/aacEnc_rom.cpp2486
-rw-r--r--fdk-aac/libAACenc/src/aacEnc_rom.h217
-rw-r--r--fdk-aac/libAACenc/src/aacenc.cpp1057
-rw-r--r--fdk-aac/libAACenc/src/aacenc.h394
-rw-r--r--fdk-aac/libAACenc/src/aacenc_lib.cpp2575
-rw-r--r--fdk-aac/libAACenc/src/aacenc_pns.cpp541
-rw-r--r--fdk-aac/libAACenc/src/aacenc_pns.h124
-rw-r--r--fdk-aac/libAACenc/src/aacenc_tns.cpp1210
-rw-r--r--fdk-aac/libAACenc/src/aacenc_tns.h213
-rw-r--r--fdk-aac/libAACenc/src/adj_thr.cpp2924
-rw-r--r--fdk-aac/libAACenc/src/adj_thr.h166
-rw-r--r--fdk-aac/libAACenc/src/adj_thr_data.h175
-rw-r--r--fdk-aac/libAACenc/src/band_nrg.cpp361
-rw-r--r--fdk-aac/libAACenc/src/band_nrg.h142
-rw-r--r--fdk-aac/libAACenc/src/bandwidth.cpp360
-rw-r--r--fdk-aac/libAACenc/src/bandwidth.h114
-rw-r--r--fdk-aac/libAACenc/src/bit_cnt.cpp950
-rw-r--r--fdk-aac/libAACenc/src/bit_cnt.h200
-rw-r--r--fdk-aac/libAACenc/src/bitenc.cpp1362
-rw-r--r--fdk-aac/libAACenc/src/bitenc.h184
-rw-r--r--fdk-aac/libAACenc/src/block_switch.cpp582
-rw-r--r--fdk-aac/libAACenc/src/block_switch.h162
-rw-r--r--fdk-aac/libAACenc/src/channel_map.cpp664
-rw-r--r--fdk-aac/libAACenc/src/channel_map.h136
-rw-r--r--fdk-aac/libAACenc/src/chaosmeasure.cpp191
-rw-r--r--fdk-aac/libAACenc/src/chaosmeasure.h112
-rw-r--r--fdk-aac/libAACenc/src/dyn_bits.cpp665
-rw-r--r--fdk-aac/libAACenc/src/dyn_bits.h160
-rw-r--r--fdk-aac/libAACenc/src/grp_data.cpp264
-rw-r--r--fdk-aac/libAACenc/src/grp_data.h123
-rw-r--r--fdk-aac/libAACenc/src/intensity.cpp810
-rw-r--r--fdk-aac/libAACenc/src/intensity.h121
-rw-r--r--fdk-aac/libAACenc/src/interface.h168
-rw-r--r--fdk-aac/libAACenc/src/line_pe.cpp234
-rw-r--r--fdk-aac/libAACenc/src/line_pe.h148
-rw-r--r--fdk-aac/libAACenc/src/metadata_compressor.cpp1579
-rw-r--r--fdk-aac/libAACenc/src/metadata_compressor.h255
-rw-r--r--fdk-aac/libAACenc/src/metadata_main.cpp1191
-rw-r--r--fdk-aac/libAACenc/src/metadata_main.h226
-rw-r--r--fdk-aac/libAACenc/src/mps_main.cpp529
-rw-r--r--fdk-aac/libAACenc/src/mps_main.h270
-rw-r--r--fdk-aac/libAACenc/src/ms_stereo.cpp295
-rw-r--r--fdk-aac/libAACenc/src/ms_stereo.h117
-rw-r--r--fdk-aac/libAACenc/src/noisedet.cpp235
-rw-r--r--fdk-aac/libAACenc/src/noisedet.h116
-rw-r--r--fdk-aac/libAACenc/src/pns_func.h138
-rw-r--r--fdk-aac/libAACenc/src/pnsparam.cpp574
-rw-r--r--fdk-aac/libAACenc/src/pnsparam.h149
-rw-r--r--fdk-aac/libAACenc/src/pre_echo_control.cpp176
-rw-r--r--fdk-aac/libAACenc/src/pre_echo_control.h118
-rw-r--r--fdk-aac/libAACenc/src/psy_configuration.cpp801
-rw-r--r--fdk-aac/libAACenc/src/psy_configuration.h171
-rw-r--r--fdk-aac/libAACenc/src/psy_const.h169
-rw-r--r--fdk-aac/libAACenc/src/psy_data.h169
-rw-r--r--fdk-aac/libAACenc/src/psy_main.cpp1348
-rw-r--r--fdk-aac/libAACenc/src/psy_main.h161
-rw-r--r--fdk-aac/libAACenc/src/qc_data.h299
-rw-r--r--fdk-aac/libAACenc/src/qc_main.cpp1555
-rw-r--r--fdk-aac/libAACenc/src/qc_main.h158
-rw-r--r--fdk-aac/libAACenc/src/quantize.cpp401
-rw-r--r--fdk-aac/libAACenc/src/quantize.h127
-rw-r--r--fdk-aac/libAACenc/src/sf_estim.cpp1292
-rw-r--r--fdk-aac/libAACenc/src/sf_estim.h124
-rw-r--r--fdk-aac/libAACenc/src/spreading.cpp125
-rw-r--r--fdk-aac/libAACenc/src/spreading.h113
-rw-r--r--fdk-aac/libAACenc/src/tns_func.h129
-rw-r--r--fdk-aac/libAACenc/src/tonality.cpp219
-rw-r--r--fdk-aac/libAACenc/src/tonality.h115
-rw-r--r--fdk-aac/libAACenc/src/transform.cpp294
-rw-r--r--fdk-aac/libAACenc/src/transform.h163
72 files changed, 34653 insertions, 0 deletions
diff --git a/fdk-aac/libAACenc/src/aacEnc_ram.cpp b/fdk-aac/libAACenc/src/aacEnc_ram.cpp
new file mode 100644
index 0000000..77b1131
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacEnc_ram.cpp
@@ -0,0 +1,208 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser, M. Gayer
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Memory layout
+ \author Markus Lohwasser
+*/
+
+#include "aacEnc_ram.h"
+
+C_AALLOC_MEM(AACdynamic_RAM, FIXP_DBL, AAC_ENC_DYN_RAM_SIZE / sizeof(FIXP_DBL))
+
+/*
+ Static memory areas, must not be overwritten in other sections of the decoder
+ !
+*/
+
+/*
+ The structure AacEncoder contains all Encoder structures.
+*/
+
+C_ALLOC_MEM(Ram_aacEnc_AacEncoder, struct AAC_ENC, 1)
+
+/*
+ The structure PSY_INTERNAl contains all psych configuration and data pointer.
+ * PsyStatic holds last and current Psych data.
+ * PsyInputBuffer contains time input. Signal is needed at the beginning of
+ Psych. Memory can be reused after signal is in time domain.
+ * PsyData contains spectral, nrg and threshold information. Necessary data
+ are copied into PsyOut, so memory is available after leaving psych.
+ * TnsData, ChaosMeasure, PnsData are temporarily necessary, e.g. use memory
+ from PsyInputBuffer.
+*/
+
+C_ALLOC_MEM2(Ram_aacEnc_PsyElement, PSY_ELEMENT, 1, ((8)))
+
+C_ALLOC_MEM(Ram_aacEnc_PsyInternal, PSY_INTERNAL, 1)
+C_ALLOC_MEM2(Ram_aacEnc_PsyStatic, PSY_STATIC, 1, (8))
+
+C_ALLOC_MEM2(Ram_aacEnc_PsyInputBuffer, INT_PCM, MAX_INPUT_BUFFER_SIZE, (8))
+
+PSY_DYNAMIC *GetRam_aacEnc_PsyDynamic(int n, UCHAR *dynamic_RAM) {
+ FDK_ASSERT(dynamic_RAM != 0);
+ /* The reinterpret_cast is used to suppress a compiler warning. We know that
+ * (dynamic_RAM + P_BUF_1 + n*sizeof(PSY_DYNAMIC)) is sufficiently aligned, so
+ * the cast is safe */
+ return reinterpret_cast<PSY_DYNAMIC *>(reinterpret_cast<void *>(
+ dynamic_RAM + P_BUF_1 + n * sizeof(PSY_DYNAMIC)));
+}
+
+/*
+ The structure PSY_OUT holds all psychoaccoustic data needed
+ in quantization module
+*/
+C_ALLOC_MEM2(Ram_aacEnc_PsyOut, PSY_OUT, 1, (1))
+
+C_ALLOC_MEM2(Ram_aacEnc_PsyOutElements, PSY_OUT_ELEMENT, 1, (1) * ((8)))
+C_ALLOC_MEM2(Ram_aacEnc_PsyOutChannel, PSY_OUT_CHANNEL, 1, (1) * (8))
+
+/*
+ The structure QC_STATE contains preinitialized settings and quantizer
+ structures.
+ * AdjustThreshold structure contains element-wise settings.
+ * ElementBits contains elemnt-wise bit consumption settings.
+ * When CRC is active, lookup table is necessary for fast crc calculation.
+ * Bitcounter contains buffer to find optimal codebooks and minimal bit
+ consumption. Values are temporarily, so dynamic memory can be used.
+*/
+
+C_ALLOC_MEM(Ram_aacEnc_QCstate, QC_STATE, 1)
+C_ALLOC_MEM(Ram_aacEnc_AdjustThreshold, ADJ_THR_STATE, 1)
+
+C_ALLOC_MEM2(Ram_aacEnc_AdjThrStateElement, ATS_ELEMENT, 1, ((8)))
+C_ALLOC_MEM2(Ram_aacEnc_ElementBits, ELEMENT_BITS, 1, ((8)))
+C_ALLOC_MEM(Ram_aacEnc_BitCntrState, struct BITCNTR_STATE, 1)
+
+INT *GetRam_aacEnc_BitLookUp(int n, UCHAR *dynamic_RAM) {
+ FDK_ASSERT(dynamic_RAM != 0);
+ /* The reinterpret_cast is used to suppress a compiler warning. We know that
+ * (dynamic_RAM + P_BUF_1) is sufficiently aligned, so the cast is safe */
+ return reinterpret_cast<INT *>(
+ reinterpret_cast<void *>(dynamic_RAM + P_BUF_1));
+}
+INT *GetRam_aacEnc_MergeGainLookUp(int n, UCHAR *dynamic_RAM) {
+ FDK_ASSERT(dynamic_RAM != 0);
+ /* The reinterpret_cast is used to suppress a compiler warning. We know that
+ * (dynamic_RAM + P_BUF_1 + sizeof(INT)*(MAX_SFB_LONG*(CODE_BOOK_ESC_NDX+1)))
+ * is sufficiently aligned, so the cast is safe */
+ return reinterpret_cast<INT *>(reinterpret_cast<void *>(
+ dynamic_RAM + P_BUF_1 +
+ sizeof(INT) * (MAX_SFB_LONG * (CODE_BOOK_ESC_NDX + 1))));
+}
+
+/*
+ The structure QC_OUT contains settings and structures holding all necessary
+ information needed in bitstreamwriter.
+*/
+
+C_ALLOC_MEM2(Ram_aacEnc_QCout, QC_OUT, 1, (1))
+C_ALLOC_MEM2(Ram_aacEnc_QCelement, QC_OUT_ELEMENT, 1, (1) * ((8)))
+QC_OUT_CHANNEL *GetRam_aacEnc_QCchannel(int n, UCHAR *dynamic_RAM) {
+ FDK_ASSERT(dynamic_RAM != 0);
+ /* The reinterpret_cast is used to suppress a compiler warning. We know that
+ * (dynamic_RAM + P_BUF_0 + n*sizeof(QC_OUT_CHANNEL)) is sufficiently aligned,
+ * so the cast is safe */
+ return reinterpret_cast<QC_OUT_CHANNEL *>(reinterpret_cast<void *>(
+ dynamic_RAM + P_BUF_0 + n * sizeof(QC_OUT_CHANNEL)));
+}
diff --git a/fdk-aac/libAACenc/src/aacEnc_ram.h b/fdk-aac/libAACenc/src/aacEnc_ram.h
new file mode 100644
index 0000000..0775aae
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacEnc_ram.h
@@ -0,0 +1,249 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser, M. Gayer
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Memory layout
+ \author Markus Lohwasser
+*/
+
+#ifndef AACENC_RAM_H
+#define AACENC_RAM_H
+
+#include "common_fix.h"
+
+#include "aacenc.h"
+#include "psy_data.h"
+#include "interface.h"
+#include "psy_main.h"
+#include "bitenc.h"
+#include "bit_cnt.h"
+#include "psy_const.h"
+
+#define OUTPUTBUFFER_SIZE \
+ (8192) /*!< Output buffer size has to be at least 6144 bits per channel \
+ (768 bytes). FDK bitbuffer implementation expects buffer of \
+ size 2^n. */
+
+/*
+ Moved AAC_ENC struct definition from aac_enc.cpp into aacEnc_ram.h to get size
+ and respective static memory in aacEnc_ram.cpp. aac_enc.h is the outward
+ visible header file and putting the struct into would cause necessity of
+ additional visible header files outside library.
+*/
+
+/* define hBitstream size: max AAC framelength is 6144 bits/channel */
+/*#define BUFFER_BITSTR_SIZE ((6400*(8)/bbWordSize) +((bbWordSize - 1) /
+ * bbWordSize))*/
+
+struct AAC_ENC {
+ AACENC_CONFIG *config;
+
+ INT ancillaryBitsPerFrame; /* ancillary bits per frame calculated from
+ ancillary rate */
+
+ CHANNEL_MAPPING channelMapping;
+
+ QC_STATE *qcKernel;
+ QC_OUT *qcOut[(1)];
+
+ PSY_OUT *psyOut[(1)];
+ PSY_INTERNAL *psyKernel;
+
+ /* lifetime vars */
+
+ CHANNEL_MODE encoderMode;
+ INT bandwidth90dB;
+ AACENC_BITRATE_MODE bitrateMode;
+
+ INT dontWriteAdif; /* use: write ADIF header only before 1st frame */
+
+ FIXP_DBL *dynamic_RAM;
+
+ INT maxChannels; /* used while allocation */
+ INT maxElements;
+ INT maxFrames;
+
+ AUDIO_OBJECT_TYPE aot; /* AOT to be used while encoding. */
+};
+
+#define maxSize(a, b) (((a) > (b)) ? (a) : (b))
+
+#define BIT_LOOK_UP_SIZE \
+ (sizeof(INT) * (MAX_SFB_LONG * (CODE_BOOK_ESC_NDX + 1)))
+#define MERGE_GAIN_LOOK_UP_SIZE (sizeof(INT) * MAX_SFB_LONG)
+
+/* Size of AhFlag buffer in function FDKaacEnc_adaptThresholdsToPe() */
+#define ADJ_THR_AH_FLAG_SIZE (sizeof(UCHAR) * ((8)) * (2) * MAX_GROUPED_SFB)
+/* Size of ThrExp buffer in function FDKaacEnc_adaptThresholdsToPe() */
+#define ADJ_THR_THR_EXP_SIZE (sizeof(FIXP_DBL) * ((8)) * (2) * MAX_GROUPED_SFB)
+/* Size of sfbNActiveLinesLdData buffer in function FDKaacEnc_correctThresh() */
+#define ADJ_THR_ACT_LIN_LD_DATA_SIZE \
+ (sizeof(FIXP_DBL) * ((8)) * (2) * MAX_GROUPED_SFB)
+/* Total amount of dynamic buffer needed in adjust thresholds functionality */
+#define ADJ_THR_SIZE \
+ (ADJ_THR_AH_FLAG_SIZE + ADJ_THR_THR_EXP_SIZE + ADJ_THR_ACT_LIN_LD_DATA_SIZE)
+
+/* Dynamic RAM - Allocation */
+/*
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ | P_BUF_0 | P_BUF_1 |
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ | QC_OUT_CH | PSY_DYN |
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ | | BitLookUp+MergeGainLookUp |
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ | | AH_FLAG | THR_EXP | ACT_LIN_LD_DATA |
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ | | Bitstream output buffer |
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++
+*/
+
+#define BUF_SIZE_0 (ALIGN_SIZE(sizeof(QC_OUT_CHANNEL) * (8)))
+#define BUF_SIZE_1 \
+ (ALIGN_SIZE(maxSize(maxSize(sizeof(PSY_DYNAMIC), \
+ (BIT_LOOK_UP_SIZE + MERGE_GAIN_LOOK_UP_SIZE)), \
+ ADJ_THR_SIZE)))
+
+#define P_BUF_0 (0)
+#define P_BUF_1 (P_BUF_0 + BUF_SIZE_0)
+
+#define AAC_ENC_DYN_RAM_SIZE (BUF_SIZE_0 + BUF_SIZE_1)
+
+H_ALLOC_MEM(AACdynamic_RAM, FIXP_DBL)
+/*
+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+END - Dynamic RAM - Allocation */
+
+/*
+ See further Memory Allocation details in aacEnc_ram.cpp
+*/
+H_ALLOC_MEM(Ram_aacEnc_AacEncoder, AAC_ENC)
+
+H_ALLOC_MEM(Ram_aacEnc_PsyElement, PSY_ELEMENT)
+
+H_ALLOC_MEM(Ram_aacEnc_PsyInternal, PSY_INTERNAL)
+H_ALLOC_MEM(Ram_aacEnc_PsyStatic, PSY_STATIC)
+H_ALLOC_MEM(Ram_aacEnc_PsyInputBuffer, INT_PCM)
+
+PSY_DYNAMIC *GetRam_aacEnc_PsyDynamic(int n, UCHAR *dynamic_RAM);
+
+H_ALLOC_MEM(Ram_aacEnc_PsyOutChannel, PSY_OUT_CHANNEL)
+
+H_ALLOC_MEM(Ram_aacEnc_PsyOut, PSY_OUT)
+H_ALLOC_MEM(Ram_aacEnc_PsyOutElements, PSY_OUT_ELEMENT)
+
+H_ALLOC_MEM(Ram_aacEnc_QCstate, QC_STATE)
+H_ALLOC_MEM(Ram_aacEnc_AdjustThreshold, ADJ_THR_STATE)
+
+H_ALLOC_MEM(Ram_aacEnc_AdjThrStateElement, ATS_ELEMENT)
+H_ALLOC_MEM(Ram_aacEnc_ElementBits, ELEMENT_BITS)
+H_ALLOC_MEM(Ram_aacEnc_BitCntrState, BITCNTR_STATE)
+
+INT *GetRam_aacEnc_BitLookUp(int n, UCHAR *dynamic_RAM);
+INT *GetRam_aacEnc_MergeGainLookUp(int n, UCHAR *dynamic_RAM);
+QC_OUT_CHANNEL *GetRam_aacEnc_QCchannel(int n, UCHAR *dynamic_RAM);
+
+H_ALLOC_MEM(Ram_aacEnc_QCout, QC_OUT)
+H_ALLOC_MEM(Ram_aacEnc_QCelement, QC_OUT_ELEMENT)
+
+#endif /* #ifndef AACENC_RAM_H */
diff --git a/fdk-aac/libAACenc/src/aacEnc_rom.cpp b/fdk-aac/libAACenc/src/aacEnc_rom.cpp
new file mode 100644
index 0000000..ac0fa9d
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacEnc_rom.cpp
@@ -0,0 +1,2486 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser, M. Gayer
+
+ Description:
+
+*******************************************************************************/
+
+#include "aacEnc_rom.h"
+
+/*
+ Huffman Tables
+*/
+const ULONG FDKaacEnc_huff_ltab1_2[3][3][3][3] = {
+ {{{0x000b0009, 0x00090007, 0x000b0009},
+ {0x000a0008, 0x00070006, 0x000a0008},
+ {0x000b0009, 0x00090008, 0x000b0009}},
+ {{0x000a0008, 0x00070006, 0x000a0007},
+ {0x00070006, 0x00050005, 0x00070006},
+ {0x00090007, 0x00070006, 0x000a0008}},
+ {{0x000b0009, 0x00090007, 0x000b0008},
+ {0x00090008, 0x00070006, 0x00090008},
+ {0x000b0009, 0x00090007, 0x000b0009}}},
+ {{{0x00090008, 0x00070006, 0x00090007},
+ {0x00070006, 0x00050005, 0x00070006},
+ {0x00090007, 0x00070006, 0x00090008}},
+ {{0x00070006, 0x00050005, 0x00070006},
+ {0x00050005, 0x00010003, 0x00050005},
+ {0x00070006, 0x00050005, 0x00070006}},
+ {{0x00090008, 0x00070006, 0x00090007},
+ {0x00070006, 0x00050005, 0x00070006},
+ {0x00090008, 0x00070006, 0x00090008}}},
+ {{{0x000b0009, 0x00090007, 0x000b0009},
+ {0x00090008, 0x00070006, 0x00090008},
+ {0x000b0008, 0x00090007, 0x000b0009}},
+ {{0x000a0008, 0x00070006, 0x00090007},
+ {0x00070006, 0x00050004, 0x00070006},
+ {0x00090008, 0x00070006, 0x000a0007}},
+ {{0x000b0009, 0x00090007, 0x000b0009},
+ {0x000a0007, 0x00070006, 0x00090008},
+ {0x000b0009, 0x00090007, 0x000b0009}}}};
+
+const ULONG FDKaacEnc_huff_ltab3_4[3][3][3][3] = {
+ {{{0x00010004, 0x00040005, 0x00080008},
+ {0x00040005, 0x00050004, 0x00080008},
+ {0x00090009, 0x00090008, 0x000a000b}},
+ {{0x00040005, 0x00060005, 0x00090008},
+ {0x00060005, 0x00060004, 0x00090008},
+ {0x00090008, 0x00090007, 0x000a000a}},
+ {{0x00090009, 0x000a0008, 0x000d000b},
+ {0x00090008, 0x00090008, 0x000b000a},
+ {0x000b000b, 0x000a000a, 0x000c000b}}},
+ {{{0x00040004, 0x00060005, 0x000a0008},
+ {0x00060004, 0x00070004, 0x000a0008},
+ {0x000a0008, 0x000a0008, 0x000c000a}},
+ {{0x00050004, 0x00070004, 0x000b0008},
+ {0x00060004, 0x00070004, 0x000a0007},
+ {0x00090008, 0x00090007, 0x000b0009}},
+ {{0x00090008, 0x000a0008, 0x000d000a},
+ {0x00080007, 0x00090007, 0x000c0009},
+ {0x000a000a, 0x000b0009, 0x000c000a}}},
+ {{{0x00080008, 0x000a0008, 0x000f000b},
+ {0x00090008, 0x000b0007, 0x000f000a},
+ {0x000d000b, 0x000e000a, 0x0010000c}},
+ {{0x00080008, 0x000a0007, 0x000e000a},
+ {0x00090007, 0x000a0007, 0x000e0009},
+ {0x000c000a, 0x000c0009, 0x000f000b}},
+ {{0x000b000b, 0x000c000a, 0x0010000c},
+ {0x000a000a, 0x000b0009, 0x000f000b},
+ {0x000c000b, 0x000c000a, 0x000f000b}}}};
+
+const ULONG FDKaacEnc_huff_ltab5_6[9][9] = {
+ {0x000d000b, 0x000c000a, 0x000b0009, 0x000b0009, 0x000a0009, 0x000b0009,
+ 0x000b0009, 0x000c000a, 0x000d000b},
+ {0x000c000a, 0x000b0009, 0x000a0008, 0x00090007, 0x00080007, 0x00090007,
+ 0x000a0008, 0x000b0009, 0x000c000a},
+ {0x000c0009, 0x000a0008, 0x00090006, 0x00080006, 0x00070006, 0x00080006,
+ 0x00090006, 0x000a0008, 0x000b0009},
+ {0x000b0009, 0x00090007, 0x00080006, 0x00050004, 0x00040004, 0x00050004,
+ 0x00080006, 0x00090007, 0x000b0009},
+ {0x000a0009, 0x00080007, 0x00070006, 0x00040004, 0x00010004, 0x00040004,
+ 0x00070006, 0x00080007, 0x000b0009},
+ {0x000b0009, 0x00090007, 0x00080006, 0x00050004, 0x00040004, 0x00050004,
+ 0x00080006, 0x00090007, 0x000b0009},
+ {0x000b0009, 0x000a0008, 0x00090006, 0x00080006, 0x00070006, 0x00080006,
+ 0x00090006, 0x000a0008, 0x000b0009},
+ {0x000c000a, 0x000b0009, 0x000a0008, 0x00090007, 0x00080007, 0x00090007,
+ 0x000a0007, 0x000b0008, 0x000c000a},
+ {0x000d000b, 0x000c000a, 0x000c0009, 0x000b0009, 0x000a0009, 0x000a0009,
+ 0x000b0009, 0x000c000a, 0x000d000b}};
+
+const ULONG FDKaacEnc_huff_ltab7_8[8][8] = {
+ {0x00010005, 0x00030004, 0x00060005, 0x00070006, 0x00080007, 0x00090008,
+ 0x000a0009, 0x000b000a},
+ {0x00030004, 0x00040003, 0x00060004, 0x00070005, 0x00080006, 0x00080007,
+ 0x00090007, 0x00090008},
+ {0x00060005, 0x00060004, 0x00070004, 0x00080005, 0x00080006, 0x00090007,
+ 0x00090007, 0x000a0008},
+ {0x00070006, 0x00070005, 0x00080005, 0x00080006, 0x00090006, 0x00090007,
+ 0x000a0008, 0x000a0008},
+ {0x00080007, 0x00080006, 0x00090006, 0x00090006, 0x000a0007, 0x000a0007,
+ 0x000a0008, 0x000b0009},
+ {0x00090008, 0x00080007, 0x00090006, 0x00090007, 0x000a0007, 0x000a0008,
+ 0x000b0008, 0x000b000a},
+ {0x000a0009, 0x00090007, 0x00090007, 0x000a0008, 0x000a0008, 0x000b0008,
+ 0x000c0009, 0x000c0009},
+ {0x000b000a, 0x000a0008, 0x000a0008, 0x000a0008, 0x000b0009, 0x000b0009,
+ 0x000c0009, 0x000c000a}};
+
+const ULONG FDKaacEnc_huff_ltab9_10[13][13] = {
+ {0x00010006, 0x00030005, 0x00060006, 0x00080006, 0x00090007, 0x000a0008,
+ 0x000a0009, 0x000b000a, 0x000b000a, 0x000c000a, 0x000c000b, 0x000d000b,
+ 0x000d000c},
+ {0x00030005, 0x00040004, 0x00060004, 0x00070005, 0x00080006, 0x00080007,
+ 0x00090007, 0x000a0008, 0x000a0008, 0x000a0009, 0x000b000a, 0x000c000a,
+ 0x000c000b},
+ {0x00060006, 0x00060004, 0x00070005, 0x00080005, 0x00080006, 0x00090006,
+ 0x000a0007, 0x000a0008, 0x000a0008, 0x000b0009, 0x000c0009, 0x000c000a,
+ 0x000c000a},
+ {0x00080006, 0x00070005, 0x00080005, 0x00090005, 0x00090006, 0x000a0007,
+ 0x000a0007, 0x000b0008, 0x000b0008, 0x000b0009, 0x000c0009, 0x000c000a,
+ 0x000d000a},
+ {0x00090007, 0x00080006, 0x00090006, 0x00090006, 0x000a0006, 0x000a0007,
+ 0x000b0007, 0x000b0008, 0x000b0008, 0x000c0009, 0x000c0009, 0x000c000a,
+ 0x000d000a},
+ {0x000a0008, 0x00090007, 0x00090006, 0x000a0007, 0x000b0007, 0x000b0007,
+ 0x000b0008, 0x000c0008, 0x000b0008, 0x000c0009, 0x000c000a, 0x000d000a,
+ 0x000d000b},
+ {0x000b0009, 0x00090007, 0x000a0007, 0x000b0007, 0x000b0007, 0x000b0008,
+ 0x000c0008, 0x000c0009, 0x000c0009, 0x000c0009, 0x000d000a, 0x000d000a,
+ 0x000d000b},
+ {0x000b0009, 0x000a0008, 0x000a0008, 0x000b0008, 0x000b0008, 0x000c0008,
+ 0x000c0009, 0x000d0009, 0x000d0009, 0x000d000a, 0x000d000a, 0x000d000b,
+ 0x000d000b},
+ {0x000b0009, 0x000a0008, 0x000a0008, 0x000b0008, 0x000b0008, 0x000b0008,
+ 0x000c0009, 0x000c0009, 0x000d000a, 0x000d000a, 0x000e000a, 0x000d000b,
+ 0x000e000b},
+ {0x000b000a, 0x000a0009, 0x000b0009, 0x000b0009, 0x000c0009, 0x000c0009,
+ 0x000c0009, 0x000c000a, 0x000d000a, 0x000d000a, 0x000e000b, 0x000e000b,
+ 0x000e000c},
+ {0x000c000a, 0x000b0009, 0x000b0009, 0x000c0009, 0x000c0009, 0x000c000a,
+ 0x000d000a, 0x000d000a, 0x000d000a, 0x000e000b, 0x000e000b, 0x000e000b,
+ 0x000f000c},
+ {0x000c000b, 0x000b000a, 0x000c0009, 0x000c000a, 0x000c000a, 0x000d000a,
+ 0x000d000a, 0x000d000a, 0x000d000b, 0x000e000b, 0x000e000b, 0x000f000b,
+ 0x000f000c},
+ {0x000d000b, 0x000c000a, 0x000c000a, 0x000c000a, 0x000d000a, 0x000d000a,
+ 0x000d000a, 0x000d000b, 0x000e000b, 0x000e000c, 0x000e000c, 0x000e000c,
+ 0x000f000c}};
+
+const UCHAR FDKaacEnc_huff_ltab11[17][17] = {
+ {0x04, 0x05, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b,
+ 0x0c, 0x0b, 0x0c, 0x0c, 0x0a},
+ {0x05, 0x04, 0x05, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a,
+ 0x0a, 0x0a, 0x0a, 0x0b, 0x08},
+ {0x06, 0x05, 0x05, 0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09,
+ 0x0a, 0x0a, 0x0a, 0x0a, 0x08},
+ {0x07, 0x06, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09,
+ 0x0a, 0x0a, 0x0a, 0x0a, 0x08},
+ {0x08, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09,
+ 0x0a, 0x0a, 0x0a, 0x0a, 0x08},
+ {0x08, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09,
+ 0x0a, 0x0a, 0x0a, 0x0a, 0x08},
+ {0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a,
+ 0x0a, 0x0a, 0x0a, 0x0a, 0x08},
+ {0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a,
+ 0x0a, 0x0a, 0x0a, 0x0a, 0x08},
+ {0x0a, 0x09, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a,
+ 0x0a, 0x0a, 0x0a, 0x0b, 0x08},
+ {0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a,
+ 0x0a, 0x0a, 0x0b, 0x0b, 0x08},
+ {0x0b, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
+ 0x0b, 0x0a, 0x0b, 0x0b, 0x08},
+ {0x0b, 0x0a, 0x09, 0x09, 0x0a, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x08},
+ {0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x09},
+ {0x0b, 0x0a, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x09},
+ {0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x09},
+ {0x0c, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0c, 0x0c, 0x09},
+ {0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x09, 0x05}};
+
+const UCHAR FDKaacEnc_huff_ltabscf[121] = {
+ 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x12, 0x13, 0x12,
+ 0x11, 0x11, 0x10, 0x11, 0x10, 0x10, 0x10, 0x10, 0x0f, 0x0f, 0x0e,
+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0b,
+ 0x0c, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x07,
+ 0x06, 0x06, 0x05, 0x04, 0x03, 0x01, 0x04, 0x04, 0x05, 0x06, 0x06,
+ 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x10, 0x0f,
+ 0x10, 0x0f, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13};
+
+const USHORT FDKaacEnc_huff_ctab1[3][3][3][3] = {{{{0x07f8, 0x01f1, 0x07fd},
+ {0x03f5, 0x0068, 0x03f0},
+ {0x07f7, 0x01ec, 0x07f5}},
+ {{0x03f1, 0x0072, 0x03f4},
+ {0x0074, 0x0011, 0x0076},
+ {0x01eb, 0x006c, 0x03f6}},
+ {{0x07fc, 0x01e1, 0x07f1},
+ {0x01f0, 0x0061, 0x01f6},
+ {0x07f2, 0x01ea, 0x07fb}}},
+ {{{0x01f2, 0x0069, 0x01ed},
+ {0x0077, 0x0017, 0x006f},
+ {0x01e6, 0x0064, 0x01e5}},
+ {{0x0067, 0x0015, 0x0062},
+ {0x0012, 0x0000, 0x0014},
+ {0x0065, 0x0016, 0x006d}},
+ {{0x01e9, 0x0063, 0x01e4},
+ {0x006b, 0x0013, 0x0071},
+ {0x01e3, 0x0070, 0x01f3}}},
+ {{{0x07fe, 0x01e7, 0x07f3},
+ {0x01ef, 0x0060, 0x01ee},
+ {0x07f0, 0x01e2, 0x07fa}},
+ {{0x03f3, 0x006a, 0x01e8},
+ {0x0075, 0x0010, 0x0073},
+ {0x01f4, 0x006e, 0x03f7}},
+ {{0x07f6, 0x01e0, 0x07f9},
+ {0x03f2, 0x0066, 0x01f5},
+ {0x07ff, 0x01f7, 0x07f4}}}};
+
+const USHORT FDKaacEnc_huff_ctab2[3][3][3][3] = {{{{0x01f3, 0x006f, 0x01fd},
+ {0x00eb, 0x0023, 0x00ea},
+ {0x01f7, 0x00e8, 0x01fa}},
+ {{0x00f2, 0x002d, 0x0070},
+ {0x0020, 0x0006, 0x002b},
+ {0x006e, 0x0028, 0x00e9}},
+ {{0x01f9, 0x0066, 0x00f8},
+ {0x00e7, 0x001b, 0x00f1},
+ {0x01f4, 0x006b, 0x01f5}}},
+ {{{0x00ec, 0x002a, 0x006c},
+ {0x002c, 0x000a, 0x0027},
+ {0x0067, 0x001a, 0x00f5}},
+ {{0x0024, 0x0008, 0x001f},
+ {0x0009, 0x0000, 0x0007},
+ {0x001d, 0x000b, 0x0030}},
+ {{0x00ef, 0x001c, 0x0064},
+ {0x001e, 0x000c, 0x0029},
+ {0x00f3, 0x002f, 0x00f0}}},
+ {{{0x01fc, 0x0071, 0x01f2},
+ {0x00f4, 0x0021, 0x00e6},
+ {0x00f7, 0x0068, 0x01f8}},
+ {{0x00ee, 0x0022, 0x0065},
+ {0x0031, 0x0002, 0x0026},
+ {0x00ed, 0x0025, 0x006a}},
+ {{0x01fb, 0x0072, 0x01fe},
+ {0x0069, 0x002e, 0x00f6},
+ {0x01ff, 0x006d, 0x01f6}}}};
+
+const USHORT FDKaacEnc_huff_ctab3[3][3][3][3] = {{{{0x0000, 0x0009, 0x00ef},
+ {0x000b, 0x0019, 0x00f0},
+ {0x01eb, 0x01e6, 0x03f2}},
+ {{0x000a, 0x0035, 0x01ef},
+ {0x0034, 0x0037, 0x01e9},
+ {0x01ed, 0x01e7, 0x03f3}},
+ {{0x01ee, 0x03ed, 0x1ffa},
+ {0x01ec, 0x01f2, 0x07f9},
+ {0x07f8, 0x03f8, 0x0ff8}}},
+ {{{0x0008, 0x0038, 0x03f6},
+ {0x0036, 0x0075, 0x03f1},
+ {0x03eb, 0x03ec, 0x0ff4}},
+ {{0x0018, 0x0076, 0x07f4},
+ {0x0039, 0x0074, 0x03ef},
+ {0x01f3, 0x01f4, 0x07f6}},
+ {{0x01e8, 0x03ea, 0x1ffc},
+ {0x00f2, 0x01f1, 0x0ffb},
+ {0x03f5, 0x07f3, 0x0ffc}}},
+ {{{0x00ee, 0x03f7, 0x7ffe},
+ {0x01f0, 0x07f5, 0x7ffd},
+ {0x1ffb, 0x3ffa, 0xffff}},
+ {{0x00f1, 0x03f0, 0x3ffc},
+ {0x01ea, 0x03ee, 0x3ffb},
+ {0x0ff6, 0x0ffa, 0x7ffc}},
+ {{0x07f2, 0x0ff5, 0xfffe},
+ {0x03f4, 0x07f7, 0x7ffb},
+ {0x0ff7, 0x0ff9, 0x7ffa}}}};
+
+const USHORT FDKaacEnc_huff_ctab4[3][3][3][3] = {{{{0x0007, 0x0016, 0x00f6},
+ {0x0018, 0x0008, 0x00ef},
+ {0x01ef, 0x00f3, 0x07f8}},
+ {{0x0019, 0x0017, 0x00ed},
+ {0x0015, 0x0001, 0x00e2},
+ {0x00f0, 0x0070, 0x03f0}},
+ {{0x01ee, 0x00f1, 0x07fa},
+ {0x00ee, 0x00e4, 0x03f2},
+ {0x07f6, 0x03ef, 0x07fd}}},
+ {{{0x0005, 0x0014, 0x00f2},
+ {0x0009, 0x0004, 0x00e5},
+ {0x00f4, 0x00e8, 0x03f4}},
+ {{0x0006, 0x0002, 0x00e7},
+ {0x0003, 0x0000, 0x006b},
+ {0x00e3, 0x0069, 0x01f3}},
+ {{0x00eb, 0x00e6, 0x03f6},
+ {0x006e, 0x006a, 0x01f4},
+ {0x03ec, 0x01f0, 0x03f9}}},
+ {{{0x00f5, 0x00ec, 0x07fb},
+ {0x00ea, 0x006f, 0x03f7},
+ {0x07f9, 0x03f3, 0x0fff}},
+ {{0x00e9, 0x006d, 0x03f8},
+ {0x006c, 0x0068, 0x01f5},
+ {0x03ee, 0x01f2, 0x07f4}},
+ {{0x07f7, 0x03f1, 0x0ffe},
+ {0x03ed, 0x01f1, 0x07f5},
+ {0x07fe, 0x03f5, 0x07fc}}}};
+
+const USHORT FDKaacEnc_huff_ctab5[9][9] = {
+ {0x1fff, 0x0ff7, 0x07f4, 0x07e8, 0x03f1, 0x07ee, 0x07f9, 0x0ff8, 0x1ffd},
+ {0x0ffd, 0x07f1, 0x03e8, 0x01e8, 0x00f0, 0x01ec, 0x03ee, 0x07f2, 0x0ffa},
+ {0x0ff4, 0x03ef, 0x01f2, 0x00e8, 0x0070, 0x00ec, 0x01f0, 0x03ea, 0x07f3},
+ {0x07eb, 0x01eb, 0x00ea, 0x001a, 0x0008, 0x0019, 0x00ee, 0x01ef, 0x07ed},
+ {0x03f0, 0x00f2, 0x0073, 0x000b, 0x0000, 0x000a, 0x0071, 0x00f3, 0x07e9},
+ {0x07ef, 0x01ee, 0x00ef, 0x0018, 0x0009, 0x001b, 0x00eb, 0x01e9, 0x07ec},
+ {0x07f6, 0x03eb, 0x01f3, 0x00ed, 0x0072, 0x00e9, 0x01f1, 0x03ed, 0x07f7},
+ {0x0ff6, 0x07f0, 0x03e9, 0x01ed, 0x00f1, 0x01ea, 0x03ec, 0x07f8, 0x0ff9},
+ {0x1ffc, 0x0ffc, 0x0ff5, 0x07ea, 0x03f3, 0x03f2, 0x07f5, 0x0ffb, 0x1ffe}};
+
+const USHORT FDKaacEnc_huff_ctab6[9][9] = {
+ {0x07fe, 0x03fd, 0x01f1, 0x01eb, 0x01f4, 0x01ea, 0x01f0, 0x03fc, 0x07fd},
+ {0x03f6, 0x01e5, 0x00ea, 0x006c, 0x0071, 0x0068, 0x00f0, 0x01e6, 0x03f7},
+ {0x01f3, 0x00ef, 0x0032, 0x0027, 0x0028, 0x0026, 0x0031, 0x00eb, 0x01f7},
+ {0x01e8, 0x006f, 0x002e, 0x0008, 0x0004, 0x0006, 0x0029, 0x006b, 0x01ee},
+ {0x01ef, 0x0072, 0x002d, 0x0002, 0x0000, 0x0003, 0x002f, 0x0073, 0x01fa},
+ {0x01e7, 0x006e, 0x002b, 0x0007, 0x0001, 0x0005, 0x002c, 0x006d, 0x01ec},
+ {0x01f9, 0x00ee, 0x0030, 0x0024, 0x002a, 0x0025, 0x0033, 0x00ec, 0x01f2},
+ {0x03f8, 0x01e4, 0x00ed, 0x006a, 0x0070, 0x0069, 0x0074, 0x00f1, 0x03fa},
+ {0x07ff, 0x03f9, 0x01f6, 0x01ed, 0x01f8, 0x01e9, 0x01f5, 0x03fb, 0x07fc}};
+
+const USHORT FDKaacEnc_huff_ctab7[8][8] = {
+ {0x0000, 0x0005, 0x0037, 0x0074, 0x00f2, 0x01eb, 0x03ed, 0x07f7},
+ {0x0004, 0x000c, 0x0035, 0x0071, 0x00ec, 0x00ee, 0x01ee, 0x01f5},
+ {0x0036, 0x0034, 0x0072, 0x00ea, 0x00f1, 0x01e9, 0x01f3, 0x03f5},
+ {0x0073, 0x0070, 0x00eb, 0x00f0, 0x01f1, 0x01f0, 0x03ec, 0x03fa},
+ {0x00f3, 0x00ed, 0x01e8, 0x01ef, 0x03ef, 0x03f1, 0x03f9, 0x07fb},
+ {0x01ed, 0x00ef, 0x01ea, 0x01f2, 0x03f3, 0x03f8, 0x07f9, 0x07fc},
+ {0x03ee, 0x01ec, 0x01f4, 0x03f4, 0x03f7, 0x07f8, 0x0ffd, 0x0ffe},
+ {0x07f6, 0x03f0, 0x03f2, 0x03f6, 0x07fa, 0x07fd, 0x0ffc, 0x0fff}};
+
+const USHORT FDKaacEnc_huff_ctab8[8][8] = {
+ {0x000e, 0x0005, 0x0010, 0x0030, 0x006f, 0x00f1, 0x01fa, 0x03fe},
+ {0x0003, 0x0000, 0x0004, 0x0012, 0x002c, 0x006a, 0x0075, 0x00f8},
+ {0x000f, 0x0002, 0x0006, 0x0014, 0x002e, 0x0069, 0x0072, 0x00f5},
+ {0x002f, 0x0011, 0x0013, 0x002a, 0x0032, 0x006c, 0x00ec, 0x00fa},
+ {0x0071, 0x002b, 0x002d, 0x0031, 0x006d, 0x0070, 0x00f2, 0x01f9},
+ {0x00ef, 0x0068, 0x0033, 0x006b, 0x006e, 0x00ee, 0x00f9, 0x03fc},
+ {0x01f8, 0x0074, 0x0073, 0x00ed, 0x00f0, 0x00f6, 0x01f6, 0x01fd},
+ {0x03fd, 0x00f3, 0x00f4, 0x00f7, 0x01f7, 0x01fb, 0x01fc, 0x03ff}};
+
+const USHORT FDKaacEnc_huff_ctab9[13][13] = {
+ {0x0000, 0x0005, 0x0037, 0x00e7, 0x01de, 0x03ce, 0x03d9, 0x07c8, 0x07cd,
+ 0x0fc8, 0x0fdd, 0x1fe4, 0x1fec},
+ {0x0004, 0x000c, 0x0035, 0x0072, 0x00ea, 0x00ed, 0x01e2, 0x03d1, 0x03d3,
+ 0x03e0, 0x07d8, 0x0fcf, 0x0fd5},
+ {0x0036, 0x0034, 0x0071, 0x00e8, 0x00ec, 0x01e1, 0x03cf, 0x03dd, 0x03db,
+ 0x07d0, 0x0fc7, 0x0fd4, 0x0fe4},
+ {0x00e6, 0x0070, 0x00e9, 0x01dd, 0x01e3, 0x03d2, 0x03dc, 0x07cc, 0x07ca,
+ 0x07de, 0x0fd8, 0x0fea, 0x1fdb},
+ {0x01df, 0x00eb, 0x01dc, 0x01e6, 0x03d5, 0x03de, 0x07cb, 0x07dd, 0x07dc,
+ 0x0fcd, 0x0fe2, 0x0fe7, 0x1fe1},
+ {0x03d0, 0x01e0, 0x01e4, 0x03d6, 0x07c5, 0x07d1, 0x07db, 0x0fd2, 0x07e0,
+ 0x0fd9, 0x0feb, 0x1fe3, 0x1fe9},
+ {0x07c4, 0x01e5, 0x03d7, 0x07c6, 0x07cf, 0x07da, 0x0fcb, 0x0fda, 0x0fe3,
+ 0x0fe9, 0x1fe6, 0x1ff3, 0x1ff7},
+ {0x07d3, 0x03d8, 0x03e1, 0x07d4, 0x07d9, 0x0fd3, 0x0fde, 0x1fdd, 0x1fd9,
+ 0x1fe2, 0x1fea, 0x1ff1, 0x1ff6},
+ {0x07d2, 0x03d4, 0x03da, 0x07c7, 0x07d7, 0x07e2, 0x0fce, 0x0fdb, 0x1fd8,
+ 0x1fee, 0x3ff0, 0x1ff4, 0x3ff2},
+ {0x07e1, 0x03df, 0x07c9, 0x07d6, 0x0fca, 0x0fd0, 0x0fe5, 0x0fe6, 0x1feb,
+ 0x1fef, 0x3ff3, 0x3ff4, 0x3ff5},
+ {0x0fe0, 0x07ce, 0x07d5, 0x0fc6, 0x0fd1, 0x0fe1, 0x1fe0, 0x1fe8, 0x1ff0,
+ 0x3ff1, 0x3ff8, 0x3ff6, 0x7ffc},
+ {0x0fe8, 0x07df, 0x0fc9, 0x0fd7, 0x0fdc, 0x1fdc, 0x1fdf, 0x1fed, 0x1ff5,
+ 0x3ff9, 0x3ffb, 0x7ffd, 0x7ffe},
+ {0x1fe7, 0x0fcc, 0x0fd6, 0x0fdf, 0x1fde, 0x1fda, 0x1fe5, 0x1ff2, 0x3ffa,
+ 0x3ff7, 0x3ffc, 0x3ffd, 0x7fff}};
+
+const USHORT FDKaacEnc_huff_ctab10[13][13] = {
+ {0x0022, 0x0008, 0x001d, 0x0026, 0x005f, 0x00d3, 0x01cf, 0x03d0, 0x03d7,
+ 0x03ed, 0x07f0, 0x07f6, 0x0ffd},
+ {0x0007, 0x0000, 0x0001, 0x0009, 0x0020, 0x0054, 0x0060, 0x00d5, 0x00dc,
+ 0x01d4, 0x03cd, 0x03de, 0x07e7},
+ {0x001c, 0x0002, 0x0006, 0x000c, 0x001e, 0x0028, 0x005b, 0x00cd, 0x00d9,
+ 0x01ce, 0x01dc, 0x03d9, 0x03f1},
+ {0x0025, 0x000b, 0x000a, 0x000d, 0x0024, 0x0057, 0x0061, 0x00cc, 0x00dd,
+ 0x01cc, 0x01de, 0x03d3, 0x03e7},
+ {0x005d, 0x0021, 0x001f, 0x0023, 0x0027, 0x0059, 0x0064, 0x00d8, 0x00df,
+ 0x01d2, 0x01e2, 0x03dd, 0x03ee},
+ {0x00d1, 0x0055, 0x0029, 0x0056, 0x0058, 0x0062, 0x00ce, 0x00e0, 0x00e2,
+ 0x01da, 0x03d4, 0x03e3, 0x07eb},
+ {0x01c9, 0x005e, 0x005a, 0x005c, 0x0063, 0x00ca, 0x00da, 0x01c7, 0x01ca,
+ 0x01e0, 0x03db, 0x03e8, 0x07ec},
+ {0x01e3, 0x00d2, 0x00cb, 0x00d0, 0x00d7, 0x00db, 0x01c6, 0x01d5, 0x01d8,
+ 0x03ca, 0x03da, 0x07ea, 0x07f1},
+ {0x01e1, 0x00d4, 0x00cf, 0x00d6, 0x00de, 0x00e1, 0x01d0, 0x01d6, 0x03d1,
+ 0x03d5, 0x03f2, 0x07ee, 0x07fb},
+ {0x03e9, 0x01cd, 0x01c8, 0x01cb, 0x01d1, 0x01d7, 0x01df, 0x03cf, 0x03e0,
+ 0x03ef, 0x07e6, 0x07f8, 0x0ffa},
+ {0x03eb, 0x01dd, 0x01d3, 0x01d9, 0x01db, 0x03d2, 0x03cc, 0x03dc, 0x03ea,
+ 0x07ed, 0x07f3, 0x07f9, 0x0ff9},
+ {0x07f2, 0x03ce, 0x01e4, 0x03cb, 0x03d8, 0x03d6, 0x03e2, 0x03e5, 0x07e8,
+ 0x07f4, 0x07f5, 0x07f7, 0x0ffb},
+ {0x07fa, 0x03ec, 0x03df, 0x03e1, 0x03e4, 0x03e6, 0x03f0, 0x07e9, 0x07ef,
+ 0x0ff8, 0x0ffe, 0x0ffc, 0x0fff}};
+
+const USHORT FDKaacEnc_huff_ctab11[21][17] = {
+ {0x0000, 0x0006, 0x0019, 0x003d, 0x009c, 0x00c6, 0x01a7, 0x0390, 0x03c2,
+ 0x03df, 0x07e6, 0x07f3, 0x0ffb, 0x07ec, 0x0ffa, 0x0ffe, 0x038e},
+ {0x0005, 0x0001, 0x0008, 0x0014, 0x0037, 0x0042, 0x0092, 0x00af, 0x0191,
+ 0x01a5, 0x01b5, 0x039e, 0x03c0, 0x03a2, 0x03cd, 0x07d6, 0x00ae},
+ {0x0017, 0x0007, 0x0009, 0x0018, 0x0039, 0x0040, 0x008e, 0x00a3, 0x00b8,
+ 0x0199, 0x01ac, 0x01c1, 0x03b1, 0x0396, 0x03be, 0x03ca, 0x009d},
+ {0x003c, 0x0015, 0x0016, 0x001a, 0x003b, 0x0044, 0x0091, 0x00a5, 0x00be,
+ 0x0196, 0x01ae, 0x01b9, 0x03a1, 0x0391, 0x03a5, 0x03d5, 0x0094},
+ {0x009a, 0x0036, 0x0038, 0x003a, 0x0041, 0x008c, 0x009b, 0x00b0, 0x00c3,
+ 0x019e, 0x01ab, 0x01bc, 0x039f, 0x038f, 0x03a9, 0x03cf, 0x0093},
+ {0x00bf, 0x003e, 0x003f, 0x0043, 0x0045, 0x009e, 0x00a7, 0x00b9, 0x0194,
+ 0x01a2, 0x01ba, 0x01c3, 0x03a6, 0x03a7, 0x03bb, 0x03d4, 0x009f},
+ {0x01a0, 0x008f, 0x008d, 0x0090, 0x0098, 0x00a6, 0x00b6, 0x00c4, 0x019f,
+ 0x01af, 0x01bf, 0x0399, 0x03bf, 0x03b4, 0x03c9, 0x03e7, 0x00a8},
+ {0x01b6, 0x00ab, 0x00a4, 0x00aa, 0x00b2, 0x00c2, 0x00c5, 0x0198, 0x01a4,
+ 0x01b8, 0x038c, 0x03a4, 0x03c4, 0x03c6, 0x03dd, 0x03e8, 0x00ad},
+ {0x03af, 0x0192, 0x00bd, 0x00bc, 0x018e, 0x0197, 0x019a, 0x01a3, 0x01b1,
+ 0x038d, 0x0398, 0x03b7, 0x03d3, 0x03d1, 0x03db, 0x07dd, 0x00b4},
+ {0x03de, 0x01a9, 0x019b, 0x019c, 0x01a1, 0x01aa, 0x01ad, 0x01b3, 0x038b,
+ 0x03b2, 0x03b8, 0x03ce, 0x03e1, 0x03e0, 0x07d2, 0x07e5, 0x00b7},
+ {0x07e3, 0x01bb, 0x01a8, 0x01a6, 0x01b0, 0x01b2, 0x01b7, 0x039b, 0x039a,
+ 0x03ba, 0x03b5, 0x03d6, 0x07d7, 0x03e4, 0x07d8, 0x07ea, 0x00ba},
+ {0x07e8, 0x03a0, 0x01bd, 0x01b4, 0x038a, 0x01c4, 0x0392, 0x03aa, 0x03b0,
+ 0x03bc, 0x03d7, 0x07d4, 0x07dc, 0x07db, 0x07d5, 0x07f0, 0x00c1},
+ {0x07fb, 0x03c8, 0x03a3, 0x0395, 0x039d, 0x03ac, 0x03ae, 0x03c5, 0x03d8,
+ 0x03e2, 0x03e6, 0x07e4, 0x07e7, 0x07e0, 0x07e9, 0x07f7, 0x0190},
+ {0x07f2, 0x0393, 0x01be, 0x01c0, 0x0394, 0x0397, 0x03ad, 0x03c3, 0x03c1,
+ 0x03d2, 0x07da, 0x07d9, 0x07df, 0x07eb, 0x07f4, 0x07fa, 0x0195},
+ {0x07f8, 0x03bd, 0x039c, 0x03ab, 0x03a8, 0x03b3, 0x03b9, 0x03d0, 0x03e3,
+ 0x03e5, 0x07e2, 0x07de, 0x07ed, 0x07f1, 0x07f9, 0x07fc, 0x0193},
+ {0x0ffd, 0x03dc, 0x03b6, 0x03c7, 0x03cc, 0x03cb, 0x03d9, 0x03da, 0x07d3,
+ 0x07e1, 0x07ee, 0x07ef, 0x07f5, 0x07f6, 0x0ffc, 0x0fff, 0x019d},
+ {0x01c2, 0x00b5, 0x00a1, 0x0096, 0x0097, 0x0095, 0x0099, 0x00a0, 0x00a2,
+ 0x00ac, 0x00a9, 0x00b1, 0x00b3, 0x00bb, 0x00c0, 0x018f, 0x0004},
+ {0x0018, 0x002e, 0x0000, 0x005a, 0x00a5, 0x00f8, 0x00b7, 0x0094, 0x00f9,
+ 0x004d, 0x0021, 0x002b, 0x004f, 0x007b, 0x00bc, 0x0046, 0x0015},
+ {0x0042, 0x0037, 0x0078, 0x000d, 0x0068, 0x005f, 0x000d, 0x005e, 0x005a,
+ 0x00be, 0x0063, 0x007e, 0x001f, 0x0092, 0x001a, 0x00ab, 0x0032},
+ {0x00e6, 0x0037, 0x0000, 0x0058, 0x000b, 0x005a, 0x00e1, 0x005d, 0x0029,
+ 0x0017, 0x007e, 0x0069, 0x00aa, 0x0054, 0x0029, 0x0032, 0x0041},
+ {0x0046, 0x00ea, 0x0034, 0x00ea, 0x0011, 0x001b, 0x00a9, 0x0094, 0x00e2,
+ 0x0031, 0x00d0, 0x00e5, 0x0007, 0x0070, 0x0069, 0x003e, 0x0021}};
+
+const ULONG FDKaacEnc_huff_ctabscf[121] = {
+ 0x0003ffe8, 0x0003ffe6, 0x0003ffe7, 0x0003ffe5, 0x0007fff5, 0x0007fff1,
+ 0x0007ffed, 0x0007fff6, 0x0007ffee, 0x0007ffef, 0x0007fff0, 0x0007fffc,
+ 0x0007fffd, 0x0007ffff, 0x0007fffe, 0x0007fff7, 0x0007fff8, 0x0007fffb,
+ 0x0007fff9, 0x0003ffe4, 0x0007fffa, 0x0003ffe3, 0x0001ffef, 0x0001fff0,
+ 0x0000fff5, 0x0001ffee, 0x0000fff2, 0x0000fff3, 0x0000fff4, 0x0000fff1,
+ 0x00007ff6, 0x00007ff7, 0x00003ff9, 0x00003ff5, 0x00003ff7, 0x00003ff3,
+ 0x00003ff6, 0x00003ff2, 0x00001ff7, 0x00001ff5, 0x00000ff9, 0x00000ff7,
+ 0x00000ff6, 0x000007f9, 0x00000ff4, 0x000007f8, 0x000003f9, 0x000003f7,
+ 0x000003f5, 0x000001f8, 0x000001f7, 0x000000fa, 0x000000f8, 0x000000f6,
+ 0x00000079, 0x0000003a, 0x00000038, 0x0000001a, 0x0000000b, 0x00000004,
+ 0x00000000, 0x0000000a, 0x0000000c, 0x0000001b, 0x00000039, 0x0000003b,
+ 0x00000078, 0x0000007a, 0x000000f7, 0x000000f9, 0x000001f6, 0x000001f9,
+ 0x000003f4, 0x000003f6, 0x000003f8, 0x000007f5, 0x000007f4, 0x000007f6,
+ 0x000007f7, 0x00000ff5, 0x00000ff8, 0x00001ff4, 0x00001ff6, 0x00001ff8,
+ 0x00003ff8, 0x00003ff4, 0x0000fff0, 0x00007ff4, 0x0000fff6, 0x00007ff5,
+ 0x0003ffe2, 0x0007ffd9, 0x0007ffda, 0x0007ffdb, 0x0007ffdc, 0x0007ffdd,
+ 0x0007ffde, 0x0007ffd8, 0x0007ffd2, 0x0007ffd3, 0x0007ffd4, 0x0007ffd5,
+ 0x0007ffd6, 0x0007fff2, 0x0007ffdf, 0x0007ffe7, 0x0007ffe8, 0x0007ffe9,
+ 0x0007ffea, 0x0007ffeb, 0x0007ffe6, 0x0007ffe0, 0x0007ffe1, 0x0007ffe2,
+ 0x0007ffe3, 0x0007ffe4, 0x0007ffe5, 0x0007ffd7, 0x0007ffec, 0x0007fff4,
+ 0x0007fff3};
+
+/*
+ table of (0.50000...1.00000) ^0.75
+*/
+const FIXP_QTD FDKaacEnc_mTab_3_4[MANT_SIZE] = {
+ QTC(0x4c1bf829), QTC(0x4c3880de), QTC(0x4c550603), QTC(0x4c71879c),
+ QTC(0x4c8e05aa), QTC(0x4caa8030), QTC(0x4cc6f72f), QTC(0x4ce36aab),
+ QTC(0x4cffdaa4), QTC(0x4d1c471d), QTC(0x4d38b019), QTC(0x4d55159a),
+ QTC(0x4d7177a1), QTC(0x4d8dd631), QTC(0x4daa314b), QTC(0x4dc688f3),
+ QTC(0x4de2dd2a), QTC(0x4dff2df2), QTC(0x4e1b7b4d), QTC(0x4e37c53d),
+ QTC(0x4e540bc5), QTC(0x4e704ee6), QTC(0x4e8c8ea3), QTC(0x4ea8cafd),
+ QTC(0x4ec503f7), QTC(0x4ee13992), QTC(0x4efd6bd0), QTC(0x4f199ab4),
+ QTC(0x4f35c640), QTC(0x4f51ee75), QTC(0x4f6e1356), QTC(0x4f8a34e4),
+ QTC(0x4fa65321), QTC(0x4fc26e10), QTC(0x4fde85b2), QTC(0x4ffa9a0a),
+ QTC(0x5016ab18), QTC(0x5032b8e0), QTC(0x504ec362), QTC(0x506acaa1),
+ QTC(0x5086cea0), QTC(0x50a2cf5e), QTC(0x50becce0), QTC(0x50dac725),
+ QTC(0x50f6be31), QTC(0x5112b205), QTC(0x512ea2a3), QTC(0x514a900d),
+ QTC(0x51667a45), QTC(0x5182614c), QTC(0x519e4524), QTC(0x51ba25cf),
+ QTC(0x51d60350), QTC(0x51f1dda7), QTC(0x520db4d6), QTC(0x522988e0),
+ QTC(0x524559c6), QTC(0x52612789), QTC(0x527cf22d), QTC(0x5298b9b1),
+ QTC(0x52b47e19), QTC(0x52d03f65), QTC(0x52ebfd98), QTC(0x5307b8b4),
+ QTC(0x532370b9), QTC(0x533f25aa), QTC(0x535ad789), QTC(0x53768656),
+ QTC(0x53923215), QTC(0x53addac6), QTC(0x53c9806b), QTC(0x53e52306),
+ QTC(0x5400c298), QTC(0x541c5f24), QTC(0x5437f8ab), QTC(0x54538f2e),
+ QTC(0x546f22af), QTC(0x548ab330), QTC(0x54a640b3), QTC(0x54c1cb38),
+ QTC(0x54dd52c2), QTC(0x54f8d753), QTC(0x551458eb), QTC(0x552fd78d),
+ QTC(0x554b5339), QTC(0x5566cbf3), QTC(0x558241bb), QTC(0x559db492),
+ QTC(0x55b9247b), QTC(0x55d49177), QTC(0x55effb87), QTC(0x560b62ad),
+ QTC(0x5626c6eb), QTC(0x56422842), QTC(0x565d86b4), QTC(0x5678e242),
+ QTC(0x56943aee), QTC(0x56af90b9), QTC(0x56cae3a4), QTC(0x56e633b2),
+ QTC(0x570180e4), QTC(0x571ccb3b), QTC(0x573812b8), QTC(0x5753575e),
+ QTC(0x576e992e), QTC(0x5789d829), QTC(0x57a51450), QTC(0x57c04da6),
+ QTC(0x57db842b), QTC(0x57f6b7e1), QTC(0x5811e8c9), QTC(0x582d16e6),
+ QTC(0x58484238), QTC(0x58636ac0), QTC(0x587e9081), QTC(0x5899b37c),
+ QTC(0x58b4d3b1), QTC(0x58cff123), QTC(0x58eb0bd3), QTC(0x590623c2),
+ QTC(0x592138f2), QTC(0x593c4b63), QTC(0x59575b19), QTC(0x59726812),
+ QTC(0x598d7253), QTC(0x59a879da), QTC(0x59c37eab), QTC(0x59de80c6),
+ QTC(0x59f9802d), QTC(0x5a147ce0), QTC(0x5a2f76e2), QTC(0x5a4a6e34),
+ QTC(0x5a6562d6), QTC(0x5a8054cb), QTC(0x5a9b4414), QTC(0x5ab630b2),
+ QTC(0x5ad11aa6), QTC(0x5aec01f1), QTC(0x5b06e696), QTC(0x5b21c895),
+ QTC(0x5b3ca7ef), QTC(0x5b5784a6), QTC(0x5b725ebc), QTC(0x5b8d3631),
+ QTC(0x5ba80b06), QTC(0x5bc2dd3e), QTC(0x5bddacd9), QTC(0x5bf879d8),
+ QTC(0x5c13443d), QTC(0x5c2e0c09), QTC(0x5c48d13e), QTC(0x5c6393dc),
+ QTC(0x5c7e53e5), QTC(0x5c99115a), QTC(0x5cb3cc3c), QTC(0x5cce848d),
+ QTC(0x5ce93a4e), QTC(0x5d03ed80), QTC(0x5d1e9e24), QTC(0x5d394c3b),
+ QTC(0x5d53f7c7), QTC(0x5d6ea0c9), QTC(0x5d894742), QTC(0x5da3eb33),
+ QTC(0x5dbe8c9e), QTC(0x5dd92b84), QTC(0x5df3c7e5), QTC(0x5e0e61c3),
+ QTC(0x5e28f920), QTC(0x5e438dfc), QTC(0x5e5e2059), QTC(0x5e78b037),
+ QTC(0x5e933d99), QTC(0x5eadc87e), QTC(0x5ec850e9), QTC(0x5ee2d6da),
+ QTC(0x5efd5a53), QTC(0x5f17db54), QTC(0x5f3259e0), QTC(0x5f4cd5f6),
+ QTC(0x5f674f99), QTC(0x5f81c6c8), QTC(0x5f9c3b87), QTC(0x5fb6add4),
+ QTC(0x5fd11db3), QTC(0x5feb8b23), QTC(0x6005f626), QTC(0x60205ebd),
+ QTC(0x603ac4e9), QTC(0x605528ac), QTC(0x606f8a05), QTC(0x6089e8f7),
+ QTC(0x60a44583), QTC(0x60be9fa9), QTC(0x60d8f76b), QTC(0x60f34cca),
+ QTC(0x610d9fc7), QTC(0x6127f062), QTC(0x61423e9e), QTC(0x615c8a7a),
+ QTC(0x6176d3f9), QTC(0x61911b1b), QTC(0x61ab5fe1), QTC(0x61c5a24d),
+ QTC(0x61dfe25f), QTC(0x61fa2018), QTC(0x62145b7a), QTC(0x622e9485),
+ QTC(0x6248cb3b), QTC(0x6262ff9d), QTC(0x627d31ab), QTC(0x62976167),
+ QTC(0x62b18ed1), QTC(0x62cbb9eb), QTC(0x62e5e2b6), QTC(0x63000933),
+ QTC(0x631a2d62), QTC(0x63344f45), QTC(0x634e6edd), QTC(0x63688c2b),
+ QTC(0x6382a730), QTC(0x639cbfec), QTC(0x63b6d661), QTC(0x63d0ea90),
+ QTC(0x63eafc7a), QTC(0x64050c1f), QTC(0x641f1982), QTC(0x643924a2),
+ QTC(0x64532d80), QTC(0x646d341f), QTC(0x6487387e), QTC(0x64a13a9e),
+ QTC(0x64bb3a81), QTC(0x64d53828), QTC(0x64ef3393), QTC(0x65092cc4),
+ QTC(0x652323bb), QTC(0x653d1879), QTC(0x65570b00), QTC(0x6570fb50),
+ QTC(0x658ae96b), QTC(0x65a4d550), QTC(0x65bebf01), QTC(0x65d8a680),
+ QTC(0x65f28bcc), QTC(0x660c6ee8), QTC(0x66264fd3), QTC(0x66402e8f),
+ QTC(0x665a0b1c), QTC(0x6673e57d), QTC(0x668dbdb0), QTC(0x66a793b8),
+ QTC(0x66c16795), QTC(0x66db3949), QTC(0x66f508d4), QTC(0x670ed636),
+ QTC(0x6728a172), QTC(0x67426a87), QTC(0x675c3177), QTC(0x6775f643),
+ QTC(0x678fb8eb), QTC(0x67a97971), QTC(0x67c337d5), QTC(0x67dcf418),
+ QTC(0x67f6ae3b), QTC(0x6810663f), QTC(0x682a1c25), QTC(0x6843cfed),
+ QTC(0x685d8199), QTC(0x68773129), QTC(0x6890de9f), QTC(0x68aa89fa),
+ QTC(0x68c4333d), QTC(0x68ddda67), QTC(0x68f77f7a), QTC(0x69112277),
+ QTC(0x692ac35e), QTC(0x69446230), QTC(0x695dfeee), QTC(0x6977999a),
+ QTC(0x69913232), QTC(0x69aac8ba), QTC(0x69c45d31), QTC(0x69ddef98),
+ QTC(0x69f77ff0), QTC(0x6a110e3a), QTC(0x6a2a9a77), QTC(0x6a4424a8),
+ QTC(0x6a5daccc), QTC(0x6a7732e6), QTC(0x6a90b6f6), QTC(0x6aaa38fd),
+ QTC(0x6ac3b8fb), QTC(0x6add36f2), QTC(0x6af6b2e2), QTC(0x6b102ccd),
+ QTC(0x6b29a4b2), QTC(0x6b431a92), QTC(0x6b5c8e6f), QTC(0x6b76004a),
+ QTC(0x6b8f7022), QTC(0x6ba8ddf9), QTC(0x6bc249d0), QTC(0x6bdbb3a7),
+ QTC(0x6bf51b80), QTC(0x6c0e815a), QTC(0x6c27e537), QTC(0x6c414718),
+ QTC(0x6c5aa6fd), QTC(0x6c7404e7), QTC(0x6c8d60d7), QTC(0x6ca6bace),
+ QTC(0x6cc012cc), QTC(0x6cd968d2), QTC(0x6cf2bce1), QTC(0x6d0c0ef9),
+ QTC(0x6d255f1d), QTC(0x6d3ead4b), QTC(0x6d57f985), QTC(0x6d7143cc),
+ QTC(0x6d8a8c21), QTC(0x6da3d283), QTC(0x6dbd16f5), QTC(0x6dd65976),
+ QTC(0x6def9a08), QTC(0x6e08d8ab), QTC(0x6e221560), QTC(0x6e3b5027),
+ QTC(0x6e548902), QTC(0x6e6dbff1), QTC(0x6e86f4f5), QTC(0x6ea0280e),
+ QTC(0x6eb9593e), QTC(0x6ed28885), QTC(0x6eebb5e3), QTC(0x6f04e15a),
+ QTC(0x6f1e0aea), QTC(0x6f373294), QTC(0x6f505859), QTC(0x6f697c39),
+ QTC(0x6f829e35), QTC(0x6f9bbe4e), QTC(0x6fb4dc85), QTC(0x6fcdf8d9),
+ QTC(0x6fe7134d), QTC(0x70002be0), QTC(0x70194293), QTC(0x70325767),
+ QTC(0x704b6a5d), QTC(0x70647b76), QTC(0x707d8ab1), QTC(0x70969811),
+ QTC(0x70afa394), QTC(0x70c8ad3d), QTC(0x70e1b50c), QTC(0x70fabb01),
+ QTC(0x7113bf1d), QTC(0x712cc161), QTC(0x7145c1ce), QTC(0x715ec064),
+ QTC(0x7177bd24), QTC(0x7190b80f), QTC(0x71a9b124), QTC(0x71c2a866),
+ QTC(0x71db9dd4), QTC(0x71f49170), QTC(0x720d8339), QTC(0x72267331),
+ QTC(0x723f6159), QTC(0x72584db0), QTC(0x72713838), QTC(0x728a20f1),
+ QTC(0x72a307db), QTC(0x72bbecf9), QTC(0x72d4d049), QTC(0x72edb1ce),
+ QTC(0x73069187), QTC(0x731f6f75), QTC(0x73384b98), QTC(0x735125f3),
+ QTC(0x7369fe84), QTC(0x7382d54d), QTC(0x739baa4e), QTC(0x73b47d89),
+ QTC(0x73cd4efd), QTC(0x73e61eab), QTC(0x73feec94), QTC(0x7417b8b8),
+ QTC(0x74308319), QTC(0x74494bb6), QTC(0x74621291), QTC(0x747ad7aa),
+ QTC(0x74939b02), QTC(0x74ac5c98), QTC(0x74c51c6f), QTC(0x74ddda86),
+ QTC(0x74f696de), QTC(0x750f5178), QTC(0x75280a54), QTC(0x7540c174),
+ QTC(0x755976d7), QTC(0x75722a7e), QTC(0x758adc69), QTC(0x75a38c9b),
+ QTC(0x75bc3b12), QTC(0x75d4e7cf), QTC(0x75ed92d4), QTC(0x76063c21),
+ QTC(0x761ee3b6), QTC(0x76378994), QTC(0x76502dbc), QTC(0x7668d02e),
+ QTC(0x768170eb), QTC(0x769a0ff3), QTC(0x76b2ad47), QTC(0x76cb48e7),
+ QTC(0x76e3e2d5), QTC(0x76fc7b10), QTC(0x7715119a), QTC(0x772da673),
+ QTC(0x7746399b), QTC(0x775ecb13), QTC(0x77775adc), QTC(0x778fe8f6),
+ QTC(0x77a87561), QTC(0x77c1001f), QTC(0x77d98930), QTC(0x77f21095),
+ QTC(0x780a964d), QTC(0x78231a5b), QTC(0x783b9cbd), QTC(0x78541d75),
+ QTC(0x786c9c84), QTC(0x788519e9), QTC(0x789d95a6), QTC(0x78b60fbb),
+ QTC(0x78ce8828), QTC(0x78e6feef), QTC(0x78ff740f), QTC(0x7917e78a),
+ QTC(0x7930595f), QTC(0x7948c990), QTC(0x7961381d), QTC(0x7979a506),
+ QTC(0x7992104c), QTC(0x79aa79f0), QTC(0x79c2e1f1), QTC(0x79db4852),
+ QTC(0x79f3ad11), QTC(0x7a0c1031), QTC(0x7a2471b0), QTC(0x7a3cd191),
+ QTC(0x7a552fd3), QTC(0x7a6d8c76), QTC(0x7a85e77d), QTC(0x7a9e40e6),
+ QTC(0x7ab698b2), QTC(0x7aceeee3), QTC(0x7ae74378), QTC(0x7aff9673),
+ QTC(0x7b17e7d2), QTC(0x7b303799), QTC(0x7b4885c5), QTC(0x7b60d259),
+ QTC(0x7b791d55), QTC(0x7b9166b9), QTC(0x7ba9ae86), QTC(0x7bc1f4bc),
+ QTC(0x7bda395c), QTC(0x7bf27c66), QTC(0x7c0abddb), QTC(0x7c22fdbb),
+ QTC(0x7c3b3c07), QTC(0x7c5378c0), QTC(0x7c6bb3e5), QTC(0x7c83ed78),
+ QTC(0x7c9c2579), QTC(0x7cb45be9), QTC(0x7ccc90c7), QTC(0x7ce4c414),
+ QTC(0x7cfcf5d2), QTC(0x7d152600), QTC(0x7d2d549f), QTC(0x7d4581b0),
+ QTC(0x7d5dad32), QTC(0x7d75d727), QTC(0x7d8dff8f), QTC(0x7da6266a),
+ QTC(0x7dbe4bba), QTC(0x7dd66f7d), QTC(0x7dee91b6), QTC(0x7e06b264),
+ QTC(0x7e1ed188), QTC(0x7e36ef22), QTC(0x7e4f0b34), QTC(0x7e6725bd),
+ QTC(0x7e7f3ebd), QTC(0x7e975636), QTC(0x7eaf6c28), QTC(0x7ec78093),
+ QTC(0x7edf9378), QTC(0x7ef7a4d7), QTC(0x7f0fb4b1), QTC(0x7f27c307),
+ QTC(0x7f3fcfd8), QTC(0x7f57db25), QTC(0x7f6fe4ef), QTC(0x7f87ed36),
+ QTC(0x7f9ff3fb), QTC(0x7fb7f93e), QTC(0x7fcffcff), QTC(0x7fe7ff40)};
+
+/*
+ table of pow(2.0,0.25*q)/2.0, q[0..4)
+*/
+const FIXP_QTD FDKaacEnc_quantTableQ[4] = {QTC(0x40000000), QTC(0x4c1bf7ff),
+ QTC(0x5a82797f), QTC(0x6ba27e7f)};
+
+/*
+ table of pow(2.0,0.75*e)/8.0, e[0..4)
+*/
+const FIXP_QTD FDKaacEnc_quantTableE[4] = {QTC(0x10000000), QTC(0x1ae89f99),
+ QTC(0x2d413ccd), QTC(0x4c1bf828)};
+
+/*
+ table to count used number of bits
+*/
+const SHORT FDKaacEnc_sideInfoTabLong[] = {
+ 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
+ 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
+ 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
+ 0x0009, 0x0009, 0x0009, 0x0009, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e,
+ 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e,
+ 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e};
+
+const SHORT FDKaacEnc_sideInfoTabShort[] = {
+ 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x000a,
+ 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000d, 0x000d};
+
+/*
+ Psy Configuration constants
+*/
+
+const SFB_PARAM_LONG p_FDKaacEnc_8000_long_1024 = {
+ 40, {12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 16,
+ 16, 16, 16, 16, 16, 16, 20, 20, 20, 20, 24, 24, 24, 28,
+ 28, 32, 36, 36, 40, 44, 48, 52, 56, 60, 64, 80}};
+const SFB_PARAM_SHORT p_FDKaacEnc_8000_short_128 = {
+ 15, {4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 16, 20, 20}};
+
+const SFB_PARAM_LONG p_FDKaacEnc_11025_long_1024 = {
+ 43, {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28,
+ 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64}};
+const SFB_PARAM_SHORT p_FDKaacEnc_11025_short_128 = {
+ 15, {4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20}};
+
+const SFB_PARAM_LONG p_FDKaacEnc_12000_long_1024 = {
+ 43, {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28,
+ 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64}};
+const SFB_PARAM_SHORT p_FDKaacEnc_12000_short_128 = {
+ 15, {4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20}};
+
+const SFB_PARAM_LONG p_FDKaacEnc_16000_long_1024 = {
+ 43, {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28,
+ 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64}};
+const SFB_PARAM_SHORT p_FDKaacEnc_16000_short_128 = {
+ 15, {4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20}};
+const SFB_PARAM_LONG p_FDKaacEnc_22050_long_1024 = {
+ 47, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24,
+ 28, 28, 32, 36, 36, 40, 44, 48, 52, 52, 64, 64, 64, 64, 64}};
+const SFB_PARAM_SHORT p_FDKaacEnc_22050_short_128 = {
+ 15, {4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20}};
+const SFB_PARAM_LONG p_FDKaacEnc_24000_long_1024 = {
+ 47, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24,
+ 28, 28, 32, 36, 36, 40, 44, 48, 52, 52, 64, 64, 64, 64, 64}};
+const SFB_PARAM_SHORT p_FDKaacEnc_24000_short_128 = {
+ 15, {4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20}};
+const SFB_PARAM_LONG p_FDKaacEnc_32000_long_1024 = {
+ 51, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8,
+ 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}};
+const SFB_PARAM_SHORT p_FDKaacEnc_32000_short_128 = {
+ 14, {4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16}};
+const SFB_PARAM_LONG p_FDKaacEnc_44100_long_1024 = {
+ 49, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8,
+ 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 96}};
+const SFB_PARAM_SHORT p_FDKaacEnc_44100_short_128 = {
+ 14, {4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16}};
+const SFB_PARAM_LONG p_FDKaacEnc_48000_long_1024 = {
+ 49, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8,
+ 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 96}};
+const SFB_PARAM_SHORT p_FDKaacEnc_48000_short_128 = {
+ 14, {4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16}};
+const SFB_PARAM_LONG p_FDKaacEnc_64000_long_1024 = {
+ 47, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8,
+ 8, 8, 12, 12, 12, 16, 16, 16, 20, 24, 24, 28, 36, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}};
+const SFB_PARAM_SHORT p_FDKaacEnc_64000_short_128 = {
+ 12, {4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36}};
+const SFB_PARAM_LONG p_FDKaacEnc_88200_long_1024 = {
+ 41, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 16, 16, 24, 28,
+ 36, 44, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}};
+const SFB_PARAM_SHORT p_FDKaacEnc_88200_short_128 = {
+ 12, {4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36}};
+const SFB_PARAM_LONG p_FDKaacEnc_96000_long_1024 = {
+ 41, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 16, 16, 24, 28,
+ 36, 44, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}};
+const SFB_PARAM_SHORT p_FDKaacEnc_96000_short_128 = {
+ 12, {4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36}};
+
+/*
+ TNS filter coefficients
+*/
+
+/*
+ 3 bit resolution
+*/
+const FIXP_LPC FDKaacEnc_tnsEncCoeff3[8] = {
+ FX_DBL2FXCONST_LPC(0x81f1d201), FX_DBL2FXCONST_LPC(0x91261481),
+ FX_DBL2FXCONST_LPC(0xadb92301), FX_DBL2FXCONST_LPC(0xd438af00),
+ FX_DBL2FXCONST_LPC(0x00000000), FX_DBL2FXCONST_LPC(0x37898080),
+ FX_DBL2FXCONST_LPC(0x64130dff), FX_DBL2FXCONST_LPC(0x7cca6fff)};
+const FIXP_LPC FDKaacEnc_tnsCoeff3Borders[8] = {
+ FX_DBL2FXCONST_LPC(0x80000001) /*-4*/,
+ FX_DBL2FXCONST_LPC(0x87b826df) /*-3*/,
+ FX_DBL2FXCONST_LPC(0x9df24154) /*-2*/,
+ FX_DBL2FXCONST_LPC(0xbfffffe5) /*-1*/,
+ FX_DBL2FXCONST_LPC(0xe9c5e578) /* 0*/,
+ FX_DBL2FXCONST_LPC(0x1c7b90f0) /* 1*/,
+ FX_DBL2FXCONST_LPC(0x4fce83a9) /* 2*/,
+ FX_DBL2FXCONST_LPC(0x7352f2c3) /* 3*/
+};
+
+/*
+ 4 bit resolution
+*/
+const FIXP_LPC FDKaacEnc_tnsEncCoeff4[16] = {
+ FX_DBL2FXCONST_LPC(0x808bc881), FX_DBL2FXCONST_LPC(0x84e2e581),
+ FX_DBL2FXCONST_LPC(0x8d6b4a01), FX_DBL2FXCONST_LPC(0x99da9201),
+ FX_DBL2FXCONST_LPC(0xa9c45701), FX_DBL2FXCONST_LPC(0xbc9dde81),
+ FX_DBL2FXCONST_LPC(0xd1c2d500), FX_DBL2FXCONST_LPC(0xe87ae540),
+ FX_DBL2FXCONST_LPC(0x00000000), FX_DBL2FXCONST_LPC(0x1a9cd9c0),
+ FX_DBL2FXCONST_LPC(0x340ff240), FX_DBL2FXCONST_LPC(0x4b3c8bff),
+ FX_DBL2FXCONST_LPC(0x5f1f5e7f), FX_DBL2FXCONST_LPC(0x6ed9eb7f),
+ FX_DBL2FXCONST_LPC(0x79bc387f), FX_DBL2FXCONST_LPC(0x7f4c7e7f)};
+const FIXP_LPC FDKaacEnc_tnsCoeff4Borders[16] = {
+ FX_DBL2FXCONST_LPC(0x80000001) /*-8*/,
+ FX_DBL2FXCONST_LPC(0x822deff0) /*-7*/,
+ FX_DBL2FXCONST_LPC(0x88a4bfe6) /*-6*/,
+ FX_DBL2FXCONST_LPC(0x932c159d) /*-5*/,
+ FX_DBL2FXCONST_LPC(0xa16827c2) /*-4*/,
+ FX_DBL2FXCONST_LPC(0xb2dcde27) /*-3*/,
+ FX_DBL2FXCONST_LPC(0xc6f20b91) /*-2*/,
+ FX_DBL2FXCONST_LPC(0xdcf89c64) /*-1*/,
+ FX_DBL2FXCONST_LPC(0xf4308ce1) /* 0*/,
+ FX_DBL2FXCONST_LPC(0x0d613054) /* 1*/,
+ FX_DBL2FXCONST_LPC(0x278dde80) /* 2*/,
+ FX_DBL2FXCONST_LPC(0x4000001b) /* 3*/,
+ FX_DBL2FXCONST_LPC(0x55a6127b) /* 4*/,
+ FX_DBL2FXCONST_LPC(0x678dde8f) /* 5*/,
+ FX_DBL2FXCONST_LPC(0x74ef0ed7) /* 6*/,
+ FX_DBL2FXCONST_LPC(0x7d33f0da) /* 7*/
+};
+const FIXP_DBL FDKaacEnc_mTab_4_3Elc[512] = {
+ FL2FXCONST_DBL(0.3968502629920499), FL2FXCONST_DBL(0.3978840634868335),
+ FL2FXCONST_DBL(0.3989185359354711), FL2FXCONST_DBL(0.3999536794661432),
+ FL2FXCONST_DBL(0.4009894932098531), FL2FXCONST_DBL(0.4020259763004115),
+ FL2FXCONST_DBL(0.4030631278744227), FL2FXCONST_DBL(0.4041009470712695),
+ FL2FXCONST_DBL(0.4051394330330996), FL2FXCONST_DBL(0.4061785849048110),
+ FL2FXCONST_DBL(0.4072184018340380), FL2FXCONST_DBL(0.4082588829711372),
+ FL2FXCONST_DBL(0.4093000274691739), FL2FXCONST_DBL(0.4103418344839078),
+ FL2FXCONST_DBL(0.4113843031737798), FL2FXCONST_DBL(0.4124274326998980),
+ FL2FXCONST_DBL(0.4134712222260245), FL2FXCONST_DBL(0.4145156709185620),
+ FL2FXCONST_DBL(0.4155607779465400), FL2FXCONST_DBL(0.4166065424816022),
+ FL2FXCONST_DBL(0.4176529636979932), FL2FXCONST_DBL(0.4187000407725452),
+ FL2FXCONST_DBL(0.4197477728846652), FL2FXCONST_DBL(0.4207961592163222),
+ FL2FXCONST_DBL(0.4218451989520345), FL2FXCONST_DBL(0.4228948912788567),
+ FL2FXCONST_DBL(0.4239452353863673), FL2FXCONST_DBL(0.4249962304666564),
+ FL2FXCONST_DBL(0.4260478757143130), FL2FXCONST_DBL(0.4271001703264124),
+ FL2FXCONST_DBL(0.4281531135025046), FL2FXCONST_DBL(0.4292067044446017),
+ FL2FXCONST_DBL(0.4302609423571658), FL2FXCONST_DBL(0.4313158264470970),
+ FL2FXCONST_DBL(0.4323713559237216), FL2FXCONST_DBL(0.4334275299987803),
+ FL2FXCONST_DBL(0.4344843478864161), FL2FXCONST_DBL(0.4355418088031630),
+ FL2FXCONST_DBL(0.4365999119679339), FL2FXCONST_DBL(0.4376586566020096),
+ FL2FXCONST_DBL(0.4387180419290272), FL2FXCONST_DBL(0.4397780671749683),
+ FL2FXCONST_DBL(0.4408387315681480), FL2FXCONST_DBL(0.4419000343392039),
+ FL2FXCONST_DBL(0.4429619747210847), FL2FXCONST_DBL(0.4440245519490388),
+ FL2FXCONST_DBL(0.4450877652606038), FL2FXCONST_DBL(0.4461516138955953),
+ FL2FXCONST_DBL(0.4472160970960963), FL2FXCONST_DBL(0.4482812141064458),
+ FL2FXCONST_DBL(0.4493469641732286), FL2FXCONST_DBL(0.4504133465452648),
+ FL2FXCONST_DBL(0.4514803604735984), FL2FXCONST_DBL(0.4525480052114875),
+ FL2FXCONST_DBL(0.4536162800143939), FL2FXCONST_DBL(0.4546851841399719),
+ FL2FXCONST_DBL(0.4557547168480591), FL2FXCONST_DBL(0.4568248774006652),
+ FL2FXCONST_DBL(0.4578956650619623), FL2FXCONST_DBL(0.4589670790982746),
+ FL2FXCONST_DBL(0.4600391187780688), FL2FXCONST_DBL(0.4611117833719430),
+ FL2FXCONST_DBL(0.4621850721526184), FL2FXCONST_DBL(0.4632589843949278),
+ FL2FXCONST_DBL(0.4643335193758069), FL2FXCONST_DBL(0.4654086763742842),
+ FL2FXCONST_DBL(0.4664844546714713), FL2FXCONST_DBL(0.4675608535505532),
+ FL2FXCONST_DBL(0.4686378722967790), FL2FXCONST_DBL(0.4697155101974522),
+ FL2FXCONST_DBL(0.4707937665419216), FL2FXCONST_DBL(0.4718726406215713),
+ FL2FXCONST_DBL(0.4729521317298118), FL2FXCONST_DBL(0.4740322391620711),
+ FL2FXCONST_DBL(0.4751129622157845), FL2FXCONST_DBL(0.4761943001903867),
+ FL2FXCONST_DBL(0.4772762523873015), FL2FXCONST_DBL(0.4783588181099338),
+ FL2FXCONST_DBL(0.4794419966636599), FL2FXCONST_DBL(0.4805257873558190),
+ FL2FXCONST_DBL(0.4816101894957042), FL2FXCONST_DBL(0.4826952023945537),
+ FL2FXCONST_DBL(0.4837808253655421), FL2FXCONST_DBL(0.4848670577237714),
+ FL2FXCONST_DBL(0.4859538987862632), FL2FXCONST_DBL(0.4870413478719488),
+ FL2FXCONST_DBL(0.4881294043016621), FL2FXCONST_DBL(0.4892180673981298),
+ FL2FXCONST_DBL(0.4903073364859640), FL2FXCONST_DBL(0.4913972108916533),
+ FL2FXCONST_DBL(0.4924876899435545), FL2FXCONST_DBL(0.4935787729718844),
+ FL2FXCONST_DBL(0.4946704593087116), FL2FXCONST_DBL(0.4957627482879484),
+ FL2FXCONST_DBL(0.4968556392453423), FL2FXCONST_DBL(0.4979491315184684),
+ FL2FXCONST_DBL(0.4990432244467211), FL2FXCONST_DBL(0.5001379173713062),
+ FL2FXCONST_DBL(0.5012332096352328), FL2FXCONST_DBL(0.5023291005833056),
+ FL2FXCONST_DBL(0.5034255895621171), FL2FXCONST_DBL(0.5045226759200399),
+ FL2FXCONST_DBL(0.5056203590072181), FL2FXCONST_DBL(0.5067186381755611),
+ FL2FXCONST_DBL(0.5078175127787346), FL2FXCONST_DBL(0.5089169821721536),
+ FL2FXCONST_DBL(0.5100170457129749), FL2FXCONST_DBL(0.5111177027600893),
+ FL2FXCONST_DBL(0.5122189526741143), FL2FXCONST_DBL(0.5133207948173868),
+ FL2FXCONST_DBL(0.5144232285539552), FL2FXCONST_DBL(0.5155262532495726),
+ FL2FXCONST_DBL(0.5166298682716894), FL2FXCONST_DBL(0.5177340729894460),
+ FL2FXCONST_DBL(0.5188388667736652), FL2FXCONST_DBL(0.5199442489968457),
+ FL2FXCONST_DBL(0.5210502190331544), FL2FXCONST_DBL(0.5221567762584198),
+ FL2FXCONST_DBL(0.5232639200501247), FL2FXCONST_DBL(0.5243716497873989),
+ FL2FXCONST_DBL(0.5254799648510130), FL2FXCONST_DBL(0.5265888646233705),
+ FL2FXCONST_DBL(0.5276983484885021), FL2FXCONST_DBL(0.5288084158320574),
+ FL2FXCONST_DBL(0.5299190660412995), FL2FXCONST_DBL(0.5310302985050975),
+ FL2FXCONST_DBL(0.5321421126139198), FL2FXCONST_DBL(0.5332545077598274),
+ FL2FXCONST_DBL(0.5343674833364678), FL2FXCONST_DBL(0.5354810387390675),
+ FL2FXCONST_DBL(0.5365951733644262), FL2FXCONST_DBL(0.5377098866109097),
+ FL2FXCONST_DBL(0.5388251778784438), FL2FXCONST_DBL(0.5399410465685075),
+ FL2FXCONST_DBL(0.5410574920841272), FL2FXCONST_DBL(0.5421745138298695),
+ FL2FXCONST_DBL(0.5432921112118353), FL2FXCONST_DBL(0.5444102836376534),
+ FL2FXCONST_DBL(0.5455290305164744), FL2FXCONST_DBL(0.5466483512589642),
+ FL2FXCONST_DBL(0.5477682452772976), FL2FXCONST_DBL(0.5488887119851529),
+ FL2FXCONST_DBL(0.5500097507977050), FL2FXCONST_DBL(0.5511313611316194),
+ FL2FXCONST_DBL(0.5522535424050467), FL2FXCONST_DBL(0.5533762940376158),
+ FL2FXCONST_DBL(0.5544996154504284), FL2FXCONST_DBL(0.5556235060660528),
+ FL2FXCONST_DBL(0.5567479653085183), FL2FXCONST_DBL(0.5578729926033087),
+ FL2FXCONST_DBL(0.5589985873773569), FL2FXCONST_DBL(0.5601247490590389),
+ FL2FXCONST_DBL(0.5612514770781683), FL2FXCONST_DBL(0.5623787708659898),
+ FL2FXCONST_DBL(0.5635066298551742), FL2FXCONST_DBL(0.5646350534798125),
+ FL2FXCONST_DBL(0.5657640411754097), FL2FXCONST_DBL(0.5668935923788799),
+ FL2FXCONST_DBL(0.5680237065285404), FL2FXCONST_DBL(0.5691543830641059),
+ FL2FXCONST_DBL(0.5702856214266832), FL2FXCONST_DBL(0.5714174210587655),
+ FL2FXCONST_DBL(0.5725497814042271), FL2FXCONST_DBL(0.5736827019083177),
+ FL2FXCONST_DBL(0.5748161820176573), FL2FXCONST_DBL(0.5759502211802304),
+ FL2FXCONST_DBL(0.5770848188453810), FL2FXCONST_DBL(0.5782199744638067),
+ FL2FXCONST_DBL(0.5793556874875542), FL2FXCONST_DBL(0.5804919573700131),
+ FL2FXCONST_DBL(0.5816287835659116), FL2FXCONST_DBL(0.5827661655313104),
+ FL2FXCONST_DBL(0.5839041027235979), FL2FXCONST_DBL(0.5850425946014850),
+ FL2FXCONST_DBL(0.5861816406250000), FL2FXCONST_DBL(0.5873212402554834),
+ FL2FXCONST_DBL(0.5884613929555826), FL2FXCONST_DBL(0.5896020981892474),
+ FL2FXCONST_DBL(0.5907433554217242), FL2FXCONST_DBL(0.5918851641195517),
+ FL2FXCONST_DBL(0.5930275237505556), FL2FXCONST_DBL(0.5941704337838434),
+ FL2FXCONST_DBL(0.5953138936897999), FL2FXCONST_DBL(0.5964579029400819),
+ FL2FXCONST_DBL(0.5976024610076139), FL2FXCONST_DBL(0.5987475673665825),
+ FL2FXCONST_DBL(0.5998932214924321), FL2FXCONST_DBL(0.6010394228618597),
+ FL2FXCONST_DBL(0.6021861709528106), FL2FXCONST_DBL(0.6033334652444733),
+ FL2FXCONST_DBL(0.6044813052172748), FL2FXCONST_DBL(0.6056296903528761),
+ FL2FXCONST_DBL(0.6067786201341671), FL2FXCONST_DBL(0.6079280940452625),
+ FL2FXCONST_DBL(0.6090781115714966), FL2FXCONST_DBL(0.6102286721994192),
+ FL2FXCONST_DBL(0.6113797754167908), FL2FXCONST_DBL(0.6125314207125777),
+ FL2FXCONST_DBL(0.6136836075769482), FL2FXCONST_DBL(0.6148363355012674),
+ FL2FXCONST_DBL(0.6159896039780929), FL2FXCONST_DBL(0.6171434125011708),
+ FL2FXCONST_DBL(0.6182977605654305), FL2FXCONST_DBL(0.6194526476669808),
+ FL2FXCONST_DBL(0.6206080733031054), FL2FXCONST_DBL(0.6217640369722584),
+ FL2FXCONST_DBL(0.6229205381740598), FL2FXCONST_DBL(0.6240775764092919),
+ FL2FXCONST_DBL(0.6252351511798939), FL2FXCONST_DBL(0.6263932619889586),
+ FL2FXCONST_DBL(0.6275519083407275), FL2FXCONST_DBL(0.6287110897405869),
+ FL2FXCONST_DBL(0.6298708056950635), FL2FXCONST_DBL(0.6310310557118203),
+ FL2FXCONST_DBL(0.6321918392996523), FL2FXCONST_DBL(0.6333531559684823),
+ FL2FXCONST_DBL(0.6345150052293571), FL2FXCONST_DBL(0.6356773865944432),
+ FL2FXCONST_DBL(0.6368402995770224), FL2FXCONST_DBL(0.6380037436914881),
+ FL2FXCONST_DBL(0.6391677184533411), FL2FXCONST_DBL(0.6403322233791856),
+ FL2FXCONST_DBL(0.6414972579867254), FL2FXCONST_DBL(0.6426628217947594),
+ FL2FXCONST_DBL(0.6438289143231779), FL2FXCONST_DBL(0.6449955350929588),
+ FL2FXCONST_DBL(0.6461626836261636), FL2FXCONST_DBL(0.6473303594459330),
+ FL2FXCONST_DBL(0.6484985620764839), FL2FXCONST_DBL(0.6496672910431047),
+ FL2FXCONST_DBL(0.6508365458721518), FL2FXCONST_DBL(0.6520063260910459),
+ FL2FXCONST_DBL(0.6531766312282679), FL2FXCONST_DBL(0.6543474608133552),
+ FL2FXCONST_DBL(0.6555188143768979), FL2FXCONST_DBL(0.6566906914505349),
+ FL2FXCONST_DBL(0.6578630915669509), FL2FXCONST_DBL(0.6590360142598715),
+ FL2FXCONST_DBL(0.6602094590640603), FL2FXCONST_DBL(0.6613834255153149),
+ FL2FXCONST_DBL(0.6625579131504635), FL2FXCONST_DBL(0.6637329215073610),
+ FL2FXCONST_DBL(0.6649084501248851), FL2FXCONST_DBL(0.6660844985429335),
+ FL2FXCONST_DBL(0.6672610663024197), FL2FXCONST_DBL(0.6684381529452691),
+ FL2FXCONST_DBL(0.6696157580144163), FL2FXCONST_DBL(0.6707938810538011),
+ FL2FXCONST_DBL(0.6719725216083646), FL2FXCONST_DBL(0.6731516792240465),
+ FL2FXCONST_DBL(0.6743313534477807), FL2FXCONST_DBL(0.6755115438274927),
+ FL2FXCONST_DBL(0.6766922499120955), FL2FXCONST_DBL(0.6778734712514865),
+ FL2FXCONST_DBL(0.6790552073965435), FL2FXCONST_DBL(0.6802374578991223),
+ FL2FXCONST_DBL(0.6814202223120524), FL2FXCONST_DBL(0.6826035001891340),
+ FL2FXCONST_DBL(0.6837872910851345), FL2FXCONST_DBL(0.6849715945557853),
+ FL2FXCONST_DBL(0.6861564101577784), FL2FXCONST_DBL(0.6873417374487629),
+ FL2FXCONST_DBL(0.6885275759873420), FL2FXCONST_DBL(0.6897139253330697),
+ FL2FXCONST_DBL(0.6909007850464473), FL2FXCONST_DBL(0.6920881546889198),
+ FL2FXCONST_DBL(0.6932760338228737), FL2FXCONST_DBL(0.6944644220116332),
+ FL2FXCONST_DBL(0.6956533188194565), FL2FXCONST_DBL(0.6968427238115332),
+ FL2FXCONST_DBL(0.6980326365539813), FL2FXCONST_DBL(0.6992230566138435),
+ FL2FXCONST_DBL(0.7004139835590845), FL2FXCONST_DBL(0.7016054169585869),
+ FL2FXCONST_DBL(0.7027973563821499), FL2FXCONST_DBL(0.7039898014004843),
+ FL2FXCONST_DBL(0.7051827515852106), FL2FXCONST_DBL(0.7063762065088554),
+ FL2FXCONST_DBL(0.7075701657448483), FL2FXCONST_DBL(0.7087646288675196),
+ FL2FXCONST_DBL(0.7099595954520960), FL2FXCONST_DBL(0.7111550650746988),
+ FL2FXCONST_DBL(0.7123510373123402), FL2FXCONST_DBL(0.7135475117429202),
+ FL2FXCONST_DBL(0.7147444879452244), FL2FXCONST_DBL(0.7159419654989200),
+ FL2FXCONST_DBL(0.7171399439845538), FL2FXCONST_DBL(0.7183384229835486),
+ FL2FXCONST_DBL(0.7195374020782005), FL2FXCONST_DBL(0.7207368808516762),
+ FL2FXCONST_DBL(0.7219368588880097), FL2FXCONST_DBL(0.7231373357720997),
+ FL2FXCONST_DBL(0.7243383110897066), FL2FXCONST_DBL(0.7255397844274496),
+ FL2FXCONST_DBL(0.7267417553728043), FL2FXCONST_DBL(0.7279442235140992),
+ FL2FXCONST_DBL(0.7291471884405130), FL2FXCONST_DBL(0.7303506497420724),
+ FL2FXCONST_DBL(0.7315546070096487), FL2FXCONST_DBL(0.7327590598349553),
+ FL2FXCONST_DBL(0.7339640078105445), FL2FXCONST_DBL(0.7351694505298055),
+ FL2FXCONST_DBL(0.7363753875869610), FL2FXCONST_DBL(0.7375818185770647),
+ FL2FXCONST_DBL(0.7387887430959987), FL2FXCONST_DBL(0.7399961607404706),
+ FL2FXCONST_DBL(0.7412040711080108), FL2FXCONST_DBL(0.7424124737969701),
+ FL2FXCONST_DBL(0.7436213684065166), FL2FXCONST_DBL(0.7448307545366334),
+ FL2FXCONST_DBL(0.7460406317881158), FL2FXCONST_DBL(0.7472509997625686),
+ FL2FXCONST_DBL(0.7484618580624036), FL2FXCONST_DBL(0.7496732062908372),
+ FL2FXCONST_DBL(0.7508850440518872), FL2FXCONST_DBL(0.7520973709503704),
+ FL2FXCONST_DBL(0.7533101865919009), FL2FXCONST_DBL(0.7545234905828862),
+ FL2FXCONST_DBL(0.7557372825305252), FL2FXCONST_DBL(0.7569515620428062),
+ FL2FXCONST_DBL(0.7581663287285035), FL2FXCONST_DBL(0.7593815821971756),
+ FL2FXCONST_DBL(0.7605973220591619), FL2FXCONST_DBL(0.7618135479255810),
+ FL2FXCONST_DBL(0.7630302594083277), FL2FXCONST_DBL(0.7642474561200708),
+ FL2FXCONST_DBL(0.7654651376742505), FL2FXCONST_DBL(0.7666833036850760),
+ FL2FXCONST_DBL(0.7679019537675227), FL2FXCONST_DBL(0.7691210875373307),
+ FL2FXCONST_DBL(0.7703407046110011), FL2FXCONST_DBL(0.7715608046057948),
+ FL2FXCONST_DBL(0.7727813871397293), FL2FXCONST_DBL(0.7740024518315765),
+ FL2FXCONST_DBL(0.7752239983008605), FL2FXCONST_DBL(0.7764460261678551),
+ FL2FXCONST_DBL(0.7776685350535814), FL2FXCONST_DBL(0.7788915245798054),
+ FL2FXCONST_DBL(0.7801149943690360), FL2FXCONST_DBL(0.7813389440445223),
+ FL2FXCONST_DBL(0.7825633732302513), FL2FXCONST_DBL(0.7837882815509458),
+ FL2FXCONST_DBL(0.7850136686320621), FL2FXCONST_DBL(0.7862395340997874),
+ FL2FXCONST_DBL(0.7874658775810378), FL2FXCONST_DBL(0.7886926987034559),
+ FL2FXCONST_DBL(0.7899199970954088), FL2FXCONST_DBL(0.7911477723859853),
+ FL2FXCONST_DBL(0.7923760242049944), FL2FXCONST_DBL(0.7936047521829623),
+ FL2FXCONST_DBL(0.7948339559511308), FL2FXCONST_DBL(0.7960636351414546),
+ FL2FXCONST_DBL(0.7972937893865995), FL2FXCONST_DBL(0.7985244183199399),
+ FL2FXCONST_DBL(0.7997555215755570), FL2FXCONST_DBL(0.8009870987882359),
+ FL2FXCONST_DBL(0.8022191495934644), FL2FXCONST_DBL(0.8034516736274301),
+ FL2FXCONST_DBL(0.8046846705270185), FL2FXCONST_DBL(0.8059181399298110),
+ FL2FXCONST_DBL(0.8071520814740822), FL2FXCONST_DBL(0.8083864947987989),
+ FL2FXCONST_DBL(0.8096213795436166), FL2FXCONST_DBL(0.8108567353488784),
+ FL2FXCONST_DBL(0.8120925618556127), FL2FXCONST_DBL(0.8133288587055308),
+ FL2FXCONST_DBL(0.8145656255410253), FL2FXCONST_DBL(0.8158028620051674),
+ FL2FXCONST_DBL(0.8170405677417053), FL2FXCONST_DBL(0.8182787423950622),
+ FL2FXCONST_DBL(0.8195173856103341), FL2FXCONST_DBL(0.8207564970332875),
+ FL2FXCONST_DBL(0.8219960763103580), FL2FXCONST_DBL(0.8232361230886477),
+ FL2FXCONST_DBL(0.8244766370159234), FL2FXCONST_DBL(0.8257176177406150),
+ FL2FXCONST_DBL(0.8269590649118125), FL2FXCONST_DBL(0.8282009781792650),
+ FL2FXCONST_DBL(0.8294433571933784), FL2FXCONST_DBL(0.8306862016052132),
+ FL2FXCONST_DBL(0.8319295110664831), FL2FXCONST_DBL(0.8331732852295520),
+ FL2FXCONST_DBL(0.8344175237474336), FL2FXCONST_DBL(0.8356622262737878),
+ FL2FXCONST_DBL(0.8369073924629202), FL2FXCONST_DBL(0.8381530219697793),
+ FL2FXCONST_DBL(0.8393991144499545), FL2FXCONST_DBL(0.8406456695596752),
+ FL2FXCONST_DBL(0.8418926869558079), FL2FXCONST_DBL(0.8431401662958544),
+ FL2FXCONST_DBL(0.8443881072379507), FL2FXCONST_DBL(0.8456365094408642),
+ FL2FXCONST_DBL(0.8468853725639923), FL2FXCONST_DBL(0.8481346962673606),
+ FL2FXCONST_DBL(0.8493844802116208), FL2FXCONST_DBL(0.8506347240580492),
+ FL2FXCONST_DBL(0.8518854274685442), FL2FXCONST_DBL(0.8531365901056253),
+ FL2FXCONST_DBL(0.8543882116324307), FL2FXCONST_DBL(0.8556402917127157),
+ FL2FXCONST_DBL(0.8568928300108512), FL2FXCONST_DBL(0.8581458261918209),
+ FL2FXCONST_DBL(0.8593992799212207), FL2FXCONST_DBL(0.8606531908652563),
+ FL2FXCONST_DBL(0.8619075586907414), FL2FXCONST_DBL(0.8631623830650962),
+ FL2FXCONST_DBL(0.8644176636563452), FL2FXCONST_DBL(0.8656734001331161),
+ FL2FXCONST_DBL(0.8669295921646375), FL2FXCONST_DBL(0.8681862394207371),
+ FL2FXCONST_DBL(0.8694433415718407), FL2FXCONST_DBL(0.8707008982889695),
+ FL2FXCONST_DBL(0.8719589092437391), FL2FXCONST_DBL(0.8732173741083574),
+ FL2FXCONST_DBL(0.8744762925556232), FL2FXCONST_DBL(0.8757356642589241),
+ FL2FXCONST_DBL(0.8769954888922352), FL2FXCONST_DBL(0.8782557661301171),
+ FL2FXCONST_DBL(0.8795164956477146), FL2FXCONST_DBL(0.8807776771207545),
+ FL2FXCONST_DBL(0.8820393102255443), FL2FXCONST_DBL(0.8833013946389704),
+ FL2FXCONST_DBL(0.8845639300384969), FL2FXCONST_DBL(0.8858269161021629),
+ FL2FXCONST_DBL(0.8870903525085819), FL2FXCONST_DBL(0.8883542389369399),
+ FL2FXCONST_DBL(0.8896185750669933), FL2FXCONST_DBL(0.8908833605790678),
+ FL2FXCONST_DBL(0.8921485951540565), FL2FXCONST_DBL(0.8934142784734187),
+ FL2FXCONST_DBL(0.8946804102191776), FL2FXCONST_DBL(0.8959469900739191),
+ FL2FXCONST_DBL(0.8972140177207906), FL2FXCONST_DBL(0.8984814928434985),
+ FL2FXCONST_DBL(0.8997494151263077), FL2FXCONST_DBL(0.9010177842540390),
+ FL2FXCONST_DBL(0.9022865999120682), FL2FXCONST_DBL(0.9035558617863242),
+ FL2FXCONST_DBL(0.9048255695632878), FL2FXCONST_DBL(0.9060957229299895),
+ FL2FXCONST_DBL(0.9073663215740092), FL2FXCONST_DBL(0.9086373651834729),
+ FL2FXCONST_DBL(0.9099088534470528), FL2FXCONST_DBL(0.9111807860539647),
+ FL2FXCONST_DBL(0.9124531626939672), FL2FXCONST_DBL(0.9137259830573594),
+ FL2FXCONST_DBL(0.9149992468349805), FL2FXCONST_DBL(0.9162729537182071),
+ FL2FXCONST_DBL(0.9175471033989524), FL2FXCONST_DBL(0.9188216955696648),
+ FL2FXCONST_DBL(0.9200967299233258), FL2FXCONST_DBL(0.9213722061534494),
+ FL2FXCONST_DBL(0.9226481239540795), FL2FXCONST_DBL(0.9239244830197896),
+ FL2FXCONST_DBL(0.9252012830456805), FL2FXCONST_DBL(0.9264785237273793),
+ FL2FXCONST_DBL(0.9277562047610376), FL2FXCONST_DBL(0.9290343258433305),
+ FL2FXCONST_DBL(0.9303128866714547), FL2FXCONST_DBL(0.9315918869431275),
+ FL2FXCONST_DBL(0.9328713263565848), FL2FXCONST_DBL(0.9341512046105802),
+ FL2FXCONST_DBL(0.9354315214043836), FL2FXCONST_DBL(0.9367122764377792),
+ FL2FXCONST_DBL(0.9379934694110648), FL2FXCONST_DBL(0.9392751000250497),
+ FL2FXCONST_DBL(0.9405571679810542), FL2FXCONST_DBL(0.9418396729809072),
+ FL2FXCONST_DBL(0.9431226147269456), FL2FXCONST_DBL(0.9444059929220124),
+ FL2FXCONST_DBL(0.9456898072694558), FL2FXCONST_DBL(0.9469740574731275),
+ FL2FXCONST_DBL(0.9482587432373810), FL2FXCONST_DBL(0.9495438642670713),
+ FL2FXCONST_DBL(0.9508294202675522), FL2FXCONST_DBL(0.9521154109446763),
+ FL2FXCONST_DBL(0.9534018360047926), FL2FXCONST_DBL(0.9546886951547455),
+ FL2FXCONST_DBL(0.9559759881018738), FL2FXCONST_DBL(0.9572637145540087),
+ FL2FXCONST_DBL(0.9585518742194732), FL2FXCONST_DBL(0.9598404668070802),
+ FL2FXCONST_DBL(0.9611294920261317), FL2FXCONST_DBL(0.9624189495864168),
+ FL2FXCONST_DBL(0.9637088391982110), FL2FXCONST_DBL(0.9649991605722750),
+ FL2FXCONST_DBL(0.9662899134198524), FL2FXCONST_DBL(0.9675810974526697),
+ FL2FXCONST_DBL(0.9688727123829343), FL2FXCONST_DBL(0.9701647579233330),
+ FL2FXCONST_DBL(0.9714572337870316), FL2FXCONST_DBL(0.9727501396876727),
+ FL2FXCONST_DBL(0.9740434753393749), FL2FXCONST_DBL(0.9753372404567313),
+ FL2FXCONST_DBL(0.9766314347548087), FL2FXCONST_DBL(0.9779260579491460),
+ FL2FXCONST_DBL(0.9792211097557527), FL2FXCONST_DBL(0.9805165898911081),
+ FL2FXCONST_DBL(0.9818124980721600), FL2FXCONST_DBL(0.9831088340163232),
+ FL2FXCONST_DBL(0.9844055974414786), FL2FXCONST_DBL(0.9857027880659716),
+ FL2FXCONST_DBL(0.9870004056086111), FL2FXCONST_DBL(0.9882984497886684),
+ FL2FXCONST_DBL(0.9895969203258759), FL2FXCONST_DBL(0.9908958169404255),
+ FL2FXCONST_DBL(0.9921951393529680), FL2FXCONST_DBL(0.9934948872846116),
+ FL2FXCONST_DBL(0.9947950604569206), FL2FXCONST_DBL(0.9960956585919144),
+ FL2FXCONST_DBL(0.9973966814120665), FL2FXCONST_DBL(0.9986981286403025)};
+
+const FIXP_DBL FDKaacEnc_specExpMantTableCombElc[4][14] = {
+ {FL2FXCONST_DBL(0.5000000000000000), FL2FXCONST_DBL(0.6299605249474366),
+ FL2FXCONST_DBL(0.7937005259840998), FL2FXCONST_DBL(0.5000000000000000),
+ FL2FXCONST_DBL(0.6299605249474366), FL2FXCONST_DBL(0.7937005259840998),
+ FL2FXCONST_DBL(0.5000000000000000), FL2FXCONST_DBL(0.6299605249474366),
+ FL2FXCONST_DBL(0.7937005259840998), FL2FXCONST_DBL(0.5000000000000000),
+ FL2FXCONST_DBL(0.6299605249474366), FL2FXCONST_DBL(0.7937005259840998),
+ FL2FXCONST_DBL(0.5000000000000000), FL2FXCONST_DBL(0.6299605249474366)},
+
+ {FL2FXCONST_DBL(0.5946035575013605), FL2FXCONST_DBL(0.7491535384383408),
+ FL2FXCONST_DBL(0.9438743126816935), FL2FXCONST_DBL(0.5946035575013605),
+ FL2FXCONST_DBL(0.7491535384383408), FL2FXCONST_DBL(0.9438743126816935),
+ FL2FXCONST_DBL(0.5946035575013605), FL2FXCONST_DBL(0.7491535384383408),
+ FL2FXCONST_DBL(0.9438743126816935), FL2FXCONST_DBL(0.5946035575013605),
+ FL2FXCONST_DBL(0.7491535384383408), FL2FXCONST_DBL(0.9438743126816935),
+ FL2FXCONST_DBL(0.5946035575013605), FL2FXCONST_DBL(0.7491535384383408)},
+
+ {FL2FXCONST_DBL(0.7071067811865476), FL2FXCONST_DBL(0.8908987181403393),
+ FL2FXCONST_DBL(0.5612310241546865), FL2FXCONST_DBL(0.7071067811865476),
+ FL2FXCONST_DBL(0.8908987181403393), FL2FXCONST_DBL(0.5612310241546865),
+ FL2FXCONST_DBL(0.7071067811865476), FL2FXCONST_DBL(0.8908987181403393),
+ FL2FXCONST_DBL(0.5612310241546865), FL2FXCONST_DBL(0.7071067811865476),
+ FL2FXCONST_DBL(0.8908987181403393), FL2FXCONST_DBL(0.5612310241546865),
+ FL2FXCONST_DBL(0.7071067811865476), FL2FXCONST_DBL(0.8908987181403393)},
+
+ {FL2FXCONST_DBL(0.8408964152537145), FL2FXCONST_DBL(0.5297315471796477),
+ FL2FXCONST_DBL(0.6674199270850172), FL2FXCONST_DBL(0.8408964152537145),
+ FL2FXCONST_DBL(0.5297315471796477), FL2FXCONST_DBL(0.6674199270850172),
+ FL2FXCONST_DBL(0.8408964152537145), FL2FXCONST_DBL(0.5297315471796477),
+ FL2FXCONST_DBL(0.6674199270850172), FL2FXCONST_DBL(0.8408964152537145),
+ FL2FXCONST_DBL(0.5297315471796477), FL2FXCONST_DBL(0.6674199270850172),
+ FL2FXCONST_DBL(0.8408964152537145), FL2FXCONST_DBL(0.5297315471796477)}};
+
+const UCHAR FDKaacEnc_specExpTableComb[4][14] = {
+ {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18},
+ {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18},
+ {1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 16, 17, 18},
+ {1, 3, 4, 5, 7, 8, 9, 11, 12, 13, 15, 16, 17, 19}};
+
+#define WTS0 1
+#define WTS1 0
+#define WTS2 -2
+
+const FIXP_WTB ELDAnalysis512[1536] = {
+ /* part 0 */
+ WTC0(0xfac5a770), WTC0(0xfaafbab8), WTC0(0xfa996a40), WTC0(0xfa82bbd0),
+ WTC0(0xfa6bb538), WTC0(0xfa545c38), WTC0(0xfa3cb698), WTC0(0xfa24ca28),
+ WTC0(0xfa0c9ca8), WTC0(0xf9f433e8), WTC0(0xf9db9580), WTC0(0xf9c2c298),
+ WTC0(0xf9a9b800), WTC0(0xf9907250), WTC0(0xf976ee38), WTC0(0xf95d2b88),
+ WTC0(0xf9432d10), WTC0(0xf928f5c0), WTC0(0xf90e8868), WTC0(0xf8f3e400),
+ WTC0(0xf8d903a0), WTC0(0xf8bde238), WTC0(0xf8a27af0), WTC0(0xf886cde8),
+ WTC0(0xf86ae020), WTC0(0xf84eb6c0), WTC0(0xf83256f8), WTC0(0xf815c4b8),
+ WTC0(0xf7f902c0), WTC0(0xf7dc13b0), WTC0(0xf7befa60), WTC0(0xf7a1ba40),
+ WTC0(0xf78457c0), WTC0(0xf766d780), WTC0(0xf7493d90), WTC0(0xf72b8990),
+ WTC0(0xf70db5f0), WTC0(0xf6efbd30), WTC0(0xf6d19a20), WTC0(0xf6b352e0),
+ WTC0(0xf694f8c0), WTC0(0xf6769da0), WTC0(0xf6585310), WTC0(0xf63a28d0),
+ WTC0(0xf61c2c60), WTC0(0xf5fe6b10), WTC0(0xf5e0f250), WTC0(0xf5c3ceb0),
+ WTC0(0xf5a70be0), WTC0(0xf58ab5a0), WTC0(0xf56ed7b0), WTC0(0xf5537e40),
+ WTC0(0xf538b610), WTC0(0xf51e8bf0), WTC0(0xf5050c90), WTC0(0xf4ec4330),
+ WTC0(0xf4d439b0), WTC0(0xf4bcf9b0), WTC0(0xf4a68ce0), WTC0(0xf490fa80),
+ WTC0(0xf47c4760), WTC0(0xf4687830), WTC0(0xf4558f00), WTC0(0xf4434fc0),
+ WTC0(0xf4314070), WTC0(0xf41ee450), WTC0(0xf40bc130), WTC0(0xf3f799c0),
+ WTC0(0xf3e26d30), WTC0(0xf3cc3d70), WTC0(0xf3b50c80), WTC0(0xf39cdd60),
+ WTC0(0xf383b440), WTC0(0xf3699550), WTC0(0xf34e84c0), WTC0(0xf33286b0),
+ WTC0(0xf3159f10), WTC0(0xf2f7d1b0), WTC0(0xf2d92290), WTC0(0xf2b994d0),
+ WTC0(0xf2992ad0), WTC0(0xf277e6d0), WTC0(0xf255cb60), WTC0(0xf232dd00),
+ WTC0(0xf20f2240), WTC0(0xf1eaa1d0), WTC0(0xf1c56240), WTC0(0xf19f63d0),
+ WTC0(0xf178a0f0), WTC0(0xf15113a0), WTC0(0xf128b5c0), WTC0(0xf0ff7fd0),
+ WTC0(0xf0d56860), WTC0(0xf0aa6610), WTC0(0xf07e6fd0), WTC0(0xf0518190),
+ WTC0(0xf0239cd0), WTC0(0xeff4c320), WTC0(0xefc4f720), WTC0(0xef945080),
+ WTC0(0xef62fce0), WTC0(0xef312a40), WTC0(0xeeff05c0), WTC0(0xeecca2c0),
+ WTC0(0xee99faa0), WTC0(0xee6705a0), WTC0(0xee33bb60), WTC0(0xee000060),
+ WTC0(0xedcba660), WTC0(0xed967e80), WTC0(0xed605b80), WTC0(0xed293b40),
+ WTC0(0xecf146a0), WTC0(0xecb8a8a0), WTC0(0xec7f8bc0), WTC0(0xec461260),
+ WTC0(0xec0c5720), WTC0(0xebd27440), WTC0(0xeb988220), WTC0(0xeb5e7040),
+ WTC0(0xeb2404c0), WTC0(0xeae90440), WTC0(0xeaad33c0), WTC0(0xea7066c0),
+ WTC0(0xea327f60), WTC0(0xe9f36000), WTC0(0xe9b2ed60), WTC0(0xe9713920),
+ WTC0(0xe92e81e0), WTC0(0xe8eb08c0), WTC0(0xe8a70e60), WTC0(0xe862d8e0),
+ WTC0(0xe81eb340), WTC0(0xe7dae8a0), WTC0(0xe797c1a0), WTC0(0xe7554ca0),
+ WTC0(0xe7135dc0), WTC0(0xe6d1c6a0), WTC0(0xe6905720), WTC0(0xe64eb9c0),
+ WTC0(0xe60c7300), WTC0(0xe5c90600), WTC0(0xe583f920), WTC0(0xe53d1ce0),
+ WTC0(0xe4f48c80), WTC0(0xe4aa6640), WTC0(0xe45ecaa0), WTC0(0xe4120be0),
+ WTC0(0xe3c4ae60), WTC0(0xe3773860), WTC0(0xe32a2ea0), WTC0(0xe2ddeea0),
+ WTC0(0xe292af00), WTC0(0xe248a4a0), WTC0(0xe2000140), WTC0(0xe1b8b640),
+ WTC0(0xe1727440), WTC0(0xe12ce900), WTC0(0xe0e7c280), WTC0(0xe0a2b420),
+ WTC0(0xe05d76c0), WTC0(0xe017c360), WTC0(0xdfd15440), WTC0(0xdf8a0540),
+ WTC0(0xdf41d300), WTC0(0xdef8bb40), WTC0(0xdeaebd40), WTC0(0xde63e7c0),
+ WTC0(0xde185940), WTC0(0xddcc3180), WTC0(0xdd7f9000), WTC0(0xdd329e80),
+ WTC0(0xdce58e80), WTC0(0xdc989300), WTC0(0xdc4bde40), WTC0(0xdbff96c0),
+ WTC0(0xdbb3d780), WTC0(0xdb68bb80), WTC0(0xdb1e5c80), WTC0(0xdad4c380),
+ WTC0(0xda8be840), WTC0(0xda43c1c0), WTC0(0xd9fc4740), WTC0(0xd9b56640),
+ WTC0(0xd96f0440), WTC0(0xd9290600), WTC0(0xd8e35080), WTC0(0xd89dcd40),
+ WTC0(0xd8586b40), WTC0(0xd8131940), WTC0(0xd7cdc640), WTC0(0xd7886180),
+ WTC0(0xd742dc80), WTC0(0xd6fd2780), WTC0(0xd6b73400), WTC0(0xd670fd80),
+ WTC0(0xd62a8a40), WTC0(0xd5e3e080), WTC0(0xd59d0840), WTC0(0xd5562b80),
+ WTC0(0xd50f9540), WTC0(0xd4c992c0), WTC0(0xd4846f80), WTC0(0xd4405a80),
+ WTC0(0xd3fd6580), WTC0(0xd3bba140), WTC0(0xd37b1c80), WTC0(0xd33bb780),
+ WTC0(0xd2fd2400), WTC0(0xd2bf1240), WTC0(0xd2813300), WTC0(0xd2435ac0),
+ WTC0(0xd2057fc0), WTC0(0xd1c79a00), WTC0(0xd189a240), WTC0(0xd14b9dc0),
+ WTC0(0xd10d9e00), WTC0(0xd0cfb580), WTC0(0xd091f6c0), WTC0(0xd0548100),
+ WTC0(0xd0177f40), WTC0(0xcfdb1cc0), WTC0(0xcf9f84c0), WTC0(0xcf64d780),
+ WTC0(0xcf2b2b00), WTC0(0xcef29440), WTC0(0xcebb2640), WTC0(0xce84c000),
+ WTC0(0xce4f0bc0), WTC0(0xce19b200), WTC0(0xcde45d40), WTC0(0xcdaeedc0),
+ WTC0(0xcd7979c0), WTC0(0xcd4419c0), WTC0(0xcd0ee6c0), WTC0(0xccda0540),
+ WTC0(0xcca5a500), WTC0(0xcc71f640), WTC0(0xcc3f2800), WTC0(0xcc0d4300),
+ WTC0(0xcbdc2a00), WTC0(0xcbabbe80), WTC0(0xcb7be200), WTC0(0xcb4c8200),
+ WTC0(0xcb1d9800), WTC0(0xcaef1d40), WTC0(0xcac10bc0), WTC0(0xca936440),
+ WTC0(0xca662d00), WTC0(0xca396d40), WTC0(0xca0d2b80), WTC0(0xc9e16f80),
+ WTC0(0xc9b63f80), WTC0(0xc98ba2c0), WTC0(0xc961a000), WTC0(0xc9383ec0),
+ WTC0(0xc90a0440), WTC0(0xc8e0d280), WTC0(0xc8b73b80), WTC0(0xc88d4900),
+ WTC0(0xc86304c0), WTC0(0xc83878c0), WTC0(0xc80dae80), WTC0(0xc7e2afc0),
+ WTC0(0xc7b78640), WTC0(0xc78c3c40), WTC0(0xc760da80), WTC0(0xc7356640),
+ WTC0(0xc709de40), WTC0(0xc6de41c0), WTC0(0xc6b28fc0), WTC0(0xc686bd40),
+ WTC0(0xc65ab600), WTC0(0xc62e6580), WTC0(0xc601b880), WTC0(0xc5d4bac0),
+ WTC0(0xc5a79640), WTC0(0xc57a76c0), WTC0(0xc54d8780), WTC0(0xc520e840),
+ WTC0(0xc4f4acc0), WTC0(0xc4c8e880), WTC0(0xc49dad80), WTC0(0xc472e640),
+ WTC0(0xc44856c0), WTC0(0xc41dc140), WTC0(0xc3f2e940), WTC0(0xc3c7bc00),
+ WTC0(0xc39c4f00), WTC0(0xc370b9c0), WTC0(0xc34513c0), WTC0(0xc3197940),
+ WTC0(0xc2ee0a00), WTC0(0xc2c2e640), WTC0(0xc2982d80), WTC0(0xc26df5c0),
+ WTC0(0xc2444b00), WTC0(0xc21b3940), WTC0(0xc1f2cbc0), WTC0(0xc1cb05c0),
+ WTC0(0xc1a3e340), WTC0(0xc17d5f00), WTC0(0xc15773c0), WTC0(0xc1320940),
+ WTC0(0xc10cf480), WTC0(0xc0e80a00), WTC0(0xc0c31f00), WTC0(0xc09e2640),
+ WTC0(0xc0792ec0), WTC0(0xc0544940), WTC0(0xc02f86c0), WTC0(0xc00b04c0),
+ WTC0(0xbfe6ed01), WTC0(0xbfc36a01), WTC0(0xbfa0a581), WTC0(0xbf7eb581),
+ WTC0(0xbf5d9a81), WTC0(0xbf3d5501), WTC0(0xbf1de601), WTC0(0xbeff4801),
+ WTC0(0xbee17201), WTC0(0xbec45881), WTC0(0xbea7f301), WTC0(0xbe8c3781),
+ WTC0(0xbe712001), WTC0(0xbe56a381), WTC0(0xbe3cbc01), WTC0(0xbe236001),
+ WTC0(0xbe0a8581), WTC0(0xbdf22181), WTC0(0xbdda2a01), WTC0(0xbdc29a81),
+ WTC0(0xbdab7181), WTC0(0xbd94b001), WTC0(0xbd7e5581), WTC0(0xbd686681),
+ WTC0(0xbd52eb01), WTC0(0xbd3deb81), WTC0(0xbd297181), WTC0(0xbd158801),
+ WTC0(0xbd023f01), WTC0(0xbcefa601), WTC0(0xbcddcc81), WTC0(0xbcccbd01),
+ WTC0(0xbcbc7e01), WTC0(0xbcad1501), WTC0(0xbc9e8801), WTC0(0xbc90d481),
+ WTC0(0xbc83f201), WTC0(0xbc77d601), WTC0(0xbc6c7781), WTC0(0xbc61c401),
+ WTC0(0xbc57a301), WTC0(0xbc4dfb81), WTC0(0xbc44b481), WTC0(0xbc3bbc01),
+ WTC0(0xbc330781), WTC0(0xbc2a8c81), WTC0(0xbc224181), WTC0(0xbc1a2401),
+ WTC0(0xbc123b81), WTC0(0xbc0a8f01), WTC0(0xbc032601), WTC0(0xbbfc0f81),
+ WTC0(0xbbf56181), WTC0(0xbbef3301), WTC0(0xbbe99981), WTC0(0xbbe49d01),
+ WTC0(0xbbe03801), WTC0(0xbbdc6481), WTC0(0xbbd91b81), WTC0(0xbbd64d01),
+ WTC0(0xbbd3e101), WTC0(0xbbd1bd81), WTC0(0xbbcfca81), WTC0(0xbbce0601),
+ WTC0(0xbbcc8201), WTC0(0xbbcb5301), WTC0(0xbbca8d01), WTC0(0xbbca5081),
+ WTC0(0xbbcaca01), WTC0(0xbbcc2681), WTC0(0xbbce9181), WTC0(0xbbd21281),
+ WTC0(0xbbd68c81), WTC0(0xbbdbe201), WTC0(0xbbe1f401), WTC0(0xbbe89901),
+ WTC0(0xbbef9b81), WTC0(0xbbf6c601), WTC0(0xbbfde481), WTC0(0xbc04e381),
+ WTC0(0xbc0bcf81), WTC0(0xbc12b801), WTC0(0xbc19ab01), WTC0(0xbc20ae01),
+ WTC0(0xbc27bd81), WTC0(0xbc2ed681), WTC0(0xbc35f501), WTC0(0xbc3d1801),
+ WTC0(0xbc444081), WTC0(0xbc4b6e81), WTC0(0xbc52a381), WTC0(0xbc59df81),
+ WTC0(0xbc612301), WTC0(0xbc686e01), WTC0(0xbc6fc101), WTC0(0xbc771c01),
+ WTC0(0xbc7e7e01), WTC0(0xbc85e801), WTC0(0xbc8d5901), WTC0(0xbc94d201),
+ WTC0(0xbc9c5281), WTC0(0xbca3db01), WTC0(0xbcab6c01), WTC0(0xbcb30601),
+ WTC0(0xbcbaa801), WTC0(0xbcc25181), WTC0(0xbcca0301), WTC0(0xbcd1bb81),
+ WTC0(0xbcd97c81), WTC0(0xbce14601), WTC0(0xbce91801), WTC0(0xbcf0f381),
+ WTC0(0xbcf8d781), WTC0(0xbd00c381), WTC0(0xbd08b781), WTC0(0xbd10b381),
+ WTC0(0xbd18b781), WTC0(0xbd20c401), WTC0(0xbd28d981), WTC0(0xbd30f881),
+ WTC0(0xbd391f81), WTC0(0xbd414f01), WTC0(0xbd498601), WTC0(0xbd51c481),
+ WTC0(0xbd5a0b01), WTC0(0xbd625981), WTC0(0xbd6ab101), WTC0(0xbd731081),
+ WTC0(0xbd7b7781), WTC0(0xbd83e681), WTC0(0xbd8c5c01), WTC0(0xbd94d801),
+ WTC0(0xbd9d5b81), WTC0(0xbda5e601), WTC0(0xbdae7881), WTC0(0xbdb71201),
+ WTC0(0xbdbfb281), WTC0(0xbdc85981), WTC0(0xbdd10681), WTC0(0xbdd9b981),
+ WTC0(0xbde27201), WTC0(0xbdeb3101), WTC0(0xbdf3f701), WTC0(0xbdfcc301),
+ WTC0(0xbe059481), WTC0(0xbe0e6c01), WTC0(0xbe174781), WTC0(0xbe202801),
+ WTC0(0xbe290d01), WTC0(0xbe31f701), WTC0(0xbe3ae601), WTC0(0xbe43da81),
+ WTC0(0xbe4cd381), WTC0(0xbe55d001), WTC0(0xbe5ed081), WTC0(0xbe67d381),
+ WTC0(0xbe70da01), WTC0(0xbe79e481), WTC0(0xbe82f301), WTC0(0xbe8c0501),
+ WTC0(0xbe951a81), WTC0(0xbe9e3281), WTC0(0xbea74c81), WTC0(0xbeb06881),
+ WTC0(0xbeb98681), WTC0(0xbec2a781), WTC0(0xbecbca81), WTC0(0xbed4f081),
+ WTC0(0xbede1901), WTC0(0xbee74281), WTC0(0xbef06d01), WTC0(0xbef99901),
+ WTC0(0xbf02c581), WTC0(0xbf0bf381), WTC0(0xbf152381), WTC0(0xbf1e5501),
+ WTC0(0xbf278801), WTC0(0xbf30bb01), WTC0(0xbf39ee81), WTC0(0xbf432281),
+ WTC0(0xbf4c5681), WTC0(0xbf558b01), WTC0(0xbf5ec101), WTC0(0xbf67f801),
+ WTC0(0xbf712f01), WTC0(0xbf7a6681), WTC0(0xbf839d81), WTC0(0xbf8cd481),
+ WTC0(0xbf960b01), WTC0(0xbf9f4181), WTC0(0xbfa87901), WTC0(0xbfb1b101),
+ WTC0(0xbfbae981), WTC0(0xbfc42201), WTC0(0xbfcd5a01), WTC0(0xbfd69101),
+ WTC0(0xbfdfc781), WTC0(0xbfe8fc01), WTC0(0xbff22f81), WTC0(0xbffb6081),
+ /* part 1 */
+ WTC1(0x80093e01), WTC1(0x801b9b01), WTC1(0x802df701), WTC1(0x80405101),
+ WTC1(0x8052a881), WTC1(0x8064fc81), WTC1(0x80774c81), WTC1(0x80899881),
+ WTC1(0x809bdf01), WTC1(0x80ae1f81), WTC1(0x80c05a01), WTC1(0x80d28d81),
+ WTC1(0x80e4bb81), WTC1(0x80f6e481), WTC1(0x81090981), WTC1(0x811b2981),
+ WTC1(0x812d4481), WTC1(0x813f5981), WTC1(0x81516701), WTC1(0x81636d81),
+ WTC1(0x81756d81), WTC1(0x81876781), WTC1(0x81995c01), WTC1(0x81ab4b01),
+ WTC1(0x81bd3401), WTC1(0x81cf1581), WTC1(0x81e0ee81), WTC1(0x81f2bf81),
+ WTC1(0x82048881), WTC1(0x82164a81), WTC1(0x82280581), WTC1(0x8239b981),
+ WTC1(0x824b6601), WTC1(0x825d0901), WTC1(0x826ea201), WTC1(0x82803101),
+ WTC1(0x8291b601), WTC1(0x82a33281), WTC1(0x82b4a601), WTC1(0x82c61101),
+ WTC1(0x82d77201), WTC1(0x82e8c801), WTC1(0x82fa1181), WTC1(0x830b4f81),
+ WTC1(0x831c8101), WTC1(0x832da781), WTC1(0x833ec381), WTC1(0x834fd481),
+ WTC1(0x8360d901), WTC1(0x8371d081), WTC1(0x8382ba01), WTC1(0x83939501),
+ WTC1(0x83a46181), WTC1(0x83b52101), WTC1(0x83c5d381), WTC1(0x83d67881),
+ WTC1(0x83e70f01), WTC1(0x83f79681), WTC1(0x84080d81), WTC1(0x84187401),
+ WTC1(0x8428ca01), WTC1(0x84391081), WTC1(0x84494881), WTC1(0x84597081),
+ WTC1(0x84698881), WTC1(0x84798f81), WTC1(0x84898481), WTC1(0x84996701),
+ WTC1(0x84a93801), WTC1(0x84b8f801), WTC1(0x84c8a701), WTC1(0x84d84601),
+ WTC1(0x84e7d381), WTC1(0x84f74e01), WTC1(0x8506b581), WTC1(0x85160981),
+ WTC1(0x85254a81), WTC1(0x85347901), WTC1(0x85439601), WTC1(0x8552a181),
+ WTC1(0x85619a01), WTC1(0x85707f81), WTC1(0x857f5101), WTC1(0x858e0e01),
+ WTC1(0x859cb781), WTC1(0x85ab4f01), WTC1(0x85b9d481), WTC1(0x85c84801),
+ WTC1(0x85d6a981), WTC1(0x85e4f801), WTC1(0x85f33281), WTC1(0x86015981),
+ WTC1(0x860f6e01), WTC1(0x861d7081), WTC1(0x862b6201), WTC1(0x86394301),
+ WTC1(0x86471281), WTC1(0x8654d001), WTC1(0x86627b01), WTC1(0x86701381),
+ WTC1(0x867d9a81), WTC1(0x868b1001), WTC1(0x86987581), WTC1(0x86a5ca81),
+ WTC1(0x86b30f01), WTC1(0x86c04381), WTC1(0x86cd6681), WTC1(0x86da7901),
+ WTC1(0x86e77b81), WTC1(0x86f46d81), WTC1(0x87014f81), WTC1(0x870e2301),
+ WTC1(0x871ae981), WTC1(0x8727a381), WTC1(0x87345381), WTC1(0x8740f681),
+ WTC1(0x874d8681), WTC1(0x8759fd01), WTC1(0x87665481), WTC1(0x87729701),
+ WTC1(0x877ede01), WTC1(0x878b4301), WTC1(0x8797dd81), WTC1(0x87a48b01),
+ WTC1(0x87b0ef01), WTC1(0x87bcab81), WTC1(0x87c76201), WTC1(0x87d0ca81),
+ WTC1(0x87fdd781), WTC1(0x881dd301), WTC1(0x88423301), WTC1(0x886a8a81),
+ WTC1(0x88962981), WTC1(0x88c45e81), WTC1(0x88f47901), WTC1(0x8925f101),
+ WTC1(0x89586901), WTC1(0x898b8301), WTC1(0x89bee581), WTC1(0x89f26101),
+ WTC1(0x8a25f301), WTC1(0x8a599a81), WTC1(0x8a8d5801), WTC1(0x8ac13381),
+ WTC1(0x8af53e81), WTC1(0x8b298b81), WTC1(0x8b5e2c81), WTC1(0x8b933001),
+ WTC1(0x8bc8a401), WTC1(0x8bfe9401), WTC1(0x8c350d01), WTC1(0x8c6c1b01),
+ WTC1(0x8ca3cb01), WTC1(0x8cdc2901), WTC1(0x8d154081), WTC1(0x8d4f1b01),
+ WTC1(0x8d89be81), WTC1(0x8dc53001), WTC1(0x8e017581), WTC1(0x8e3e9481),
+ WTC1(0x8e7c9301), WTC1(0x8ebb7581), WTC1(0x8efb4181), WTC1(0x8f3bfb01),
+ WTC1(0x8f7da401), WTC1(0x8fc03f01), WTC1(0x9003ce81), WTC1(0x90485401),
+ WTC1(0x908dd101), WTC1(0x90d44781), WTC1(0x911bb981), WTC1(0x91642781),
+ WTC1(0x91ad9281), WTC1(0x91f7f981), WTC1(0x92435d01), WTC1(0x928fbe01),
+ WTC1(0x92dd1b01), WTC1(0x932b7501), WTC1(0x937acb01), WTC1(0x93cb1c81),
+ WTC1(0x941c6901), WTC1(0x946eaf81), WTC1(0x94c1ee01), WTC1(0x95162381),
+ WTC1(0x956b4f81), WTC1(0x95c17081), WTC1(0x96188501), WTC1(0x96708b81),
+ WTC1(0x96c98381), WTC1(0x97236b01), WTC1(0x977e4181), WTC1(0x97da0481),
+ WTC1(0x9836b201), WTC1(0x98944901), WTC1(0x98f2c601), WTC1(0x99522801),
+ WTC1(0x99b26c81), WTC1(0x9a139101), WTC1(0x9a759301), WTC1(0x9ad87081),
+ WTC1(0x9b3c2801), WTC1(0x9ba0b701), WTC1(0x9c061b81), WTC1(0x9c6c5481),
+ WTC1(0x9cd35f81), WTC1(0x9d3b3b81), WTC1(0x9da3e601), WTC1(0x9e0d5e01),
+ WTC1(0x9e779f81), WTC1(0x9ee2a901), WTC1(0x9f4e7801), WTC1(0x9fbb0981),
+ WTC1(0xa0285d81), WTC1(0xa0967201), WTC1(0xa1054701), WTC1(0xa174da81),
+ WTC1(0xa1e52a81), WTC1(0xa2563501), WTC1(0xa2c7f801), WTC1(0xa33a7201),
+ WTC1(0xa3ada281), WTC1(0xa4218801), WTC1(0xa4962181), WTC1(0xa50b6e81),
+ WTC1(0xa5816e81), WTC1(0xa5f81f81), WTC1(0xa66f8201), WTC1(0xa6e79401),
+ WTC1(0xa7605601), WTC1(0xa7d9c681), WTC1(0xa853e501), WTC1(0xa8ceb201),
+ WTC1(0xa94a2c01), WTC1(0xa9c65401), WTC1(0xaa432981), WTC1(0xaac0ad01),
+ WTC1(0xab3edf01), WTC1(0xabbdc001), WTC1(0xac3d5001), WTC1(0xacbd9081),
+ WTC1(0xad3e8101), WTC1(0xadc02281), WTC1(0xae427481), WTC1(0xaec57801),
+ WTC1(0xaf492f01), WTC1(0xafcd9a81), WTC1(0xb052bc01), WTC1(0xb0d89401),
+ WTC1(0xb15f2381), WTC1(0xb1e66a01), WTC1(0xb26e6881), WTC1(0xb2f71f01),
+ WTC1(0xb3808d81), WTC1(0xb40ab501), WTC1(0xb4959501), WTC1(0xb5212e81),
+ WTC1(0x4a6cf67f), WTC1(0x49dffeff), WTC1(0x495265ff), WTC1(0x48c4277f),
+ WTC1(0x4835407f), WTC1(0x47a5aeff), WTC1(0x471570ff), WTC1(0x468484ff),
+ WTC1(0x45f2eaff), WTC1(0x4560a2ff), WTC1(0x44cdad7f), WTC1(0x443a0c7f),
+ WTC1(0x43a5c07f), WTC1(0x4310caff), WTC1(0x427b2bff), WTC1(0x41e4e3ff),
+ WTC1(0x414df2ff), WTC1(0x40b6557f), WTC1(0x401e06ff), WTC1(0x3f8503c0),
+ WTC1(0x3eeb4e00), WTC1(0x3e50ebc0), WTC1(0x3db5e680), WTC1(0x3d1a4680),
+ WTC1(0x3c7e10c0), WTC1(0x3be14cc0), WTC1(0x3b4402c0), WTC1(0x3aa63800),
+ WTC1(0x3a07e840), WTC1(0x39690880), WTC1(0x38c98700), WTC1(0x38295b40),
+ WTC1(0x37888a80), WTC1(0x36e71d40), WTC1(0x36451d80), WTC1(0x35a29400),
+ WTC1(0x34ff8800), WTC1(0x345c04c0), WTC1(0x33b81940), WTC1(0x3313d200),
+ WTC1(0x326f3800), WTC1(0x31ca5600), WTC1(0x31253840), WTC1(0x307fe8c0),
+ WTC1(0x2fda6e40), WTC1(0x2f34ce40), WTC1(0x2e8f0e40), WTC1(0x2de92ec0),
+ WTC1(0x2d432780), WTC1(0x2c9cea40), WTC1(0x2bf66300), WTC1(0x2b4f88c0),
+ WTC1(0x2aa864c0), WTC1(0x2a010240), WTC1(0x29596e40), WTC1(0x28b1ba80),
+ WTC1(0x2809ff40), WTC1(0x27625b80), WTC1(0x26baf580), WTC1(0x2613e7c0),
+ WTC1(0x256d3dc0), WTC1(0x24c70300), WTC1(0x24214380), WTC1(0x237c0800),
+ WTC1(0x22d75400), WTC1(0x22332a80), WTC1(0x218f8cc0), WTC1(0x20ec7e40),
+ WTC1(0x204a04c0), WTC1(0x1fa82540), WTC1(0x1f06e300), WTC1(0x1e664000),
+ WTC1(0x1dc63bc0), WTC1(0x1d26d3c0), WTC1(0x1c8803a0), WTC1(0x1be9cc40),
+ WTC1(0x1b4c34c0), WTC1(0x1aaf4480), WTC1(0x1a130260), WTC1(0x197774a0),
+ WTC1(0x18dca260), WTC1(0x184294e0), WTC1(0x17a95840), WTC1(0x1710fd80),
+ WTC1(0x16799ce0), WTC1(0x15e35340), WTC1(0x154e41a0), WTC1(0x14ba8360),
+ WTC1(0x14282be0), WTC1(0x13975100), WTC1(0x13080aa0), WTC1(0x127a6240),
+ WTC1(0x11ee50a0), WTC1(0x1163cc80), WTC1(0x10dacb20), WTC1(0x105333a0),
+ WTC1(0x0fccdb30), WTC1(0x0f478f40), WTC1(0x0ec31700), WTC1(0x0e3f4e80),
+ WTC1(0x0dbc27f0), WTC1(0x0d399000), WTC1(0x0cb76d00), WTC1(0x0c359d50),
+ WTC1(0x0bb3fd50), WTC1(0x0b326bd0), WTC1(0x0ab0ca80), WTC1(0x0a2f0dc0),
+ WTC1(0x09ad40c0), WTC1(0x092b7a90), WTC1(0x08a9db80), WTC1(0x08285c80),
+ WTC1(0x07a6c7b8), WTC1(0x0724e4e0), WTC1(0x06a27b80), WTC1(0x061f52f8),
+ WTC1(0x059b2ad0), WTC1(0x0515b568), WTC1(0x048ea058), WTC1(0x04066408),
+ WTC1(0x037e52d8), WTC1(0x02f7d3c8), WTC1(0x0274614c), WTC1(0x01f63008),
+ WTC1(0x0180403a), WTC1(0x0115c442), WTC1(0x00ba09e2), WTC1(0x006f077c),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ /* part 2 */
+ WTC2(0xfff36be1), WTC2(0xffdafbc1), WTC2(0xffc28035), WTC2(0xffa9fe8a),
+ WTC2(0xff917c08), WTC2(0xff78fdfc), WTC2(0xff6089af), WTC2(0xff48246c),
+ WTC2(0xff2fd37f), WTC2(0xff179c31), WTC2(0xfeff83b6), WTC2(0xfee78d18),
+ WTC2(0xfecfb93e), WTC2(0xfeb808f2), WTC2(0xfea07d06), WTC2(0xfe8916b4),
+ WTC2(0xfe71d7a0), WTC2(0xfe5ac174), WTC2(0xfe43d5d6), WTC2(0xfe2d167e),
+ WTC2(0xfe16852e), WTC2(0xfe0023a6), WTC2(0xfde9f3f8), WTC2(0xfdd3ff7c),
+ WTC2(0xfdbe56c0), WTC2(0xfda90aa8), WTC2(0xfd942b78), WTC2(0xfd7fbb20),
+ WTC2(0xfd6bad50), WTC2(0xfd57f510), WTC2(0xfd44857c), WTC2(0xfd3153fc),
+ WTC2(0xfd1e5840), WTC2(0xfd0b8a0c), WTC2(0xfcf8e180), WTC2(0xfce65eec),
+ WTC2(0xfcd40ad0), WTC2(0xfcc1ee0c), WTC2(0xfcb011e8), WTC2(0xfc9e896c),
+ WTC2(0xfc8d716c), WTC2(0xfc7ce720), WTC2(0xfc6d072c), WTC2(0xfc5de09c),
+ WTC2(0xfc4f74e8), WTC2(0xfc41c4e8), WTC2(0xfc34d0dc), WTC2(0xfc288a68),
+ WTC2(0xfc1cd49c), WTC2(0xfc1191e0), WTC2(0xfc06a4d0), WTC2(0xfbfbf3e8),
+ WTC2(0xfbf16990), WTC2(0xfbe6f068), WTC2(0xfbdc7428), WTC2(0xfbd1fc68),
+ WTC2(0xfbc7ac50), WTC2(0xfbbda868), WTC2(0xfbb41500), WTC2(0xfbab1438),
+ WTC2(0xfba2c5f8), WTC2(0xfb9b4a00), WTC2(0xfb94bfa8), WTC2(0xfb8f3b48),
+ WTC2(0xfb8ac638), WTC2(0xfb876970), WTC2(0xfb852d20), WTC2(0xfb840ae0),
+ WTC2(0xfb83ed60), WTC2(0xfb84bec0), WTC2(0xfb866918), WTC2(0xfb88d4a8),
+ WTC2(0xfb8be810), WTC2(0xfb8f89d0), WTC2(0xfb93a080), WTC2(0xfb981418),
+ WTC2(0xfb9ccdf0), WTC2(0xfba1b770), WTC2(0xfba6bae0), WTC2(0xfbabd5c0),
+ WTC2(0xfbb118d8), WTC2(0xfbb695c0), WTC2(0xfbbc5e90), WTC2(0xfbc29030),
+ WTC2(0xfbc95268), WTC2(0xfbd0cd78), WTC2(0xfbd929c8), WTC2(0xfbe294d0),
+ WTC2(0xfbed4108), WTC2(0xfbf96118), WTC2(0xfc0726c8), WTC2(0xfc16b064),
+ WTC2(0xfc280890), WTC2(0xfc3b3920), WTC2(0xfc504a98), WTC2(0xfc67271c),
+ WTC2(0xfc7f9a74), WTC2(0xfc996f18), WTC2(0xfcb46eb8), WTC2(0xfcd050b0),
+ WTC2(0xfcecba24), WTC2(0xfd094f64), WTC2(0xfd25b720), WTC2(0xfd41ce40),
+ WTC2(0xfd5da7f8), WTC2(0xfd7959d8), WTC2(0xfd94fb74), WTC2(0xfdb0d3fc),
+ WTC2(0xfdcd5a34), WTC2(0xfdeb06e4), WTC2(0xfe0a5184), WTC2(0xfe2b92c4),
+ WTC2(0xfe4f0486), WTC2(0xfe74df54), WTC2(0xfe9d5886), WTC2(0xfec85b92),
+ WTC2(0xfef58a16), WTC2(0xff248275), WTC2(0xff54e401), WTC2(0xff866330),
+ WTC2(0xffb8c99b), WTC2(0xffebe1c9), WTC2(0x001f786a), WTC2(0x00538bf9),
+ WTC2(0x00884cbc), WTC2(0x00bded23), WTC2(0x00f49f54), WTC2(0x012c8ee4),
+ WTC2(0x0165e0d2), WTC2(0x01a0b9d6), WTC2(0x01dd3d80), WTC2(0x021b74d4),
+ WTC2(0x025b4e48), WTC2(0x029cb730), WTC2(0x02df9d0c), WTC2(0x0323f1a4),
+ WTC2(0x0369ab00), WTC2(0x03b0bf5c), WTC2(0x03f925a0), WTC2(0x0442e3d8),
+ WTC2(0x048e0f40), WTC2(0x04dabdb0), WTC2(0x05290430), WTC2(0x0578e428),
+ WTC2(0x05ca4b60), WTC2(0x061d26c0), WTC2(0x067163d8), WTC2(0x06c6ff10),
+ WTC2(0x071e03b0), WTC2(0x07767da0), WTC2(0x07d07918), WTC2(0x082c08e0),
+ WTC2(0x08894660), WTC2(0x08e84b70), WTC2(0x094930b0), WTC2(0x09abf8d0),
+ WTC2(0x0a109020), WTC2(0x0a76e210), WTC2(0x0adeda50), WTC2(0x0b486b80),
+ WTC2(0x0bb38f00), WTC2(0x0c203e80), WTC2(0x0c8e73e0), WTC2(0x0cfe2c30),
+ WTC2(0x0d6f6820), WTC2(0x0de22850), WTC2(0x0e566d90), WTC2(0x0ecc3dd0),
+ WTC2(0x0f43a3a0), WTC2(0x0fbca9f0), WTC2(0x10375b80), WTC2(0x10b3be20),
+ WTC2(0x1131d280), WTC2(0x11b19960), WTC2(0x123313a0), WTC2(0x12b64380),
+ WTC2(0x133b2d00), WTC2(0x13c1d440), WTC2(0x144a3d60), WTC2(0x14d46900),
+ WTC2(0x15605480), WTC2(0x15edfd20), WTC2(0x167d6040), WTC2(0x170e7e80),
+ WTC2(0x17a15b80), WTC2(0x1835fb00), WTC2(0x18cc60a0), WTC2(0x19648dc0),
+ WTC2(0x19fe80e0), WTC2(0x1a9a38a0), WTC2(0x1b37b3e0), WTC2(0x1bd6f400),
+ WTC2(0x1c77fd20), WTC2(0x1d1ad400), WTC2(0x1dbf7c80), WTC2(0x1e65f820),
+ WTC2(0x1f0e4540), WTC2(0x1fb861e0), WTC2(0x20644cc0), WTC2(0x21120640),
+ WTC2(0x21c19240), WTC2(0x2272f480), WTC2(0x23263000), WTC2(0x23db4580),
+ WTC2(0x24923340), WTC2(0x254af700), WTC2(0x26058e80), WTC2(0x26c1fa00),
+ WTC2(0x27803d00), WTC2(0x28405a40), WTC2(0x29025500), WTC2(0x29c62d40),
+ WTC2(0x2a8be0c0), WTC2(0x2b536cc0), WTC2(0x2c1ccf80), WTC2(0x2ce80840),
+ WTC2(0x2db519c0), WTC2(0x2e840600), WTC2(0x2f54cf80), WTC2(0x302775c0),
+ WTC2(0x30fbf640), WTC2(0x31d24e00), WTC2(0x32aa7a00), WTC2(0x338479c0),
+ WTC2(0x34604e40), WTC2(0x353df900), WTC2(0x361d7ac0), WTC2(0x36fed200),
+ WTC2(0x37e1fb40), WTC2(0x38c6f240), WTC2(0x39adb2c0), WTC2(0x3a963a00),
+ WTC2(0x3b808740), WTC2(0x3c6c9880), WTC2(0x3d5a6cc0), WTC2(0x3e4a0040),
+ WTC2(0x3f3b4bc0), WTC2(0x402e48ff), WTC2(0x4122f17f), WTC2(0x42193f7f),
+ WTC2(0x43112eff), WTC2(0x440abbff), WTC2(0x4505e2ff), WTC2(0x46029e7f),
+ WTC2(0x4700e9ff), WTC2(0x4800bfff), WTC2(0x49021bff), WTC2(0x4a050eff),
+ WTC2(0x4b09bc7f), WTC2(0x4c104aff), WTC2(0x4d18df7f), WTC2(0x4e23a07f),
+ WTC2(0x4f30b2ff), WTC2(0x50403c7f), WTC2(0x515262ff), WTC2(0x52674b7f),
+ WTC2(0x001678b2), WTC2(0x00061a3b), WTC2(0xfffb4622), WTC2(0xfff5ea94),
+ WTC2(0xfff5f5b9), WTC2(0xfffb55bd), WTC2(0x0005f8cb), WTC2(0x0015cd0c),
+ WTC2(0x002ac0ac), WTC2(0x0044c1d5), WTC2(0x0063beb2), WTC2(0x0087a56d),
+ WTC2(0x00b06431), WTC2(0x00dde929), WTC2(0x01102280), WTC2(0x0146fe5e),
+ WTC2(0x01826af2), WTC2(0x01c25662), WTC2(0x0206aedc), WTC2(0x024f6288),
+ WTC2(0x029c5f94), WTC2(0x02ed9424), WTC2(0x0342ee6c), WTC2(0x039c5c90),
+ WTC2(0x03f9ccbc), WTC2(0x045b2d18), WTC2(0x04c06bd8), WTC2(0x05297718),
+ WTC2(0x05963d10), WTC2(0x0606abe8), WTC2(0x067ab1c0), WTC2(0x06f23cd0),
+ WTC2(0x076d3b40), WTC2(0x07eb9b38), WTC2(0x086d4ae0), WTC2(0x08f23860),
+ WTC2(0x097a51f0), WTC2(0x0a0585b0), WTC2(0x0a93c1d0), WTC2(0x0b24f470),
+ WTC2(0x0bb90bc0), WTC2(0x0c4ff5f0), WTC2(0x0ce9a130), WTC2(0x0d85fb90),
+ WTC2(0x0e24f360), WTC2(0x0ec676b0), WTC2(0x0f6a73b0), WTC2(0x1010d880),
+ WTC2(0x10b99360), WTC2(0x11649280), WTC2(0x1211c400), WTC2(0x12c115e0),
+ WTC2(0x137276a0), WTC2(0x1425d420), WTC2(0x14db1ca0), WTC2(0x15923e60),
+ WTC2(0x164b2780), WTC2(0x1705c620), WTC2(0x17c20860), WTC2(0x187fdca0),
+ WTC2(0x193f30e0), WTC2(0x19fff340), WTC2(0x1ac21200), WTC2(0x1b857b40),
+ WTC2(0x1c4a1d40), WTC2(0x1d0fe600), WTC2(0x1dd6c3e0), WTC2(0x1e9ea4e0),
+ WTC2(0x1f677740), WTC2(0x20312940), WTC2(0x20fba8c0), WTC2(0x21c6e440),
+ WTC2(0x2292c9c0), WTC2(0x235f4780), WTC2(0x242c4b80), WTC2(0x24f9c400),
+ WTC2(0x25c79f40), WTC2(0x2695cb40), WTC2(0x27643680), WTC2(0x2832cec0),
+ WTC2(0x29018240), WTC2(0x29d03f80), WTC2(0x2a9ef480), WTC2(0x2b6d8f00),
+ WTC2(0x2c3bfdc0), WTC2(0x2d0a2ec0), WTC2(0x2dd81000), WTC2(0x2ea58fc0),
+ WTC2(0x2f729c40), WTC2(0x303f2380), WTC2(0x310b1400), WTC2(0x31d65b80),
+ WTC2(0x32a0e840), WTC2(0x336aa8c0), WTC2(0x34338ac0), WTC2(0x34fb7cc0),
+ WTC2(0x35c26cc0), WTC2(0x36884900), WTC2(0x374cff80), WTC2(0x38107e80),
+ WTC2(0x38d2b440), WTC2(0x39938ec0), WTC2(0x3a52fc40), WTC2(0x3b10eb00),
+ WTC2(0x3bcd4900), WTC2(0x3c880480), WTC2(0x3d410bc0), WTC2(0x3df84d00),
+ WTC2(0x3eadb600), WTC2(0x3f613540), WTC2(0x4012b8ff), WTC2(0x40c22eff),
+ WTC2(0x416f85ff), WTC2(0x421aab7f), WTC2(0x42c38e7f), WTC2(0x436a1c7f),
+ WTC2(0x440e437f), WTC2(0x44aff27f), WTC2(0x454f167f), WTC2(0x45eb9eff),
+ WTC2(0x468578ff), WTC2(0x471c937f), WTC2(0x47b0dc7f), WTC2(0x484241ff),
+ WTC2(0x48d0b1ff), WTC2(0x495c1a7f), WTC2(0x49e46a7f), WTC2(0x4a698f7f),
+ WTC2(0x4aeb77ff), WTC2(0x4b6a11ff), WTC2(0x4be54b7f), WTC2(0x4c5d12ff),
+ WTC2(0x4cd155ff), WTC2(0x4d4203ff), WTC2(0x4daf09ff), WTC2(0x4e18567f),
+ WTC2(0x4e7dd77f), WTC2(0x4edf7b7f), WTC2(0x4f3d307f), WTC2(0x4f96e47f),
+ WTC2(0x4fec85ff), WTC2(0x503e02ff), WTC2(0x508b497f), WTC2(0x50d447ff),
+ WTC2(0x5118ec7f), WTC2(0x515924ff), WTC2(0x5194dfff), WTC2(0x51cc0b7f),
+ WTC2(0x51fe95ff), WTC2(0x522c6cff), WTC2(0x52557eff), WTC2(0x5279b9ff),
+ WTC2(0x52990c7f), WTC2(0x52b364ff), WTC2(0x52c8b07f), WTC2(0x52d8ddff),
+ WTC2(0x52e3db7f), WTC2(0x52e996ff), WTC2(0x52e9ff7f), WTC2(0x52e501ff),
+ WTC2(0x52da8cff), WTC2(0x52ca8f7f), WTC2(0x52b4f67f), WTC2(0x5299b07f),
+ WTC2(0x5278ac7f), WTC2(0x5251d77f), WTC2(0x52251fff), WTC2(0x51f274ff),
+ WTC2(0x51b9c37f), WTC2(0x517af9ff), WTC2(0x5136077f), WTC2(0x50ead8ff),
+ WTC2(0x50995cff), WTC2(0x504181ff), WTC2(0x4fe335ff), WTC2(0x4f7e677f),
+ WTC2(0x4f1303ff), WTC2(0x4ea0f9ff), WTC2(0x4e2837ff), WTC2(0x4da8ab7f),
+ WTC2(0x4d2242ff), WTC2(0x4c94ecff), WTC2(0x4c0096ff), WTC2(0x4b652f7f),
+ WTC2(0x4ac2a4ff), WTC2(0x4a18e4ff), WTC2(0x4967ddff), WTC2(0x48af7e7f),
+ WTC2(0x47efb3ff), WTC2(0x47286cff), WTC2(0x4659ad7f), WTC2(0x45856f7f),
+ WTC2(0x44afa3ff), WTC2(0x43dc507f), WTC2(0x430f657f), WTC2(0x424ad47f),
+ WTC2(0x418e927f), WTC2(0x40da7bff), WTC2(0x402e6f7f), WTC2(0x3f8a3100),
+ WTC2(0x3eed6f40), WTC2(0x3e57d700), WTC2(0x3dc914c0), WTC2(0x3d40cc40),
+ WTC2(0x3cbe98c0), WTC2(0x3c421540), WTC2(0x3bcadbc0), WTC2(0x3b588880),
+ WTC2(0x3aeab780), WTC2(0x3a810540), WTC2(0x3a1b0e00), WTC2(0x39b86d00),
+ WTC2(0x3958bcc0), WTC2(0x38fb9700), WTC2(0x38a095c0), WTC2(0x38473d80),
+ WTC2(0x37eeff40), WTC2(0x37974b40), WTC2(0x373f9500), WTC2(0x36e7ae00),
+ WTC2(0x368fc4c0), WTC2(0x36380b80), WTC2(0x35e0b300), WTC2(0x3589c140),
+ WTC2(0x35331180), WTC2(0x34dc7c80), WTC2(0x3485dc80), WTC2(0x342f1600),
+ WTC2(0x33d81780), WTC2(0x3380d0c0), WTC2(0x33293100), WTC2(0x32d11800),
+ WTC2(0x32785780), WTC2(0x321ec0c0), WTC2(0x31c42680), WTC2(0x316885c0),
+ WTC2(0x310c0580), WTC2(0x30aecec0), WTC2(0x30510940), WTC2(0x2ff2b8c0),
+ WTC2(0x2f93bf40), WTC2(0x2f33fc00), WTC2(0x2ed350c0), WTC2(0x2e71ba80),
+ WTC2(0x2e0f5340), WTC2(0x2dac35c0), WTC2(0x2d487c80), WTC2(0x2ce431c0),
+ WTC2(0x2c7f4fc0), WTC2(0x2c19d080), WTC2(0x2bb3ad80), WTC2(0x2b4ce080),
+ WTC2(0x2ae56340), WTC2(0x2a7d2f80), WTC2(0x2a143f00), WTC2(0x29aa8b40)};
+
+const FIXP_WTB ELDAnalysis480[1440] = {
+ WTC0(0xfacfbef0), WTC0(0xfab88c18), WTC0(0xfaa0e520), WTC0(0xfa88d110),
+ WTC0(0xfa7056e8), WTC0(0xfa577db0), WTC0(0xfa3e4c70), WTC0(0xfa24ca28),
+ WTC0(0xfa0afde0), WTC0(0xf9f0eea0), WTC0(0xf9d6a2c8), WTC0(0xf9bc1ab8),
+ WTC0(0xf9a15230), WTC0(0xf9864510), WTC0(0xf96af058), WTC0(0xf94f55c0),
+ WTC0(0xf93378e0), WTC0(0xf9175d80), WTC0(0xf8fb0468), WTC0(0xf8de68b8),
+ WTC0(0xf8c18438), WTC0(0xf8a450d8), WTC0(0xf886cde8), WTC0(0xf8690148),
+ WTC0(0xf84af148), WTC0(0xf82ca410), WTC0(0xf80e1e18), WTC0(0xf7ef62a0),
+ WTC0(0xf7d074e0), WTC0(0xf7b15870), WTC0(0xf7921240), WTC0(0xf772a7a0),
+ WTC0(0xf7531e50), WTC0(0xf7337820), WTC0(0xf713afd0), WTC0(0xf6f3bea0),
+ WTC0(0xf6d39dc0), WTC0(0xf6b352e0), WTC0(0xf692f280), WTC0(0xf6729250),
+ WTC0(0xf65247a0), WTC0(0xf63224c0), WTC0(0xf6123a00), WTC0(0xf5f297c0),
+ WTC0(0xf5d34dd0), WTC0(0xf5b46b10), WTC0(0xf595fd90), WTC0(0xf5781390),
+ WTC0(0xf55abba0), WTC0(0xf53e0510), WTC0(0xf521ff70), WTC0(0xf506ba30),
+ WTC0(0xf4ec4330), WTC0(0xf4d2a680), WTC0(0xf4b9efe0), WTC0(0xf4a22ac0),
+ WTC0(0xf48b5f70), WTC0(0xf4759310), WTC0(0xf460cde0), WTC0(0xf44cfcc0),
+ WTC0(0xf439aff0), WTC0(0xf4264e00), WTC0(0xf4123d90), WTC0(0xf3fd1370),
+ WTC0(0xf3e6be00), WTC0(0xf3cf41a0), WTC0(0xf3b6a030), WTC0(0xf39cdd60),
+ WTC0(0xf381fe00), WTC0(0xf3660760), WTC0(0xf348fe70), WTC0(0xf32ae820),
+ WTC0(0xf30bc940), WTC0(0xf2eba690), WTC0(0xf2ca8480), WTC0(0xf2a86670),
+ WTC0(0xf2854f40), WTC0(0xf2614190), WTC0(0xf23c41e0), WTC0(0xf21657a0),
+ WTC0(0xf1ef8ae0), WTC0(0xf1c7e3e0), WTC0(0xf19f63d0), WTC0(0xf1760450),
+ WTC0(0xf14bbdf0), WTC0(0xf1208960), WTC0(0xf0f45cd0), WTC0(0xf0c72ce0),
+ WTC0(0xf098ee00), WTC0(0xf06996f0), WTC0(0xf0392620), WTC0(0xf0079e10),
+ WTC0(0xefd4ffc0), WTC0(0xefa15ca0), WTC0(0xef6ce600), WTC0(0xef37d460),
+ WTC0(0xef025f80), WTC0(0xeecca2c0), WTC0(0xee969760), WTC0(0xee603440),
+ WTC0(0xee296d20), WTC0(0xedf21c00), WTC0(0xedba07e0), WTC0(0xed80f640),
+ WTC0(0xed46bf40), WTC0(0xed0b7b00), WTC0(0xeccf5fc0), WTC0(0xec92a120),
+ WTC0(0xec556d60), WTC0(0xec17e700), WTC0(0xebda2d40), WTC0(0xeb9c5fa0),
+ WTC0(0xeb5e7040), WTC0(0xeb201b20), WTC0(0xeae117c0), WTC0(0xeaa12000),
+ WTC0(0xea600180), WTC0(0xea1d9940), WTC0(0xe9d9c160), WTC0(0xe99468a0),
+ WTC0(0xe94dc040), WTC0(0xe9061940), WTC0(0xe8bdc140), WTC0(0xe8750ae0),
+ WTC0(0xe82c4fa0), WTC0(0xe7e3ea40), WTC0(0xe79c35e0), WTC0(0xe7554ca0),
+ WTC0(0xe70efc00), WTC0(0xe6c90c20), WTC0(0xe6833f00), WTC0(0xe63d2300),
+ WTC0(0xe5f620a0), WTC0(0xe5ad9dc0), WTC0(0xe5632080), WTC0(0xe5169da0),
+ WTC0(0xe4c83e60), WTC0(0xe4782400), WTC0(0xe4269840), WTC0(0xe3d42dc0),
+ WTC0(0xe38188c0), WTC0(0xe32f4be0), WTC0(0xe2ddeea0), WTC0(0xe28db520),
+ WTC0(0xe23ee000), WTC0(0xe1f1a580), WTC0(0xe1a5e3a0), WTC0(0xe15b35a0),
+ WTC0(0xe1113860), WTC0(0xe0c78a00), WTC0(0xe07dd0e0), WTC0(0xe033b7c0),
+ WTC0(0xdfe8e680), WTC0(0xdf9d1fc0), WTC0(0xdf5055c0), WTC0(0xdf0287c0),
+ WTC0(0xdeb3b340), WTC0(0xde63e7c0), WTC0(0xde134a00), WTC0(0xddc20000),
+ WTC0(0xdd703180), WTC0(0xdd1e1280), WTC0(0xdccbe080), WTC0(0xdc79d980),
+ WTC0(0xdc283600), WTC0(0xdbd71e00), WTC0(0xdb86b140), WTC0(0xdb3710c0),
+ WTC0(0xdae850c0), WTC0(0xda9a6bc0), WTC0(0xda4d5640), WTC0(0xda010640),
+ WTC0(0xd9b56640), WTC0(0xd96a5700), WTC0(0xd91fb700), WTC0(0xd8d56600),
+ WTC0(0xd88b4a40), WTC0(0xd8414f00), WTC0(0xd7f75f80), WTC0(0xd7ad6740),
+ WTC0(0xd76352c0), WTC0(0xd7191040), WTC0(0xd6ce8c80), WTC0(0xd683bd00),
+ WTC0(0xd638a5c0), WTC0(0xd5ed4f80), WTC0(0xd5a1c240), WTC0(0xd5562b80),
+ WTC0(0xd50ae500), WTC0(0xd4c04c80), WTC0(0xd476bb40), WTC0(0xd42e62c0),
+ WTC0(0xd3e75680), WTC0(0xd3a1ad00), WTC0(0xd35d6780), WTC0(0xd31a4300),
+ WTC0(0xd2d7dc00), WTC0(0xd295d080), WTC0(0xd253d8c0), WTC0(0xd211df40),
+ WTC0(0xd1cfdbc0), WTC0(0xd18dc480), WTC0(0xd14b9dc0), WTC0(0xd1097c80),
+ WTC0(0xd0c77700), WTC0(0xd085a500), WTC0(0xd0442f40), WTC0(0xd0034a80),
+ WTC0(0xcfc32c00), WTC0(0xcf840400), WTC0(0xcf45f400), WTC0(0xcf0913c0),
+ WTC0(0xcecd8000), WTC0(0xce932c80), WTC0(0xce59bf40), WTC0(0xce20cd40),
+ WTC0(0xcde7ec40), WTC0(0xcdaeedc0), WTC0(0xcd75ea00), WTC0(0xcd3cfec0),
+ WTC0(0xcd044b40), WTC0(0xcccbff00), WTC0(0xcc945480), WTC0(0xcc5d8780),
+ WTC0(0xcc27c3c0), WTC0(0xcbf2fc40), WTC0(0xcbbf0a00), WTC0(0xcb8bc7c0),
+ WTC0(0xcb591880), WTC0(0xcb26f0c0), WTC0(0xcaf54980), WTC0(0xcac41ac0),
+ WTC0(0xca936440), WTC0(0xca632d80), WTC0(0xca337f00), WTC0(0xca046180),
+ WTC0(0xc9d5dd40), WTC0(0xc9a7fa80), WTC0(0xc97ac200), WTC0(0xc94e3c00),
+ WTC0(0xc91d1840), WTC0(0xc8f15980), WTC0(0xc8c52340), WTC0(0xc8988100),
+ WTC0(0xc86b7f00), WTC0(0xc83e28c0), WTC0(0xc8108a80), WTC0(0xc7e2afc0),
+ WTC0(0xc7b4a480), WTC0(0xc7867480), WTC0(0xc7582b40), WTC0(0xc729cc80),
+ WTC0(0xc6fb5700), WTC0(0xc6ccca40), WTC0(0xc69e2180), WTC0(0xc66f49c0),
+ WTC0(0xc64029c0), WTC0(0xc610a740), WTC0(0xc5e0bfc0), WTC0(0xc5b09e80),
+ WTC0(0xc5807900), WTC0(0xc5508440), WTC0(0xc520e840), WTC0(0xc4f1bdc0),
+ WTC0(0xc4c31d00), WTC0(0xc4951780), WTC0(0xc4678a00), WTC0(0xc43a28c0),
+ WTC0(0xc40ca800), WTC0(0xc3deccc0), WTC0(0xc3b09940), WTC0(0xc3822c00),
+ WTC0(0xc353a0c0), WTC0(0xc3251740), WTC0(0xc2f6b500), WTC0(0xc2c8a140),
+ WTC0(0xc29b02c0), WTC0(0xc26df5c0), WTC0(0xc2418940), WTC0(0xc215cbc0),
+ WTC0(0xc1eaca00), WTC0(0xc1c08680), WTC0(0xc196fb00), WTC0(0xc16e22c0),
+ WTC0(0xc145f040), WTC0(0xc11e3a80), WTC0(0xc0f6cc00), WTC0(0xc0cf6ec0),
+ WTC0(0xc0a802c0), WTC0(0xc0809280), WTC0(0xc0593340), WTC0(0xc031f880),
+ WTC0(0xc00b04c0), WTC0(0xbfe48981), WTC0(0xbfbebb81), WTC0(0xbf99cb01),
+ WTC0(0xbf75cc81), WTC0(0xbf52c101), WTC0(0xbf30a901), WTC0(0xbf0f8301),
+ WTC0(0xbeef4601), WTC0(0xbecfe601), WTC0(0xbeb15701), WTC0(0xbe938c81),
+ WTC0(0xbe767e81), WTC0(0xbe5a2301), WTC0(0xbe3e7201), WTC0(0xbe236001),
+ WTC0(0xbe08e181), WTC0(0xbdeee981), WTC0(0xbdd56b81), WTC0(0xbdbc6381),
+ WTC0(0xbda3d081), WTC0(0xbd8bb281), WTC0(0xbd740b81), WTC0(0xbd5ce281),
+ WTC0(0xbd464281), WTC0(0xbd303581), WTC0(0xbd1ac801), WTC0(0xbd060c81),
+ WTC0(0xbcf21601), WTC0(0xbcdef701), WTC0(0xbcccbd01), WTC0(0xbcbb7001),
+ WTC0(0xbcab1781), WTC0(0xbc9bb901), WTC0(0xbc8d5101), WTC0(0xbc7fd301),
+ WTC0(0xbc733401), WTC0(0xbc676501), WTC0(0xbc5c4c81), WTC0(0xbc51cb01),
+ WTC0(0xbc47c281), WTC0(0xbc3e1981), WTC0(0xbc34c081), WTC0(0xbc2bab01),
+ WTC0(0xbc22cd81), WTC0(0xbc1a2401), WTC0(0xbc11b681), WTC0(0xbc098d81),
+ WTC0(0xbc01b381), WTC0(0xbbfa3c01), WTC0(0xbbf34281), WTC0(0xbbece281),
+ WTC0(0xbbe73201), WTC0(0xbbe23281), WTC0(0xbbdddb01), WTC0(0xbbda2501),
+ WTC0(0xbbd70201), WTC0(0xbbd45601), WTC0(0xbbd20301), WTC0(0xbbcfea81),
+ WTC0(0xbbce0601), WTC0(0xbbcc6b01), WTC0(0xbbcb3201), WTC0(0xbbca7481),
+ WTC0(0xbbca5d01), WTC0(0xbbcb2281), WTC0(0xbbccfc81), WTC0(0xbbd01301),
+ WTC0(0xbbd45881), WTC0(0xbbd9a781), WTC0(0xbbdfdb81), WTC0(0xbbe6c801),
+ WTC0(0xbbee2f81), WTC0(0xbbf5d181), WTC0(0xbbfd6c01), WTC0(0xbc04e381),
+ WTC0(0xbc0c4581), WTC0(0xbc13a481), WTC0(0xbc1b1081), WTC0(0xbc228f01),
+ WTC0(0xbc2a1a81), WTC0(0xbc31af01), WTC0(0xbc394901), WTC0(0xbc40e881),
+ WTC0(0xbc488e81), WTC0(0xbc503b81), WTC0(0xbc57f101), WTC0(0xbc5fae81),
+ WTC0(0xbc677501), WTC0(0xbc6f4401), WTC0(0xbc771c01), WTC0(0xbc7efc81),
+ WTC0(0xbc86e581), WTC0(0xbc8ed701), WTC0(0xbc96d101), WTC0(0xbc9ed481),
+ WTC0(0xbca6e101), WTC0(0xbcaef701), WTC0(0xbcb71701), WTC0(0xbcbf4001),
+ WTC0(0xbcc77181), WTC0(0xbccfac01), WTC0(0xbcd7ef01), WTC0(0xbce03b81),
+ WTC0(0xbce89281), WTC0(0xbcf0f381), WTC0(0xbcf95e81), WTC0(0xbd01d281),
+ WTC0(0xbd0a4f81), WTC0(0xbd12d581), WTC0(0xbd1b6501), WTC0(0xbd23ff01),
+ WTC0(0xbd2ca281), WTC0(0xbd355081), WTC0(0xbd3e0801), WTC0(0xbd46c801),
+ WTC0(0xbd4f9101), WTC0(0xbd586281), WTC0(0xbd613d81), WTC0(0xbd6a2201),
+ WTC0(0xbd731081), WTC0(0xbd7c0781), WTC0(0xbd850701), WTC0(0xbd8e0e01),
+ WTC0(0xbd971c81), WTC0(0xbda03381), WTC0(0xbda95301), WTC0(0xbdb27b01),
+ WTC0(0xbdbbab01), WTC0(0xbdc4e301), WTC0(0xbdce2181), WTC0(0xbdd76701),
+ WTC0(0xbde0b301), WTC0(0xbdea0681), WTC0(0xbdf36101), WTC0(0xbdfcc301),
+ WTC0(0xbe062b81), WTC0(0xbe0f9a01), WTC0(0xbe190d81), WTC0(0xbe228681),
+ WTC0(0xbe2c0501), WTC0(0xbe358901), WTC0(0xbe3f1381), WTC0(0xbe48a301),
+ WTC0(0xbe523781), WTC0(0xbe5bd001), WTC0(0xbe656c01), WTC0(0xbe6f0c01),
+ WTC0(0xbe78b001), WTC0(0xbe825801), WTC0(0xbe8c0501), WTC0(0xbe95b581),
+ WTC0(0xbe9f6901), WTC0(0xbea91f01), WTC0(0xbeb2d681), WTC0(0xbebc9181),
+ WTC0(0xbec64e81), WTC0(0xbed00f81), WTC0(0xbed9d281), WTC0(0xbee39801),
+ WTC0(0xbeed5f01), WTC0(0xbef72681), WTC0(0xbf00ef81), WTC0(0xbf0aba01),
+ WTC0(0xbf148681), WTC0(0xbf1e5501), WTC0(0xbf282501), WTC0(0xbf31f501),
+ WTC0(0xbf3bc601), WTC0(0xbf459681), WTC0(0xbf4f6801), WTC0(0xbf593a01),
+ WTC0(0xbf630d81), WTC0(0xbf6ce201), WTC0(0xbf76b701), WTC0(0xbf808b81),
+ WTC0(0xbf8a5f81), WTC0(0xbf943301), WTC0(0xbf9e0701), WTC0(0xbfa7dc01),
+ WTC0(0xbfb1b101), WTC0(0xbfbb8701), WTC0(0xbfc55c81), WTC0(0xbfcf3181),
+ WTC0(0xbfd90601), WTC0(0xbfe2d901), WTC0(0xbfecaa81), WTC0(0xbff67a01),
+ /* part 1 */
+ WTC1(0x80130981), WTC1(0x80269f81), WTC1(0x803a3381), WTC1(0x804dc481),
+ WTC1(0x80615281), WTC1(0x8074dc01), WTC1(0x80886081), WTC1(0x809bdf01),
+ WTC1(0x80af5701), WTC1(0x80c2c781), WTC1(0x80d63101), WTC1(0x80e99401),
+ WTC1(0x80fcf181), WTC1(0x81104a01), WTC1(0x81239d81), WTC1(0x8136ea01),
+ WTC1(0x814a2f81), WTC1(0x815d6c01), WTC1(0x8170a181), WTC1(0x8183cf81),
+ WTC1(0x8196f781), WTC1(0x81aa1981), WTC1(0x81bd3401), WTC1(0x81d04681),
+ WTC1(0x81e34f81), WTC1(0x81f64f01), WTC1(0x82094581), WTC1(0x821c3401),
+ WTC1(0x822f1b01), WTC1(0x8241fa01), WTC1(0x8254cf01), WTC1(0x82679901),
+ WTC1(0x827a5801), WTC1(0x828d0b01), WTC1(0x829fb401), WTC1(0x82b25301),
+ WTC1(0x82c4e801), WTC1(0x82d77201), WTC1(0x82e9ef01), WTC1(0x82fc5f01),
+ WTC1(0x830ec081), WTC1(0x83211501), WTC1(0x83335c81), WTC1(0x83459881),
+ WTC1(0x8357c701), WTC1(0x8369e781), WTC1(0x837bf801), WTC1(0x838df801),
+ WTC1(0x839fe801), WTC1(0x83b1c881), WTC1(0x83c39a81), WTC1(0x83d55d01),
+ WTC1(0x83e70f01), WTC1(0x83f8b001), WTC1(0x840a3e81), WTC1(0x841bb981),
+ WTC1(0x842d2281), WTC1(0x843e7a81), WTC1(0x844fc081), WTC1(0x8460f581),
+ WTC1(0x84721701), WTC1(0x84832481), WTC1(0x84941d81), WTC1(0x84a50201),
+ WTC1(0x84b5d301), WTC1(0x84c69101), WTC1(0x84d73c01), WTC1(0x84e7d381),
+ WTC1(0x84f85581), WTC1(0x8508c181), WTC1(0x85191801), WTC1(0x85295881),
+ WTC1(0x85398481), WTC1(0x85499d01), WTC1(0x8559a081), WTC1(0x85698e81),
+ WTC1(0x85796601), WTC1(0x85892681), WTC1(0x8598d081), WTC1(0x85a86581),
+ WTC1(0x85b7e601), WTC1(0x85c75201), WTC1(0x85d6a981), WTC1(0x85e5eb81),
+ WTC1(0x85f51681), WTC1(0x86042c01), WTC1(0x86132c01), WTC1(0x86221801),
+ WTC1(0x8630f181), WTC1(0x863fb701), WTC1(0x864e6901), WTC1(0x865d0581),
+ WTC1(0x866b8d81), WTC1(0x867a0081), WTC1(0x86886001), WTC1(0x8696ad01),
+ WTC1(0x86a4e781), WTC1(0x86b30f01), WTC1(0x86c12401), WTC1(0x86cf2601),
+ WTC1(0x86dd1481), WTC1(0x86eaf081), WTC1(0x86f8ba81), WTC1(0x87067281),
+ WTC1(0x87141b01), WTC1(0x8721b481), WTC1(0x872f4201), WTC1(0x873cc201),
+ WTC1(0x874a2f01), WTC1(0x87578181), WTC1(0x8764b101), WTC1(0x8771c601),
+ WTC1(0x877ede01), WTC1(0x878c1881), WTC1(0x87998f01), WTC1(0x87a70e81),
+ WTC1(0x87b42481), WTC1(0x87c05e81), WTC1(0x87cb5101), WTC1(0x87d4ac81),
+ WTC1(0x87e73d81), WTC1(0x88124281), WTC1(0x88353501), WTC1(0x885f8481),
+ WTC1(0x888d3181), WTC1(0x88be1681), WTC1(0x88f13801), WTC1(0x8925f101),
+ WTC1(0x895bcd01), WTC1(0x89925a81), WTC1(0x89c92f81), WTC1(0x8a001f01),
+ WTC1(0x8a372881), WTC1(0x8a6e4a01), WTC1(0x8aa58681), WTC1(0x8adcee01),
+ WTC1(0x8b149701), WTC1(0x8b4c9701), WTC1(0x8b850281), WTC1(0x8bbde981),
+ WTC1(0x8bf75b01), WTC1(0x8c316681), WTC1(0x8c6c1b01), WTC1(0x8ca78781),
+ WTC1(0x8ce3ba81), WTC1(0x8d20c301), WTC1(0x8d5eaa01), WTC1(0x8d9d7781),
+ WTC1(0x8ddd3201), WTC1(0x8e1de001), WTC1(0x8e5f8881), WTC1(0x8ea23201),
+ WTC1(0x8ee5e301), WTC1(0x8f2aa101), WTC1(0x8f706f01), WTC1(0x8fb74f81),
+ WTC1(0x8fff4601), WTC1(0x90485401), WTC1(0x90927b81), WTC1(0x90ddc001),
+ WTC1(0x912a2201), WTC1(0x9177a301), WTC1(0x91c64301), WTC1(0x92160301),
+ WTC1(0x9266e281), WTC1(0x92b8e101), WTC1(0x930bff81), WTC1(0x93603d01),
+ WTC1(0x93b59901), WTC1(0x940c1281), WTC1(0x9463a881), WTC1(0x94bc5981),
+ WTC1(0x95162381), WTC1(0x95710601), WTC1(0x95ccff01), WTC1(0x962a0c81),
+ WTC1(0x96882e01), WTC1(0x96e76101), WTC1(0x9747a481), WTC1(0x97a8f681),
+ WTC1(0x980b5501), WTC1(0x986ebd81), WTC1(0x98d32d81), WTC1(0x9938a281),
+ WTC1(0x999f1981), WTC1(0x9a069001), WTC1(0x9a6f0381), WTC1(0x9ad87081),
+ WTC1(0x9b42d581), WTC1(0x9bae2f81), WTC1(0x9c1a7c81), WTC1(0x9c87ba81),
+ WTC1(0x9cf5e701), WTC1(0x9d650081), WTC1(0x9dd50481), WTC1(0x9e45f081),
+ WTC1(0x9eb7c101), WTC1(0x9f2a7281), WTC1(0x9f9e0301), WTC1(0xa0127081),
+ WTC1(0xa087b981), WTC1(0xa0fddd81), WTC1(0xa174da81), WTC1(0xa1ecae01),
+ WTC1(0xa2655581), WTC1(0xa2dece81), WTC1(0xa3591801), WTC1(0xa3d43001),
+ WTC1(0xa4501601), WTC1(0xa4ccc901), WTC1(0xa54a4701), WTC1(0xa5c89001),
+ WTC1(0xa647a301), WTC1(0xa6c77e01), WTC1(0xa7482101), WTC1(0xa7c98b01),
+ WTC1(0xa84bbb81), WTC1(0xa8ceb201), WTC1(0xa9526d81), WTC1(0xa9d6ef01),
+ WTC1(0xaa5c3601), WTC1(0xaae24301), WTC1(0xab691681), WTC1(0xabf0b181),
+ WTC1(0xac791401), WTC1(0xad023f01), WTC1(0xad8c3301), WTC1(0xae16f001),
+ WTC1(0xaea27681), WTC1(0xaf2ec901), WTC1(0xafbbe801), WTC1(0xb049d601),
+ WTC1(0xb0d89401), WTC1(0xb1682281), WTC1(0xb1f88181), WTC1(0xb289b181),
+ WTC1(0xb31bb301), WTC1(0xb3ae8601), WTC1(0xb4422b81), WTC1(0xb4d6a381),
+ WTC1(0x4a5a327f), WTC1(0x49c4adff), WTC1(0x492e637f), WTC1(0x48974f7f),
+ WTC1(0x47ff6d7f), WTC1(0x4766baff), WTC1(0x46cd35ff), WTC1(0x4632dd7f),
+ WTC1(0x4597b0ff), WTC1(0x44fbb1ff), WTC1(0x445eeaff), WTC1(0x43c165ff),
+ WTC1(0x4323227f), WTC1(0x4284277f), WTC1(0x41e48aff), WTC1(0x4144557f),
+ WTC1(0x40a3867f), WTC1(0x4001f5ff), WTC1(0x3f5f5d80), WTC1(0x3ebbad00),
+ WTC1(0x3e16ee40), WTC1(0x3d713d00), WTC1(0x3ccab700), WTC1(0x3c236500),
+ WTC1(0x3b7b5800), WTC1(0x3ad2ecc0), WTC1(0x3a2a6540), WTC1(0x3981b7c0),
+ WTC1(0x38d8ba00), WTC1(0x382f01c0), WTC1(0x37846240), WTC1(0x36d8eb00),
+ WTC1(0x362c9ec0), WTC1(0x357f7a00), WTC1(0x34d18340), WTC1(0x3422c900),
+ WTC1(0x33736c40), WTC1(0x32c39040), WTC1(0x32134280), WTC1(0x31629280),
+ WTC1(0x30b1a000), WTC1(0x30008380), WTC1(0x2f4f4240), WTC1(0x2e9df180),
+ WTC1(0x2decc780), WTC1(0x2d3bd640), WTC1(0x2c8b0cc0), WTC1(0x2bda3080),
+ WTC1(0x2b28ec80), WTC1(0x2a773500), WTC1(0x29c51b40), WTC1(0x291293c0),
+ WTC1(0x285f9280), WTC1(0x27ac35c0), WTC1(0x26f8ab40), WTC1(0x26454c00),
+ WTC1(0x25925600), WTC1(0x24dfd580), WTC1(0x242ddd40), WTC1(0x237c87c0),
+ WTC1(0x22cbe240), WTC1(0x221bef40), WTC1(0x216cb040), WTC1(0x20be2800),
+ WTC1(0x20105c80), WTC1(0x1f6352a0), WTC1(0x1eb71240), WTC1(0x1e0ba140),
+ WTC1(0x1d60fe40), WTC1(0x1cb723e0), WTC1(0x1c0e0300), WTC1(0x1b6596c0),
+ WTC1(0x1abde8a0), WTC1(0x1a16fbe0), WTC1(0x1970c680), WTC1(0x18cb4840),
+ WTC1(0x18268e20), WTC1(0x1782a0c0), WTC1(0x16df8960), WTC1(0x163d6300),
+ WTC1(0x159c52c0), WTC1(0x14fc87e0), WTC1(0x145e2c80), WTC1(0x13c15b60),
+ WTC1(0x13263240), WTC1(0x128cd9a0), WTC1(0x11f562a0), WTC1(0x115fc1c0),
+ WTC1(0x10cbf160), WTC1(0x1039f200), WTC1(0x0fa9a080), WTC1(0x0f1abd90),
+ WTC1(0x0e8d01d0), WTC1(0x0e003330), WTC1(0x0d743590), WTC1(0x0ce8ef40),
+ WTC1(0x0c5e1900), WTC1(0x0bd35d70), WTC1(0x0b488eb0), WTC1(0x0abd8410),
+ WTC1(0x0a320a00), WTC1(0x09a60e70), WTC1(0x0919ab00), WTC1(0x088d0de0),
+ WTC1(0x080065e0), WTC1(0x07739710), WTC1(0x06e65808), WTC1(0x06588348),
+ WTC1(0x05ca0ae0), WTC1(0x053aaaf8), WTC1(0x04a9faf0), WTC1(0x0417f698),
+ WTC1(0x03859ff4), WTC1(0x02f49be4), WTC1(0x0266b668), WTC1(0x01de554e),
+ WTC1(0x015f50ca), WTC1(0x00eb7e5d), WTC1(0x00904f24), WTC1(0x00212889),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ /* part 2 */
+ WTC2(0xfffece02), WTC2(0xffe4c3df), WTC2(0xffcaaa55), WTC2(0xffb087d1),
+ WTC2(0xff9662bf), WTC2(0xff7c418b), WTC2(0xff622aa0), WTC2(0xff48246c),
+ WTC2(0xff2e355a), WTC2(0xff1463db), WTC2(0xfefab608), WTC2(0xfee12f0a),
+ WTC2(0xfec7cfd2), WTC2(0xfeae995a), WTC2(0xfe958cc4), WTC2(0xfe7cabce),
+ WTC2(0xfe63f882), WTC2(0xfe4b74e0), WTC2(0xfe3322f6), WTC2(0xfe1b04dc),
+ WTC2(0xfe031ccc), WTC2(0xfdeb6cf0), WTC2(0xfdd3ff7c), WTC2(0xfdbce834),
+ WTC2(0xfda63bb8), WTC2(0xfd900c68), WTC2(0xfd7a590c), WTC2(0xfd6511b4),
+ WTC2(0xfd5026c0), WTC2(0xfd3b8954), WTC2(0xfd272df0), WTC2(0xfd130adc),
+ WTC2(0xfcff15ac), WTC2(0xfceb4a68), WTC2(0xfcd7b110), WTC2(0xfcc454d0),
+ WTC2(0xfcb14064), WTC2(0xfc9e896c), WTC2(0xfc8c5264), WTC2(0xfc7abef0),
+ WTC2(0xfc69f078), WTC2(0xfc59f5e8), WTC2(0xfc4acfec), WTC2(0xfc3c8060),
+ WTC2(0xfc2f0264), WTC2(0xfc223b7c), WTC2(0xfc160714), WTC2(0xfc0a4150),
+ WTC2(0xfbfec920), WTC2(0xfbf38320), WTC2(0xfbe855d0), WTC2(0xfbdd2740),
+ WTC2(0xfbd1fc68), WTC2(0xfbc6fea0), WTC2(0xfbbc5a48), WTC2(0xfbb23b48),
+ WTC2(0xfba8ca78), WTC2(0xfba02e50), WTC2(0xfb988de0), WTC2(0xfb920b40),
+ WTC2(0xfb8cb870), WTC2(0xfb889f68), WTC2(0xfb85cbe8), WTC2(0xfb843dd0),
+ WTC2(0xfb83df78), WTC2(0xfb8495d0), WTC2(0xfb864660), WTC2(0xfb88d4a8),
+ WTC2(0xfb8c21e8), WTC2(0xfb900f28), WTC2(0xfb947dc0), WTC2(0xfb9950c0),
+ WTC2(0xfb9e6d08), WTC2(0xfba3b658), WTC2(0xfba91908), WTC2(0xfbae9e08),
+ WTC2(0xfbb45bd0), WTC2(0xfbba66f8), WTC2(0xfbc0dcf0), WTC2(0xfbc7ead8),
+ WTC2(0xfbcfc200), WTC2(0xfbd89330), WTC2(0xfbe294d0), WTC2(0xfbee03d0),
+ WTC2(0xfbfb1de8), WTC2(0xfc0a1da4), WTC2(0xfc1b22e0), WTC2(0xfc2e38f0),
+ WTC2(0xfc436d48), WTC2(0xfc5abf7c), WTC2(0xfc74024c), WTC2(0xfc8ef2e8),
+ WTC2(0xfcab51ac), WTC2(0xfcc8d024), WTC2(0xfce704f0), WTC2(0xfd0580cc),
+ WTC2(0xfd23d4d0), WTC2(0xfd41ce40), WTC2(0xfd5f81b0), WTC2(0xfd7d08f0),
+ WTC2(0xfd9a8560), WTC2(0xfdb85938), WTC2(0xfdd71798), WTC2(0xfdf753b8),
+ WTC2(0xfe1993ee), WTC2(0xfe3e30f8), WTC2(0xfe656cba), WTC2(0xfe8f8fdc),
+ WTC2(0xfebca8a4), WTC2(0xfeec590e), WTC2(0xff1e285c), WTC2(0xff51a0b7),
+ WTC2(0xff866330), WTC2(0xffbc2cbb), WTC2(0xfff2bbff), WTC2(0x0029d79d),
+ WTC2(0x00618a22), WTC2(0x009a1185), WTC2(0x00d3aa8c), WTC2(0x010e8ff6),
+ WTC2(0x014af29e), WTC2(0x0188fe56), WTC2(0x01c8e108), WTC2(0x020ab3c4),
+ WTC2(0x024e68a8), WTC2(0x0293e824), WTC2(0x02db1bc8), WTC2(0x0323f1a4),
+ WTC2(0x036e5d6c), WTC2(0x03ba5320), WTC2(0x0407c938), WTC2(0x0456cad0),
+ WTC2(0x04a77288), WTC2(0x04f9db88), WTC2(0x054e1888), WTC2(0x05a41ef0),
+ WTC2(0x05fbd6e0), WTC2(0x065528c0), WTC2(0x06b00838), WTC2(0x070c7ee0),
+ WTC2(0x076a9bb0), WTC2(0x07ca6d10), WTC2(0x082c08e0), WTC2(0x088f8da0),
+ WTC2(0x08f51ac0), WTC2(0x095ccc20), WTC2(0x09c69f70), WTC2(0x0a327b40),
+ WTC2(0x0aa046d0), WTC2(0x0b0febb0), WTC2(0x0b815dd0), WTC2(0x0bf49600),
+ WTC2(0x0c698c50), WTC2(0x0ce03ba0), WTC2(0x0d58a380), WTC2(0x0dd2c510),
+ WTC2(0x0e4ea110), WTC2(0x0ecc3dd0), WTC2(0x0f4ba800), WTC2(0x0fcced10),
+ WTC2(0x10501960), WTC2(0x10d532a0), WTC2(0x115c39c0), WTC2(0x11e52fa0),
+ WTC2(0x12701560), WTC2(0x12fcef20), WTC2(0x138bc200), WTC2(0x141c9300),
+ WTC2(0x14af64a0), WTC2(0x154434e0), WTC2(0x15db0020), WTC2(0x1673c360),
+ WTC2(0x170e7e80), WTC2(0x17ab35e0), WTC2(0x1849ee40), WTC2(0x18eaaba0),
+ WTC2(0x198d6f00), WTC2(0x1a3236a0), WTC2(0x1ad90080), WTC2(0x1b81cc60),
+ WTC2(0x1c2c9da0), WTC2(0x1cd97980), WTC2(0x1d8865c0), WTC2(0x1e396540),
+ WTC2(0x1eec7700), WTC2(0x1fa198c0), WTC2(0x2058c840), WTC2(0x21120640),
+ WTC2(0x21cd5700), WTC2(0x228abec0), WTC2(0x234a4180), WTC2(0x240bdf80),
+ WTC2(0x24cf95c0), WTC2(0x259561c0), WTC2(0x265d4200), WTC2(0x27273840),
+ WTC2(0x27f348c0), WTC2(0x28c17700), WTC2(0x2991c500), WTC2(0x2a643080),
+ WTC2(0x2b38b680), WTC2(0x2c0f53c0), WTC2(0x2ce80840), WTC2(0x2dc2d680),
+ WTC2(0x2e9fc100), WTC2(0x2f7ecac0), WTC2(0x305ff280), WTC2(0x314334c0),
+ WTC2(0x32288e00), WTC2(0x330ffb80), WTC2(0x33f97d80), WTC2(0x34e515c0),
+ WTC2(0x35d2c5c0), WTC2(0x36c28d00), WTC2(0x37b467c0), WTC2(0x38a85080),
+ WTC2(0x399e4240), WTC2(0x3a963a00), WTC2(0x3b903600), WTC2(0x3c8c3480),
+ WTC2(0x3d8a3380), WTC2(0x3e8a2dc0), WTC2(0x3f8c1b40), WTC2(0x408ff2ff),
+ WTC2(0x4195ae7f), WTC2(0x429d477f), WTC2(0x43a6b87f), WTC2(0x44b1fdff),
+ WTC2(0x45bf11ff), WTC2(0x46cdee7f), WTC2(0x47de8cff), WTC2(0x48f0e77f),
+ WTC2(0x4a050eff), WTC2(0x4b1b2dff), WTC2(0x4c3372ff), WTC2(0x4d4e0bff),
+ WTC2(0x4e6b257f), WTC2(0x4f8aedff), WTC2(0x50ad92ff), WTC2(0x51d341ff),
+ WTC2(0x002006a9), WTC2(0x000bfb36), WTC2(0xfffe45ac), WTC2(0xfff6d064),
+ WTC2(0xfff585bc), WTC2(0xfffa500d), WTC2(0x000519b4), WTC2(0x0015cd0c),
+ WTC2(0x002c5470), WTC2(0x00489a3b), WTC2(0x006a88c8), WTC2(0x00920a74),
+ WTC2(0x00bf0999), WTC2(0x00f17092), WTC2(0x012929bc), WTC2(0x01661f70),
+ WTC2(0x01a83c0c), WTC2(0x01ef69e8), WTC2(0x023b9364), WTC2(0x028ca2d4),
+ WTC2(0x02e2829c), WTC2(0x033d1d10), WTC2(0x039c5c90), WTC2(0x04002b78),
+ WTC2(0x04687418), WTC2(0x04d520e0), WTC2(0x05461c18), WTC2(0x05bb5020),
+ WTC2(0x0634a758), WTC2(0x06b20c20), WTC2(0x073368c8), WTC2(0x07b8a7b0),
+ WTC2(0x0841b340), WTC2(0x08ce75b0), WTC2(0x095ed980), WTC2(0x09f2c900),
+ WTC2(0x0a8a2e80), WTC2(0x0b24f470), WTC2(0x0bc30510), WTC2(0x0c644ad0),
+ WTC2(0x0d08b010), WTC2(0x0db01f10), WTC2(0x0e5a8250), WTC2(0x0f07c400),
+ WTC2(0x0fb7cea0), WTC2(0x106a8c80), WTC2(0x111fe800), WTC2(0x11d7cb60),
+ WTC2(0x12922120), WTC2(0x134ed3a0), WTC2(0x140dcd00), WTC2(0x14cef7e0),
+ WTC2(0x15923e60), WTC2(0x16578b00), WTC2(0x171ec820), WTC2(0x17e7e020),
+ WTC2(0x18b2bd20), WTC2(0x197f49c0), WTC2(0x1a4d7040), WTC2(0x1b1d1b00),
+ WTC2(0x1bee3460), WTC2(0x1cc0a6a0), WTC2(0x1d945c40), WTC2(0x1e693f80),
+ WTC2(0x1f3f3ac0), WTC2(0x20163880), WTC2(0x20ee22c0), WTC2(0x21c6e440),
+ WTC2(0x22a06740), WTC2(0x237a9600), WTC2(0x24555ac0), WTC2(0x2530a040),
+ WTC2(0x260c5080), WTC2(0x26e85600), WTC2(0x27c49b00), WTC2(0x28a10a00),
+ WTC2(0x297d8d80), WTC2(0x2a5a0f80), WTC2(0x2b367a80), WTC2(0x2c12b8c0),
+ WTC2(0x2ceeb500), WTC2(0x2dca5940), WTC2(0x2ea58fc0), WTC2(0x2f804340),
+ WTC2(0x305a5dc0), WTC2(0x3133ca00), WTC2(0x320c7200), WTC2(0x32e44000),
+ WTC2(0x33bb1ec0), WTC2(0x3490f880), WTC2(0x3565b7c0), WTC2(0x36394640),
+ WTC2(0x370b8f00), WTC2(0x37dc7c00), WTC2(0x38abf7c0), WTC2(0x3979ecc0),
+ WTC2(0x3a464500), WTC2(0x3b10eb00), WTC2(0x3bd9c940), WTC2(0x3ca0c9c0),
+ WTC2(0x3d65d740), WTC2(0x3e28dc00), WTC2(0x3ee9c240), WTC2(0x3fa87480),
+ WTC2(0x4064dcff), WTC2(0x411ee67f), WTC2(0x41d67a7f), WTC2(0x428b847f),
+ WTC2(0x433ded7f), WTC2(0x43eda0ff), WTC2(0x449a887f), WTC2(0x45448f7f),
+ WTC2(0x45eb9eff), WTC2(0x468fa1ff), WTC2(0x473082ff), WTC2(0x47ce2c7f),
+ WTC2(0x4868887f), WTC2(0x48ff80ff), WTC2(0x499300ff), WTC2(0x4a22f2ff),
+ WTC2(0x4aaf407f), WTC2(0x4b37d47f), WTC2(0x4bbc997f), WTC2(0x4c3d78ff),
+ WTC2(0x4cba5e7f), WTC2(0x4d33337f), WTC2(0x4da7e27f), WTC2(0x4e18567f),
+ WTC2(0x4e8478ff), WTC2(0x4eec347f), WTC2(0x4f4f737f), WTC2(0x4fae20ff),
+ WTC2(0x500825ff), WTC2(0x505d6dff), WTC2(0x50ade37f), WTC2(0x50f96f7f),
+ WTC2(0x513ffdff), WTC2(0x518177ff), WTC2(0x51bdc87f), WTC2(0x51f4d9ff),
+ WTC2(0x5226967f), WTC2(0x5252e87f), WTC2(0x5279b9ff), WTC2(0x529af5ff),
+ WTC2(0x52b6867f), WTC2(0x52cc55ff), WTC2(0x52dc4eff), WTC2(0x52e65aff),
+ WTC2(0x52ea657f), WTC2(0x52e857ff), WTC2(0x52e01d7f), WTC2(0x52d19fff),
+ WTC2(0x52bcc9ff), WTC2(0x52a1857f), WTC2(0x527fbd7f), WTC2(0x52575b7f),
+ WTC2(0x52284a7f), WTC2(0x51f274ff), WTC2(0x51b5c47f), WTC2(0x5172247f),
+ WTC2(0x51277dff), WTC2(0x50d5bc7f), WTC2(0x507cc9ff), WTC2(0x501c90ff),
+ WTC2(0x4fb4fb7f), WTC2(0x4f45f3ff), WTC2(0x4ecf64ff), WTC2(0x4e5138ff),
+ WTC2(0x4dcb597f), WTC2(0x4d3db1ff), WTC2(0x4ca82bff), WTC2(0x4c0ab27f),
+ WTC2(0x4b652f7f), WTC2(0x4ab78d7f), WTC2(0x4a01b67f), WTC2(0x4943957f),
+ WTC2(0x487d12ff), WTC2(0x47ae1f7f), WTC2(0x46d68f7f), WTC2(0x45f7187f),
+ WTC2(0x4513597f), WTC2(0x4430467f), WTC2(0x4352d2ff), WTC2(0x427e6bff),
+ WTC2(0x41b390ff), WTC2(0x40f2077f), WTC2(0x4039a87f), WTC2(0x3f8a3100),
+ WTC2(0x3ee33e00), WTC2(0x3e446ac0), WTC2(0x3dad5180), WTC2(0x3d1d7fc0),
+ WTC2(0x3c947b00), WTC2(0x3c11c7c0), WTC2(0x3b94ebc0), WTC2(0x3b1d6dc0),
+ WTC2(0x3aaad480), WTC2(0x3a3ca740), WTC2(0x39d26c40), WTC2(0x396ba8c0),
+ WTC2(0x3907e080), WTC2(0x38a69800), WTC2(0x38473d80), WTC2(0x37e923c0),
+ WTC2(0x378b9b80), WTC2(0x372e0380), WTC2(0x36d03a80), WTC2(0x36727f00),
+ WTC2(0x36150e40), WTC2(0x35b81540), WTC2(0x355b8000), WTC2(0x34ff1dc0),
+ WTC2(0x34a2bfc0), WTC2(0x34463e80), WTC2(0x33e982c0), WTC2(0x338c7880),
+ WTC2(0x332f0bc0), WTC2(0x32d11800), WTC2(0x327265c0), WTC2(0x3212bbc0),
+ WTC2(0x31b1e740), WTC2(0x314fef00), WTC2(0x30ed0540), WTC2(0x30895c80),
+ WTC2(0x30251880), WTC2(0x2fc02880), WTC2(0x2f5a6480), WTC2(0x2ef3a480),
+ WTC2(0x2e8bd640), WTC2(0x2e231100), WTC2(0x2db97680), WTC2(0x2d4f2700),
+ WTC2(0x2ce431c0), WTC2(0x2c789080), WTC2(0x2c0c3bc0), WTC2(0x2b9f2bc0),
+ WTC2(0x2b315940), WTC2(0x2ac2bc00), WTC2(0x2a534cc0), WTC2(0x29e303c0)};
+
+const FIXP_WTB ELDAnalysis256[768] = {
+ WTC(0xfababde8), WTC(0xfa8e1e6a), WTC(0xfa6012a9), WTC(0xfa30c8dd),
+ WTC(0xfa006f4b), WTC(0xf9cf32c4), WTC(0xf99d1cc8), WTC(0xf96a148d),
+ WTC(0xf936184d), WTC(0xf9013d5b), WTC(0xf8cb7b67), WTC(0xf894ace0),
+ WTC(0xf85cd28e), WTC(0xf82413f8), WTC(0xf7ea90af), WTC(0xf7b05ee6),
+ WTC(0xf7759b0b), WTC(0xf73a671f), WTC(0xf6febea3), WTC(0xf6c27a0e),
+ WTC(0xf685ca33), WTC(0xf6493907), WTC(0xf60d437b), WTC(0xf5d2551f),
+ WTC(0xf598d273), WTC(0xf561199e), WTC(0xf52b8c6f), WTC(0xf4f8907d),
+ WTC(0xf4c87fdf), WTC(0xf49ba806), WTC(0xf4724286), WTC(0xf44c6127),
+ WTC(0xf4282435), WTC(0xf401ceae), WTC(0xf3d775a1), WTC(0xf3a91477),
+ WTC(0xf376c33f), WTC(0xf340a328), WTC(0xf306d4d6), WTC(0xf2c9775c),
+ WTC(0xf288a3ed), WTC(0xf2446e2a), WTC(0xf1fcfa45), WTC(0xf1b27b2d),
+ WTC(0xf164f3f4), WTC(0xf114365c), WTC(0xf0c00532), WTC(0xf06817a9),
+ WTC(0xf00c4ea4), WTC(0xefacbc7f), WTC(0xef4a205f), WTC(0xeee5dc33),
+ WTC(0xee808a0d), WTC(0xee19eeb2), WTC(0xedb12f6e), WTC(0xed44e8eb),
+ WTC(0xecd50a13), WTC(0xec62d8dd), WTC(0xebef68b2), WTC(0xeb7b805c),
+ WTC(0xeb069af4), WTC(0xea8eef1c), WTC(0xea131c86), WTC(0xe99234c6),
+ WTC(0xe90cd9c2), WTC(0xe884f65b), WTC(0xe7fcbd6d), WTC(0xe7767300),
+ WTC(0xe6f289d0), WTC(0xe66f958a), WTC(0xe5eae99f), WTC(0xe560c403),
+ WTC(0xe4cfaaa1), WTC(0xe43887dc), WTC(0xe39dedc4), WTC(0xe303f190),
+ WTC(0xe26d7f5d), WTC(0xe1dc34ff), WTC(0xe14f9ced), WTC(0xe0c53cd0),
+ WTC(0xe03ab085), WTC(0xdfadc948), WTC(0xdf1d640c), WTC(0xde896bb6),
+ WTC(0xddf256ad), WTC(0xdd591e3d), WTC(0xdcbf0aec), WTC(0xdc25ab0a),
+ WTC(0xdb8e334c), WTC(0xdaf97794), WTC(0xda67bed9), WTC(0xd9d8c524),
+ WTC(0xd94bfa62), WTC(0xd8c089b5), WTC(0xd835c151), WTC(0xd7ab1704),
+ WTC(0xd7200906), WTC(0xd69420dc), WTC(0xd6073c0d), WTC(0xd5799615),
+ WTC(0xd4ec7c87), WTC(0xd46241c9), WTC(0xd3dc5bde), WTC(0xd35b4a79),
+ WTC(0xd2de1032), WTC(0xd26246f5), WTC(0xd1e68ed2), WTC(0xd16aa0a4),
+ WTC(0xd0eea5d2), WTC(0xd073302b), WTC(0xcff93749), WTC(0xcf820f45),
+ WTC(0xcf0ebb30), WTC(0xce9fd702), WTC(0xce34596c), WTC(0xcdc9a803),
+ WTC(0xcd5ec5d6), WTC(0xccf468ec), WTC(0xcc8bb41e), WTC(0xcc2619cc),
+ WTC(0xcbc3e090), WTC(0xcb6422f5), WTC(0xcb064d2f), WTC(0xcaaa2a6d),
+ WTC(0xca4fbdc9), WTC(0xc9f73c43), WTC(0xc9a0dc9b), WTC(0xc94cdd02),
+ WTC(0xc8f578a4), WTC(0xc8a24d15), WTC(0xc84dc71f), WTC(0xc7f83516),
+ WTC(0xc7a1e4b9), WTC(0xc74b22b1), WTC(0xc6f41284), WTC(0xc69cabc1),
+ WTC(0xc644986d), WTC(0xc5eb4167), WTC(0xc5910312), WTC(0xc5372c7f),
+ WTC(0xc4deba2e), WTC(0xc4883eca), WTC(0xc43310f0), WTC(0xc3dd5c5a),
+ WTC(0xc3868802), WTC(0xc32f431d), WTC(0xc2d86c9e), WTC(0xc28300a6),
+ WTC(0xc22fae33), WTC(0xc1ded3f7), WTC(0xc1908d7d), WTC(0xc144b0ed),
+ WTC(0xc0fa7cee), WTC(0xc0b0a3b5), WTC(0xc066b8d3), WTC(0xc01d3b32),
+ WTC(0xbfd5161c), WTC(0xbf8f92af), WTC(0xbf4d5cea), WTC(0xbf0e7d5e),
+ WTC(0xbed2ce3a), WTC(0xbe9a0062), WTC(0xbe63cec2), WTC(0xbe2ffd2f),
+ WTC(0xbdfe4565), WTC(0xbdce5568), WTC(0xbda003df), WTC(0xbd735018),
+ WTC(0xbd485b2c), WTC(0xbd1f69bd), WTC(0xbcf8db7c), WTC(0xbcd52b0a),
+ WTC(0xbcb4ae4a), WTC(0xbc979382), WTC(0xbc7dcbab), WTC(0xbc6709dc),
+ WTC(0xbc52c1b1), WTC(0xbc402f2b), WTC(0xbc2ec37b), WTC(0xbc1e2cb3),
+ WTC(0xbc0e5d5f), WTC(0xbbff8f23), WTC(0xbbf238d2), WTC(0xbbe707d4),
+ WTC(0xbbde3c63), WTC(0xbbd7a658), WTC(0xbbd2c7f0), WTC(0xbbcee18b),
+ WTC(0xbbcbdebb), WTC(0xbbca5ab1), WTC(0xbbcb5622), WTC(0xbbd032e4),
+ WTC(0xbbd91d4d), WTC(0xbbe53757), WTC(0xbbf32f54), WTC(0xbc016781),
+ WTC(0xbc0f433a), WTC(0xbc1d2aa4), WTC(0xbc2b4912), WTC(0xbc3985df),
+ WTC(0xbc47d6b9), WTC(0xbc564099), WTC(0xbc64c78a), WTC(0xbc736d96),
+ WTC(0xbc823210), WTC(0xbc911484), WTC(0xbca015b8), WTC(0xbcaf37eb),
+ WTC(0xbcbe7bc3), WTC(0xbccdde4d), WTC(0xbcdd6037), WTC(0xbced049a),
+ WTC(0xbcfccc81), WTC(0xbd0cb482), WTC(0xbd1cbcaa), WTC(0xbd2ce7ea),
+ WTC(0xbd3d363b), WTC(0xbd4da445), WTC(0xbd5e312d), WTC(0xbd6edfd1),
+ WTC(0xbd7fae14), WTC(0xbd90991b), WTC(0xbda19fcf), WTC(0xbdb2c464),
+ WTC(0xbdc4053b), WTC(0xbdd55f4b), WTC(0xbde6d0a0), WTC(0xbdf85c51),
+ WTC(0xbe09ffa3), WTC(0xbe1bb724), WTC(0xbe2d8160), WTC(0xbe3f5f98),
+ WTC(0xbe515144), WTC(0xbe6351a9), WTC(0xbe755ebd), WTC(0xbe877b8e),
+ WTC(0xbe99a63d), WTC(0xbeabda45), WTC(0xbebe16b0), WTC(0xbed05d1c),
+ WTC(0xbee2ada9), WTC(0xbef502e2), WTC(0xbf075c40), WTC(0xbf19bc0b),
+ WTC(0xbf2c217f), WTC(0xbf3e887a), WTC(0xbf50f09d), WTC(0xbf635c77),
+ WTC(0xbf75cac0), WTC(0xbf883905), WTC(0xbf9aa62b), WTC(0xbfad14f1),
+ WTC(0xbfbf85c7), WTC(0xbfd1f592), WTC(0xbfe461fc), WTC(0xbff6c86a),
+ WTC(0x80126c8d), WTC(0x80372448), WTC(0x805bd2fd), WTC(0x80807315),
+ WTC(0x80a4fffa), WTC(0x80c9748d), WTC(0x80edd08b), WTC(0x81121a23),
+ WTC(0x81364fde), WTC(0x815a6b16), WTC(0x817e6b36), WTC(0x81a25433),
+ WTC(0x81c625c8), WTC(0x81e9d801), WTC(0x820d6a5c), WTC(0x8230e060),
+ WTC(0x825438c0), WTC(0x82776ac7), WTC(0x829a7555), WTC(0x82bd5ca3),
+ WTC(0x82e01e80), WTC(0x8302b200), WTC(0x83251590), WTC(0x83474d79),
+ WTC(0x8369566f), WTC(0x838b2957), WTC(0x83acc2d9), WTC(0x83ce27c1),
+ WTC(0x83ef54b9), WTC(0x841042d1), WTC(0x8430ef15), WTC(0x84515e84),
+ WTC(0x84718e32), WTC(0x84917804), WTC(0x84b11a25), WTC(0x84d0788d),
+ WTC(0x84ef9322), WTC(0x850e61ec), WTC(0x852ce400), WTC(0x854b1e0a),
+ WTC(0x85690f2c), WTC(0x8586b207), WTC(0x85a4057b), WTC(0x85c1107d),
+ WTC(0x85ddd335), WTC(0x85fa485e), WTC(0x86167172), WTC(0x8632549d),
+ WTC(0x864df388), WTC(0x8669497e), WTC(0x86845757), WTC(0x869f2218),
+ WTC(0x86b9ab5a), WTC(0x86d3f1bf), WTC(0x86edf68f), WTC(0x8707baf1),
+ WTC(0x872147e0), WTC(0x873aa6fc), WTC(0x8753c571), WTC(0x876c76e6),
+ WTC(0x87850ab7), WTC(0x879e373b), WTC(0x87b6ea37), WTC(0x87cc4188),
+ WTC(0x880d4300), WTC(0x8855e9ff), WTC(0x88acfca0), WTC(0x890d0f94),
+ WTC(0x8971e7d5), WTC(0x89d8a0c1), WTC(0x8a3fc425), WTC(0x8aa74105),
+ WTC(0x8b0f5b93), WTC(0x8b78a107), WTC(0x8be38bb3), WTC(0x8c508092),
+ WTC(0x8cbfe384), WTC(0x8d3214f1), WTC(0x8da75d21), WTC(0x8e1fe96c),
+ WTC(0x8e9be76a), WTC(0x8f1b806c), WTC(0x8f9ed314), WTC(0x9025f26a),
+ WTC(0x90b0ecea), WTC(0x913fd0eb), WTC(0x91d2a684), WTC(0x92696dea),
+ WTC(0x93042868), WTC(0x93a2d456), WTC(0x94456d20), WTC(0x94ebe9e5),
+ WTC(0x95964178), WTC(0x96446a05), WTC(0x96f65958), WTC(0x97ac059a),
+ WTC(0x98656089), WTC(0x99225a80), WTC(0x99e2e2e8), WTC(0x9aa6e666),
+ WTC(0x9b6e54b8), WTC(0x9c391d99), WTC(0x9d07338a), WTC(0x9dd8888d),
+ WTC(0x9ead0b5c), WTC(0x9f84a871), WTC(0xa05f4fb3), WTC(0xa13cf913),
+ WTC(0xa21d9891), WTC(0xa3011e27), WTC(0xa3e77eb4), WTC(0xa4d0b190),
+ WTC(0xa5bcb0d7), WTC(0xa6ab750c), WTC(0xa79cf884), WTC(0xa89135cb),
+ WTC(0xa9882a44), WTC(0xaa81d578), WTC(0xab7e39a6), WTC(0xac7d5a36),
+ WTC(0xad7f3ba5), WTC(0xae83dfed), WTC(0xaf8b4e16), WTC(0xb095911c),
+ WTC(0xb1a2afd1), WTC(0xb2b2ac9f), WTC(0xb3c58807), WTC(0xb4db4d5e),
+ WTC(0x4a268ead), WTC(0x490b5ba7), WTC(0x47ed8d30), WTC(0x46cd10c5),
+ WTC(0x45a9dcc1), WTC(0x4483f267), WTC(0x435b5aeb), WTC(0x42301d12),
+ WTC(0x41023a15), WTC(0x3fd19bf1), WTC(0x3e9e31e1), WTC(0x3d682986),
+ WTC(0x3c2fc001), WTC(0x3af52d8f), WTC(0x39b88b7d), WTC(0x38798642),
+ WTC(0x3737e6d3), WTC(0x35f3e98a), WTC(0x34add45c), WTC(0x33660083),
+ WTC(0x321ccf3a), WTC(0x30d2963e), WTC(0x2f87a28f), WTC(0x2e3c22cd),
+ WTC(0x2cf010e5), WTC(0x2ba2ffe5), WTC(0x2a54ba93), WTC(0x290596f5),
+ WTC(0x27b62806), WTC(0x266762b8), WTC(0x251a11b1), WTC(0x23ce94f9),
+ WTC(0x22852ddb), WTC(0x213df340), WTC(0x1ff90185), WTC(0x1eb67d94),
+ WTC(0x1d767485), WTC(0x1c38d477), WTC(0x1afda747), WTC(0x19c5248b),
+ WTC(0x188f8259), WTC(0x175d0d40), WTC(0x162e5320), WTC(0x150436cd),
+ WTC(0x13df8d3f), WTC(0x12c102f1), WTC(0x11a8dd65), WTC(0x1096d490),
+ WTC(0x0f8a1755), WTC(0x0e811dcd), WTC(0x0d7acb9a), WTC(0x0c767d00),
+ WTC(0x0b7334d9), WTC(0x0a6fef31), WTC(0x096c5a87), WTC(0x08691adb),
+ WTC(0x0765e395), WTC(0x06610309), WTC(0x0558a0d2), WTC(0x044a946c),
+ WTC(0x033acb52), WTC(0x0234706f), WTC(0x014939dc), WTC(0x00928577),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xffe73593), WTC(0xffb63fcf), WTC(0xff853c1f), WTC(0xff5454d7),
+ WTC(0xff23b44b), WTC(0xfef38417), WTC(0xfec3dc9a), WTC(0xfe94c511),
+ WTC(0xfe664753), WTC(0xfe387086), WTC(0xfe0b4e63), WTC(0xfddef15c),
+ WTC(0xfdb3a3f6), WTC(0xfd89e611), WTC(0xfd61c750), WTC(0xfd3ae585),
+ WTC(0xfd14ec09), WTC(0xfcef9b06), WTC(0xfccaf509), WTC(0xfca74180),
+ WTC(0xfc8518a3), WTC(0xfc655c7a), WTC(0xfc488545), WTC(0xfc2e9998),
+ WTC(0xfc1726bb), WTC(0xfc01463f), WTC(0xfbec2c64), WTC(0xfbd735ce),
+ WTC(0xfbc29e8e), WTC(0xfbaf8042), WTC(0xfb9eeba0), WTC(0xfb91dc05),
+ WTC(0xfb88f420), WTC(0xfb8479eb), WTC(0xfb84398b), WTC(0xfb87884b),
+ WTC(0xfb8da8bf), WTC(0xfb95d020), WTC(0xfb9f3e49), WTC(0xfba9448a),
+ WTC(0xfbb3cf10), WTC(0xfbbf67e7), WTC(0xfbccf65d), WTC(0xfbddba58),
+ WTC(0xfbf31f46), WTC(0xfc0eb236), WTC(0xfc3164f0), WTC(0xfc5b8269),
+ WTC(0xfc8c5bcd), WTC(0xfcc248ee), WTC(0xfcfb056c), WTC(0xfd33cc26),
+ WTC(0xfd6b84ee), WTC(0xfda2d9e7), WTC(0xfddc03fb), WTC(0xfe1aaf57),
+ WTC(0xfe61a0af), WTC(0xfeb28df7), WTC(0xff0cd343), WTC(0xff6d8388),
+ WTC(0xffd24331), WTC(0x00396fe3), WTC(0x00a2fb3e), WTC(0x01107050),
+ WTC(0x01831900), WTC(0x01fc2377), WTC(0x027bd1fc), WTC(0x03019a2d),
+ WTC(0x038d0a88), WTC(0x041dd88f), WTC(0x04b43495), WTC(0x0550c1ef),
+ WTC(0x05f38bd6), WTC(0x069c0523), WTC(0x074a114e), WTC(0x07fe0ceb),
+ WTC(0x08b88e33), WTC(0x097a5965), WTC(0x0a438318), WTC(0x0b137046),
+ WTC(0x0be9b5ab), WTC(0x0cc61fa9), WTC(0x0da897b2), WTC(0x0e9123b3),
+ WTC(0x0f7ff200), WTC(0x10755696), WTC(0x11717f94), WTC(0x127474a0),
+ WTC(0x137e489d), WTC(0x148f1b02), WTC(0x15a6f15e), WTC(0x16c5b7c9),
+ WTC(0x17eb72b1), WTC(0x19183e51), WTC(0x1a4c2444), WTC(0x1b871b1c),
+ WTC(0x1cc92e92), WTC(0x1e127ffc), WTC(0x1f6319b9), WTC(0x20baef78),
+ WTC(0x221a0861), WTC(0x23807f94), WTC(0x24ee5a89), WTC(0x2663898d),
+ WTC(0x27e0101e), WTC(0x2964058d), WTC(0x2aef6bcf), WTC(0x2c8230fc),
+ WTC(0x2e1c545b), WTC(0x2fbde72b), WTC(0x3166e76f), WTC(0x33173f5d),
+ WTC(0x34cee8c3), WTC(0x368debe1), WTC(0x38543d4f), WTC(0x3a21bd94),
+ WTC(0x3bf6576f), WTC(0x3dd1ff07), WTC(0x3fb4948e), WTC(0x419de414),
+ WTC(0x438dc202), WTC(0x45840e7d), WTC(0x4780a435), WTC(0x4983609f),
+ WTC(0x4b8cc548), WTC(0x4d9df796), WTC(0x4fb81f46), WTC(0x51dc8690),
+ WTC(0x000d970d), WTC(0xfff7ea67), WTC(0xfff7fc3d), WTC(0x000d3de2),
+ WTC(0x003720ad), WTC(0x007515f1), WTC(0x00c68f04), WTC(0x012afd3b),
+ WTC(0x01a1d1ec), WTC(0x022a7e69), WTC(0x02c47408), WTC(0x036f2420),
+ WTC(0x042a0001), WTC(0x04f47905), WTC(0x05ce007e), WTC(0x06b607be),
+ WTC(0x07ac0028), WTC(0x08af5b01), WTC(0x09bf89a7), WTC(0x0adbfd6d),
+ WTC(0x0c042798), WTC(0x0d377997), WTC(0x0e7564b5), WTC(0x0fbd5a3a),
+ WTC(0x110ecb85), WTC(0x126929fb), WTC(0x13cbe6e6), WTC(0x15367376),
+ WTC(0x16a8413f), WTC(0x1820c15f), WTC(0x199f6568), WTC(0x1b239e6b),
+ WTC(0x1cacdde2), WTC(0x1e3a951a), WTC(0x1fcc356f), WTC(0x2161301f),
+ WTC(0x22f8f6b7), WTC(0x2492fa4a), WTC(0x262eac3f), WTC(0x27cb7e20),
+ WTC(0x2968e0c4), WTC(0x2b064625), WTC(0x2ca31f1a), WTC(0x2e3edd2a),
+ WTC(0x2fd8f19f), WTC(0x3170ce00), WTC(0x3305e32c), WTC(0x3497a2df),
+ WTC(0x36257e78), WTC(0x37aee70b), WTC(0x39334e05), WTC(0x3ab22498),
+ WTC(0x3c2adc2c), WTC(0x3d9ce645), WTC(0x3f07b3ef), WTC(0x406ab6ca),
+ WTC(0x41c56001), WTC(0x4317214a), WTC(0x445f6b34), WTC(0x459daf5d),
+ WTC(0x46d15f56), WTC(0x47f9ed71), WTC(0x4916d11f), WTC(0x4a275770),
+ WTC(0x4b2b2fff), WTC(0x4c219eae), WTC(0x4d0a20cb), WTC(0x4de4288e),
+ WTC(0x4eaf263d), WTC(0x4f6a8bb8), WTC(0x5015ca33), WTC(0x50b052dd),
+ WTC(0x51399757), WTC(0x51b108c6), WTC(0x5216190a), WTC(0x5268387c),
+ WTC(0x52a6d933), WTC(0x52d16c19), WTC(0x52e7628b), WTC(0x52e82ea3),
+ WTC(0x52d3407d), WTC(0x52a80a28), WTC(0x5265fd43), WTC(0x520c8a1d),
+ WTC(0x519b22c8), WTC(0x511138e0), WTC(0x506e3c82), WTC(0x4fb1a037),
+ WTC(0x4edad4e3), WTC(0x4de94c2d), WTC(0x4cdc76d8), WTC(0x4bb3c683),
+ WTC(0x4a6eacd2), WTC(0x490c9abe), WTC(0x478d04f1), WTC(0x45f00420),
+ WTC(0x4445673f), WTC(0x42ac0d2e), WTC(0x41338364), WTC(0x3fdb5b58),
+ WTC(0x3ea1c30f), WTC(0x3d842780), WTC(0x3c7fa763), WTC(0x3b911b96),
+ WTC(0x3ab560bf), WTC(0x39e95908), WTC(0x3929debb), WTC(0x3873bd4d),
+ WTC(0x37c31db2), WTC(0x3713a59c), WTC(0x3663deb2), WTC(0x35b52f23),
+ WTC(0x3507c61e), WTC(0x345a7f42), WTC(0x33ac7e0c), WTC(0x32fd366f),
+ WTC(0x324baa28), WTC(0x319674e9), WTC(0x30dd7e1a), WTC(0x3021f3e8),
+ WTC(0x2f63f903), WTC(0x2ea2a1aa), WTC(0x2dddd97b), WTC(0x2d166985),
+ WTC(0x2c4ca42f), WTC(0x2b805cca), WTC(0x2ab162aa), WTC(0x29df7b17),
+};
+
+const FIXP_WTB ELDAnalysis240[720] = {
+ WTC(0xfab9477b), WTC(0xfa899344), WTC(0xfa5845dd), WTC(0xfa259762),
+ WTC(0xf9f1c005), WTC(0xf9bcefe6), WTC(0xf9871e8b), WTC(0xf9503397),
+ WTC(0xf9183f47), WTC(0xf8df4eac), WTC(0xf8a53ba7), WTC(0xf869f0be),
+ WTC(0xf82d9759), WTC(0xf7f0593e), WTC(0xf7b2520a), WTC(0xf773a37c),
+ WTC(0xf73475ce), WTC(0xf6f4bedd), WTC(0xf6b455a8), WTC(0xf6739525),
+ WTC(0xf6332510), WTC(0xf5f3938b), WTC(0xf5b56073), WTC(0xf57900bd),
+ WTC(0xf53ee82d), WTC(0xf5079149), WTC(0xf4d36ffc), WTC(0xf4a2e526),
+ WTC(0xf4763d91), WTC(0xf44d9872), WTC(0xf426eaed), WTC(0xf3fdc161),
+ WTC(0xf3d001ff), WTC(0xf39dafcc), WTC(0xf366eb43), WTC(0xf32bdcdc),
+ WTC(0xf2ecab80), WTC(0xf2a97b34), WTC(0xf26265ae), WTC(0xf2178a6f),
+ WTC(0xf1c92458), WTC(0xf17752b9), WTC(0xf121e6ac), WTC(0xf0c89a63),
+ WTC(0xf06b15ef), WTC(0xf0092e86), WTC(0xefa2fd42), WTC(0xef397ebc),
+ WTC(0xeece51c6), WTC(0xee61e8b6), WTC(0xedf3d92e), WTC(0xed82c330),
+ WTC(0xed0d58bb), WTC(0xec94891b), WTC(0xec19d435), WTC(0xeb9e4e4e),
+ WTC(0xeb221000), WTC(0xeaa32422), WTC(0xea1fb440), WTC(0xe99695d2),
+ WTC(0xe90859ab), WTC(0xe8775114), WTC(0xe7e62b37), WTC(0xe7578147),
+ WTC(0xe6cb3ac1), WTC(0xe63f5696), WTC(0xe5afe916), WTC(0xe519090f),
+ WTC(0xe47aab0d), WTC(0xe3d6c2d0), WTC(0xe331dae7), WTC(0xe29031e1),
+ WTC(0xe1f40926), WTC(0xe15d87d2), WTC(0xe0c9d727), WTC(0xe0360ad5),
+ WTC(0xdf9f81af), WTC(0xdf04f9f9), WTC(0xde66697f), WTC(0xddc48ca1),
+ WTC(0xdd20a42a), WTC(0xdc7c6853), WTC(0xdbd9a476), WTC(0xdb398a8c),
+ WTC(0xda9cd7c2), WTC(0xda0365cf), WTC(0xd96cad85), WTC(0xd8d7b7a3),
+ WTC(0xd8439e8c), WTC(0xd7afb73d), WTC(0xd71b6347), WTC(0xd686149a),
+ WTC(0xd5efab2c), WTC(0xd558877e), WTC(0xd4c29dbc), WTC(0xd430a0aa),
+ WTC(0xd3a3d490), WTC(0xd31c588f), WTC(0xd297e075), WTC(0xd213ef33),
+ WTC(0xd18fd566), WTC(0xd10b8d3f), WTC(0xd087b250), WTC(0xd0054ef2),
+ WTC(0xcf85f94a), WTC(0xcf0af5f7), WTC(0xce94faf5), WTC(0xce229409),
+ WTC(0xcdb0b5f8), WTC(0xcd3ec554), WTC(0xcccdbf58), WTC(0xcc5f39d5),
+ WTC(0xcbf49ef5), WTC(0xcb8d5f73), WTC(0xcb28801c), WTC(0xcac5a265),
+ WTC(0xca64ad2e), WTC(0xca05d7fd), WTC(0xc9a96602), WTC(0xc94f9f79),
+ WTC(0xc8f2b954), WTC(0xc899e795), WTC(0xc83f94aa), WTC(0xc7e41f63),
+ WTC(0xc787e69f), WTC(0xc72b3fd0), WTC(0xc6ce3f0f), WTC(0xc670c175),
+ WTC(0xc61224cf), WTC(0xc5b21fec), WTC(0xc55202a4), WTC(0xc4f3353a),
+ WTC(0xc4968597), WTC(0xc43b93f2), WTC(0xc3e03d26), WTC(0xc383a011),
+ WTC(0xc3268aed), WTC(0xc2ca1039), WTC(0xc26f5bcc), WTC(0xc21726c9),
+ WTC(0xc1c1d5b2), WTC(0xc16f66ba), WTC(0xc11f76d9), WTC(0xc0d0a9f6),
+ WTC(0xc081cddb), WTC(0xc0333180), WTC(0xbfe5bb54), WTC(0xbf9aee90),
+ WTC(0xbf53d587), WTC(0xbf108855), WTC(0xbed0de05), WTC(0xbe9477d7),
+ WTC(0xbe5b030f), WTC(0xbe243642), WTC(0xbdefb72f), WTC(0xbdbd29df),
+ WTC(0xbd8c71ab), WTC(0xbd5d99cb), WTC(0xbd30e375), WTC(0xbd06afcc),
+ WTC(0xbcdf8c7f), WTC(0xbcbbf704), WTC(0xbc9c307e), WTC(0xbc803b86),
+ WTC(0xbc67c0c7), WTC(0xbc521d3d), WTC(0xbc3e6561), WTC(0xbc2bf2cb),
+ WTC(0xbc1a6872), WTC(0xbc09ce15), WTC(0xbbfa764f), WTC(0xbbed1356),
+ WTC(0xbbe257fa), WTC(0xbbda4099), WTC(0xbbd46a31), WTC(0xbbcffa76),
+ WTC(0xbbcc766d), WTC(0xbbca782f), WTC(0xbbcb16c7), WTC(0xbbcff77c),
+ WTC(0xbbd978e6), WTC(0xbbe68e5f), WTC(0xbbf593ed), WTC(0xbc04a834),
+ WTC(0xbc136941), WTC(0xbc2252c3), WTC(0xbc31723d), WTC(0xbc40ab92),
+ WTC(0xbc4ffe2d), WTC(0xbc5f7072), WTC(0xbc6f0520), WTC(0xbc7ebd23),
+ WTC(0xbc8e9746), WTC(0xbc9e942f), WTC(0xbcaeb633), WTC(0xbcbefe8b),
+ WTC(0xbccf69bb), WTC(0xbcdff92e), WTC(0xbcf0b04f), WTC(0xbd018ebd),
+ WTC(0xbd129192), WTC(0xbd23b9b8), WTC(0xbd350afb), WTC(0xbd46820e),
+ WTC(0xbd581bfc), WTC(0xbd69db11), WTC(0xbd7bbf57), WTC(0xbd8dc584),
+ WTC(0xbd9feaad), WTC(0xbdb231a4), WTC(0xbdc498ea), WTC(0xbdd71cd1),
+ WTC(0xbde9bb57), WTC(0xbdfc77d9), WTC(0xbe0f4e93), WTC(0xbe223ae5),
+ WTC(0xbe353cf5), WTC(0xbe485689), WTC(0xbe5b8329), WTC(0xbe6ebe88),
+ WTC(0xbe820afd), WTC(0xbe956811), WTC(0xbea8d109), WTC(0xbebc4352),
+ WTC(0xbecfc0fb), WTC(0xbee34a07), WTC(0xbef6d884), WTC(0xbf0a6bb1),
+ WTC(0xbf1e0685), WTC(0xbf31a685), WTC(0xbf45483c), WTC(0xbf58eb6b),
+ WTC(0xbf6c9376), WTC(0xbf803c90), WTC(0xbf93e4b9), WTC(0xbfa78d05),
+ WTC(0xbfbb3830), WTC(0xbfcee339), WTC(0xbfe28aa9), WTC(0xbff62b89),
+ WTC(0x8013a5f4), WTC(0x803acfd6), WTC(0x8061eec7), WTC(0x8088fc73),
+ WTC(0x80aff270), WTC(0x80d6cbe5), WTC(0x80fd8c2a), WTC(0x812437a8),
+ WTC(0x814ac94f), WTC(0x81713adc), WTC(0x81979098), WTC(0x81bdccb7),
+ WTC(0x81e3e738), WTC(0x8209dd04), WTC(0x822fb23a), WTC(0x825565bb),
+ WTC(0x827aed94), WTC(0x82a04909), WTC(0x82c57c85), WTC(0x82ea831c),
+ WTC(0x830f539d), WTC(0x8333eeba), WTC(0x8358585a), WTC(0x837c882e),
+ WTC(0x83a07742), WTC(0x83c428a5), WTC(0x83e79c4c), WTC(0x840aca65),
+ WTC(0x842dad81), WTC(0x84504ac0), WTC(0x84729fb1), WTC(0x8494a4f1),
+ WTC(0x84b65932), WTC(0x84d7c0f8), WTC(0x84f8d936), WTC(0x85199a59),
+ WTC(0x853a05a1), WTC(0x855a2023), WTC(0x8579e46e), WTC(0x85994d55),
+ WTC(0x85b86190), WTC(0x85d723e6), WTC(0x85f58fa9), WTC(0x8613a3ce),
+ WTC(0x863167b5), WTC(0x864eddfe), WTC(0x866c0138), WTC(0x8688d2e4),
+ WTC(0x86a55901), WTC(0x86c19497), WTC(0x86dd8390), WTC(0x86f9288f),
+ WTC(0x871487e0), WTC(0x872fadd0), WTC(0x874a9a1e), WTC(0x876519d0),
+ WTC(0x877f471e), WTC(0x8799fb36), WTC(0x87b48b97), WTC(0x87cba021),
+ WTC(0x880f67ae), WTC(0x885e0f91), WTC(0x88bc84cd), WTC(0x89244640),
+ WTC(0x8990a45d), WTC(0x89fe6766), WTC(0x8a6c9065), WTC(0x8adb31e6),
+ WTC(0x8b4ad5b3), WTC(0x8bbc2068), WTC(0x8c2f93ff), WTC(0x8ca5a922),
+ WTC(0x8d1ed72d), WTC(0x8d9b7ddb), WTC(0x8e1bd6cc), WTC(0x8ea01924),
+ WTC(0x8f287716), WTC(0x8fb5143e), WTC(0x9046074e), WTC(0x90db612b),
+ WTC(0x91753263), WTC(0x92138094), WTC(0x92b64cf3), WTC(0x935d96c9),
+ WTC(0x94095a56), WTC(0x94b98fd4), WTC(0x956e2a87), WTC(0x96271ff6),
+ WTC(0x96e46309), WTC(0x97a5e80d), WTC(0x986b9e55), WTC(0x993572af),
+ WTC(0x9a0350ce), WTC(0x9ad52154), WTC(0x9baad10f), WTC(0x9c844cdd),
+ WTC(0x9d618437), WTC(0x9e4265b2), WTC(0x9f26d9ad), WTC(0xa00ec9b0),
+ WTC(0xa0fa2916), WTC(0xa1e8ec20), WTC(0xa2daffa4), WTC(0xa3d05468),
+ WTC(0xa4c8e007), WTC(0xa5c49ae4), WTC(0xa6c37c24), WTC(0xa7c57d03),
+ WTC(0xa8ca9750), WTC(0xa9d2c7f2), WTC(0xaade0f6f), WTC(0xabec7177),
+ WTC(0xacfdf2b1), WTC(0xae129740), WTC(0xaf2a6321), WTC(0xb04563a6),
+ WTC(0xb163a2e6), WTC(0xb28524c4), WTC(0xb3a9eaf7), WTC(0xb4d1ff1b),
+ WTC(0x4a1d2880), WTC(0x48eee56e), WTC(0x47bda882), WTC(0x46895c79),
+ WTC(0x4551f8a1), WTC(0x4417817b), WTC(0x42da023d), WTC(0x419980ca),
+ WTC(0x4055f463), WTC(0x3f0f3b51), WTC(0x3dc56e18), WTC(0x3c78d943),
+ WTC(0x3b29bf3d), WTC(0x39d84ea0), WTC(0x3884337d), WTC(0x372d2371),
+ WTC(0x35d364ea), WTC(0x34774cef), WTC(0x33194d3a), WTC(0x31b9d586),
+ WTC(0x30594fcf), WTC(0x2ef80b63), WTC(0x2d9630d5), WTC(0x2c337c00),
+ WTC(0x2acf6a9e), WTC(0x296a3205), WTC(0x28046825), WTC(0x269f1752),
+ WTC(0x253b5314), WTC(0x23d9993f), WTC(0x227a3c77), WTC(0x211d59a0),
+ WTC(0x1fc314fd), WTC(0x1e6b9834), WTC(0x1d16eb58), WTC(0x1bc4f82e),
+ WTC(0x1a75e481), WTC(0x1929f389), WTC(0x17e16ee3), WTC(0x169cd758),
+ WTC(0x155d1ae5), WTC(0x14235182), WTC(0x12f051de), WTC(0x11c4993b),
+ WTC(0x109fdf4c), WTC(0x0f81351c), WTC(0x0e66c5e6), WTC(0x0d4f4b16),
+ WTC(0x0c39f013), WTC(0x0b25765d), WTC(0x0a10c51e), WTC(0x08fbee35),
+ WTC(0x07e7986f), WTC(0x06d25fe7), WTC(0x05ba1b52), WTC(0x049c33b7),
+ WTC(0x0379ceb9), WTC(0x025ee7c7), WTC(0x015edc1c), WTC(0x00978deb),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xffe59474), WTC(0xffb158f8), WTC(0xff7d1275), WTC(0xff48f44c),
+ WTC(0xff1531e3), WTC(0xfee1faa9), WTC(0xfeaf626e), WTC(0xfe7d7227),
+ WTC(0xfe4c383f), WTC(0xfe1bc4ff), WTC(0xfdec297f), WTC(0xfdbd9f6c),
+ WTC(0xfd90bbf0), WTC(0xfd65ba73), WTC(0xfd3c2d32), WTC(0xfd13ab35),
+ WTC(0xfcebe811), WTC(0xfcc4eeae), WTC(0xfc9f1d64), WTC(0xfc7b48b0),
+ WTC(0xfc5a7282), WTC(0xfc3cef9b), WTC(0xfc229f4c), WTC(0xfc0a9e29),
+ WTC(0xfbf3dccb), WTC(0xfbdd80c3), WTC(0xfbc7556c), WTC(0xfbb289cf),
+ WTC(0xfba06f99), WTC(0xfb923aca), WTC(0xfb88bb57), WTC(0xfb84457f),
+ WTC(0xfb848c2e), WTC(0xfb88bd28), WTC(0xfb8feda1), WTC(0xfb9928eb),
+ WTC(0xfba38b9e), WTC(0xfbae711c), WTC(0xfbba3538), WTC(0xfbc7af9d),
+ WTC(0xfbd8485e), WTC(0xfbeda238), WTC(0xfc099de4), WTC(0xfc2d981f),
+ WTC(0xfc59fd0d), WTC(0xfc8e1583), WTC(0xfcc7e0d7), WTC(0xfd048d03),
+ WTC(0xfd40dfaf), WTC(0xfd7c1d35), WTC(0xfdb767cc), WTC(0xfdf64a9f),
+ WTC(0xfe3d0242), WTC(0xfe8e3316), WTC(0xfeead2b9), WTC(0xff4fff8c),
+ WTC(0xffba7b11), WTC(0x00281cae), WTC(0x009847d1), WTC(0x010cb653),
+ WTC(0x01870639), WTC(0x02089db5), WTC(0x0291b571), WTC(0x0321a4c1),
+ WTC(0x03b7eda0), WTC(0x04544c7f), WTC(0x04f74134), WTC(0x05a16810),
+ WTC(0x06525829), WTC(0x070994d4), WTC(0x07c767ba), WTC(0x088c69b8),
+ WTC(0x09598634), WTC(0x0a2f14ca), WTC(0x0b0c677b), WTC(0x0bf0f576),
+ WTC(0x0cdc7f73), WTC(0x0dceed54), WTC(0x0ec84a00), WTC(0x0fc8db86),
+ WTC(0x10d10278), WTC(0x11e0e05e), WTC(0x12f880cc), WTC(0x1418049b),
+ WTC(0x153f86b3), WTC(0x166ef5a3), WTC(0x17a64878), WTC(0x18e59dde),
+ WTC(0x1a2d088b), WTC(0x1b7c7e41), WTC(0x1cd40ab7), WTC(0x1e33d542),
+ WTC(0x1f9be7a5), WTC(0x210c344f), WTC(0x2284cb85), WTC(0x2405ca48),
+ WTC(0x258f2b7f), WTC(0x2720e063), WTC(0x28bafd49), WTC(0x2a5d950c),
+ WTC(0x2c0896e4), WTC(0x2dbbf7d4), WTC(0x2f77ca28), WTC(0x313c1273),
+ WTC(0x3308b7e4), WTC(0x34ddb0ec), WTC(0x36bb06b7), WTC(0x38a0a935),
+ WTC(0x3a8e7270), WTC(0x3c844ca9), WTC(0x3e82267e), WTC(0x4087ccfa),
+ WTC(0x42950352), WTC(0x44a99ce7), WTC(0x46c57093), WTC(0x48e84dbe),
+ WTC(0x4b127506), WTC(0x4d452d29), WTC(0x4f81e066), WTC(0x51ca11c4),
+ WTC(0x000c82e8), WTC(0xfff6f40c), WTC(0xfffa1260), WTC(0x001530bf),
+ WTC(0x0047a202), WTC(0x0090b903), WTC(0x00efc89f), WTC(0x016423af),
+ WTC(0x01ed1d0e), WTC(0x028a0796), WTC(0x033a3620), WTC(0x03fcfb89),
+ WTC(0x04d1aaaa), WTC(0x05b7965c), WTC(0x06ae1179), WTC(0x07b46ee8),
+ WTC(0x08ca0173), WTC(0x09ee1c00), WTC(0x0b201162), WTC(0x0c5f346e),
+ WTC(0x0daad808), WTC(0x0f024f17), WTC(0x1064ec4b), WTC(0x11d202c4),
+ WTC(0x1348e514), WTC(0x14c8e62f), WTC(0x1651590a), WTC(0x17e19051),
+ WTC(0x1978df27), WTC(0x1b169812), WTC(0x1cba0e15), WTC(0x1e629407),
+ WTC(0x200f7cd4), WTC(0x21c01b29), WTC(0x2373c228), WTC(0x2529c453),
+ WTC(0x26e174b9), WTC(0x289a262f), WTC(0x2a532bba), WTC(0x2c0bd7b2),
+ WTC(0x2dc37d92), WTC(0x2f796fce), WTC(0x312d017a), WTC(0x32dd8513),
+ WTC(0x348a4dde), WTC(0x3632aeb3), WTC(0x37d5fa29), WTC(0x39738334),
+ WTC(0x3b0a9c99), WTC(0x3c9a9926), WTC(0x3e22cc21), WTC(0x3fa287dc),
+ WTC(0x41191f89), WTC(0x4285e5fc), WTC(0x43e82e02), WTC(0x453f4a40),
+ WTC(0x468a8dd9), WTC(0x47c94c23), WTC(0x48fadc7c), WTC(0x4a1e75f9),
+ WTC(0x4b339ecf), WTC(0x4c3981b1), WTC(0x4d2f7cd3), WTC(0x4e14e381),
+ WTC(0x4ee90804), WTC(0x4fab3d6a), WTC(0x505ad6bd), WTC(0x50f726a3),
+ WTC(0x517f7fea), WTC(0x51f335fd), WTC(0x52519b0f), WTC(0x529a01f2),
+ WTC(0x52cbbe31), WTC(0x52e621d9), WTC(0x52e880aa), WTC(0x52d22c7a),
+ WTC(0x52a278a5), WTC(0x5258b880), WTC(0x51f43e1d), WTC(0x51745c38),
+ WTC(0x50d8669e), WTC(0x501faf0e), WTC(0x4f49897e), WTC(0x4e554804),
+ WTC(0x4d423d9e), WTC(0x4c0fbd8b), WTC(0x4abd1a4d), WTC(0x4949a698),
+ WTC(0x47b4b7f9), WTC(0x45fe2b6d), WTC(0x44375019), WTC(0x4284e96e),
+ WTC(0x40f7efa2), WTC(0x3f8f8b33), WTC(0x3e494311), WTC(0x3d21e35b),
+ WTC(0x3c15c621), WTC(0x3b2115f3), WTC(0x3a4008aa), WTC(0x396ed2a6),
+ WTC(0x38a99a1d), WTC(0x37ec1177), WTC(0x3730f154), WTC(0x36756c15),
+ WTC(0x35bafb0d), WTC(0x35020093), WTC(0x34492381), WTC(0x338f6226),
+ WTC(0x32d40a34), WTC(0x3215bd73), WTC(0x315302ce), WTC(0x308c7c41),
+ WTC(0x2fc3532f), WTC(0x2ef6de8f), WTC(0x2e265a7f), WTC(0x2d527bfd),
+ WTC(0x2c7bf035), WTC(0x2ba2975b), WTC(0x2ac63552), WTC(0x29e686ca),
+};
+
+const FIXP_WTB ELDAnalysis128[384] = {
+ WTC(0xfaa49e98), WTC(0xfa48929f), WTC(0xf9e7eb39), WTC(0xf983b829),
+ WTC(0xf91bc5cb), WTC(0xf8b0376f), WTC(0xf8408d62), WTC(0xf7cd8c1e),
+ WTC(0xf7580da3), WTC(0xf6e0b0dc), WTC(0xf667753c), WTC(0xf5efa4cf),
+ WTC(0xf57cb6de), WTC(0xf511b62b), WTC(0xf4b1a860), WTC(0xf45ee8f8),
+ WTC(0xf415710d), WTC(0xf3c0c4f3), WTC(0xf35c2af9), WTC(0xf2e89620),
+ WTC(0xf266f3cb), WTC(0xf1d819bf), WTC(0xf13cff2f), WTC(0xf09489d2),
+ WTC(0xefdcfa80), WTC(0xef182059), WTC(0xee4d6c60), WTC(0xed7b8da7),
+ WTC(0xec9c27b1), WTC(0xebb57d0d), WTC(0xeacb3918), WTC(0xe9d35591),
+ WTC(0xe8c9176e), WTC(0xe7b93e42), WTC(0xe6b10e47), WTC(0xe5a6b875),
+ WTC(0xe484c345), WTC(0xe3509f1b), WTC(0xe224254c), WTC(0xe10a4e18),
+ WTC(0xdff4a668), WTC(0xded3d881), WTC(0xdda5ed98), WTC(0xdc722d13),
+ WTC(0xdb437360), WTC(0xda1fefed), WTC(0xd90623b2), WTC(0xd7f070f5),
+ WTC(0xd6da361b), WTC(0xd5c0786f), WTC(0xd4a6e188), WTC(0xd39b37b4),
+ WTC(0xd2a01ff2), WTC(0xd1a8a05c), WTC(0xd0b0cf47), WTC(0xcfbd3527),
+ WTC(0xced6b8d7), WTC(0xcdff0a66), WTC(0xcd2978a4), WTC(0xcc587183),
+ WTC(0xcb93bfdb), WTC(0xcad80773), WTC(0xca233c2b), WTC(0xc9768b5e),
+ WTC(0xc8cc130c), WTC(0xc8231acd), WTC(0xc7768de4), WTC(0xc6c86bdf),
+ WTC(0xc6181aa1), WTC(0xc563f6ce), WTC(0xc4b33a2a), WTC(0xc4085fcf),
+ WTC(0xc35ae72e), WTC(0xc2ad7adf), WTC(0xc206ed94), WTC(0xc16a5744),
+ WTC(0xc0d59625), WTC(0xc041e21b), WTC(0xbfb1ee05), WTC(0xbf2d82ea),
+ WTC(0xbeb60fe9), WTC(0xbe499da8), WTC(0xbde61891), WTC(0xbd8975b6),
+ WTC(0xbd339d36), WTC(0xbce6a08b), WTC(0xbca5b2f9), WTC(0xbc721002),
+ WTC(0xbc494d41), WTC(0xbc266160), WTC(0xbc06d14f), WTC(0xbbec52c7),
+ WTC(0xbbdaaf79), WTC(0xbbd0be99), WTC(0xbbcae139), WTC(0xbbcd359c),
+ WTC(0xbbded5d3), WTC(0xbbfa58cf), WTC(0xbc162f9d), WTC(0xbc326534),
+ WTC(0xbc4f081c), WTC(0xbc6c1678), WTC(0xbc899f93), WTC(0xbca7a263),
+ WTC(0xbcc62954), WTC(0xbce52ddc), WTC(0xbd04bc7f), WTC(0xbd24cd8f),
+ WTC(0xbd456998), WTC(0xbd668428), WTC(0xbd88207c), WTC(0xbdaa2e4b),
+ WTC(0xbdccaf3e), WTC(0xbdef932c), WTC(0xbe12d936), WTC(0xbe366dd6),
+ WTC(0xbe5a4fd9), WTC(0xbe7e6b49), WTC(0xbea2bf3f), WTC(0xbec738b5),
+ WTC(0xbeebd791), WTC(0xbf108b49), WTC(0xbf3554aa), WTC(0xbf5a25cf),
+ WTC(0xbf7f020b), WTC(0xbfa3dd25), WTC(0xbfc8be1e), WTC(0xbfed95f6),
+ WTC(0x8024c933), WTC(0x806e24fb), WTC(0x80b73d96), WTC(0x80fff78c),
+ WTC(0x8148612f), WTC(0x8190626e), WTC(0x81d8030a), WTC(0x821f28e1),
+ WTC(0x8265d6be), WTC(0x82abed56), WTC(0x82f16e40), WTC(0x833636d2),
+ WTC(0x837a470a), WTC(0x83bd7be6), WTC(0x83ffd415), WTC(0x84412e66),
+ WTC(0x84818c4f), WTC(0x84c0d18c), WTC(0x84ff0429), WTC(0x853c09a5),
+ WTC(0x8577eacf), WTC(0x85b29402), WTC(0x85ec17bf), WTC(0x86246b50),
+ WTC(0x865ba7d7), WTC(0x8691c4c0), WTC(0x86c6d72a), WTC(0x86fae06c),
+ WTC(0x872dfcd1), WTC(0x87602c6a), WTC(0x87918a27), WTC(0x87c22ef8),
+ WTC(0x882f7c20), WTC(0x88dc38ab), WTC(0x89a52f47), WTC(0x8a737635),
+ WTC(0x8b43d08d), WTC(0x8c19be9f), WTC(0x8cf89ce7), WTC(0x8de337e9),
+ WTC(0x8edb3e02), WTC(0x8fe1e815), WTC(0x90f7e107), WTC(0x921d8b95),
+ WTC(0x9353008c), WTC(0x94982fd7), WTC(0x95ecdc6d), WTC(0x9750b87f),
+ WTC(0x98c36ad6), WTC(0x9a447674), WTC(0x9bd34e9c), WTC(0x9d6f76fa),
+ WTC(0x9f18780d), WTC(0xa0cdc487), WTC(0xa28eff8e), WTC(0xa45bbe4b),
+ WTC(0xa633baaf), WTC(0xa816bff0), WTC(0xaa04a90d), WTC(0xabfd7205),
+ WTC(0xae01356b), WTC(0xb0101477), WTC(0xb22a5244), WTC(0xb4500b02),
+ WTC(0x499946f3), WTC(0x475da5af), WTC(0x45173dce), WTC(0x42c610ad),
+ WTC(0x406a44b0), WTC(0x3e037ce8), WTC(0x3b92b806), WTC(0x39195cd0),
+ WTC(0x36962f17), WTC(0x340a1b28), WTC(0x3177cde6), WTC(0x2ee1f20d),
+ WTC(0x2c49b0d6), WTC(0x29ad3d74), WTC(0x270e9ec1), WTC(0x2474132f),
+ WTC(0x21e14a01), WTC(0x1f57704e), WTC(0x1cd758ce), WTC(0x1a610d48),
+ WTC(0x17f5db88), WTC(0x1598a188), WTC(0x134f7a40), WTC(0x111f1ca0),
+ WTC(0x0f053b83), WTC(0x0cf871db), WTC(0x0af19e60), WTC(0x08eaa56d),
+ WTC(0x06e3c473), WTC(0x04d25cc9), WTC(0x02b59b4d), WTC(0x00e5bc4c),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xffcebf14), WTC(0xff6cc249), WTC(0xff0b8bda), WTC(0xfeac3e5f),
+ WTC(0xfe4f4638), WTC(0xfdf5052f), WTC(0xfd9e8cf4), WTC(0xfd4e34ea),
+ WTC(0xfd023142), WTC(0xfcb8f6f7), WTC(0xfc74e090), WTC(0xfc3b33e8),
+ WTC(0xfc0c1254), WTC(0xfbe1b2eb), WTC(0xfbb8ce73), WTC(0xfb97e511),
+ WTC(0xfb86273d), WTC(0xfb857a3e), WTC(0xfb918813), WTC(0xfba43692),
+ WTC(0xfbb96f24), WTC(0xfbd4dcc3), WTC(0xfc000cd5), WTC(0xfc458653),
+ WTC(0xfca6cd98), WTC(0xfd178c8e), WTC(0xfd872979), WTC(0xfdfa721e),
+ WTC(0xfe88c77c), WTC(0xff3c8b5c), WTC(0x00059ebc), WTC(0x00d91db0),
+ WTC(0x01bec555), WTC(0x02bdfb80), WTC(0x03d4c846), WTC(0x0501ad53),
+ WTC(0x064719b2), WTC(0x07a34a2b), WTC(0x0918814b), WTC(0x0aaaaa6b),
+ WTC(0x0c5728b9), WTC(0x0e1c1a0f), WTC(0x0ff9ccd1), WTC(0x11f21ffb),
+ WTC(0x1405d073), WTC(0x1635776b), WTC(0x1880f4e5), WTC(0x1ae8bdcb),
+ WTC(0x1d6cede3), WTC(0x200e1d93), WTC(0x22cc56fd), WTC(0x25a80858),
+ WTC(0x28a11bdd), WTC(0x2bb7e363), WTC(0x2eec2f0f), WTC(0x323e298d),
+ WTC(0x35ad7f0b), WTC(0x393a1989), WTC(0x3ce34a65), WTC(0x40a8683d),
+ WTC(0x44881c94), WTC(0x48813cb3), WTC(0x4c94523d), WTC(0x50c8eff0),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x0053a1ea), WTC(0x00f67066),
+ WTC(0x01e3f61b), WTC(0x0317bdaf), WTC(0x048d51ca), WTC(0x06403d11),
+ WTC(0x082c0a34), WTC(0x0a4c43d2), WTC(0x0c9c748e), WTC(0x0f182718),
+ WTC(0x11bae616), WTC(0x14803c1b), WTC(0x1763b3e6), WTC(0x1a60d832),
+ WTC(0x1d73336b), WTC(0x20965068), WTC(0x23c5b9d6), WTC(0x26fcfa1a),
+ WTC(0x2a379c30), WTC(0x2d712a75), WTC(0x30a52fba), WTC(0x33cf36a9),
+ WTC(0x36eaca15), WTC(0x39f3743b), WTC(0x3ce4bfc2), WTC(0x3fba37b8),
+ WTC(0x426f6671), WTC(0x44ffd6e8), WTC(0x47671326), WTC(0x49a0b2d0),
+ WTC(0x4ba81be1), WTC(0x4d78fd1e), WTC(0x4f0ed503), WTC(0x50652e28),
+ WTC(0x51779351), WTC(0x52418fbe), WTC(0x52bead75), WTC(0x52ea76cc),
+ WTC(0x52c07793), WTC(0x523c3918), WTC(0x5159470e), WTC(0x50132b36),
+ WTC(0x4e657128), WTC(0x4c4ba31d), WTC(0x49c14b60), WTC(0x46c1e9e4),
+ WTC(0x4374e179), WTC(0x408377b1), WTC(0x3e0fa0aa), WTC(0x3c05d584),
+ WTC(0x3a4d9888), WTC(0x38cdd8fa), WTC(0x376b75c4), WTC(0x360c51a7),
+ WTC(0x34b12fdc), WTC(0x33550d9f), WTC(0x31f1955c), WTC(0x307ffcb2),
+ WTC(0x2f03c44d), WTC(0x2d7a6b86), WTC(0x2be6d3d4), WTC(0x2a48d219),
+};
+
+const FIXP_WTB ELDAnalysis120[360] = {
+ WTC(0xfaa1a40a), WTC(0xfa3f173d), WTC(0xf9d7760c), WTC(0xf96bcc12),
+ WTC(0xf8fbe82c), WTC(0xf887bb26), WTC(0xf80f131a), WTC(0xf7930d03),
+ WTC(0xf714aeaf), WTC(0xf693f5a1), WTC(0xf613385b), WTC(0xf596ef0e),
+ WTC(0xf522dcc4), WTC(0xf4bab1f6), WTC(0xf461700c), WTC(0xf412e1fe),
+ WTC(0xf3b769b1), WTC(0xf349eaca), WTC(0xf2cb9164), WTC(0xf23d6d7b),
+ WTC(0xf1a0ab28), WTC(0xf0f5c20f), WTC(0xf03aadd9), WTC(0xef6e8c66),
+ WTC(0xee984910), WTC(0xedbbcbf8), WTC(0xecd1435b), WTC(0xebdc1b77),
+ WTC(0xeae31338), WTC(0xe9dbea9a), WTC(0xe8c005ea), WTC(0xe79e7068),
+ WTC(0xe6856dce), WTC(0xe5657c79), WTC(0xe42928e9), WTC(0xe2e0756e),
+ WTC(0xe1a83cf5), WTC(0xe0801fab), WTC(0xdf52bfeb), WTC(0xde15d1b1),
+ WTC(0xdcce71ba), WTC(0xdb8931bf), WTC(0xda4fbbe8), WTC(0xd9220a98),
+ WTC(0xd7f9af0c), WTC(0xd6d0e1df), WTC(0xd5a41f15), WTC(0xd4790330),
+ WTC(0xd35f84b8), WTC(0xd255e881), WTC(0xd14daf00), WTC(0xd04638e2),
+ WTC(0xcf47dff7), WTC(0xce5b8850), WTC(0xcd77b1d6), WTC(0xcc960ec0),
+ WTC(0xcbc0a6a4), WTC(0xcaf6d4f7), WTC(0xca34fa7d), WTC(0xc97c26c0),
+ WTC(0xc8c6868a), WTC(0xc811f873), WTC(0xc7599db8), WTC(0xc69f9780),
+ WTC(0xc5e24043), WTC(0xc5226384), WTC(0xc468f547), WTC(0xc3b20be9),
+ WTC(0xc2f826f0), WTC(0xc242ea02), WTC(0xc19844ae), WTC(0xc0f80714),
+ WTC(0xc05a6da1), WTC(0xbfbfe6d3), WTC(0xbf31b5b4), WTC(0xbeb24843),
+ WTC(0xbe3f4cb4), WTC(0xbdd63599), WTC(0xbd74c6b2), WTC(0xbd1b7128),
+ WTC(0xbccd4b41), WTC(0xbc8dc08e), WTC(0xbc5ca2bd), WTC(0xbc3509f1),
+ WTC(0xbc11f904), WTC(0xbbf37848), WTC(0xbbddfb6b), WTC(0xbbd214ea),
+ WTC(0xbbcb3a11), WTC(0xbbcce581), WTC(0xbbdfa6ba), WTC(0xbbfd2fa5),
+ WTC(0xbc1ad516), WTC(0xbc390c16), WTC(0xbc57b323), WTC(0xbc76dd1f),
+ WTC(0xbc969172), WTC(0xbcb6d611), WTC(0xbcd7ac8e), WTC(0xbcf91af9),
+ WTC(0xbd1b20bd), WTC(0xbd3dc1f5), WTC(0xbd60f678), WTC(0xbd84bec7),
+ WTC(0xbda909c0), WTC(0xbdcdd76e), WTC(0xbdf3161c), WTC(0xbe18c1e5),
+ WTC(0xbe3ec6c5), WTC(0xbe651f19), WTC(0xbe8bb78b), WTC(0xbeb288e1),
+ WTC(0xbed9848b), WTC(0xbf00a16f), WTC(0xbf27d681), WTC(0xbf4f1958),
+ WTC(0xbf76680e), WTC(0xbf9db85c), WTC(0xbfc50e09), WTC(0xbfec5bdf),
+ WTC(0x80273bdb), WTC(0x807577de), WTC(0x80c3630d), WTC(0x8110e4cb),
+ WTC(0x815e05da), WTC(0x81aab20f), WTC(0x81f6e68e), WTC(0x824290d0),
+ WTC(0x828da04c), WTC(0x82d8061f), WTC(0x8321a740), WTC(0x836a77f9),
+ WTC(0x83b2574f), WTC(0x83f93cc1), WTC(0x843f04a6), WTC(0x8483acd1),
+ WTC(0x84c71639), WTC(0x850944da), WTC(0x854a1d3a), WTC(0x8589a437),
+ WTC(0x85c7ccf9), WTC(0x8604a42f), WTC(0x86402cfb), WTC(0x867a740d),
+ WTC(0x86b37ff2), WTC(0x86eb5f6f), WTC(0x87222109), WTC(0x8757eb5f),
+ WTC(0x878c8341), WTC(0x87c0be51), WTC(0x88345fca), WTC(0x88ef97fb),
+ WTC(0x89c778c5), WTC(0x8aa3cc20), WTC(0x8b833d56), WTC(0x8c6a42a9),
+ WTC(0x8d5cb787), WTC(0x8e5d7787), WTC(0x8f6e3c5b), WTC(0x90902640),
+ WTC(0x91c3ca28), WTC(0x9309622d), WTC(0x9460e7d0), WTC(0x95ca1ad2),
+ WTC(0x97449dff), WTC(0x98d00612), WTC(0x9a6bbc19), WTC(0x9c17164d),
+ WTC(0x9dd180fc), WTC(0x9f9a6304), WTC(0xa1711f56), WTC(0xa355425e),
+ WTC(0xa5465846), WTC(0xa744190f), WTC(0xa94e4ca9), WTC(0xab64dcf0),
+ WTC(0xad87e068), WTC(0xafb77bfa), WTC(0xb1f3fb2b), WTC(0xb43d885c),
+ WTC(0x49866451), WTC(0x4723e56b), WTC(0x44b51e8d), WTC(0x423a2180),
+ WTC(0x3fb2fe0f), WTC(0x3d1f78f2), WTC(0x3a8153b7), WTC(0x37d906ff),
+ WTC(0x35259e7e), WTC(0x3269ba18), WTC(0x2fa8c1ea), WTC(0x2ce4fbab),
+ WTC(0x2a1cebd5), WTC(0x27519ac1), WTC(0x248a2de9), WTC(0x21cb7a79),
+ WTC(0x1f16fc13), WTC(0x1c6d9a50), WTC(0x19cf83c1), WTC(0x173e9943),
+ WTC(0x14bf6a71), WTC(0x12598f74), WTC(0x100fe27f), WTC(0x0ddab46a),
+ WTC(0x0bafab9d), WTC(0x09864fc7), WTC(0x075d3ac8), WTC(0x052c0fc2),
+ WTC(0x02ea842b), WTC(0x00f21d19), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xffcb7b4d), WTC(0xff62fb20), WTC(0xfefb82e2), WTC(0xfe965482),
+ WTC(0xfe33e4bf), WTC(0xfdd4b9b5), WTC(0xfd7b04ec), WTC(0xfd27cfe4),
+ WTC(0xfcd84cfd), WTC(0xfc8ce1d4), WTC(0xfc4b45e1), WTC(0xfc1666da),
+ WTC(0xfbe8af26), WTC(0xfbbcad9e), WTC(0xfb98c6ad), WTC(0xfb85dd87),
+ WTC(0xfb86355b), WTC(0xfb94589b), WTC(0xfba8ed8a), WTC(0xfbc0a735),
+ WTC(0xfbe23f8d), WTC(0xfc1a92c4), WTC(0xfc73315f), WTC(0xfce611a1),
+ WTC(0xfd5e94d9), WTC(0xfdd61cab), WTC(0xfe6427fd), WTC(0xff1c92da),
+ WTC(0xfff10542), WTC(0x00d1d58a), WTC(0x01c6daab), WTC(0x02d8dbc3),
+ WTC(0x040557a6), WTC(0x054b6f91), WTC(0x06ad2b2b), WTC(0x0828f4c5),
+ WTC(0x09c348d1), WTC(0x0b7dcb56), WTC(0x0d54d98e), WTC(0x0f47a599),
+ WTC(0x1157fa1b), WTC(0x138743ae), WTC(0x15d6423f), WTC(0x1844f0ae),
+ WTC(0x1ad3c273), WTC(0x1d82e65c), WTC(0x205306e1), WTC(0x23443d5c),
+ WTC(0x2656fae8), WTC(0x298b3a5a), WTC(0x2ce13a7d), WTC(0x3058e0e3),
+ WTC(0x33f22950), WTC(0x37acd0b2), WTC(0x3b885e6b), WTC(0x3f840412),
+ WTC(0x439e65ee), WTC(0x47d6014e), WTC(0x4c2aa857), WTC(0x50a46876),
+ WTC(0xfffe9b02), WTC(0x0004ac61), WTC(0x0069639d), WTC(0x0127578b),
+ WTC(0x02391efe), WTC(0x039950cc), WTC(0x054283bf), WTC(0x072f4eba),
+ WTC(0x095a488c), WTC(0x0bbe0802), WTC(0x0e5523f9), WTC(0x111a332e),
+ WTC(0x1407cca2), WTC(0x171886f5), WTC(0x1a46f927), WTC(0x1d8db9e1),
+ WTC(0x20e7600d), WTC(0x244e82a3), WTC(0x27bdb846), WTC(0x2b2f97a8),
+ WTC(0x2e9eb7ea), WTC(0x3205afd1), WTC(0x355f161c), WTC(0x38a581d7),
+ WTC(0x3bd3894a), WTC(0x3ee3c398), WTC(0x41d0c7ae), WTC(0x44952cb8),
+ WTC(0x472b8856), WTC(0x498e7eee), WTC(0x4bb88245), WTC(0x4da44d9f),
+ WTC(0x4f4c6b7d), WTC(0x50ab7298), WTC(0x51bbfa11), WTC(0x527898fb),
+ WTC(0x52dbe5f2), WTC(0x52e07778), WTC(0x5280e51f), WTC(0x51b7c4f1),
+ WTC(0x507fadc7), WTC(0x4ed336dd), WTC(0x4cacf749), WTC(0x4a078534),
+ WTC(0x46dd6dcc), WTC(0x43599e22), WTC(0x403f48da), WTC(0x3db1ed89),
+ WTC(0x3b98bd24), WTC(0x39d5b003), WTC(0x384a3292), WTC(0x36d328ff),
+ WTC(0x355e63a6), WTC(0x33ec69d8), WTC(0x32755ebd), WTC(0x30f01fce),
+ WTC(0x2f5d9646), WTC(0x2dbcc615), WTC(0x2c0fa145), WTC(0x2a56ce53),
+};
diff --git a/fdk-aac/libAACenc/src/aacEnc_rom.h b/fdk-aac/libAACenc/src/aacEnc_rom.h
new file mode 100644
index 0000000..fd50cab
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacEnc_rom.h
@@ -0,0 +1,217 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser, M. Gayer
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Memory layout
+ \author Markus Lohwasser
+*/
+
+#ifndef AACENC_ROM_H
+#define AACENC_ROM_H
+
+#include "common_fix.h"
+
+#include "psy_const.h"
+#include "psy_configuration.h"
+#include "FDK_tools_rom.h"
+#include "FDK_lpc.h"
+
+/*
+ Huffman Tables
+*/
+extern const ULONG FDKaacEnc_huff_ltab1_2[3][3][3][3];
+extern const ULONG FDKaacEnc_huff_ltab3_4[3][3][3][3];
+extern const ULONG FDKaacEnc_huff_ltab5_6[9][9];
+extern const ULONG FDKaacEnc_huff_ltab7_8[8][8];
+extern const ULONG FDKaacEnc_huff_ltab9_10[13][13];
+extern const UCHAR FDKaacEnc_huff_ltab11[17][17];
+extern const UCHAR FDKaacEnc_huff_ltabscf[121];
+extern const USHORT FDKaacEnc_huff_ctab1[3][3][3][3];
+extern const USHORT FDKaacEnc_huff_ctab2[3][3][3][3];
+extern const USHORT FDKaacEnc_huff_ctab3[3][3][3][3];
+extern const USHORT FDKaacEnc_huff_ctab4[3][3][3][3];
+extern const USHORT FDKaacEnc_huff_ctab5[9][9];
+extern const USHORT FDKaacEnc_huff_ctab6[9][9];
+extern const USHORT FDKaacEnc_huff_ctab7[8][8];
+extern const USHORT FDKaacEnc_huff_ctab8[8][8];
+extern const USHORT FDKaacEnc_huff_ctab9[13][13];
+extern const USHORT FDKaacEnc_huff_ctab10[13][13];
+extern const USHORT FDKaacEnc_huff_ctab11[21][17];
+extern const ULONG FDKaacEnc_huff_ctabscf[121];
+
+/*
+ quantizer
+*/
+#define MANT_DIGITS 9
+#define MANT_SIZE (1 << MANT_DIGITS)
+
+#if defined(ARCH_PREFER_MULT_32x16)
+#define FIXP_QTD FIXP_SGL
+#define QTC FX_DBL2FXCONST_SGL
+#else
+#define FIXP_QTD FIXP_DBL
+#define QTC
+#endif
+
+extern const FIXP_QTD FDKaacEnc_mTab_3_4[MANT_SIZE];
+extern const FIXP_QTD FDKaacEnc_quantTableQ[4];
+extern const FIXP_QTD FDKaacEnc_quantTableE[4];
+
+extern const FIXP_DBL FDKaacEnc_mTab_4_3Elc[512];
+extern const FIXP_DBL FDKaacEnc_specExpMantTableCombElc[4][14];
+extern const UCHAR FDKaacEnc_specExpTableComb[4][14];
+
+/*
+ table to count used number of bits
+*/
+extern const SHORT FDKaacEnc_sideInfoTabLong[];
+extern const SHORT FDKaacEnc_sideInfoTabShort[];
+
+/*
+ Psy Configuration constants
+*/
+extern const SFB_PARAM_LONG p_FDKaacEnc_8000_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_8000_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_11025_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_11025_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_12000_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_12000_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_16000_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_16000_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_22050_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_22050_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_24000_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_24000_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_32000_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_32000_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_44100_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_44100_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_48000_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_48000_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_64000_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_64000_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_88200_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_88200_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_96000_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_96000_short_128;
+
+/*
+ TNS filter coefficients
+*/
+extern const FIXP_LPC FDKaacEnc_tnsEncCoeff3[8];
+extern const FIXP_LPC FDKaacEnc_tnsCoeff3Borders[8];
+extern const FIXP_LPC FDKaacEnc_tnsEncCoeff4[16];
+extern const FIXP_LPC FDKaacEnc_tnsCoeff4Borders[16];
+
+#define WTC0 WTC
+#define WTC1 WTC
+#define WTC2 WTC
+
+extern const FIXP_WTB ELDAnalysis512[1536];
+extern const FIXP_WTB ELDAnalysis480[1440];
+extern const FIXP_WTB ELDAnalysis256[768];
+extern const FIXP_WTB ELDAnalysis240[720];
+extern const FIXP_WTB ELDAnalysis128[384];
+extern const FIXP_WTB ELDAnalysis120[360];
+
+#endif /* #ifndef AACENC_ROM_H */
diff --git a/fdk-aac/libAACenc/src/aacenc.cpp b/fdk-aac/libAACenc/src/aacenc.cpp
new file mode 100644
index 0000000..372df31
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacenc.cpp
@@ -0,0 +1,1057 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Schug / A. Groeschel
+
+ Description: fast aac coder functions
+
+*******************************************************************************/
+
+#include "aacenc.h"
+
+#include "bitenc.h"
+#include "interface.h"
+#include "psy_configuration.h"
+#include "psy_main.h"
+#include "qc_main.h"
+#include "bandwidth.h"
+#include "channel_map.h"
+#include "tns_func.h"
+#include "aacEnc_ram.h"
+
+#include "genericStds.h"
+
+#define BITRES_MAX_LD 4000
+#define BITRES_MIN_LD 500
+#define BITRATE_MAX_LD 70000 /* Max assumed bitrate for bitres calculation */
+#define BITRATE_MIN_LD 12000 /* Min assumed bitrate for bitres calculation */
+
+INT FDKaacEnc_CalcBitsPerFrame(const INT bitRate, const INT frameLength,
+ const INT samplingRate) {
+ int shift = 0;
+ while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength &&
+ (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate) {
+ shift++;
+ }
+
+ return (bitRate * (frameLength >> shift)) / (samplingRate >> shift);
+}
+
+INT FDKaacEnc_CalcBitrate(const INT bitsPerFrame, const INT frameLength,
+ const INT samplingRate) {
+ int shift = 0;
+ while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength &&
+ (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate) {
+ shift++;
+ }
+
+ return (bitsPerFrame * (samplingRate >> shift)) / (frameLength >> shift);
+}
+
+static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(
+ INT bitRate, INT framelength, INT ancillaryRate, INT *ancillaryBitsPerFrame,
+ INT sampleRate);
+
+INT FDKaacEnc_LimitBitrate(HANDLE_TRANSPORTENC hTpEnc, AUDIO_OBJECT_TYPE aot,
+ INT coreSamplingRate, INT frameLength, INT nChannels,
+ INT nChannelsEff, INT bitRate, INT averageBits,
+ INT *pAverageBitsPerFrame,
+ AACENC_BITRATE_MODE bitrateMode, INT nSubFrames) {
+ INT transportBits, prevBitRate, averageBitsPerFrame, minBitrate = 0, iter = 0;
+ INT minBitsPerFrame = 40 * nChannels;
+ if (isLowDelay(aot)) {
+ minBitrate = 8000 * nChannelsEff;
+ }
+
+ do {
+ prevBitRate = bitRate;
+ averageBitsPerFrame =
+ FDKaacEnc_CalcBitsPerFrame(bitRate, frameLength, coreSamplingRate) /
+ nSubFrames;
+
+ if (pAverageBitsPerFrame != NULL) {
+ *pAverageBitsPerFrame = averageBitsPerFrame;
+ }
+
+ if (hTpEnc != NULL) {
+ transportBits = transportEnc_GetStaticBits(hTpEnc, averageBitsPerFrame);
+ } else {
+ /* Assume some worst case */
+ transportBits = 208;
+ }
+
+ bitRate = fMax(bitRate,
+ fMax(minBitrate,
+ FDKaacEnc_CalcBitrate((minBitsPerFrame + transportBits),
+ frameLength, coreSamplingRate)));
+ FDK_ASSERT(bitRate >= 0);
+
+ bitRate = fMin(bitRate, FDKaacEnc_CalcBitrate(
+ (nChannelsEff * MIN_BUFSIZE_PER_EFF_CHAN),
+ frameLength, coreSamplingRate));
+ FDK_ASSERT(bitRate >= 0);
+
+ } while (prevBitRate != bitRate && iter++ < 3);
+
+ //fprintf(stderr, "FDKaacEnc_LimitBitrate(): bitRate=%d\n", bitRate);
+ return bitRate;
+}
+
+typedef struct {
+ AACENC_BITRATE_MODE bitrateMode;
+ int chanBitrate[2]; /* mono/stereo settings */
+} CONFIG_TAB_ENTRY_VBR;
+
+static const CONFIG_TAB_ENTRY_VBR configTabVBR[] = {
+ {AACENC_BR_MODE_CBR, {0, 0}},
+ {AACENC_BR_MODE_VBR_1, {32000, 20000}},
+ {AACENC_BR_MODE_VBR_2, {40000, 32000}},
+ {AACENC_BR_MODE_VBR_3, {56000, 48000}},
+ {AACENC_BR_MODE_VBR_4, {72000, 64000}},
+ {AACENC_BR_MODE_VBR_5, {112000, 96000}}};
+
+/*-----------------------------------------------------------------------------
+
+ functionname: FDKaacEnc_GetVBRBitrate
+ description: Get VBR bitrate from vbr quality
+ input params: int vbrQuality (VBR0, VBR1, VBR2)
+ channelMode
+ returns: vbr bitrate
+
+ ------------------------------------------------------------------------------*/
+INT FDKaacEnc_GetVBRBitrate(AACENC_BITRATE_MODE bitrateMode,
+ CHANNEL_MODE channelMode) {
+ INT bitrate = 0;
+ INT monoStereoMode = 0; /* default mono */
+
+ if (FDKaacEnc_GetMonoStereoMode(channelMode) == EL_MODE_STEREO) {
+ monoStereoMode = 1;
+ }
+
+ switch (bitrateMode) {
+ case AACENC_BR_MODE_VBR_1:
+ case AACENC_BR_MODE_VBR_2:
+ case AACENC_BR_MODE_VBR_3:
+ case AACENC_BR_MODE_VBR_4:
+ case AACENC_BR_MODE_VBR_5:
+ bitrate = configTabVBR[bitrateMode].chanBitrate[monoStereoMode];
+ break;
+ case AACENC_BR_MODE_INVALID:
+ case AACENC_BR_MODE_CBR:
+ case AACENC_BR_MODE_SFR:
+ case AACENC_BR_MODE_FF:
+ default:
+ bitrate = 0;
+ break;
+ }
+
+ /* convert channel bitrate to overall bitrate*/
+ bitrate *= FDKaacEnc_GetChannelModeConfiguration(channelMode)->nChannelsEff;
+
+ return bitrate;
+}
+
+/**
+ * \brief Convert encoder bitreservoir value for transport library.
+ *
+ * \param hAacEnc Encoder handle
+ *
+ * \return Corrected bitreservoir level used in transport library.
+ */
+static INT FDKaacEnc_EncBitresToTpBitres(const HANDLE_AAC_ENC hAacEnc) {
+ INT transportBitreservoir = 0;
+
+ switch (hAacEnc->bitrateMode) {
+ case AACENC_BR_MODE_CBR:
+ transportBitreservoir =
+ hAacEnc->qcKernel->bitResTot; /* encoder bitreservoir level */
+ break;
+ case AACENC_BR_MODE_VBR_1:
+ case AACENC_BR_MODE_VBR_2:
+ case AACENC_BR_MODE_VBR_3:
+ case AACENC_BR_MODE_VBR_4:
+ case AACENC_BR_MODE_VBR_5:
+ transportBitreservoir = FDK_INT_MAX; /* signal variable bitrate */
+ break;
+ case AACENC_BR_MODE_SFR:
+ transportBitreservoir = 0; /* super framing and fixed framing */
+ break; /* without bitreservoir signaling */
+ default:
+ case AACENC_BR_MODE_INVALID:
+ transportBitreservoir = 0; /* invalid configuration*/
+ }
+
+ if (hAacEnc->config->audioMuxVersion == 2) {
+ transportBitreservoir =
+ MIN_BUFSIZE_PER_EFF_CHAN * hAacEnc->channelMapping.nChannelsEff;
+ }
+
+ return transportBitreservoir;
+}
+
+INT FDKaacEnc_GetBitReservoirState(const HANDLE_AAC_ENC hAacEncoder) {
+ return FDKaacEnc_EncBitresToTpBitres(hAacEncoder);
+}
+
+/*-----------------------------------------------------------------------------
+
+ functionname: FDKaacEnc_AacInitDefaultConfig
+ description: gives reasonable default configuration
+ returns: ---
+
+ ------------------------------------------------------------------------------*/
+void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config) {
+ /* make the preinitialization of the structs flexible */
+ FDKmemclear(config, sizeof(AACENC_CONFIG));
+
+ /* default ancillary */
+ config->anc_Rate = 0; /* no ancillary data */
+ config->ancDataBitRate = 0; /* no additional consumed bitrate */
+
+ /* default configurations */
+ config->bitRate = -1; /* bitrate must be set*/
+ config->averageBits =
+ -1; /* instead of bitrate/s we can configure bits/superframe */
+ config->bitrateMode =
+ AACENC_BR_MODE_CBR; /* set bitrate mode to constant bitrate */
+ config->bandWidth = 0; /* get bandwidth from table */
+ config->useTns = TNS_ENABLE_MASK; /* tns enabled completly */
+ config->usePns =
+ 1; /* depending on channelBitrate this might be set to 0 later */
+ config->useIS = 1; /* Intensity Stereo Configuration */
+ config->useMS = 1; /* MS Stereo tool */
+ config->framelength = -1; /* Framesize not configured */
+ config->syntaxFlags = 0; /* default syntax with no specialities */
+ config->epConfig = -1; /* no ER syntax -> no additional error protection */
+ config->nSubFrames = 1; /* default, no sub frames */
+ config->channelOrder = CH_ORDER_MPEG; /* Use MPEG channel ordering. */
+ config->channelMode = MODE_UNKNOWN;
+ config->minBitsPerFrame = -1; /* minum number of bits in each AU */
+ config->maxBitsPerFrame = -1; /* minum number of bits in each AU */
+ config->audioMuxVersion = -1; /* audio mux version not configured */
+ config->downscaleFactor =
+ 1; /* downscale factor for ELD reduced delay mode, 1 is normal ELD */
+}
+
+/*---------------------------------------------------------------------------
+
+ functionname: FDKaacEnc_Open
+ description: allocate and initialize a new encoder instance
+ returns: error code
+
+ ---------------------------------------------------------------------------*/
+AAC_ENCODER_ERROR FDKaacEnc_Open(HANDLE_AAC_ENC *phAacEnc, const INT nElements,
+ const INT nChannels, const INT nSubFrames) {
+ AAC_ENCODER_ERROR ErrorStatus;
+ AAC_ENC *hAacEnc = NULL;
+ UCHAR *dynamicRAM = NULL;
+
+ if (phAacEnc == NULL) {
+ return AAC_ENC_INVALID_HANDLE;
+ }
+
+ /* allocate encoder structure */
+ hAacEnc = GetRam_aacEnc_AacEncoder();
+ if (hAacEnc == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto bail;
+ }
+ FDKmemclear(hAacEnc, sizeof(AAC_ENC));
+
+ if (NULL == (hAacEnc->dynamic_RAM = GetAACdynamic_RAM())) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto bail;
+ }
+ dynamicRAM = (UCHAR *)hAacEnc->dynamic_RAM;
+
+ /* allocate the Psy aud Psy Out structure */
+ ErrorStatus =
+ FDKaacEnc_PsyNew(&hAacEnc->psyKernel, nElements, nChannels, dynamicRAM);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+
+ ErrorStatus = FDKaacEnc_PsyOutNew(hAacEnc->psyOut, nElements, nChannels,
+ nSubFrames, dynamicRAM);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+
+ /* allocate the Q&C Out structure */
+ ErrorStatus = FDKaacEnc_QCOutNew(hAacEnc->qcOut, nElements, nChannels,
+ nSubFrames, dynamicRAM);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+
+ /* allocate the Q&C kernel */
+ ErrorStatus = FDKaacEnc_QCNew(&hAacEnc->qcKernel, nElements, dynamicRAM);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+
+ hAacEnc->maxChannels = nChannels;
+ hAacEnc->maxElements = nElements;
+ hAacEnc->maxFrames = nSubFrames;
+
+bail:
+ *phAacEnc = hAacEnc;
+ return ErrorStatus;
+}
+
+AAC_ENCODER_ERROR FDKaacEnc_Initialize(
+ HANDLE_AAC_ENC hAacEnc,
+ AACENC_CONFIG *config, /* pre-initialized config struct */
+ HANDLE_TRANSPORTENC hTpEnc, ULONG initFlags) {
+ AAC_ENCODER_ERROR ErrorStatus;
+ INT psyBitrate, tnsMask; // INT profile = 1;
+ CHANNEL_MAPPING *cm = NULL;
+
+ INT mbfac_e, qbw;
+ FIXP_DBL mbfac, bw_ratio;
+ QC_INIT qcInit;
+ INT averageBitsPerFrame = 0;
+ int bitresMin = 0; /* the bitreservoir is always big for AAC-LC */
+ const CHANNEL_MODE prevChannelMode = hAacEnc->encoderMode;
+
+ if (config == NULL) return AAC_ENC_INVALID_HANDLE;
+
+ /******************* sanity checks *******************/
+
+ /* check config structure */
+ if (config->nChannels < 1 || config->nChannels > (8)) {
+ return AAC_ENC_UNSUPPORTED_CHANNELCONFIG;
+ }
+
+ /* check sample rate */
+ switch (config->sampleRate) {
+ case 8000:
+ case 11025:
+ case 12000:
+ case 16000:
+ case 22050:
+ case 24000:
+ case 32000:
+ case 44100:
+ case 48000:
+ case 64000:
+ case 88200:
+ case 96000:
+ break;
+ default:
+ return AAC_ENC_UNSUPPORTED_SAMPLINGRATE;
+ }
+
+ /* bitrate has to be set */
+ if (config->bitRate == -1) {
+ return AAC_ENC_UNSUPPORTED_BITRATE;
+ }
+
+ INT superframe_size = 110*8*(config->bitRate/8000);
+ INT frames_per_superframe = 6;
+ INT staticBits = 0;
+ if((config->syntaxFlags & AC_DAB) && hTpEnc) {
+ staticBits = transportEnc_GetStaticBits(hTpEnc, 0);
+ switch(config->sampleRate) {
+ case 48000:
+ frames_per_superframe=6;
+ break;
+ case 32000:
+ frames_per_superframe=4;
+ break;
+ case 24000:
+ frames_per_superframe=3;
+ break;
+ case 16000:
+ frames_per_superframe=2;
+ break;
+ }
+
+ //config->nSubFrames = frames_per_superframe;
+ //fprintf(stderr, "DAB+ superframe size=%d\n", superframe_size);
+ config->bitRate = (superframe_size - 16*(frames_per_superframe-1) - staticBits) * 1000/120;
+ //fprintf(stderr, "DAB+ tuned bitrate=%d\n", config->bitRate);
+ config->maxBitsPerFrame = (superframe_size - 16*(frames_per_superframe-1) - staticBits) / frames_per_superframe;
+ config->maxBitsPerFrame += 7; /*padding*/
+ //config->bitreservoir=(superframe_size - 16*(frames_per_superframe-1) - staticBits - 2*8)/frames_per_superframe;
+ //fprintf(stderr, "DAB+ tuned maxBitsPerFrame=%d\n", (superframe_size - 16*(frames_per_superframe-1) - staticBits)/frames_per_superframe);
+ }
+
+ /* check bit rate */
+
+ if (FDKaacEnc_LimitBitrate(
+ hTpEnc, config->audioObjectType, config->sampleRate,
+ config->framelength, config->nChannels,
+ FDKaacEnc_GetChannelModeConfiguration(config->channelMode)
+ ->nChannelsEff,
+ config->bitRate, config->averageBits, &averageBitsPerFrame,
+ config->bitrateMode, config->nSubFrames) != config->bitRate &&
+ !(AACENC_BR_MODE_IS_VBR(config->bitrateMode))) {
+ return AAC_ENC_UNSUPPORTED_BITRATE;
+ }
+
+ if (config->syntaxFlags & AC_ER_VCB11) {
+ return AAC_ENC_UNSUPPORTED_ER_FORMAT;
+ }
+ if (config->syntaxFlags & AC_ER_HCR) {
+ return AAC_ENC_UNSUPPORTED_ER_FORMAT;
+ }
+
+ /* check frame length */
+ switch (config->framelength) {
+ case 1024:
+ case 960:
+ if (isLowDelay(config->audioObjectType)) {
+ return AAC_ENC_INVALID_FRAME_LENGTH;
+ }
+ break;
+ case 128:
+ case 256:
+ case 512:
+ case 120:
+ case 240:
+ case 480:
+ if (!isLowDelay(config->audioObjectType)) {
+ return AAC_ENC_INVALID_FRAME_LENGTH;
+ }
+ break;
+ default:
+ return AAC_ENC_INVALID_FRAME_LENGTH;
+ }
+
+ if (config->anc_Rate != 0) {
+ ErrorStatus = FDKaacEnc_InitCheckAncillary(
+ config->bitRate, config->framelength, config->anc_Rate,
+ &hAacEnc->ancillaryBitsPerFrame, config->sampleRate);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+
+ /* update estimated consumed bitrate */
+ config->ancDataBitRate +=
+ FDKaacEnc_CalcBitrate(hAacEnc->ancillaryBitsPerFrame,
+ config->framelength, config->sampleRate);
+ }
+
+ /* maximal allowed DSE bytes in frame */
+ config->maxAncBytesPerAU =
+ fMin((256), fMax(0, FDKaacEnc_CalcBitsPerFrame(
+ (config->bitRate - (config->nChannels * 8000)),
+ config->framelength, config->sampleRate) >>
+ 3));
+
+ /* bind config to hAacEnc->config */
+ hAacEnc->config = config;
+
+ /* set hAacEnc->bitrateMode */
+ hAacEnc->bitrateMode = config->bitrateMode;
+
+ hAacEnc->encoderMode = config->channelMode;
+
+ ErrorStatus = FDKaacEnc_InitChannelMapping(
+ hAacEnc->encoderMode, config->channelOrder, &hAacEnc->channelMapping);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+
+ cm = &hAacEnc->channelMapping;
+
+ ErrorStatus = FDKaacEnc_DetermineBandWidth(
+ config->bandWidth, config->bitRate - config->ancDataBitRate,
+ hAacEnc->bitrateMode, config->sampleRate, config->framelength, cm,
+ hAacEnc->encoderMode, &hAacEnc->config->bandWidth);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+
+ hAacEnc->bandwidth90dB = (INT)hAacEnc->config->bandWidth;
+
+ tnsMask = config->useTns ? TNS_ENABLE_MASK : 0x0;
+ psyBitrate = config->bitRate - config->ancDataBitRate;
+
+ if ((hAacEnc->encoderMode != prevChannelMode) || (initFlags != 0)) {
+ /* Reinitialize psych states in case of channel configuration change ore if
+ * full reset requested. */
+ ErrorStatus = FDKaacEnc_psyInit(hAacEnc->psyKernel, hAacEnc->psyOut,
+ hAacEnc->maxFrames, hAacEnc->maxChannels,
+ config->audioObjectType, cm);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+ }
+
+ ErrorStatus = FDKaacEnc_psyMainInit(
+ hAacEnc->psyKernel, config->audioObjectType, cm, config->sampleRate,
+ config->framelength, psyBitrate, tnsMask, hAacEnc->bandwidth90dB,
+ config->usePns, config->useIS, config->useMS, config->syntaxFlags,
+ initFlags);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+
+ ErrorStatus = FDKaacEnc_QCOutInit(hAacEnc->qcOut, hAacEnc->maxFrames, cm);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+
+ qcInit.channelMapping = &hAacEnc->channelMapping;
+ qcInit.sceCpe = 0;
+
+ if (AACENC_BR_MODE_IS_VBR(config->bitrateMode)) {
+ qcInit.averageBits = (averageBitsPerFrame + 7) & ~7;
+ qcInit.bitRes = MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff;
+ qcInit.maxBits = MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff;
+ qcInit.maxBits = (config->maxBitsPerFrame != -1)
+ ? fixMin(qcInit.maxBits, config->maxBitsPerFrame)
+ : qcInit.maxBits;
+ qcInit.maxBits = fixMax(qcInit.maxBits, (averageBitsPerFrame + 7) & ~7);
+ qcInit.minBits =
+ (config->minBitsPerFrame != -1) ? config->minBitsPerFrame : 0;
+ qcInit.minBits = fixMin(qcInit.minBits, averageBitsPerFrame & ~7);
+ } else {
+ INT bitreservoir = -1; /* default bitrservoir size*/
+ if (isLowDelay(config->audioObjectType)) {
+ INT brPerChannel = config->bitRate / config->nChannels;
+ brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel));
+
+ /* bitreservoir =
+ * (maxBitRes-minBitRes)/(maxBitRate-minBitrate)*(bitRate-minBitrate)+minBitRes;
+ */
+ FIXP_DBL slope = fDivNorm(
+ (brPerChannel - BITRATE_MIN_LD),
+ BITRATE_MAX_LD - BITRATE_MIN_LD); /* calc slope for interpolation */
+ bitreservoir = fMultI(slope, (INT)(BITRES_MAX_LD - BITRES_MIN_LD)) +
+ BITRES_MIN_LD; /* interpolate */
+ bitreservoir = bitreservoir & ~7; /* align to bytes */
+ bitresMin = BITRES_MIN_LD;
+ }
+
+ int maxBitres;
+ qcInit.averageBits = (averageBitsPerFrame + 7) & ~7;
+ maxBitres =
+ (MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff) - qcInit.averageBits;
+ qcInit.bitRes =
+ (bitreservoir != -1) ? fMin(bitreservoir, maxBitres) : maxBitres;
+
+ qcInit.maxBits = fixMin(MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff,
+ ((averageBitsPerFrame + 7) & ~7) + qcInit.bitRes);
+ qcInit.maxBits = (config->maxBitsPerFrame != -1)
+ ? fixMin(qcInit.maxBits, config->maxBitsPerFrame)
+ : qcInit.maxBits;
+ qcInit.maxBits =
+ fixMin(MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff,
+ fixMax(qcInit.maxBits, (averageBitsPerFrame + 7 + 8) & ~7));
+
+ qcInit.minBits = fixMax(
+ 0, ((averageBitsPerFrame - 1) & ~7) - qcInit.bitRes -
+ transportEnc_GetStaticBits(
+ hTpEnc, ((averageBitsPerFrame + 7) & ~7) + qcInit.bitRes));
+ qcInit.minBits = (config->minBitsPerFrame != -1)
+ ? fixMax(qcInit.minBits, config->minBitsPerFrame)
+ : qcInit.minBits;
+ qcInit.minBits = fixMin(
+ qcInit.minBits, (averageBitsPerFrame -
+ transportEnc_GetStaticBits(hTpEnc, qcInit.maxBits)) &
+ ~7);
+ }
+
+ qcInit.sampleRate = config->sampleRate;
+ qcInit.isLowDelay = isLowDelay(config->audioObjectType) ? 1 : 0;
+ qcInit.nSubFrames = config->nSubFrames;
+ qcInit.padding.paddingRest = config->sampleRate;
+
+ if (qcInit.bitRes >= bitresMin * config->nChannels) {
+ qcInit.bitResMode = AACENC_BR_MODE_FULL; /* full bitreservoir */
+ } else if (qcInit.bitRes > 0) {
+ qcInit.bitResMode = AACENC_BR_MODE_REDUCED; /* reduced bitreservoir */
+ } else {
+ qcInit.bitResMode = AACENC_BR_MODE_DISABLED; /* disabled bitreservoir */
+ }
+
+ /* Configure bitrate distribution strategy. */
+ switch (config->channelMode) {
+ case MODE_1_2:
+ case MODE_1_2_1:
+ case MODE_1_2_2:
+ case MODE_1_2_2_1:
+ case MODE_6_1:
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_BACK:
+ case MODE_7_1_TOP_FRONT:
+ case MODE_7_1_REAR_SURROUND:
+ case MODE_7_1_FRONT_CENTER:
+ qcInit.bitDistributionMode = 0; /* over all elements bitrate estimation */
+ break;
+ case MODE_1:
+ case MODE_2:
+ default: /* all non mpeg defined channel modes */
+ qcInit.bitDistributionMode = 1; /* element-wise bit bitrate estimation */
+ } /* config->channelMode */
+
+ /* Calc meanPe: qcInit.meanPe = 10.0f * FRAME_LEN_LONG *
+ * hAacEnc->bandwidth90dB/(config->sampleRate/2.0f); */
+ bw_ratio =
+ fDivNorm((FIXP_DBL)(10 * config->framelength * hAacEnc->bandwidth90dB),
+ (FIXP_DBL)(config->sampleRate), &qbw);
+ qcInit.meanPe =
+ fMax((INT)scaleValue(bw_ratio, qbw + 1 - (DFRACT_BITS - 1)), 1);
+
+ /* Calc maxBitFac, scale it to 24 bit accuracy */
+ mbfac = fDivNorm(qcInit.maxBits, qcInit.averageBits / qcInit.nSubFrames,
+ &mbfac_e);
+ qcInit.maxBitFac = scaleValue(mbfac, -(DFRACT_BITS - 1 - 24 - mbfac_e));
+
+ switch (config->bitrateMode) {
+ case AACENC_BR_MODE_CBR:
+ qcInit.bitrateMode = QCDATA_BR_MODE_CBR;
+ break;
+ case AACENC_BR_MODE_VBR_1:
+ qcInit.bitrateMode = QCDATA_BR_MODE_VBR_1;
+ break;
+ case AACENC_BR_MODE_VBR_2:
+ qcInit.bitrateMode = QCDATA_BR_MODE_VBR_2;
+ break;
+ case AACENC_BR_MODE_VBR_3:
+ qcInit.bitrateMode = QCDATA_BR_MODE_VBR_3;
+ break;
+ case AACENC_BR_MODE_VBR_4:
+ qcInit.bitrateMode = QCDATA_BR_MODE_VBR_4;
+ break;
+ case AACENC_BR_MODE_VBR_5:
+ qcInit.bitrateMode = QCDATA_BR_MODE_VBR_5;
+ break;
+ case AACENC_BR_MODE_SFR:
+ qcInit.bitrateMode = QCDATA_BR_MODE_SFR;
+ break;
+ case AACENC_BR_MODE_FF:
+ qcInit.bitrateMode = QCDATA_BR_MODE_FF;
+ break;
+ default:
+ ErrorStatus = AAC_ENC_UNSUPPORTED_BITRATE_MODE;
+ goto bail;
+ }
+
+ qcInit.invQuant = (config->useRequant) ? 2 : 0;
+
+ /* maxIterations should be set to the maximum number of requantization
+ * iterations that are allowed before the crash recovery functionality is
+ * activated. This setting should be adjusted to the processing power
+ * available, i.e. to the processing power headroom in one frame that is still
+ * left after normal encoding without requantization. Please note that if
+ * activated this functionality is used most likely only in cases where the
+ * encoder is operating beyond recommended settings, i.e. the audio quality is
+ * suboptimal anyway. Activating the crash recovery does not further reduce
+ * audio quality significantly in these cases. */
+ if (isLowDelay(config->audioObjectType)) {
+ qcInit.maxIterations = 2;
+ } else {
+ qcInit.maxIterations = 5;
+ }
+
+ qcInit.bitrate = config->bitRate - config->ancDataBitRate;
+
+ qcInit.staticBits = transportEnc_GetStaticBits(
+ hTpEnc, qcInit.averageBits / qcInit.nSubFrames);
+
+ ErrorStatus = FDKaacEnc_QCInit(hAacEnc->qcKernel, &qcInit, initFlags);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+
+ /* Map virtual aot's to intern aot used in bitstream writer. */
+ switch (hAacEnc->config->audioObjectType) {
+ case AOT_MP2_AAC_LC:
+ hAacEnc->aot = AOT_AAC_LC;
+ break;
+ case AOT_MP2_SBR:
+ hAacEnc->aot = AOT_SBR;
+ break;
+ default:
+ hAacEnc->aot = hAacEnc->config->audioObjectType;
+ }
+
+ /* common things */
+
+ return AAC_ENC_OK;
+
+bail:
+
+ return ErrorStatus;
+}
+
+/*---------------------------------------------------------------------------
+
+ functionname: FDKaacEnc_EncodeFrame
+ description: encodes one frame
+ returns: error code
+
+ ---------------------------------------------------------------------------*/
+AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame(
+ HANDLE_AAC_ENC hAacEnc, /* encoder handle */
+ HANDLE_TRANSPORTENC hTpEnc, INT_PCM *RESTRICT inputBuffer,
+ const UINT inputBufferBufSize, INT *nOutBytes,
+ AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS]) {
+ AAC_ENCODER_ERROR ErrorStatus;
+ int el, n, c = 0;
+ UCHAR extPayloadUsed[MAX_TOTAL_EXT_PAYLOADS];
+
+ CHANNEL_MAPPING *cm = &hAacEnc->channelMapping;
+
+ PSY_OUT *psyOut = hAacEnc->psyOut[c];
+ QC_OUT *qcOut = hAacEnc->qcOut[c];
+
+ FDKmemclear(extPayloadUsed, MAX_TOTAL_EXT_PAYLOADS * sizeof(UCHAR));
+
+ qcOut->elementExtBits = 0; /* sum up all extended bit of each element */
+ qcOut->staticBits = 0; /* sum up side info bits of each element */
+ qcOut->totalNoRedPe = 0; /* sum up PE */
+
+ /* advance psychoacoustics */
+ for (el = 0; el < cm->nElements; el++) {
+ ELEMENT_INFO elInfo = cm->elInfo[el];
+
+ if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
+ (elInfo.elType == ID_LFE)) {
+ int ch;
+
+ /* update pointer!*/
+ for (ch = 0; ch < elInfo.nChannelsInEl; ch++) {
+ PSY_OUT_CHANNEL *psyOutChan =
+ psyOut->psyOutElement[el]->psyOutChannel[ch];
+ QC_OUT_CHANNEL *qcOutChan = qcOut->qcElement[el]->qcOutChannel[ch];
+
+ psyOutChan->mdctSpectrum = qcOutChan->mdctSpectrum;
+ psyOutChan->sfbSpreadEnergy = qcOutChan->sfbSpreadEnergy;
+ psyOutChan->sfbEnergy = qcOutChan->sfbEnergy;
+ psyOutChan->sfbEnergyLdData = qcOutChan->sfbEnergyLdData;
+ psyOutChan->sfbMinSnrLdData = qcOutChan->sfbMinSnrLdData;
+ psyOutChan->sfbThresholdLdData = qcOutChan->sfbThresholdLdData;
+ }
+
+ ErrorStatus = FDKaacEnc_psyMain(
+ elInfo.nChannelsInEl, hAacEnc->psyKernel->psyElement[el],
+ hAacEnc->psyKernel->psyDynamic, hAacEnc->psyKernel->psyConf,
+ psyOut->psyOutElement[el], inputBuffer, inputBufferBufSize,
+ cm->elInfo[el].ChannelIndex, cm->nChannels);
+
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+
+ /* FormFactor, Pe and staticBitDemand calculation */
+ ErrorStatus = FDKaacEnc_QCMainPrepare(
+ &elInfo, hAacEnc->qcKernel->hAdjThr->adjThrStateElem[el],
+ psyOut->psyOutElement[el], qcOut->qcElement[el], hAacEnc->aot,
+ hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
+
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+
+ /*-------------------------------------------- */
+
+ qcOut->qcElement[el]->extBitsUsed = 0;
+ qcOut->qcElement[el]->nExtensions = 0;
+ /* reset extension payload */
+ FDKmemclear(&qcOut->qcElement[el]->extension,
+ (1) * sizeof(QC_OUT_EXTENSION));
+
+ for (n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++) {
+ if (!extPayloadUsed[n] && (extPayload[n].associatedChElement == el) &&
+ (extPayload[n].dataSize > 0) && (extPayload[n].pData != NULL)) {
+ int idx = qcOut->qcElement[el]->nExtensions++;
+
+ qcOut->qcElement[el]->extension[idx].type =
+ extPayload[n].dataType; /* Perform a sanity check on the type? */
+ qcOut->qcElement[el]->extension[idx].nPayloadBits =
+ extPayload[n].dataSize;
+ qcOut->qcElement[el]->extension[idx].pPayload = extPayload[n].pData;
+ /* Now ask the bitstream encoder how many bits we need to encode the
+ * data with the current bitstream syntax: */
+ qcOut->qcElement[el]->extBitsUsed += FDKaacEnc_writeExtensionData(
+ NULL, &qcOut->qcElement[el]->extension[idx], 0, 0,
+ hAacEnc->config->syntaxFlags, hAacEnc->aot,
+ hAacEnc->config->epConfig);
+ extPayloadUsed[n] = 1;
+ }
+ }
+
+ /* sum up extension and static bits for all channel elements */
+ qcOut->elementExtBits += qcOut->qcElement[el]->extBitsUsed;
+ qcOut->staticBits += qcOut->qcElement[el]->staticBitsUsed;
+
+ /* sum up pe */
+ qcOut->totalNoRedPe += qcOut->qcElement[el]->peData.pe;
+ }
+ }
+
+ qcOut->nExtensions = 0;
+ qcOut->globalExtBits = 0;
+
+ /* reset extension payload */
+ FDKmemclear(&qcOut->extension, (2 + 2) * sizeof(QC_OUT_EXTENSION));
+
+ /* Add extension payload not assigned to an channel element
+ (Ancillary data is the only supported type up to now) */
+ for (n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++) {
+ if (!extPayloadUsed[n] && (extPayload[n].associatedChElement == -1) &&
+ (extPayload[n].pData != NULL)) {
+ UINT payloadBits = 0;
+
+ if (extPayload[n].dataType == EXT_DATA_ELEMENT) {
+ if (hAacEnc->ancillaryBitsPerFrame) {
+ /* granted frame dse bitrate */
+ payloadBits = hAacEnc->ancillaryBitsPerFrame;
+ } else {
+ /* write anc data if bitrate constraint fulfilled */
+ if ((extPayload[n].dataSize >> 3) <=
+ hAacEnc->config->maxAncBytesPerAU) {
+ payloadBits = extPayload[n].dataSize;
+ }
+ }
+ payloadBits = fixMin(extPayload[n].dataSize, payloadBits);
+ } else {
+ payloadBits = extPayload[n].dataSize;
+ }
+
+ if (payloadBits > 0) {
+ int idx = qcOut->nExtensions++;
+
+ qcOut->extension[idx].type =
+ extPayload[n].dataType; /* Perform a sanity check on the type? */
+ qcOut->extension[idx].nPayloadBits = payloadBits;
+ qcOut->extension[idx].pPayload = extPayload[n].pData;
+ /* Now ask the bitstream encoder how many bits we need to encode the
+ * data with the current bitstream syntax: */
+ qcOut->globalExtBits += FDKaacEnc_writeExtensionData(
+ NULL, &qcOut->extension[idx], 0, 0, hAacEnc->config->syntaxFlags,
+ hAacEnc->aot, hAacEnc->config->epConfig);
+ if (extPayload[n].dataType == EXT_DATA_ELEMENT) {
+ /* substract the processed bits */
+ extPayload[n].dataSize -= payloadBits;
+ }
+ extPayloadUsed[n] = 1;
+ }
+ }
+ }
+
+ if (!(hAacEnc->config->syntaxFlags & (AC_SCALABLE | AC_ER))) {
+ qcOut->globalExtBits += EL_ID_BITS; /* add bits for ID_END */
+ }
+
+ /* build bitstream all nSubFrames */
+ {
+ INT totalBits = 0; /* Total AU bits */
+ ;
+ INT avgTotalBits = 0;
+
+ /*-------------------------------------------- */
+ /* Get average total bits */
+ /*-------------------------------------------- */
+ {
+ /* frame wise bitrate adaption */
+ FDKaacEnc_AdjustBitrate(
+ hAacEnc->qcKernel, cm, &avgTotalBits, hAacEnc->config->bitRate,
+ hAacEnc->config->sampleRate, hAacEnc->config->framelength);
+
+ /* adjust super frame bitrate */
+ avgTotalBits *= hAacEnc->config->nSubFrames;
+ }
+
+ /* Make first estimate of transport header overhead.
+ Take maximum possible frame size into account to prevent bitreservoir
+ underrun. */
+ hAacEnc->qcKernel->globHdrBits = transportEnc_GetStaticBits(
+ hTpEnc, avgTotalBits + hAacEnc->qcKernel->bitResTot);
+
+ /*-------------------------------------------- */
+ /*-------------------------------------------- */
+ /*-------------------------------------------- */
+
+ ErrorStatus = FDKaacEnc_QCMain(
+ hAacEnc->qcKernel, hAacEnc->psyOut, hAacEnc->qcOut, avgTotalBits, cm,
+ hAacEnc->aot, hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
+
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+ /*-------------------------------------------- */
+
+ /*-------------------------------------------- */
+ ErrorStatus = FDKaacEnc_updateFillBits(
+ cm, hAacEnc->qcKernel, hAacEnc->qcKernel->elementBits, hAacEnc->qcOut);
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+
+ /*-------------------------------------------- */
+ ErrorStatus = FDKaacEnc_FinalizeBitConsumption(
+ cm, hAacEnc->qcKernel, qcOut, qcOut->qcElement, hTpEnc, hAacEnc->aot,
+ hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+ /*-------------------------------------------- */
+ totalBits += qcOut->totalBits;
+
+ /*-------------------------------------------- */
+ FDKaacEnc_updateBitres(cm, hAacEnc->qcKernel, hAacEnc->qcOut);
+
+ /*-------------------------------------------- */
+
+ /* for ( all sub frames ) ... */
+ /* write bitstream header */
+ if (TRANSPORTENC_OK !=
+ transportEnc_WriteAccessUnit(hTpEnc, totalBits,
+ FDKaacEnc_EncBitresToTpBitres(hAacEnc),
+ cm->nChannelsEff)) {
+ return AAC_ENC_UNKNOWN;
+ }
+
+ /* write bitstream */
+ ErrorStatus = FDKaacEnc_WriteBitstream(
+ hTpEnc, cm, qcOut, psyOut, hAacEnc->qcKernel, hAacEnc->aot,
+ hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
+
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+
+ /* transportEnc_EndAccessUnit() is being called inside
+ * FDKaacEnc_WriteBitstream() */
+ if (TRANSPORTENC_OK != transportEnc_GetFrame(hTpEnc, nOutBytes)) {
+ return AAC_ENC_UNKNOWN;
+ }
+
+ } /* -end- if (curFrame==hAacEnc->qcKernel->nSubFrames) */
+
+ /*-------------------------------------------- */
+ return AAC_ENC_OK;
+}
+
+/*---------------------------------------------------------------------------
+
+ functionname:FDKaacEnc_Close
+ description: delete encoder instance
+ returns:
+
+ ---------------------------------------------------------------------------*/
+
+void FDKaacEnc_Close(HANDLE_AAC_ENC *phAacEnc) /* encoder handle */
+{
+ if (*phAacEnc == NULL) {
+ return;
+ }
+ AAC_ENC *hAacEnc = (AAC_ENC *)*phAacEnc;
+
+ if (hAacEnc->dynamic_RAM != NULL) FreeAACdynamic_RAM(&hAacEnc->dynamic_RAM);
+
+ FDKaacEnc_PsyClose(&hAacEnc->psyKernel, hAacEnc->psyOut);
+
+ FDKaacEnc_QCClose(&hAacEnc->qcKernel, hAacEnc->qcOut);
+
+ FreeRam_aacEnc_AacEncoder(phAacEnc);
+}
+
+/* The following functions are in this source file only for convenience and */
+/* need not be visible outside of a possible encoder library. */
+
+/* basic defines for ancillary data */
+#define MAX_ANCRATE 19200 /* ancillary rate >= 19200 isn't valid */
+
+/*---------------------------------------------------------------------------
+
+ functionname: FDKaacEnc_InitCheckAncillary
+ description: initialize and check ancillary data struct
+ return: if success or NULL if error
+
+ ---------------------------------------------------------------------------*/
+static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(
+ INT bitRate, INT framelength, INT ancillaryRate, INT *ancillaryBitsPerFrame,
+ INT sampleRate) {
+ /* don't use negative ancillary rates */
+ if (ancillaryRate < -1) return AAC_ENC_UNSUPPORTED_ANC_BITRATE;
+
+ /* check if ancillary rate is ok */
+ if ((ancillaryRate != (-1)) && (ancillaryRate != 0)) {
+ /* ancRate <= 15% of bitrate && ancRate < 19200 */
+ if ((ancillaryRate >= MAX_ANCRATE) ||
+ ((ancillaryRate * 20) > (bitRate * 3))) {
+ return AAC_ENC_UNSUPPORTED_ANC_BITRATE;
+ }
+ } else if (ancillaryRate == -1) {
+ /* if no special ancRate is requested but a ancillary file is
+ stated, then generate a ancillary rate matching to the bitrate */
+ if (bitRate >= (MAX_ANCRATE * 10)) {
+ /* ancillary rate is 19199 */
+ ancillaryRate = (MAX_ANCRATE - 1);
+ } else { /* 10% of bitrate */
+ ancillaryRate = bitRate / 10;
+ }
+ }
+
+ /* make ancillaryBitsPerFrame byte align */
+ *ancillaryBitsPerFrame =
+ FDKaacEnc_CalcBitsPerFrame(ancillaryRate, framelength, sampleRate) & ~0x7;
+
+ return AAC_ENC_OK;
+}
diff --git a/fdk-aac/libAACenc/src/aacenc.h b/fdk-aac/libAACenc/src/aacenc.h
new file mode 100644
index 0000000..291ea54
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacenc.h
@@ -0,0 +1,394 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Schug / A. Groeschel
+
+ Description: fast aac coder interface library functions
+
+*******************************************************************************/
+
+#ifndef AACENC_H
+#define AACENC_H
+
+#include "common_fix.h"
+#include "FDK_audio.h"
+
+#include "tpenc_lib.h"
+
+#include "sbr_encoder.h"
+
+#define MIN_BUFSIZE_PER_EFF_CHAN 6144
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * AAC-LC error codes.
+ */
+typedef enum {
+ AAC_ENC_OK = 0x0000, /*!< All fine. */
+
+ AAC_ENC_UNKNOWN = 0x0002, /*!< Error condition is of unknown reason, or from
+ another module. */
+
+ /* initialization errors */
+ aac_enc_init_error_start = 0x2000,
+ AAC_ENC_INVALID_HANDLE = 0x2020, /*!< The handle passed to the function call
+ was invalid (probably NULL). */
+ AAC_ENC_INVALID_FRAME_LENGTH =
+ 0x2080, /*!< Invalid frame length (must be 1024 or 960). */
+ AAC_ENC_INVALID_N_CHANNELS =
+ 0x20e0, /*!< Invalid amount of audio input channels. */
+ AAC_ENC_INVALID_SFB_TABLE = 0x2140, /*!< Internal encoder error. */
+
+ AAC_ENC_UNSUPPORTED_AOT =
+ 0x3000, /*!< The Audio Object Type (AOT) is not supported. */
+ AAC_ENC_UNSUPPORTED_FILTERBANK =
+ 0x3010, /*!< Filterbank type is not supported. */
+ AAC_ENC_UNSUPPORTED_BITRATE =
+ 0x3020, /*!< The chosen bitrate is not supported. */
+ AAC_ENC_UNSUPPORTED_BITRATE_MODE =
+ 0x3028, /*!< Unsupported bit rate mode (CBR or VBR). */
+ AAC_ENC_UNSUPPORTED_ANC_BITRATE =
+ 0x3040, /*!< Unsupported ancillay bitrate. */
+ AAC_ENC_UNSUPPORTED_ANC_MODE = 0x3060,
+ AAC_ENC_UNSUPPORTED_TRANSPORT_TYPE =
+ 0x3080, /*!< The bitstream format is not supported. */
+ AAC_ENC_UNSUPPORTED_ER_FORMAT =
+ 0x30a0, /*!< The error resilience tool format is not supported. */
+ AAC_ENC_UNSUPPORTED_EPCONFIG =
+ 0x30c0, /*!< The error protection format is not supported. */
+ AAC_ENC_UNSUPPORTED_CHANNELCONFIG =
+ 0x30e0, /*!< The channel configuration (either number or arrangement) is
+ not supported. */
+ AAC_ENC_UNSUPPORTED_SAMPLINGRATE =
+ 0x3100, /*!< Sample rate of audio input is not supported. */
+ AAC_ENC_NO_MEMORY = 0x3120, /*!< Could not allocate memory. */
+ AAC_ENC_PE_INIT_TABLE_NOT_FOUND = 0x3140, /*!< Internal encoder error. */
+
+ aac_enc_init_error_end,
+
+ /* encode errors */
+ aac_enc_error_start = 0x4000,
+ AAC_ENC_QUANT_ERROR = 0x4020, /*!< Too many bits used in quantization. */
+ AAC_ENC_WRITTEN_BITS_ERROR =
+ 0x4040, /*!< Unexpected number of written bits, differs to
+ calculated number of bits. */
+ AAC_ENC_PNS_TABLE_ERROR = 0x4060, /*!< PNS level out of range. */
+ AAC_ENC_GLOBAL_GAIN_TOO_HIGH = 0x4080, /*!< Internal quantizer error. */
+ AAC_ENC_BITRES_TOO_LOW = 0x40a0, /*!< Too few bits in bit reservoir. */
+ AAC_ENC_BITRES_TOO_HIGH = 0x40a1, /*!< Too many bits in bit reservoir. */
+ AAC_ENC_INVALID_CHANNEL_BITRATE = 0x4100,
+ AAC_ENC_INVALID_ELEMENTINFO_TYPE = 0x4120, /*!< Internal encoder error. */
+
+ AAC_ENC_WRITE_SCAL_ERROR = 0x41e0, /*!< Error writing scalefacData. */
+ AAC_ENC_WRITE_SEC_ERROR = 0x4200, /*!< Error writing sectionData. */
+ AAC_ENC_WRITE_SPEC_ERROR = 0x4220, /*!< Error writing spectralData. */
+ aac_enc_error_end
+
+} AAC_ENCODER_ERROR;
+/*-------------------------- defines --------------------------------------*/
+
+#define ANC_DATA_BUFFERSIZE 1024 /* ancBuffer size */
+
+#define MAX_TOTAL_EXT_PAYLOADS ((((8)) * (1)) + (2 + 2))
+
+typedef enum {
+ AACENC_BR_MODE_INVALID = -1, /*!< Invalid bitrate mode. */
+ AACENC_BR_MODE_CBR = 0, /*!< Constant bitrate mode. */
+ AACENC_BR_MODE_VBR_1 = 1, /*!< Variable bitrate mode, very low bitrate. */
+ AACENC_BR_MODE_VBR_2 = 2, /*!< Variable bitrate mode, low bitrate. */
+ AACENC_BR_MODE_VBR_3 = 3, /*!< Variable bitrate mode, medium bitrate. */
+ AACENC_BR_MODE_VBR_4 = 4, /*!< Variable bitrate mode, high bitrate. */
+ AACENC_BR_MODE_VBR_5 = 5, /*!< Variable bitrate mode, very high bitrate. */
+ AACENC_BR_MODE_FF = 6, /*!< Fixed frame mode. */
+ AACENC_BR_MODE_SFR = 7 /*!< Superframe mode. */
+
+} AACENC_BITRATE_MODE;
+
+#define AACENC_BR_MODE_IS_VBR(brMode) ((brMode >= 1) && (brMode <= 5))
+
+typedef enum {
+
+ CH_ORDER_MPEG =
+ 0, /*!< MPEG channel ordering (e. g. 5.1: C, L, R, SL, SR, LFE) */
+ CH_ORDER_WAV, /*!< WAV fileformat channel ordering (e. g. 5.1: L, R, C, LFE,
+ SL, SR) */
+ CH_ORDER_WG4 /*!< WG4 fileformat channel ordering (e. g. 5.1: L, R, SL, SR, C, LFE) */
+
+} CHANNEL_ORDER;
+
+/*-------------------- structure definitions ------------------------------*/
+
+struct AACENC_CONFIG {
+ INT sampleRate; /* encoder sample rate */
+ INT bitRate; /* encoder bit rate in bits/sec */
+ INT ancDataBitRate; /* additional bits consumed by anc data or sbr have to be
+ consiedered while configuration */
+
+ INT nSubFrames; /* number of frames in super frame (not ADTS/LATM subframes !)
+ */
+ AUDIO_OBJECT_TYPE audioObjectType; /* Audio Object Type */
+
+ INT averageBits; /* encoder bit rate in bits/superframe */
+ AACENC_BITRATE_MODE bitrateMode; /* encoder bitrate mode (CBR/VBR) */
+ INT nChannels; /* number of channels to process */
+ CHANNEL_ORDER channelOrder; /* input Channel ordering scheme. */
+ INT bandWidth; /* targeted audio bandwidth in Hz */
+ CHANNEL_MODE channelMode; /* encoder channel mode configuration */
+ INT framelength; /* used frame size */
+
+ UINT syntaxFlags; /* bitstreams syntax configuration */
+ SCHAR epConfig; /* error protection configuration */
+
+ INT anc_Rate; /* ancillary rate, 0 (disabled), -1 (default) else desired rate
+ */
+ UINT maxAncBytesPerAU;
+ INT minBitsPerFrame; /* minimum number of bits in AU */
+ INT maxBitsPerFrame; /* maximum number of bits in AU */
+
+ INT audioMuxVersion; /* audio mux version in loas/latm transport format */
+
+ UINT sbrRatio; /* sbr sampling rate ratio: dual- or single-rate */
+
+ UCHAR useTns; /* flag: use temporal noise shaping */
+ UCHAR usePns; /* flag: use perceptual noise substitution */
+ UCHAR useIS; /* flag: use intensity coding */
+ UCHAR useMS; /* flag: use ms stereo tool */
+
+ UCHAR useRequant; /* flag: use afterburner */
+
+ UINT downscaleFactor;
+};
+
+typedef struct {
+ UCHAR *pData; /* pointer to extension payload data */
+ UINT dataSize; /* extension payload data size in bits */
+ EXT_PAYLOAD_TYPE dataType; /* extension payload data type */
+ INT associatedChElement; /* number of the channel element the data is assigned
+ to */
+} AACENC_EXT_PAYLOAD;
+
+typedef struct AAC_ENC *HANDLE_AAC_ENC;
+
+/**
+ * \brief Calculate framesize in bits for given bit rate, frame length and
+ * sampling rate.
+ *
+ * \param bitRate Ttarget bitrate in bits per second.
+ * \param frameLength Number of audio samples in one frame.
+ * \param samplingRate Sampling rate in Hz.
+ *
+ * \return Framesize in bits per frame.
+ */
+INT FDKaacEnc_CalcBitsPerFrame(const INT bitRate, const INT frameLength,
+ const INT samplingRate);
+
+/**
+ * \brief Calculate bitrate in bits per second for given framesize, frame length
+ * and sampling rate.
+ *
+ * \param bitsPerFrame Framesize in bits per frame
+ * \param frameLength Number of audio samples in one frame.
+ * \param samplingRate Sampling rate in Hz.
+ *
+ * \return Bitrate in bits per second.
+ */
+INT FDKaacEnc_CalcBitrate(const INT bitsPerFrame, const INT frameLength,
+ const INT samplingRate);
+
+/**
+ * \brief Limit given bit rate to a valid value
+ * \param hTpEnc transport encoder handle
+ * \param aot audio object type
+ * \param coreSamplingRate the sample rate to be used for the AAC encoder
+ * \param frameLength the frameLength to be used for the AAC encoder
+ * \param nChannels number of total channels
+ * \param nChannelsEff number of effective channels
+ * \param bitRate the initial bit rate value for which the closest valid bit
+ * rate value is searched for
+ * \param averageBits average bits per frame for fixed framing. Set to -1 if not
+ * available.
+ * \param optional pointer where the current bits per frame are stored into.
+ * \param bitrateMode the current bit rate mode
+ * \param nSubFrames number of sub frames for super framing (not transport
+ * frames).
+ * \return a valid bit rate value as close as possible or identical to bitRate
+ */
+INT FDKaacEnc_LimitBitrate(HANDLE_TRANSPORTENC hTpEnc, AUDIO_OBJECT_TYPE aot,
+ INT coreSamplingRate, INT frameLength, INT nChannels,
+ INT nChannelsEff, INT bitRate, INT averageBits,
+ INT *pAverageBitsPerFrame,
+ AACENC_BITRATE_MODE bitrateMode, INT nSubFrames);
+
+/**
+ * \brief Get current state of the bit reservoir
+ * \param hAacEncoder encoder handle
+ * \return bit reservoir state in bits
+ */
+INT FDKaacEnc_GetBitReservoirState(const HANDLE_AAC_ENC hAacEncoder);
+
+/*-----------------------------------------------------------------------------
+
+ functionname: FDKaacEnc_GetVBRBitrate
+ description: Get VBR bitrate from vbr quality
+ input params: int vbrQuality (VBR0, VBR1, VBR2)
+ channelMode
+ returns: vbr bitrate
+
+------------------------------------------------------------------------------*/
+INT FDKaacEnc_GetVBRBitrate(AACENC_BITRATE_MODE bitrateMode,
+ CHANNEL_MODE channelMode);
+
+/*-----------------------------------------------------------------------------
+
+ functionname: FDKaacEnc_AacInitDefaultConfig
+ description: gives reasonable default configuration
+ returns: ---
+
+ ------------------------------------------------------------------------------*/
+void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config);
+
+/*---------------------------------------------------------------------------
+
+ functionname:FDKaacEnc_Open
+ description: allocate and initialize a new encoder instance
+ returns: 0 if success
+
+ ---------------------------------------------------------------------------*/
+AAC_ENCODER_ERROR FDKaacEnc_Open(
+ HANDLE_AAC_ENC
+ *phAacEnc, /* pointer to an encoder handle, initialized on return */
+ const INT nElements, /* number of maximal elements in instance to support */
+ const INT nChannels, /* number of maximal channels in instance to support */
+ const INT nSubFrames); /* support superframing in instance */
+
+AAC_ENCODER_ERROR FDKaacEnc_Initialize(
+ HANDLE_AAC_ENC
+ hAacEncoder, /* pointer to an encoder handle, initialized on return */
+ AACENC_CONFIG *config, /* pre-initialized config struct */
+ HANDLE_TRANSPORTENC hTpEnc, ULONG initFlags);
+
+/*---------------------------------------------------------------------------
+
+ functionname: FDKaacEnc_EncodeFrame
+ description: encode one frame
+ returns: 0 if success
+
+ ---------------------------------------------------------------------------*/
+
+AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame(
+ HANDLE_AAC_ENC hAacEnc, /* encoder handle */
+ HANDLE_TRANSPORTENC hTpEnc, INT_PCM *inputBuffer,
+ const UINT inputBufferBufSize, INT *numOutBytes,
+ AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS]);
+
+/*---------------------------------------------------------------------------
+
+ functionname:FDKaacEnc_Close
+ description: delete encoder instance
+ returns:
+
+ ---------------------------------------------------------------------------*/
+
+void FDKaacEnc_Close(HANDLE_AAC_ENC *phAacEnc); /* encoder handle */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AACENC_H */
diff --git a/fdk-aac/libAACenc/src/aacenc_lib.cpp b/fdk-aac/libAACenc/src/aacenc_lib.cpp
new file mode 100644
index 0000000..aaa6c74
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacenc_lib.cpp
@@ -0,0 +1,2575 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser
+
+ Description: FDK HE-AAC Encoder interface library functions
+
+*******************************************************************************/
+#include <stdio.h>
+#include "aacenc_lib.h"
+#include "FDK_audio.h"
+#include "aacenc.h"
+
+#include "aacEnc_ram.h"
+#include "FDK_core.h" /* FDK_tools versioning info */
+
+/* Encoder library info */
+#define AACENCODER_LIB_VL0 4
+#define AACENCODER_LIB_VL1 0
+#define AACENCODER_LIB_VL2 0
+#define AACENCODER_LIB_TITLE "AAC Encoder"
+#ifdef __ANDROID__
+#define AACENCODER_LIB_BUILD_DATE ""
+#define AACENCODER_LIB_BUILD_TIME ""
+#else
+#define AACENCODER_LIB_BUILD_DATE __DATE__
+#define AACENCODER_LIB_BUILD_TIME __TIME__
+#endif
+
+#include "pcm_utils.h"
+
+#include "sbr_encoder.h"
+#include "../src/sbrenc_ram.h"
+#include "channel_map.h"
+
+#include "psy_const.h"
+#include "bitenc.h"
+
+#include "tpenc_lib.h"
+
+#include "metadata_main.h"
+#include "mps_main.h"
+#include "sacenc_lib.h"
+
+#define SBL(fl) \
+ (fl / \
+ 8) /*!< Short block length (hardcoded to 8 short blocks per long block) */
+#define BSLA(fl) \
+ (4 * SBL(fl) + SBL(fl) / 2) /*!< AAC block switching look-ahead */
+#define DELAY_AAC(fl) (fl + BSLA(fl)) /*!< MDCT + blockswitching */
+#define DELAY_AACLD(fl) (fl) /*!< MDCT delay (no framing delay included) */
+#define DELAY_AACELD(fl) \
+ ((fl) / 2) /*!< ELD FB delay (no framing delay included) */
+
+#define MAX_DS_DELAY (100) /*!< Maximum downsampler delay in SBR. */
+#define INPUTBUFFER_SIZE \
+ (2 * (1024) + MAX_DS_DELAY + 1537) /*!< Audio input samples + downsampler \
+ delay + sbr/aac delay compensation */
+
+#define DEFAULT_HEADER_PERIOD_REPETITION_RATE \
+ 10 /*!< Default header repetition rate used in transport library and for SBR \
+ header. */
+
+////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Flags to characterize encoder modules to be supported in present instance.
+ */
+enum {
+ ENC_MODE_FLAG_AAC = 0x0001,
+ ENC_MODE_FLAG_SBR = 0x0002,
+ ENC_MODE_FLAG_PS = 0x0004,
+ ENC_MODE_FLAG_SAC = 0x0008,
+ ENC_MODE_FLAG_META = 0x0010
+};
+
+////////////////////////////////////////////////////////////////////////////////////
+typedef struct {
+ AUDIO_OBJECT_TYPE userAOT; /*!< Audio Object Type. */
+ UINT userSamplerate; /*!< Sampling frequency. */
+ UINT nChannels; /*!< will be set via channelMode. */
+ CHANNEL_MODE userChannelMode;
+ UINT userBitrate;
+ UINT userBitrateMode;
+ UINT userBandwidth;
+ UINT userAfterburner;
+ UINT userFramelength;
+ UINT userAncDataRate;
+ UINT userPeakBitrate;
+
+ UCHAR userTns; /*!< Use TNS coding. */
+ UCHAR userPns; /*!< Use PNS coding. */
+ UCHAR userIntensity; /*!< Use Intensity coding. */
+
+ TRANSPORT_TYPE userTpType; /*!< Transport type */
+ UCHAR userTpSignaling; /*!< Extension AOT signaling mode. */
+ UCHAR userTpNsubFrames; /*!< Number of sub frames in a transport frame for
+ LOAS/LATM or ADTS (default 1). */
+ UCHAR userTpAmxv; /*!< AudioMuxVersion to be used for LATM (default 0). */
+ UCHAR userTpProtection;
+ UCHAR userTpHeaderPeriod; /*!< Parameter used to configure LATM/LOAS SMC rate.
+ Moreover this parameters is used to configure
+ repetition rate of PCE in raw_data_block. */
+
+ UCHAR userErTools; /*!< Use VCB11, HCR and/or RVLC ER tool. */
+ UINT userPceAdditions; /*!< Configure additional bits in PCE. */
+
+ UCHAR userMetaDataMode; /*!< Meta data library configuration. */
+
+ UCHAR userSbrEnabled; /*!< Enable SBR for ELD. */
+ UINT userSbrRatio; /*!< SBR sampling rate ratio. Dual- or single-rate. */
+
+ UINT userDownscaleFactor;
+
+} USER_PARAM;
+
+/**
+ * SBR extenxion payload struct provides buffers to be filled in SBR encoder
+ * library.
+ */
+typedef struct {
+ UCHAR data[(1)][(8)][MAX_PAYLOAD_SIZE]; /*!< extension payload data buffer */
+ UINT dataSize[(1)][(8)]; /*!< extension payload data size in bits */
+} SBRENC_EXT_PAYLOAD;
+
+////////////////////////////////////////////////////////////////////////////////////
+
+/****************************************************************************
+ Structure Definitions
+****************************************************************************/
+
+typedef struct AACENC_CONFIG *HANDLE_AACENC_CONFIG;
+
+struct AACENCODER {
+ USER_PARAM extParam;
+ CODER_CONFIG coderConfig;
+
+ /* AAC */
+ AACENC_CONFIG aacConfig;
+ HANDLE_AAC_ENC hAacEnc;
+
+ /* SBR */
+ HANDLE_SBR_ENCODER hEnvEnc; /* SBR encoder */
+ SBRENC_EXT_PAYLOAD *pSbrPayload; /* SBR extension payload */
+
+ /* Meta Data */
+ HANDLE_FDK_METADATA_ENCODER hMetadataEnc;
+ INT metaDataAllowed; /* Signal whether chosen configuration allows metadata.
+ Necessary for delay compensation. Metadata mode is a
+ separate parameter. */
+
+ HANDLE_MPS_ENCODER hMpsEnc;
+
+ /* Transport */
+ HANDLE_TRANSPORTENC hTpEnc;
+
+ INT_PCM
+ *inputBuffer; /* Internal input buffer. Input source for AAC encoder */
+ UCHAR *outBuffer; /* Internal bitstream buffer */
+
+ INT inputBufferSize; /* Size of internal input buffer */
+ INT inputBufferSizePerChannel; /* Size of internal input buffer per channel */
+ INT outBufferInBytes; /* Size of internal bitstream buffer*/
+
+ INT inputBufferOffset; /* Where to write new input samples. */
+
+ INT nSamplesToRead; /* number of input samples neeeded for encoding one frame
+ */
+ INT nSamplesRead; /* number of input samples already in input buffer */
+ INT nZerosAppended; /* appended zeros at end of file*/
+ INT nDelay; /* codec delay */
+ INT nDelayCore; /* codec delay, w/o the SBR decoder delay */
+
+ AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS];
+
+ ULONG InitFlags; /* internal status to treggier re-initialization */
+
+ /* Memory allocation info. */
+ INT nMaxAacElements;
+ INT nMaxAacChannels;
+ INT nMaxSbrElements;
+ INT nMaxSbrChannels;
+
+ UINT encoder_modis;
+
+ /* Capability flags */
+ UINT CAPF_tpEnc;
+};
+
+typedef struct {
+ /* input */
+ ULONG nChannels; /*!< Number of audio channels. */
+ ULONG samplingRate; /*!< Encoder output sampling rate. */
+ ULONG bitrateRange; /*!< Lower bitrate range for config entry. */
+
+ /* output*/
+ UCHAR sbrMode; /*!< 0: ELD sbr off,
+ 1: ELD with downsampled sbr,
+ 2: ELD with dualrate sbr. */
+ CHANNEL_MODE chMode; /*!< Channel mode. */
+
+} ELD_SBR_CONFIGURATOR;
+
+/**
+ * \brief This table defines ELD/SBR default configurations.
+ */
+static const ELD_SBR_CONFIGURATOR eldSbrAutoConfigTab[] = {
+ {1, 48000, 0, 2, MODE_1}, {1, 48000, 64000, 0, MODE_1},
+
+ {1, 44100, 0, 2, MODE_1}, {1, 44100, 64000, 0, MODE_1},
+
+ {1, 32000, 0, 2, MODE_1}, {1, 32000, 28000, 1, MODE_1},
+ {1, 32000, 56000, 0, MODE_1},
+
+ {1, 24000, 0, 1, MODE_1}, {1, 24000, 40000, 0, MODE_1},
+
+ {1, 16000, 0, 1, MODE_1}, {1, 16000, 28000, 0, MODE_1},
+
+ {1, 15999, 0, 0, MODE_1},
+
+ {2, 48000, 0, 2, MODE_2}, {2, 48000, 44000, 2, MODE_2},
+ {2, 48000, 128000, 0, MODE_2},
+
+ {2, 44100, 0, 2, MODE_2}, {2, 44100, 44000, 2, MODE_2},
+ {2, 44100, 128000, 0, MODE_2},
+
+ {2, 32000, 0, 2, MODE_2}, {2, 32000, 32000, 2, MODE_2},
+ {2, 32000, 68000, 1, MODE_2}, {2, 32000, 96000, 0, MODE_2},
+
+ {2, 24000, 0, 1, MODE_2}, {2, 24000, 48000, 1, MODE_2},
+ {2, 24000, 80000, 0, MODE_2},
+
+ {2, 16000, 0, 1, MODE_2}, {2, 16000, 32000, 1, MODE_2},
+ {2, 16000, 64000, 0, MODE_2},
+
+ {2, 15999, 0, 0, MODE_2}
+
+};
+
+/*
+ * \brief Configure SBR for ELD configuration.
+ *
+ * This function finds default SBR configuration for ELD based on number of
+ * channels, sampling rate and bitrate.
+ *
+ * \param nChannels Number of audio channels.
+ * \param samplingRate Audio signal sampling rate.
+ * \param bitrate Encoder bitrate.
+ *
+ * \return - pointer to eld sbr configuration.
+ * - NULL, on failure.
+ */
+static const ELD_SBR_CONFIGURATOR *eldSbrConfigurator(const ULONG nChannels,
+ const ULONG samplingRate,
+ const ULONG bitrate) {
+ int i;
+ const ELD_SBR_CONFIGURATOR *pSetup = NULL;
+
+ for (i = 0;
+ i < (int)(sizeof(eldSbrAutoConfigTab) / sizeof(ELD_SBR_CONFIGURATOR));
+ i++) {
+ if ((nChannels == eldSbrAutoConfigTab[i].nChannels) &&
+ (samplingRate <= eldSbrAutoConfigTab[i].samplingRate) &&
+ (bitrate >= eldSbrAutoConfigTab[i].bitrateRange)) {
+ pSetup = &eldSbrAutoConfigTab[i];
+ }
+ }
+
+ return pSetup;
+}
+
+static inline INT isSbrActive(const HANDLE_AACENC_CONFIG hAacConfig) {
+ INT sbrUsed = 0;
+
+ /* Note: Even if implicit signalling was selected, The AOT itself here is not
+ * AOT_AAC_LC */
+ if ((hAacConfig->audioObjectType == AOT_SBR) ||
+ (hAacConfig->audioObjectType == AOT_PS) ||
+ (hAacConfig->audioObjectType == AOT_MP2_SBR) ||
+ (hAacConfig->audioObjectType == AOT_DABPLUS_SBR) ||
+ (hAacConfig->audioObjectType == AOT_DABPLUS_PS)) {
+ sbrUsed = 1;
+ }
+ if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD &&
+ (hAacConfig->syntaxFlags & AC_SBR_PRESENT)) {
+ sbrUsed = 1;
+ }
+
+ return (sbrUsed);
+}
+
+static inline INT isPsActive(const AUDIO_OBJECT_TYPE audioObjectType) {
+ INT psUsed = 0;
+
+ if ((audioObjectType == AOT_PS) ||
+ (audioObjectType == AOT_DABPLUS_PS)) {
+ psUsed = 1;
+ }
+
+ return (psUsed);
+}
+
+static CHANNEL_MODE GetCoreChannelMode(
+ const CHANNEL_MODE channelMode, const AUDIO_OBJECT_TYPE audioObjectType) {
+ CHANNEL_MODE mappedChannelMode = channelMode;
+ if ((isPsActive(audioObjectType) && (channelMode == MODE_2)) ||
+ (channelMode == MODE_212)) {
+ mappedChannelMode = MODE_1;
+ }
+ return mappedChannelMode;
+}
+
+static SBR_PS_SIGNALING getSbrSignalingMode(
+ const AUDIO_OBJECT_TYPE audioObjectType, const TRANSPORT_TYPE transportType,
+ const UCHAR transportSignaling, const UINT sbrRatio)
+
+{
+ SBR_PS_SIGNALING sbrSignaling;
+
+ if (transportType == TT_UNKNOWN || sbrRatio == 0) {
+ sbrSignaling = SIG_UNKNOWN; /* Needed parameters have not been set */
+ return sbrSignaling;
+ } else {
+ sbrSignaling =
+ SIG_EXPLICIT_HIERARCHICAL; /* default: explicit hierarchical signaling
+ */
+ }
+
+ if ((audioObjectType == AOT_AAC_LC) || (audioObjectType == AOT_SBR) ||
+ (audioObjectType == AOT_PS) || (audioObjectType == AOT_MP2_AAC_LC) ||
+ (audioObjectType == AOT_MP2_SBR) ||
+ (audioObjectType == AOT_DABPLUS_SBR) ||
+ (audioObjectType == AOT_DABPLUS_PS)) {
+ switch (transportType) {
+ case TT_MP4_ADIF:
+ case TT_MP4_ADTS:
+ sbrSignaling = SIG_IMPLICIT; /* For MPEG-2 transport types, only
+ implicit signaling is possible */
+ break;
+
+ case TT_MP4_RAW:
+ case TT_MP4_LATM_MCP1:
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LOAS:
+ default:
+ if (transportSignaling == 0xFF) {
+ /* Defaults */
+ sbrSignaling = SIG_EXPLICIT_HIERARCHICAL;
+ } else {
+ /* User set parameters */
+ /* Attention: Backward compatible explicit signaling does only work
+ * with AMV1 for LATM/LOAS */
+ sbrSignaling = (SBR_PS_SIGNALING)transportSignaling;
+ }
+ break;
+ }
+ }
+
+ return sbrSignaling;
+}
+
+/****************************************************************************
+ Allocate Encoder
+****************************************************************************/
+
+H_ALLOC_MEM(_AacEncoder, AACENCODER)
+C_ALLOC_MEM(_AacEncoder, struct AACENCODER, 1)
+
+/*
+ * Map Encoder specific config structures to CODER_CONFIG.
+ */
+static void FDKaacEnc_MapConfig(CODER_CONFIG *const cc,
+ const USER_PARAM *const extCfg,
+ const SBR_PS_SIGNALING sbrSignaling,
+ const HANDLE_AACENC_CONFIG hAacConfig) {
+ AUDIO_OBJECT_TYPE transport_AOT = AOT_NULL_OBJECT;
+ FDKmemclear(cc, sizeof(CODER_CONFIG));
+
+ cc->flags = 0;
+
+ cc->samplesPerFrame = hAacConfig->framelength;
+ cc->samplingRate = hAacConfig->sampleRate;
+ cc->extSamplingRate = extCfg->userSamplerate;
+
+ /* Map virtual aot to transport aot. */
+ switch (hAacConfig->audioObjectType) {
+ case AOT_MP2_AAC_LC:
+ case AOT_DABPLUS_AAC_LC:
+ transport_AOT = AOT_AAC_LC;
+ break;
+ case AOT_MP2_SBR:
+ case AOT_DABPLUS_SBR:
+ transport_AOT = AOT_SBR;
+ cc->flags |= CC_SBR;
+ break;
+ case AOT_DABPLUS_PS:
+ transport_AOT = AOT_PS;
+ cc->flags |= CC_SBR;
+ break;
+ default:
+ transport_AOT = hAacConfig->audioObjectType;
+ }
+
+ if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) {
+ cc->flags |= (hAacConfig->syntaxFlags & AC_SBR_PRESENT) ? CC_SBR : 0;
+ cc->flags |= (hAacConfig->syntaxFlags & AC_LD_MPS) ? CC_SAC : 0;
+ }
+
+ /* transport type is usually AAC-LC. */
+ if ((transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS)) {
+ cc->aot = AOT_AAC_LC;
+ } else {
+ cc->aot = transport_AOT;
+ }
+
+ /* Configure extension aot. */
+ if (sbrSignaling == SIG_IMPLICIT) {
+ cc->extAOT = AOT_NULL_OBJECT; /* implicit */
+ } else {
+ if ((sbrSignaling == SIG_EXPLICIT_BW_COMPATIBLE) &&
+ ((transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS))) {
+ cc->extAOT = AOT_SBR; /* explicit backward compatible */
+ } else {
+ cc->extAOT = transport_AOT; /* explicit hierarchical */
+ }
+ }
+
+ if ((transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS)) {
+ cc->sbrPresent = 1;
+ if (transport_AOT == AOT_PS) {
+ cc->psPresent = 1;
+ }
+ }
+ cc->sbrSignaling = sbrSignaling;
+
+ if (hAacConfig->downscaleFactor > 1) {
+ cc->downscaleSamplingRate = cc->samplingRate;
+ cc->samplingRate *= hAacConfig->downscaleFactor;
+ cc->extSamplingRate *= hAacConfig->downscaleFactor;
+ }
+
+ cc->bitRate = hAacConfig->bitRate;
+ cc->noChannels = hAacConfig->nChannels;
+ cc->flags |= CC_IS_BASELAYER;
+ cc->channelMode = hAacConfig->channelMode;
+
+if (extCfg->userTpType == TT_DABPLUS && hAacConfig->nSubFrames==1) {
+ switch(hAacConfig->sampleRate) {
+ case 48000:
+ cc->nSubFrames=6;
+ break;
+ case 32000:
+ cc->nSubFrames=4;
+ break;
+ case 24000:
+ cc->nSubFrames=3;
+ break;
+ case 16000:
+ cc->nSubFrames=2;
+ break;
+ }
+ //fprintf(stderr, "hAacConfig->nSubFrames=%d hAacConfig->sampleRate=%d\n", hAacConfig->nSubFrames, hAacConfig->sampleRate);
+ } else {
+ cc->nSubFrames = (hAacConfig->nSubFrames > 1 && extCfg->userTpNsubFrames == 1)
+ ? hAacConfig->nSubFrames
+ : extCfg->userTpNsubFrames;
+ }
+
+ cc->flags |= (extCfg->userTpProtection) ? CC_PROTECTION : 0;
+
+ if (extCfg->userTpHeaderPeriod != 0xFF) {
+ cc->headerPeriod = extCfg->userTpHeaderPeriod;
+ } else { /* auto-mode */
+ switch (extCfg->userTpType) {
+ case TT_MP4_ADTS:
+ case TT_MP4_LOAS:
+ case TT_MP4_LATM_MCP1:
+ cc->headerPeriod = DEFAULT_HEADER_PERIOD_REPETITION_RATE;
+ break;
+ default:
+ cc->headerPeriod = 0;
+ }
+ }
+
+ /* Mpeg-4 signaling for transport library. */
+ switch (hAacConfig->audioObjectType) {
+ case AOT_MP2_AAC_LC:
+ case AOT_MP2_SBR:
+ cc->flags &= ~CC_MPEG_ID; /* Required for ADTS. */
+ cc->extAOT = AOT_NULL_OBJECT;
+ break;
+ default:
+ cc->flags |= CC_MPEG_ID;
+ }
+
+ /* ER-tools signaling. */
+ cc->flags |= (hAacConfig->syntaxFlags & AC_ER_VCB11) ? CC_VCB11 : 0;
+ cc->flags |= (hAacConfig->syntaxFlags & AC_ER_HCR) ? CC_HCR : 0;
+ cc->flags |= (hAacConfig->syntaxFlags & AC_ER_RVLC) ? CC_RVLC : 0;
+
+ /* Matrix mixdown coefficient configuration. */
+ if ((extCfg->userPceAdditions & 0x1) && (hAacConfig->epConfig == -1) &&
+ ((cc->channelMode == MODE_1_2_2) || (cc->channelMode == MODE_1_2_2_1))) {
+ cc->matrixMixdownA = ((extCfg->userPceAdditions >> 1) & 0x3) + 1;
+ cc->flags |= (extCfg->userPceAdditions >> 3) & 0x1 ? CC_PSEUDO_SURROUND : 0;
+ } else {
+ cc->matrixMixdownA = 0;
+ }
+
+ cc->channelConfigZero = 0;
+}
+
+/*
+ * Validate prefilled pointers within buffer descriptor.
+ *
+ * \param pBufDesc Pointer to buffer descriptor
+
+ * \return - AACENC_OK, all fine.
+ * - AACENC_INVALID_HANDLE, on missing pointer initializiation.
+ * - AACENC_UNSUPPORTED_PARAMETER, on incorrect buffer descriptor
+ initialization.
+ */
+static AACENC_ERROR validateBufDesc(const AACENC_BufDesc *pBufDesc) {
+ AACENC_ERROR err = AACENC_OK;
+
+ if (pBufDesc != NULL) {
+ int i;
+ if ((pBufDesc->bufferIdentifiers == NULL) || (pBufDesc->bufSizes == NULL) ||
+ (pBufDesc->bufElSizes == NULL) || (pBufDesc->bufs == NULL)) {
+ err = AACENC_UNSUPPORTED_PARAMETER;
+ goto bail;
+ }
+ for (i = 0; i < pBufDesc->numBufs; i++) {
+ if (pBufDesc->bufs[i] == NULL) {
+ err = AACENC_UNSUPPORTED_PARAMETER;
+ goto bail;
+ }
+ }
+ } else {
+ err = AACENC_INVALID_HANDLE;
+ }
+bail:
+ return err;
+}
+
+/*
+ * Examine buffer descriptor regarding choosen identifier.
+ *
+ * \param pBufDesc Pointer to buffer descriptor
+ * \param identifier Buffer identifier to look for.
+
+ * \return - Buffer descriptor index.
+ * -1, if there is no entry available.
+ */
+static INT getBufDescIdx(const AACENC_BufDesc *pBufDesc,
+ const AACENC_BufferIdentifier identifier) {
+ INT i, idx = -1;
+
+ if (pBufDesc != NULL) {
+ for (i = 0; i < pBufDesc->numBufs; i++) {
+ if ((AACENC_BufferIdentifier)pBufDesc->bufferIdentifiers[i] ==
+ identifier) {
+ idx = i;
+ break;
+ }
+ }
+ }
+ return idx;
+}
+
+/****************************************************************************
+ Function Declarations
+****************************************************************************/
+
+AAC_ENCODER_ERROR aacEncDefaultConfig(HANDLE_AACENC_CONFIG hAacConfig,
+ USER_PARAM *config) {
+ /* make reasonable default settings */
+ FDKaacEnc_AacInitDefaultConfig(hAacConfig);
+
+ /* clear configuration structure and copy default settings */
+ FDKmemclear(config, sizeof(USER_PARAM));
+
+ /* copy encoder configuration settings */
+ config->nChannels = hAacConfig->nChannels;
+ config->userAOT = hAacConfig->audioObjectType = AOT_AAC_LC;
+ config->userSamplerate = hAacConfig->sampleRate;
+ config->userChannelMode = hAacConfig->channelMode;
+ config->userBitrate = hAacConfig->bitRate;
+ config->userBitrateMode = hAacConfig->bitrateMode;
+ config->userPeakBitrate = (UINT)-1;
+ config->userBandwidth = hAacConfig->bandWidth;
+ config->userTns = hAacConfig->useTns;
+ config->userPns = hAacConfig->usePns;
+ config->userIntensity = hAacConfig->useIS;
+ config->userAfterburner = hAacConfig->useRequant;
+ config->userFramelength = (UINT)-1;
+
+ config->userDownscaleFactor = 1;
+
+ /* initialize transport parameters */
+ config->userTpType = TT_UNKNOWN;
+ config->userTpAmxv = 0;
+ config->userTpSignaling = 0xFF; /* choose signaling automatically */
+ config->userTpNsubFrames = 1;
+ config->userTpProtection = 0; /* not crc protected*/
+ config->userTpHeaderPeriod = 0xFF; /* header period in auto mode */
+ config->userPceAdditions = 0; /* no matrix mixdown coefficient */
+ config->userMetaDataMode = 0; /* do not embed any meta data info */
+
+ config->userAncDataRate = 0;
+
+ /* SBR rate is set to 0 here, which means it should be set automatically
+ in FDKaacEnc_AdjustEncSettings() if the user did not set a rate
+ expilicitely. */
+ config->userSbrRatio = 0;
+
+ /* SBR enable set to -1 means to inquire ELD audio configurator for reasonable
+ * configuration. */
+ config->userSbrEnabled = (UCHAR)-1;
+
+ return AAC_ENC_OK;
+}
+
+static void aacEncDistributeSbrBits(CHANNEL_MAPPING *channelMapping,
+ SBR_ELEMENT_INFO *sbrElInfo, INT bitRate) {
+ INT codebits = bitRate;
+ int el;
+
+ /* Copy Element info */
+ for (el = 0; el < channelMapping->nElements; el++) {
+ sbrElInfo[el].ChannelIndex[0] = channelMapping->elInfo[el].ChannelIndex[0];
+ sbrElInfo[el].ChannelIndex[1] = channelMapping->elInfo[el].ChannelIndex[1];
+ sbrElInfo[el].elType = channelMapping->elInfo[el].elType;
+ sbrElInfo[el].bitRate =
+ fMultIfloor(channelMapping->elInfo[el].relativeBits, bitRate);
+ sbrElInfo[el].instanceTag = channelMapping->elInfo[el].instanceTag;
+ sbrElInfo[el].nChannelsInEl = channelMapping->elInfo[el].nChannelsInEl;
+ sbrElInfo[el].fParametricStereo = 0;
+ sbrElInfo[el].fDualMono = 0;
+
+ codebits -= sbrElInfo[el].bitRate;
+ }
+ sbrElInfo[0].bitRate += codebits;
+}
+
+static INT aacEncoder_LimitBitrate(const HANDLE_TRANSPORTENC hTpEnc,
+ const INT samplingRate,
+ const INT frameLength, const INT nChannels,
+ const CHANNEL_MODE channelMode, INT bitRate,
+ const INT nSubFrames, const INT sbrActive,
+ const INT sbrDownSampleRate,
+ const UINT syntaxFlags,
+ const AUDIO_OBJECT_TYPE aot) {
+ INT coreSamplingRate;
+ CHANNEL_MAPPING cm;
+
+ FDKaacEnc_InitChannelMapping(channelMode, CH_ORDER_MPEG, &cm);
+
+ if (sbrActive) {
+ coreSamplingRate =
+ samplingRate >>
+ (sbrEncoder_IsSingleRatePossible(aot) ? (sbrDownSampleRate - 1) : 1);
+ } else {
+ coreSamplingRate = samplingRate;
+ }
+
+ /* Limit bit rate in respect to the core coder */
+ bitRate = FDKaacEnc_LimitBitrate(hTpEnc, aot, coreSamplingRate, frameLength,
+ nChannels, cm.nChannelsEff, bitRate, -1,
+ NULL, AACENC_BR_MODE_INVALID, nSubFrames);
+
+ /* Limit bit rate in respect to available SBR modes if active */
+ if (sbrActive) {
+ int numIterations = 0;
+ INT initialBitrate, adjustedBitrate;
+ adjustedBitrate = bitRate;
+
+ /* Find total bitrate which provides valid configuration for each SBR
+ * element. */
+ do {
+ int e;
+ SBR_ELEMENT_INFO sbrElInfo[((8))];
+ FDK_ASSERT(cm.nElements <= ((8)));
+
+ initialBitrate = adjustedBitrate;
+
+ /* Get bit rate for each SBR element */
+ aacEncDistributeSbrBits(&cm, sbrElInfo, initialBitrate);
+
+ for (e = 0; e < cm.nElements; e++) {
+ INT sbrElementBitRateIn, sbrBitRateOut;
+
+ if (cm.elInfo[e].elType != ID_SCE && cm.elInfo[e].elType != ID_CPE) {
+ continue;
+ }
+ sbrElementBitRateIn = sbrElInfo[e].bitRate;
+
+ sbrBitRateOut = sbrEncoder_LimitBitRate(sbrElementBitRateIn,
+ cm.elInfo[e].nChannelsInEl,
+ coreSamplingRate, aot);
+
+ if (sbrBitRateOut == 0) {
+ return 0;
+ }
+
+ /* If bitrates don't match, distribution and limiting needs to be
+ determined again. Abort element loop and restart with adapted
+ bitrate. */
+ if (sbrElementBitRateIn != sbrBitRateOut) {
+ if (sbrElementBitRateIn < sbrBitRateOut) {
+ adjustedBitrate = fMax(initialBitrate,
+ (INT)fDivNorm((FIXP_DBL)(sbrBitRateOut + 8),
+ cm.elInfo[e].relativeBits));
+ break;
+ }
+
+ if (sbrElementBitRateIn > sbrBitRateOut) {
+ adjustedBitrate = fMin(initialBitrate,
+ (INT)fDivNorm((FIXP_DBL)(sbrBitRateOut - 8),
+ cm.elInfo[e].relativeBits));
+ break;
+ }
+
+ } /* sbrElementBitRateIn != sbrBitRateOut */
+
+ } /* elements */
+
+ numIterations++; /* restrict iteration to worst case of num elements */
+
+ } while ((initialBitrate != adjustedBitrate) &&
+ (numIterations <= cm.nElements));
+
+ /* Unequal bitrates mean that no reasonable bitrate configuration found. */
+ bitRate = (initialBitrate == adjustedBitrate) ? adjustedBitrate : 0;
+ }
+
+ /* Limit bit rate in respect to available MPS modes if active */
+ if ((aot == AOT_ER_AAC_ELD) && (syntaxFlags & AC_LD_MPS) &&
+ (channelMode == MODE_1)) {
+ bitRate = FDK_MpegsEnc_GetClosestBitRate(
+ aot, MODE_212, samplingRate, (sbrActive) ? sbrDownSampleRate : 0,
+ bitRate);
+ }
+
+ //fprintf(stderr, "aacEncoder_LimitBitrate(): bitRate=%d\n", bitRate);
+ return bitRate;
+}
+
+/*
+ * \brief Get CBR bitrate
+ *
+ * \hAacConfig Internal encoder config
+ * \return Bitrate
+ */
+static INT FDKaacEnc_GetCBRBitrate(const HANDLE_AACENC_CONFIG hAacConfig,
+ const INT userSbrRatio) {
+ INT bitrate = FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)
+ ->nChannelsEff *
+ hAacConfig->sampleRate;
+
+ if (isPsActive(hAacConfig->audioObjectType)) {
+ bitrate = 1 * bitrate; /* 0.5 bit per sample */
+ } else if (isSbrActive(hAacConfig)) {
+ if ((userSbrRatio == 2) ||
+ ((userSbrRatio == 0) &&
+ (hAacConfig->audioObjectType != AOT_ER_AAC_ELD))) {
+ bitrate = (bitrate + (bitrate >> 2)) >> 1; /* 0.625 bits per sample */
+ }
+ if ((userSbrRatio == 1) ||
+ ((userSbrRatio == 0) &&
+ (hAacConfig->audioObjectType == AOT_ER_AAC_ELD))) {
+ bitrate = (bitrate + (bitrate >> 3)); /* 1.125 bits per sample */
+ }
+ } else {
+ bitrate = bitrate + (bitrate >> 1); /* 1.5 bits per sample */
+ }
+
+ return bitrate;
+}
+
+/*
+ * \brief Consistency check of given USER_PARAM struct and
+ * copy back configuration from public struct into internal
+ * encoder configuration struct.
+ *
+ * \hAacEncoder Internal encoder config which is to be updated
+ * \param config User provided config (public struct)
+ * \return returns always AAC_ENC_OK
+ */
+static AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
+ USER_PARAM *config) {
+ AACENC_ERROR err = AACENC_OK;
+
+ /* Get struct pointers. */
+ HANDLE_AACENC_CONFIG hAacConfig = &hAacEncoder->aacConfig;
+
+ /* Encoder settings update. */
+ hAacConfig->sampleRate = config->userSamplerate;
+ if (config->userDownscaleFactor > 1) {
+ hAacConfig->useTns = 0;
+ hAacConfig->usePns = 0;
+ hAacConfig->useIS = 0;
+ } else {
+ hAacConfig->useTns = config->userTns;
+ hAacConfig->usePns = config->userPns;
+ hAacConfig->useIS = config->userIntensity;
+ }
+
+ hAacConfig->audioObjectType = config->userAOT;
+ hAacConfig->channelMode =
+ GetCoreChannelMode(config->userChannelMode, hAacConfig->audioObjectType);
+ hAacConfig->nChannels =
+ FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)->nChannels;
+ hAacConfig->bitrateMode = (AACENC_BITRATE_MODE)config->userBitrateMode;
+ hAacConfig->bandWidth = config->userBandwidth;
+ hAacConfig->useRequant = config->userAfterburner;
+
+ hAacConfig->anc_Rate = config->userAncDataRate;
+ hAacConfig->syntaxFlags = 0;
+ hAacConfig->epConfig = -1;
+
+ if (hAacConfig->audioObjectType != AOT_ER_AAC_ELD &&
+ config->userDownscaleFactor > 1) {
+ return AACENC_INVALID_CONFIG; /* downscaling only allowed for AOT_ER_AAC_ELD
+ */
+ }
+ if (config->userDownscaleFactor > 1 && config->userSbrEnabled == 1) {
+ return AACENC_INVALID_CONFIG; /* downscaling only allowed for AOT_ER_AAC_ELD
+ w/o SBR */
+ }
+ if (config->userDownscaleFactor > 1 && config->userChannelMode == 128) {
+ return AACENC_INVALID_CONFIG; /* disallow downscaling for AAC-ELDv2 */
+ }
+
+ if (config->userTpType == TT_MP4_LATM_MCP1 ||
+ config->userTpType == TT_MP4_LATM_MCP0 ||
+ config->userTpType == TT_MP4_LOAS) {
+ hAacConfig->audioMuxVersion = config->userTpAmxv;
+ } else {
+ hAacConfig->audioMuxVersion = -1;
+ }
+
+ /* Adapt internal AOT when necessary. */
+ switch (config->userAOT) {
+ case AOT_MP2_AAC_LC:
+ case AOT_MP2_SBR:
+ hAacConfig->usePns = 0;
+ FDK_FALLTHROUGH;
+ case AOT_AAC_LC:
+ case AOT_SBR:
+ case AOT_PS:
+ config->userTpType =
+ (config->userTpType != TT_UNKNOWN) ? config->userTpType : TT_MP4_ADTS;
+ hAacConfig->framelength = (config->userFramelength != (UINT)-1)
+ ? config->userFramelength
+ : 1024;
+ if (hAacConfig->framelength != 1024 && hAacConfig->framelength != 960) {
+ return AACENC_INVALID_CONFIG;
+ }
+ break;
+
+ case AOT_DABPLUS_SBR:
+ case AOT_DABPLUS_PS:
+ hAacConfig->syntaxFlags |= ((config->userSbrEnabled) ? AC_SBR_PRESENT : 0);
+ case AOT_DABPLUS_AAC_LC:
+ config->userTpType = (config->userTpType!=TT_UNKNOWN) ? config->userTpType : TT_DABPLUS;
+ hAacConfig->framelength = (config->userFramelength!=(UINT)-1) ? config->userFramelength : 960;
+ if (hAacConfig->framelength != 960) {
+ return AACENC_INVALID_CONFIG;
+ }
+ config->userTpSignaling=2;
+ if(config->userTpType == TT_DABPLUS)
+ hAacConfig->syntaxFlags |= AC_DAB;
+ break;
+
+ case AOT_ER_AAC_LD:
+ hAacConfig->epConfig = 0;
+ hAacConfig->syntaxFlags |= AC_ER | AC_LD;
+ hAacConfig->syntaxFlags |=
+ ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0);
+ hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0);
+ hAacConfig->syntaxFlags |= ((config->userErTools & 0x4) ? AC_ER_RVLC : 0);
+ config->userTpType =
+ (config->userTpType != TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS;
+ hAacConfig->framelength =
+ (config->userFramelength != (UINT)-1) ? config->userFramelength : 512;
+ if (hAacConfig->framelength != 512 && hAacConfig->framelength != 480) {
+ return AACENC_INVALID_CONFIG;
+ }
+ break;
+ case AOT_ER_AAC_ELD:
+ hAacConfig->epConfig = 0;
+ hAacConfig->syntaxFlags |= AC_ER | AC_ELD;
+ hAacConfig->syntaxFlags |=
+ ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0);
+ hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0);
+ hAacConfig->syntaxFlags |= ((config->userErTools & 0x4) ? AC_ER_RVLC : 0);
+ hAacConfig->syntaxFlags |=
+ ((config->userSbrEnabled == 1) ? AC_SBR_PRESENT : 0);
+ hAacConfig->syntaxFlags |=
+ ((config->userChannelMode == MODE_212) ? AC_LD_MPS : 0);
+ config->userTpType =
+ (config->userTpType != TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS;
+ hAacConfig->framelength =
+ (config->userFramelength != (UINT)-1) ? config->userFramelength : 512;
+
+ hAacConfig->downscaleFactor = config->userDownscaleFactor;
+
+ switch (config->userDownscaleFactor) {
+ case 1:
+ break;
+ case 2:
+ case 4:
+ hAacConfig->syntaxFlags |= AC_ELD_DOWNSCALE;
+ break;
+ default:
+ return AACENC_INVALID_CONFIG;
+ }
+
+ if (hAacConfig->framelength != 512 && hAacConfig->framelength != 480 &&
+ hAacConfig->framelength != 256 && hAacConfig->framelength != 240 &&
+ hAacConfig->framelength != 128 && hAacConfig->framelength != 120) {
+ return AACENC_INVALID_CONFIG;
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* Initialize SBR parameters */
+ if ((config->userSbrRatio == 0) && (isSbrActive(hAacConfig))) {
+ /* Automatic SBR ratio configuration
+ * - downsampled SBR for ELD
+ * - otherwise always dualrate SBR
+ */
+ if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) {
+ hAacConfig->sbrRatio = ((hAacConfig->syntaxFlags & AC_LD_MPS) &&
+ (hAacConfig->sampleRate >= 27713))
+ ? 2
+ : 1;
+ } else {
+ hAacConfig->sbrRatio = 2;
+ }
+ } else {
+ /* SBR ratio has been set by the user, so use it. */
+ hAacConfig->sbrRatio = isSbrActive(hAacConfig) ? config->userSbrRatio : 0;
+ }
+
+ /* Set default bitrate */
+ hAacConfig->bitRate = config->userBitrate;
+
+ switch (hAacConfig->bitrateMode) {
+ case AACENC_BR_MODE_CBR:
+ /* Set default bitrate if no external bitrate declared. */
+ if (config->userBitrate == (UINT)-1) {
+ hAacConfig->bitRate =
+ FDKaacEnc_GetCBRBitrate(hAacConfig, config->userSbrRatio);
+ }
+ hAacConfig->averageBits = -1;
+ break;
+ case AACENC_BR_MODE_VBR_1:
+ case AACENC_BR_MODE_VBR_2:
+ case AACENC_BR_MODE_VBR_3:
+ case AACENC_BR_MODE_VBR_4:
+ case AACENC_BR_MODE_VBR_5:
+ /* Get bitrate in VBR configuration */
+ /* In VBR mode; SBR-modul depends on bitrate, core encoder on bitrateMode.
+ */
+ hAacConfig->bitRate = FDKaacEnc_GetVBRBitrate(hAacConfig->bitrateMode,
+ hAacConfig->channelMode);
+ break;
+ default:
+ return AACENC_INVALID_CONFIG;
+ }
+
+ /* set bitreservoir size */
+ switch (hAacConfig->bitrateMode) {
+ case AACENC_BR_MODE_VBR_1:
+ case AACENC_BR_MODE_VBR_2:
+ case AACENC_BR_MODE_VBR_3:
+ case AACENC_BR_MODE_VBR_4:
+ case AACENC_BR_MODE_VBR_5:
+ case AACENC_BR_MODE_CBR:
+ if ((INT)config->userPeakBitrate != -1) {
+ hAacConfig->maxBitsPerFrame =
+ (FDKaacEnc_CalcBitsPerFrame(
+ fMax(hAacConfig->bitRate, (INT)config->userPeakBitrate),
+ hAacConfig->framelength, hAacConfig->sampleRate) +
+ 7) &
+ ~7;
+ } else {
+ hAacConfig->maxBitsPerFrame = -1;
+ }
+ if (hAacConfig->audioMuxVersion == 2) {
+ hAacConfig->minBitsPerFrame =
+ fMin(32 * 8, FDKaacEnc_CalcBitsPerFrame(hAacConfig->bitRate,
+ hAacConfig->framelength,
+ hAacConfig->sampleRate)) &
+ ~7;
+ }
+ break;
+ default:
+ return AACENC_INVALID_CONFIG;
+ }
+
+ /* Max bits per frame limitation depending on transport format. */
+ if ((config->userTpNsubFrames > 1)) {
+ int maxFrameLength = 8 * hAacEncoder->outBufferInBytes;
+ switch (config->userTpType) {
+ case TT_MP4_LOAS:
+ maxFrameLength =
+ fMin(maxFrameLength, 8 * (1 << 13)) / config->userTpNsubFrames;
+ break;
+ case TT_MP4_ADTS:
+ maxFrameLength = fMin(maxFrameLength, 8 * ((1 << 13) - 1)) /
+ config->userTpNsubFrames;
+ break;
+ default:
+ maxFrameLength = -1;
+ }
+ if (maxFrameLength != -1) {
+ if (hAacConfig->maxBitsPerFrame > maxFrameLength) {
+ return AACENC_INVALID_CONFIG;
+ } else if (hAacConfig->maxBitsPerFrame == -1) {
+ hAacConfig->maxBitsPerFrame = maxFrameLength;
+ }
+ }
+ }
+
+ if ((hAacConfig->audioObjectType == AOT_ER_AAC_ELD) &&
+ !(hAacConfig->syntaxFlags & AC_ELD_DOWNSCALE) &&
+ (config->userSbrEnabled == (UCHAR)-1) && (config->userSbrRatio == 0) &&
+ ((hAacConfig->syntaxFlags & AC_LD_MPS) == 0)) {
+ const ELD_SBR_CONFIGURATOR *pConfig = NULL;
+
+ if (NULL !=
+ (pConfig = eldSbrConfigurator(
+ FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)
+ ->nChannels,
+ hAacConfig->sampleRate, hAacConfig->bitRate))) {
+ hAacConfig->syntaxFlags |= (pConfig->sbrMode == 0) ? 0 : AC_SBR_PRESENT;
+ hAacConfig->syntaxFlags |= (pConfig->chMode == MODE_212) ? AC_LD_MPS : 0;
+ hAacConfig->channelMode =
+ GetCoreChannelMode(pConfig->chMode, hAacConfig->audioObjectType);
+ hAacConfig->nChannels =
+ FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)
+ ->nChannels;
+ hAacConfig->sbrRatio =
+ (pConfig->sbrMode == 0) ? 0 : (pConfig->sbrMode == 1) ? 1 : 2;
+ }
+ }
+
+ {
+ UCHAR tpSignaling =
+ getSbrSignalingMode(hAacConfig->audioObjectType, config->userTpType,
+ config->userTpSignaling, hAacConfig->sbrRatio);
+
+ if ((hAacConfig->audioObjectType == AOT_AAC_LC ||
+ hAacConfig->audioObjectType == AOT_SBR ||
+ hAacConfig->audioObjectType == AOT_PS) &&
+ (config->userTpType == TT_MP4_LATM_MCP1 ||
+ config->userTpType == TT_MP4_LATM_MCP0 ||
+ config->userTpType == TT_MP4_LOAS) &&
+ (tpSignaling == 1) && (config->userTpAmxv == 0)) {
+ /* For backward compatible explicit signaling, AMV1 has to be active */
+ return AACENC_INVALID_CONFIG;
+ }
+
+ if ((hAacConfig->audioObjectType == AOT_AAC_LC ||
+ hAacConfig->audioObjectType == AOT_SBR ||
+ hAacConfig->audioObjectType == AOT_PS) &&
+ (tpSignaling == 0) && (hAacConfig->sbrRatio == 1)) {
+ /* Downsampled SBR has to be signaled explicitely (for transmission of SBR
+ * sampling fequency) */
+ return AACENC_INVALID_CONFIG;
+ }
+ }
+
+ switch (hAacConfig->bitrateMode) {
+ case AACENC_BR_MODE_CBR:
+ case AACENC_BR_MODE_VBR_1:
+ case AACENC_BR_MODE_VBR_2:
+ case AACENC_BR_MODE_VBR_3:
+ case AACENC_BR_MODE_VBR_4:
+ case AACENC_BR_MODE_VBR_5:
+ /* We need the frame length to call aacEncoder_LimitBitrate() */
+ if (0 >= (hAacConfig->bitRate = aacEncoder_LimitBitrate(
+ NULL, hAacConfig->sampleRate, hAacConfig->framelength,
+ hAacConfig->nChannels, hAacConfig->channelMode,
+ hAacConfig->bitRate, hAacConfig->nSubFrames,
+ isSbrActive(hAacConfig), hAacConfig->sbrRatio,
+ hAacConfig->syntaxFlags, hAacConfig->audioObjectType))) {
+ return AACENC_INVALID_CONFIG;
+ }
+ break;
+ default:
+ break;
+ }
+
+#if 0 // TODO Is this still needed?
+ /* We need the frame length to call aacEncoder_LimitBitrate() */
+ hAacConfig->bitRate = aacEncoder_LimitBitrate(
+ NULL,
+ hAacConfig->sampleRate,
+ hAacConfig->framelength,
+ hAacConfig->nChannels,
+ hAacConfig->channelMode,
+ hAacConfig->bitRate,
+ hAacConfig->nSubFrames,
+ isSbrActive(hAacConfig),
+ hAacConfig->sbrRatio,
+ hAacConfig->audioObjectType
+ );
+#endif
+
+/* Configure PNS */
+ if (AACENC_BR_MODE_IS_VBR(hAacConfig->bitrateMode) /* VBR without PNS. */
+ || (hAacConfig->useTns == 0)) /* TNS required. */
+ {
+ hAacConfig->usePns = 0;
+ }
+
+ if (hAacConfig->epConfig >= 0) {
+ hAacConfig->syntaxFlags |= AC_ER;
+ if (((INT)hAacConfig->channelMode < 1) ||
+ ((INT)hAacConfig->channelMode > 14)) {
+ return AACENC_INVALID_CONFIG; /* Channel config 0 not supported. */
+ }
+ }
+
+ if ((hAacConfig->syntaxFlags & AC_LD_MPS) == 0) {
+ if (FDKaacEnc_DetermineEncoderMode(&hAacConfig->channelMode,
+ hAacConfig->nChannels) != AAC_ENC_OK) {
+ return AACENC_INVALID_CONFIG; /* nChannels doesn't match chMode, this is
+ just a check-up */
+ }
+ }
+
+ if ((hAacConfig->nChannels > hAacEncoder->nMaxAacChannels) ||
+ ((FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)
+ ->nChannelsEff > hAacEncoder->nMaxSbrChannels) &&
+ isSbrActive(hAacConfig))) {
+ return AACENC_INVALID_CONFIG; /* not enough channels allocated */
+ }
+
+ /* Meta data restriction. */
+ switch (hAacConfig->audioObjectType) {
+ /* Allow metadata support */
+ case AOT_AAC_LC:
+ case AOT_SBR:
+ case AOT_PS:
+ case AOT_MP2_AAC_LC:
+ case AOT_MP2_SBR:
+ hAacEncoder->metaDataAllowed = 1;
+ if (!((((INT)hAacConfig->channelMode >= 1) &&
+ ((INT)hAacConfig->channelMode <= 14)) ||
+ (MODE_7_1_REAR_SURROUND == hAacConfig->channelMode) ||
+ (MODE_7_1_FRONT_CENTER == hAacConfig->channelMode))) {
+ config->userMetaDataMode = 0;
+ }
+ break;
+ /* Prohibit metadata support */
+ default:
+ hAacEncoder->metaDataAllowed = 0;
+ }
+
+ return err;
+}
+
+static INT aacenc_SbrCallback(void *self, HANDLE_FDK_BITSTREAM hBs,
+ const INT sampleRateIn, const INT sampleRateOut,
+ const INT samplesPerFrame,
+ const AUDIO_OBJECT_TYPE coreCodec,
+ const MP4_ELEMENT_ID elementID,
+ const INT elementIndex, const UCHAR harmonicSbr,
+ const UCHAR stereoConfigIndex,
+ const UCHAR configMode, UCHAR *configChanged,
+ const INT downscaleFactor) {
+ HANDLE_AACENCODER hAacEncoder = (HANDLE_AACENCODER)self;
+
+ sbrEncoder_GetHeader(hAacEncoder->hEnvEnc, hBs, elementIndex, 0);
+
+ return 0;
+}
+
+INT aacenc_SscCallback(void *self, HANDLE_FDK_BITSTREAM hBs,
+ const AUDIO_OBJECT_TYPE coreCodec,
+ const INT samplingRate, const INT frameSize,
+ const INT stereoConfigIndex,
+ const INT coreSbrFrameLengthIndex, const INT configBytes,
+ const UCHAR configMode, UCHAR *configChanged) {
+ HANDLE_AACENCODER hAacEncoder = (HANDLE_AACENCODER)self;
+
+ return (FDK_MpegsEnc_WriteSpatialSpecificConfig(hAacEncoder->hMpsEnc, hBs));
+}
+
+static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, ULONG InitFlags,
+ USER_PARAM *config) {
+ AACENC_ERROR err = AACENC_OK;
+
+ INT aacBufferOffset = 0;
+ HANDLE_SBR_ENCODER *hSbrEncoder = &hAacEncoder->hEnvEnc;
+ HANDLE_AACENC_CONFIG hAacConfig = &hAacEncoder->aacConfig;
+
+ hAacEncoder->nZerosAppended = 0; /* count appended zeros */
+
+ INT frameLength = hAacConfig->framelength;
+
+ if ((InitFlags & AACENC_INIT_CONFIG)) {
+ CHANNEL_MODE prevChMode = hAacConfig->channelMode;
+
+ /* Verify settings and update: config -> heAacEncoder */
+ if ((err = FDKaacEnc_AdjustEncSettings(hAacEncoder, config)) != AACENC_OK) {
+ return err;
+ }
+ frameLength = hAacConfig->framelength; /* adapt temporal framelength */
+
+ /* Seamless channel reconfiguration in sbr not fully implemented */
+ if ((prevChMode != hAacConfig->channelMode) && isSbrActive(hAacConfig)) {
+ InitFlags |= AACENC_INIT_STATES;
+ }
+ }
+
+ /* Clear input buffer */
+ if (InitFlags == AACENC_INIT_ALL) {
+ FDKmemclear(hAacEncoder->inputBuffer,
+ sizeof(INT_PCM) * hAacEncoder->inputBufferSize);
+ }
+
+ if ((InitFlags & AACENC_INIT_CONFIG)) {
+ aacBufferOffset = 0;
+ switch (hAacConfig->audioObjectType) {
+ case AOT_ER_AAC_LD:
+ hAacEncoder->nDelay = DELAY_AACLD(hAacConfig->framelength);
+ break;
+ case AOT_ER_AAC_ELD:
+ hAacEncoder->nDelay = DELAY_AACELD(hAacConfig->framelength);
+ break;
+ default:
+ hAacEncoder->nDelay =
+ DELAY_AAC(hAacConfig->framelength); /* AAC encoder delay */
+ }
+
+ hAacConfig->ancDataBitRate = 0;
+ }
+
+ if ((NULL != hAacEncoder->hEnvEnc) && isSbrActive(hAacConfig) &&
+ ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES))) {
+ INT sbrError;
+ UINT initFlag = 0;
+ SBR_ELEMENT_INFO sbrElInfo[(8)];
+ CHANNEL_MAPPING channelMapping;
+ CHANNEL_MODE channelMode = isPsActive(hAacConfig->audioObjectType)
+ ? config->userChannelMode
+ : hAacConfig->channelMode;
+ INT numChannels = isPsActive(hAacConfig->audioObjectType)
+ ? config->nChannels
+ : hAacConfig->nChannels;
+
+ if (FDKaacEnc_InitChannelMapping(channelMode, hAacConfig->channelOrder,
+ &channelMapping) != AAC_ENC_OK) {
+ return AACENC_INIT_ERROR;
+ }
+
+ /* Check return value and if the SBR encoder can handle enough elements */
+ if (channelMapping.nElements > (8)) {
+ return AACENC_INIT_ERROR;
+ }
+
+ aacEncDistributeSbrBits(&channelMapping, sbrElInfo, hAacConfig->bitRate);
+
+ initFlag += (InitFlags & AACENC_INIT_STATES) ? 1 : 0;
+
+ /* Let the SBR encoder take a look at the configuration and change if
+ * required. */
+ sbrError = sbrEncoder_Init(
+ *hSbrEncoder, sbrElInfo, channelMapping.nElements,
+ hAacEncoder->inputBuffer, hAacEncoder->inputBufferSizePerChannel,
+ &hAacConfig->bandWidth, &aacBufferOffset, &numChannels,
+ hAacConfig->syntaxFlags, &hAacConfig->sampleRate, &hAacConfig->sbrRatio,
+ &frameLength, hAacConfig->audioObjectType, &hAacEncoder->nDelay,
+ (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) ? 1 : TRANS_FAC,
+ (config->userTpHeaderPeriod != 0xFF)
+ ? config->userTpHeaderPeriod
+ : DEFAULT_HEADER_PERIOD_REPETITION_RATE,
+ initFlag);
+
+ /* Suppress AOT reconfiguration and check error status. */
+ if ((sbrError) || (numChannels != hAacConfig->nChannels)) {
+ return AACENC_INIT_SBR_ERROR;
+ }
+
+ if (numChannels == 1) {
+ hAacConfig->channelMode = MODE_1;
+ }
+
+ /* Never use PNS if SBR is active */
+ if (hAacConfig->usePns) {
+ hAacConfig->usePns = 0;
+ }
+
+ /* estimated bitrate consumed by SBR or PS */
+ hAacConfig->ancDataBitRate = sbrEncoder_GetEstimateBitrate(*hSbrEncoder);
+
+ } /* sbr initialization */
+
+ if ((hAacEncoder->hMpsEnc != NULL) && (hAacConfig->syntaxFlags & AC_LD_MPS)) {
+ int coreCoderDelay = DELAY_AACELD(hAacConfig->framelength);
+
+ if (isSbrActive(hAacConfig)) {
+ coreCoderDelay = hAacConfig->sbrRatio * coreCoderDelay +
+ sbrEncoder_GetInputDataDelay(*hSbrEncoder);
+ }
+
+ if (MPS_ENCODER_OK !=
+ FDK_MpegsEnc_Init(hAacEncoder->hMpsEnc, hAacConfig->audioObjectType,
+ config->userSamplerate, hAacConfig->bitRate,
+ isSbrActive(hAacConfig) ? hAacConfig->sbrRatio : 0,
+ frameLength, /* for dual rate sbr this value is
+ already multiplied by 2 */
+ hAacEncoder->inputBufferSizePerChannel,
+ coreCoderDelay)) {
+ return AACENC_INIT_MPS_ERROR;
+ }
+ }
+ hAacEncoder->nDelay =
+ fMax(FDK_MpegsEnc_GetDelay(hAacEncoder->hMpsEnc), hAacEncoder->nDelay);
+
+ /*
+ * Initialize Transport - Module.
+ */
+ if ((InitFlags & AACENC_INIT_TRANSPORT)) {
+ UINT flags = 0;
+
+ FDKaacEnc_MapConfig(
+ &hAacEncoder->coderConfig, config,
+ getSbrSignalingMode(hAacConfig->audioObjectType, config->userTpType,
+ config->userTpSignaling, hAacConfig->sbrRatio),
+ hAacConfig);
+
+ /* create flags for transport encoder */
+ if (config->userTpAmxv != 0) {
+ flags |= TP_FLAG_LATM_AMV;
+ }
+ /* Clear output buffer */
+ FDKmemclear(hAacEncoder->outBuffer,
+ hAacEncoder->outBufferInBytes * sizeof(UCHAR));
+
+ /* Initialize Bitstream encoder */
+ if (transportEnc_Init(hAacEncoder->hTpEnc, hAacEncoder->outBuffer,
+ hAacEncoder->outBufferInBytes, config->userTpType,
+ &hAacEncoder->coderConfig, flags) != 0) {
+ return AACENC_INIT_TP_ERROR;
+ }
+
+ } /* transport initialization */
+
+ /*
+ * Initialize AAC - Core.
+ */
+ if ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES)) {
+ if (FDKaacEnc_Initialize(
+ hAacEncoder->hAacEnc, hAacConfig, hAacEncoder->hTpEnc,
+ (InitFlags & AACENC_INIT_STATES) ? 1 : 0) != AAC_ENC_OK) {
+ return AACENC_INIT_AAC_ERROR;
+ }
+
+ } /* aac initialization */
+
+ /*
+ * Initialize Meta Data - Encoder.
+ */
+ if (hAacEncoder->hMetadataEnc && (hAacEncoder->metaDataAllowed != 0) &&
+ ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES))) {
+ INT inputDataDelay = DELAY_AAC(hAacConfig->framelength);
+
+ if (isSbrActive(hAacConfig) && hSbrEncoder != NULL) {
+ inputDataDelay = hAacConfig->sbrRatio * inputDataDelay +
+ sbrEncoder_GetInputDataDelay(*hSbrEncoder);
+ }
+
+ if (FDK_MetadataEnc_Init(hAacEncoder->hMetadataEnc,
+ ((InitFlags & AACENC_INIT_STATES) ? 1 : 0),
+ config->userMetaDataMode, inputDataDelay,
+ frameLength, config->userSamplerate,
+ config->nChannels, config->userChannelMode,
+ hAacConfig->channelOrder) != 0) {
+ return AACENC_INIT_META_ERROR;
+ }
+
+ hAacEncoder->nDelay += FDK_MetadataEnc_GetDelay(hAacEncoder->hMetadataEnc);
+ }
+
+ /* Get custom delay, i.e. the codec delay w/o the decoder's SBR- or MPS delay
+ */
+ if ((hAacEncoder->hMpsEnc != NULL) && (hAacConfig->syntaxFlags & AC_LD_MPS)) {
+ hAacEncoder->nDelayCore =
+ hAacEncoder->nDelay -
+ fMax(0, FDK_MpegsEnc_GetDecDelay(hAacEncoder->hMpsEnc));
+ } else if (isSbrActive(hAacConfig) && hSbrEncoder != NULL) {
+ hAacEncoder->nDelayCore =
+ hAacEncoder->nDelay -
+ fMax(0, sbrEncoder_GetSbrDecDelay(hAacEncoder->hEnvEnc));
+ } else {
+ hAacEncoder->nDelayCore = hAacEncoder->nDelay;
+ }
+
+ /*
+ * Update pointer to working buffer.
+ */
+ if ((InitFlags & AACENC_INIT_CONFIG)) {
+ hAacEncoder->inputBufferOffset = aacBufferOffset;
+
+ hAacEncoder->nSamplesToRead = frameLength * config->nChannels;
+
+ } /* parameter changed */
+
+ return AACENC_OK;
+}
+
+AACENC_ERROR aacEncOpen(HANDLE_AACENCODER *phAacEncoder, const UINT encModules,
+ const UINT maxChannels) {
+ AACENC_ERROR err = AACENC_OK;
+ HANDLE_AACENCODER hAacEncoder = NULL;
+
+ if (phAacEncoder == NULL) {
+ err = AACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ /* allocate memory */
+ hAacEncoder = Get_AacEncoder();
+
+ if (hAacEncoder == NULL) {
+ err = AACENC_MEMORY_ERROR;
+ goto bail;
+ }
+
+ FDKmemclear(hAacEncoder, sizeof(AACENCODER));
+
+ /* Specify encoder modules to be allocated. */
+ if (encModules == 0) {
+ C_ALLOC_SCRATCH_START(_pLibInfo, LIB_INFO, FDK_MODULE_LAST)
+ LIB_INFO(*pLibInfo)
+ [FDK_MODULE_LAST] = (LIB_INFO(*)[FDK_MODULE_LAST])_pLibInfo;
+ FDKinitLibInfo(*pLibInfo);
+ aacEncGetLibInfo(*pLibInfo);
+
+ hAacEncoder->encoder_modis = ENC_MODE_FLAG_AAC;
+ if (FDKlibInfo_getCapabilities(*pLibInfo, FDK_SBRENC) & CAPF_SBR_HQ) {
+ hAacEncoder->encoder_modis |= ENC_MODE_FLAG_SBR;
+ }
+ if (FDKlibInfo_getCapabilities(*pLibInfo, FDK_SBRENC) & CAPF_SBR_PS_MPEG) {
+ hAacEncoder->encoder_modis |= ENC_MODE_FLAG_PS;
+ }
+ if (FDKlibInfo_getCapabilities(*pLibInfo, FDK_AACENC) & CAPF_AAC_DRC) {
+ hAacEncoder->encoder_modis |= ENC_MODE_FLAG_META;
+ }
+ hAacEncoder->encoder_modis |= ENC_MODE_FLAG_SAC;
+
+ C_ALLOC_SCRATCH_END(_pLibInfo, LIB_INFO, FDK_MODULE_LAST)
+ } else {
+ hAacEncoder->encoder_modis = encModules;
+ }
+
+ /* Determine max channel configuration. */
+ if (maxChannels == 0) {
+ hAacEncoder->nMaxAacChannels = (8);
+ hAacEncoder->nMaxSbrChannels = (8);
+ } else {
+ hAacEncoder->nMaxAacChannels = (maxChannels & 0x00FF);
+ if ((hAacEncoder->encoder_modis & ENC_MODE_FLAG_SBR)) {
+ hAacEncoder->nMaxSbrChannels = (maxChannels & 0xFF00)
+ ? (maxChannels >> 8)
+ : hAacEncoder->nMaxAacChannels;
+ }
+
+ if ((hAacEncoder->nMaxAacChannels > (8)) ||
+ (hAacEncoder->nMaxSbrChannels > (8))) {
+ err = AACENC_INVALID_CONFIG;
+ goto bail;
+ }
+ } /* maxChannels==0 */
+
+ /* Max number of elements could be tuned any more. */
+ hAacEncoder->nMaxAacElements = fixMin(((8)), hAacEncoder->nMaxAacChannels);
+ hAacEncoder->nMaxSbrElements = fixMin((8), hAacEncoder->nMaxSbrChannels);
+
+ /* In case of memory overlay, allocate memory out of libraries */
+
+ if (hAacEncoder->encoder_modis & (ENC_MODE_FLAG_SBR | ENC_MODE_FLAG_PS))
+ hAacEncoder->inputBufferSizePerChannel = INPUTBUFFER_SIZE;
+ else
+ hAacEncoder->inputBufferSizePerChannel = (1024);
+
+ hAacEncoder->inputBufferSize =
+ hAacEncoder->nMaxAacChannels * hAacEncoder->inputBufferSizePerChannel;
+
+ if (NULL == (hAacEncoder->inputBuffer = (INT_PCM *)FDKcalloc(
+ hAacEncoder->inputBufferSize, sizeof(INT_PCM)))) {
+ err = AACENC_MEMORY_ERROR;
+ goto bail;
+ }
+
+ /* Open SBR Encoder */
+ if (hAacEncoder->encoder_modis & ENC_MODE_FLAG_SBR) {
+ if (sbrEncoder_Open(
+ &hAacEncoder->hEnvEnc, hAacEncoder->nMaxSbrElements,
+ hAacEncoder->nMaxSbrChannels,
+ (hAacEncoder->encoder_modis & ENC_MODE_FLAG_PS) ? 1 : 0)) {
+ err = AACENC_MEMORY_ERROR;
+ goto bail;
+ }
+
+ if (NULL == (hAacEncoder->pSbrPayload = (SBRENC_EXT_PAYLOAD *)FDKcalloc(
+ 1, sizeof(SBRENC_EXT_PAYLOAD)))) {
+ err = AACENC_MEMORY_ERROR;
+ goto bail;
+ }
+ } /* (encoder_modis&ENC_MODE_FLAG_SBR) */
+
+ /* Open Aac Encoder */
+ if (FDKaacEnc_Open(&hAacEncoder->hAacEnc, hAacEncoder->nMaxAacElements,
+ hAacEncoder->nMaxAacChannels, (1)) != AAC_ENC_OK) {
+ err = AACENC_MEMORY_ERROR;
+ goto bail;
+ }
+
+ /* Bitstream output buffer */
+ hAacEncoder->outBufferInBytes =
+ 1 << (DFRACT_BITS - CntLeadingZeros(fixMax(
+ 1, ((1) * hAacEncoder->nMaxAacChannels * 6144) >>
+ 2))); /* buffer has to be 2^n */
+ if (NULL == (hAacEncoder->outBuffer = (UCHAR *)FDKcalloc(
+ hAacEncoder->outBufferInBytes, sizeof(UCHAR)))) {
+ err = AACENC_MEMORY_ERROR;
+ goto bail;
+ }
+
+ /* Open Meta Data Encoder */
+ if (hAacEncoder->encoder_modis & ENC_MODE_FLAG_META) {
+ if (FDK_MetadataEnc_Open(&hAacEncoder->hMetadataEnc,
+ (UINT)hAacEncoder->nMaxAacChannels)) {
+ err = AACENC_MEMORY_ERROR;
+ goto bail;
+ }
+ } /* (encoder_modis&ENC_MODE_FLAG_META) */
+
+ /* Open MPEG Surround Encoder */
+ if (hAacEncoder->encoder_modis & ENC_MODE_FLAG_SAC) {
+ if (MPS_ENCODER_OK != FDK_MpegsEnc_Open(&hAacEncoder->hMpsEnc)) {
+ err = AACENC_MEMORY_ERROR;
+ goto bail;
+ }
+ } /* (hAacEncoder->encoder_modis&ENC_MODE_FLAG_SAC) */
+
+ /* Open Transport Encoder */
+ if (transportEnc_Open(&hAacEncoder->hTpEnc) != 0) {
+ err = AACENC_MEMORY_ERROR;
+ goto bail;
+ } else {
+ C_ALLOC_SCRATCH_START(_pLibInfo, LIB_INFO, FDK_MODULE_LAST)
+
+ LIB_INFO(*pLibInfo)
+ [FDK_MODULE_LAST] = (LIB_INFO(*)[FDK_MODULE_LAST])_pLibInfo;
+
+ FDKinitLibInfo(*pLibInfo);
+ transportEnc_GetLibInfo(*pLibInfo);
+
+ /* Get capabilty flag for transport encoder. */
+ hAacEncoder->CAPF_tpEnc = FDKlibInfo_getCapabilities(*pLibInfo, FDK_TPENC);
+
+ C_ALLOC_SCRATCH_END(_pLibInfo, LIB_INFO, FDK_MODULE_LAST)
+ }
+ if (transportEnc_RegisterSbrCallback(hAacEncoder->hTpEnc, aacenc_SbrCallback,
+ hAacEncoder) != 0) {
+ err = AACENC_INIT_TP_ERROR;
+ goto bail;
+ }
+ if (transportEnc_RegisterSscCallback(hAacEncoder->hTpEnc, aacenc_SscCallback,
+ hAacEncoder) != 0) {
+ err = AACENC_INIT_TP_ERROR;
+ goto bail;
+ }
+
+ /* Initialize encoder instance with default parameters. */
+ aacEncDefaultConfig(&hAacEncoder->aacConfig, &hAacEncoder->extParam);
+
+ /* Initialize headerPeriod in coderConfig for aacEncoder_GetParam(). */
+ hAacEncoder->coderConfig.headerPeriod =
+ hAacEncoder->extParam.userTpHeaderPeriod;
+
+ /* All encoder modules have to be initialized */
+ hAacEncoder->InitFlags = AACENC_INIT_ALL;
+
+ /* Return encoder instance */
+ *phAacEncoder = hAacEncoder;
+
+ return err;
+
+bail:
+ aacEncClose(&hAacEncoder);
+
+ return err;
+}
+
+AACENC_ERROR aacEncClose(HANDLE_AACENCODER *phAacEncoder) {
+ AACENC_ERROR err = AACENC_OK;
+
+ if (phAacEncoder == NULL) {
+ err = AACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ if (*phAacEncoder != NULL) {
+ HANDLE_AACENCODER hAacEncoder = *phAacEncoder;
+
+ if (hAacEncoder->inputBuffer != NULL) {
+ FDKfree(hAacEncoder->inputBuffer);
+ hAacEncoder->inputBuffer = NULL;
+ }
+ if (hAacEncoder->outBuffer != NULL) {
+ FDKfree(hAacEncoder->outBuffer);
+ hAacEncoder->outBuffer = NULL;
+ }
+
+ if (hAacEncoder->hEnvEnc) {
+ sbrEncoder_Close(&hAacEncoder->hEnvEnc);
+ }
+ if (hAacEncoder->pSbrPayload != NULL) {
+ FDKfree(hAacEncoder->pSbrPayload);
+ hAacEncoder->pSbrPayload = NULL;
+ }
+ if (hAacEncoder->hAacEnc) {
+ FDKaacEnc_Close(&hAacEncoder->hAacEnc);
+ }
+
+ transportEnc_Close(&hAacEncoder->hTpEnc);
+
+ if (hAacEncoder->hMetadataEnc) {
+ FDK_MetadataEnc_Close(&hAacEncoder->hMetadataEnc);
+ }
+ if (hAacEncoder->hMpsEnc) {
+ FDK_MpegsEnc_Close(&hAacEncoder->hMpsEnc);
+ }
+
+ Free_AacEncoder(phAacEncoder);
+ }
+
+bail:
+ return err;
+}
+
+AACENC_ERROR aacEncEncode(const HANDLE_AACENCODER hAacEncoder,
+ const AACENC_BufDesc *inBufDesc,
+ const AACENC_BufDesc *outBufDesc,
+ const AACENC_InArgs *inargs,
+ AACENC_OutArgs *outargs) {
+ AACENC_ERROR err = AACENC_OK;
+ INT i, nBsBytes = 0;
+ INT outBytes[(1)];
+ int nExtensions = 0;
+ int ancDataExtIdx = -1;
+
+ /* deal with valid encoder handle */
+ if (hAacEncoder == NULL) {
+ err = AACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ /*
+ * Adjust user settings and trigger reinitialization.
+ */
+ if (hAacEncoder->InitFlags != 0) {
+ err =
+ aacEncInit(hAacEncoder, hAacEncoder->InitFlags, &hAacEncoder->extParam);
+
+ if (err != AACENC_OK) {
+ /* keep init flags alive! */
+ goto bail;
+ }
+ hAacEncoder->InitFlags = AACENC_INIT_NONE;
+ }
+
+ if (outargs != NULL) {
+ FDKmemclear(outargs, sizeof(AACENC_OutArgs));
+ }
+
+ if (outBufDesc != NULL) {
+ for (i = 0; i < outBufDesc->numBufs; i++) {
+ if (outBufDesc->bufs[i] != NULL) {
+ FDKmemclear(outBufDesc->bufs[i], outBufDesc->bufSizes[i]);
+ }
+ }
+ }
+
+ /*
+ * If only encoder handle given, independent (re)initialization can be
+ * triggered.
+ */
+ if ((inBufDesc == NULL) && (outBufDesc == NULL) && (inargs == NULL) &&
+ (outargs == NULL)) {
+ goto bail;
+ }
+
+ /* check if buffer descriptors are filled out properly. */
+ if ((inargs == NULL) || (outargs == NULL) ||
+ ((AACENC_OK != validateBufDesc(inBufDesc)) &&
+ (inargs->numInSamples > 0)) ||
+ (AACENC_OK != validateBufDesc(outBufDesc))) {
+ err = AACENC_UNSUPPORTED_PARAMETER;
+ goto bail;
+ }
+
+ /* reset buffer wich signals number of valid bytes in output bitstream buffer
+ */
+ FDKmemclear(outBytes, hAacEncoder->aacConfig.nSubFrames * sizeof(INT));
+
+ /*
+ * Manage incoming audio samples.
+ */
+ if ((inBufDesc != NULL) && (inargs->numInSamples > 0) &&
+ (getBufDescIdx(inBufDesc, IN_AUDIO_DATA) != -1)) {
+ /* Fetch data until nSamplesToRead reached */
+ INT idx = getBufDescIdx(inBufDesc, IN_AUDIO_DATA);
+ INT newSamples =
+ fixMax(0, fixMin(inargs->numInSamples, hAacEncoder->nSamplesToRead -
+ hAacEncoder->nSamplesRead));
+ INT_PCM *pIn =
+ hAacEncoder->inputBuffer +
+ (hAacEncoder->inputBufferOffset + hAacEncoder->nSamplesRead) /
+ hAacEncoder->aacConfig.nChannels;
+
+ /* Copy new input samples to internal buffer */
+ if (inBufDesc->bufElSizes[idx] == (INT)sizeof(INT_PCM)) {
+ FDK_deinterleave((INT_PCM *)inBufDesc->bufs[idx], pIn,
+ hAacEncoder->extParam.nChannels,
+ newSamples / hAacEncoder->extParam.nChannels,
+ hAacEncoder->inputBufferSizePerChannel);
+ } else if (inBufDesc->bufElSizes[idx] > (INT)sizeof(INT_PCM)) {
+ FDK_deinterleave((LONG *)inBufDesc->bufs[idx], pIn,
+ hAacEncoder->extParam.nChannels,
+ newSamples / hAacEncoder->extParam.nChannels,
+ hAacEncoder->inputBufferSizePerChannel);
+ } else {
+ FDK_deinterleave((SHORT *)inBufDesc->bufs[idx], pIn,
+ hAacEncoder->extParam.nChannels,
+ newSamples / hAacEncoder->extParam.nChannels,
+ hAacEncoder->inputBufferSizePerChannel);
+ }
+ hAacEncoder->nSamplesRead += newSamples;
+
+ /* Number of fetched input buffer samples. */
+ outargs->numInSamples = newSamples;
+ }
+
+ /* input buffer completely filled ? */
+ if (hAacEncoder->nSamplesRead < hAacEncoder->nSamplesToRead) {
+ /* - eof reached and flushing enabled, or
+ - return to main and wait for further incoming audio samples */
+ if (inargs->numInSamples == -1) {
+ if ((hAacEncoder->nZerosAppended < hAacEncoder->nDelay)) {
+ int nZeros = (hAacEncoder->nSamplesToRead - hAacEncoder->nSamplesRead) /
+ hAacEncoder->extParam.nChannels;
+
+ FDK_ASSERT(nZeros >= 0);
+
+ /* clear out until end-of-buffer */
+ if (nZeros) {
+ for (i = 0; i < (int)hAacEncoder->extParam.nChannels; i++) {
+ FDKmemclear(hAacEncoder->inputBuffer +
+ i * hAacEncoder->inputBufferSizePerChannel +
+ (hAacEncoder->inputBufferOffset +
+ hAacEncoder->nSamplesRead) /
+ hAacEncoder->extParam.nChannels,
+ sizeof(INT_PCM) * nZeros);
+ }
+ hAacEncoder->nZerosAppended += nZeros;
+ hAacEncoder->nSamplesRead = hAacEncoder->nSamplesToRead;
+ }
+ } else { /* flushing completed */
+ err = AACENC_ENCODE_EOF; /* eof reached */
+ goto bail;
+ }
+ } else { /* inargs->numInSamples!= -1 */
+ goto bail; /* not enough samples in input buffer and no flushing enabled
+ */
+ }
+ }
+
+ /* init payload */
+ FDKmemclear(hAacEncoder->extPayload,
+ sizeof(AACENC_EXT_PAYLOAD) * MAX_TOTAL_EXT_PAYLOADS);
+ for (i = 0; i < MAX_TOTAL_EXT_PAYLOADS; i++) {
+ hAacEncoder->extPayload[i].associatedChElement = -1;
+ }
+ if (hAacEncoder->pSbrPayload != NULL) {
+ FDKmemclear(hAacEncoder->pSbrPayload, sizeof(*hAacEncoder->pSbrPayload));
+ }
+
+ /*
+ * Calculate Meta Data info.
+ */
+ if ((hAacEncoder->hMetadataEnc != NULL) &&
+ (hAacEncoder->metaDataAllowed != 0)) {
+ const AACENC_MetaData *pMetaData = NULL;
+ AACENC_EXT_PAYLOAD *pMetaDataExtPayload = NULL;
+ UINT nMetaDataExtensions = 0;
+ INT matrix_mixdown_idx = 0;
+
+ /* New meta data info available ? */
+ if (getBufDescIdx(inBufDesc, IN_METADATA_SETUP) != -1) {
+ pMetaData =
+ (AACENC_MetaData *)
+ inBufDesc->bufs[getBufDescIdx(inBufDesc, IN_METADATA_SETUP)];
+ }
+
+ FDK_MetadataEnc_Process(
+ hAacEncoder->hMetadataEnc,
+ hAacEncoder->inputBuffer + hAacEncoder->inputBufferOffset /
+ hAacEncoder->coderConfig.noChannels,
+ hAacEncoder->inputBufferSizePerChannel, hAacEncoder->nSamplesRead,
+ pMetaData, &pMetaDataExtPayload, &nMetaDataExtensions,
+ &matrix_mixdown_idx);
+
+ for (i = 0; i < (INT)nMetaDataExtensions;
+ i++) { /* Get meta data extension payload. */
+ hAacEncoder->extPayload[nExtensions++] = pMetaDataExtPayload[i];
+ }
+
+ if ((matrix_mixdown_idx != -1) &&
+ ((hAacEncoder->extParam.userChannelMode == MODE_1_2_2) ||
+ (hAacEncoder->extParam.userChannelMode == MODE_1_2_2_1))) {
+ /* Set matrix mixdown coefficient. */
+ UINT pceValue = (UINT)((0 << 3) | ((matrix_mixdown_idx & 0x3) << 1) | 1);
+ if (hAacEncoder->extParam.userPceAdditions != pceValue) {
+ hAacEncoder->extParam.userPceAdditions = pceValue;
+ hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
+ }
+ }
+ }
+
+ /*
+ * Encode MPS data.
+ */
+ if ((hAacEncoder->hMpsEnc != NULL) &&
+ (hAacEncoder->aacConfig.syntaxFlags & AC_LD_MPS)) {
+ AACENC_EXT_PAYLOAD mpsExtensionPayload;
+ FDKmemclear(&mpsExtensionPayload, sizeof(AACENC_EXT_PAYLOAD));
+
+ if (MPS_ENCODER_OK !=
+ FDK_MpegsEnc_Process(
+ hAacEncoder->hMpsEnc,
+ hAacEncoder->inputBuffer + hAacEncoder->inputBufferOffset /
+ hAacEncoder->coderConfig.noChannels,
+ hAacEncoder->nSamplesRead, &mpsExtensionPayload)) {
+ err = AACENC_ENCODE_ERROR;
+ goto bail;
+ }
+
+ if ((mpsExtensionPayload.pData != NULL) &&
+ ((mpsExtensionPayload.dataSize != 0))) {
+ hAacEncoder->extPayload[nExtensions++] = mpsExtensionPayload;
+ }
+ }
+
+ if ((NULL != hAacEncoder->hEnvEnc) && (NULL != hAacEncoder->pSbrPayload) &&
+ isSbrActive(&hAacEncoder->aacConfig)) {
+ INT nPayload = 0;
+
+ /*
+ * Encode SBR data.
+ */
+ if (sbrEncoder_EncodeFrame(hAacEncoder->hEnvEnc, hAacEncoder->inputBuffer,
+ hAacEncoder->inputBufferSizePerChannel,
+ hAacEncoder->pSbrPayload->dataSize[nPayload],
+ hAacEncoder->pSbrPayload->data[nPayload])) {
+ err = AACENC_ENCODE_ERROR;
+ goto bail;
+ } else {
+ /* Add SBR extension payload */
+ for (i = 0; i < (8); i++) {
+ if (hAacEncoder->pSbrPayload->dataSize[nPayload][i] > 0) {
+ hAacEncoder->extPayload[nExtensions].pData =
+ hAacEncoder->pSbrPayload->data[nPayload][i];
+ {
+ hAacEncoder->extPayload[nExtensions].dataSize =
+ hAacEncoder->pSbrPayload->dataSize[nPayload][i];
+ hAacEncoder->extPayload[nExtensions].associatedChElement = i;
+ }
+ hAacEncoder->extPayload[nExtensions].dataType =
+ EXT_SBR_DATA; /* Once SBR Encoder supports SBR CRC set
+ EXT_SBR_DATA_CRC */
+ nExtensions++; /* or EXT_SBR_DATA according to configuration. */
+ FDK_ASSERT(nExtensions <= MAX_TOTAL_EXT_PAYLOADS);
+ }
+ }
+ nPayload++;
+ }
+ } /* sbrEnabled */
+
+ if ((inargs->numAncBytes > 0) &&
+ (getBufDescIdx(inBufDesc, IN_ANCILLRY_DATA) != -1)) {
+ INT idx = getBufDescIdx(inBufDesc, IN_ANCILLRY_DATA);
+ hAacEncoder->extPayload[nExtensions].dataSize = inargs->numAncBytes * 8;
+ hAacEncoder->extPayload[nExtensions].pData = (UCHAR *)inBufDesc->bufs[idx];
+ hAacEncoder->extPayload[nExtensions].dataType = EXT_DATA_ELEMENT;
+ hAacEncoder->extPayload[nExtensions].associatedChElement = -1;
+ ancDataExtIdx = nExtensions; /* store index */
+ nExtensions++;
+ }
+
+ /*
+ * Encode AAC - Core.
+ */
+ if (FDKaacEnc_EncodeFrame(hAacEncoder->hAacEnc, hAacEncoder->hTpEnc,
+ hAacEncoder->inputBuffer,
+ hAacEncoder->inputBufferSizePerChannel, outBytes,
+ hAacEncoder->extPayload) != AAC_ENC_OK) {
+ err = AACENC_ENCODE_ERROR;
+ goto bail;
+ }
+
+ if (ancDataExtIdx >= 0) {
+ outargs->numAncBytes =
+ inargs->numAncBytes -
+ (hAacEncoder->extPayload[ancDataExtIdx].dataSize >> 3);
+ }
+
+ /* samples exhausted */
+ hAacEncoder->nSamplesRead -= hAacEncoder->nSamplesToRead;
+
+ /*
+ * Delay balancing buffer handling
+ */
+ if (isSbrActive(&hAacEncoder->aacConfig)) {
+ sbrEncoder_UpdateBuffers(hAacEncoder->hEnvEnc, hAacEncoder->inputBuffer,
+ hAacEncoder->inputBufferSizePerChannel);
+ }
+
+ /*
+ * Make bitstream public
+ */
+ if ((outBufDesc != NULL) && (outBufDesc->numBufs >= 1)) {
+ INT bsIdx = getBufDescIdx(outBufDesc, OUT_BITSTREAM_DATA);
+ INT auIdx = getBufDescIdx(outBufDesc, OUT_AU_SIZES);
+
+ for (i = 0, nBsBytes = 0; i < hAacEncoder->aacConfig.nSubFrames; i++) {
+ nBsBytes += outBytes[i];
+
+ if (auIdx != -1) {
+ ((INT *)outBufDesc->bufs[auIdx])[i] = outBytes[i];
+ }
+ }
+
+ if ((bsIdx != -1) && (outBufDesc->bufSizes[bsIdx] >= nBsBytes)) {
+ FDKmemcpy(outBufDesc->bufs[bsIdx], hAacEncoder->outBuffer,
+ sizeof(UCHAR) * nBsBytes);
+ outargs->numOutBytes = nBsBytes;
+ outargs->bitResState =
+ FDKaacEnc_GetBitReservoirState(hAacEncoder->hAacEnc);
+ } else {
+ /* output buffer too small, can't write valid bitstream */
+ err = AACENC_ENCODE_ERROR;
+ goto bail;
+ }
+ }
+
+bail:
+ if (err == AACENC_ENCODE_ERROR) {
+ /* All encoder modules have to be initialized */
+ hAacEncoder->InitFlags = AACENC_INIT_ALL;
+ }
+
+ return err;
+}
+
+static AAC_ENCODER_ERROR aacEncGetConf(HANDLE_AACENCODER hAacEncoder,
+ UINT *size, UCHAR *confBuffer) {
+ FDK_BITSTREAM tmpConf;
+ UINT confType;
+ UCHAR buf[64];
+ int err;
+
+ /* Init bit buffer */
+ FDKinitBitStream(&tmpConf, buf, 64, 0, BS_WRITER);
+
+ /* write conf in tmp buffer */
+ err = transportEnc_GetConf(hAacEncoder->hTpEnc, &hAacEncoder->coderConfig,
+ &tmpConf, &confType);
+
+ /* copy data to outbuffer: length in bytes */
+ FDKbyteAlign(&tmpConf, 0);
+
+ /* Check buffer size */
+ if (FDKgetValidBits(&tmpConf) > ((*size) << 3)) return AAC_ENC_UNKNOWN;
+
+ FDKfetchBuffer(&tmpConf, confBuffer, size);
+
+ if (err != 0)
+ return AAC_ENC_UNKNOWN;
+ else
+ return AAC_ENC_OK;
+}
+
+AACENC_ERROR aacEncGetLibInfo(LIB_INFO *info) {
+ int i = 0;
+
+ if (info == NULL) {
+ return AACENC_INVALID_HANDLE;
+ }
+
+ FDK_toolsGetLibInfo(info);
+ transportEnc_GetLibInfo(info);
+ sbrEncoder_GetLibInfo(info);
+ FDK_MpegsEnc_GetLibInfo(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 AACENC_INIT_ERROR;
+ }
+
+ info[i].module_id = FDK_AACENC;
+ info[i].build_date = AACENCODER_LIB_BUILD_DATE;
+ info[i].build_time = AACENCODER_LIB_BUILD_TIME;
+ info[i].title = AACENCODER_LIB_TITLE;
+ info[i].version =
+ LIB_VERSION(AACENCODER_LIB_VL0, AACENCODER_LIB_VL1, AACENCODER_LIB_VL2);
+ ;
+ LIB_VERSION_STRING(&info[i]);
+
+ /* Capability flags */
+ info[i].flags = 0 | CAPF_AAC_1024 | CAPF_AAC_LC | CAPF_AAC_960| CAPF_AAC_512 |
+ CAPF_AAC_480 | CAPF_AAC_DRC | CAPF_AAC_ELD_DOWNSCALE;
+ /* End of flags */
+
+ return AACENC_OK;
+}
+
+AACENC_ERROR aacEncoder_SetParam(const HANDLE_AACENCODER hAacEncoder,
+ const AACENC_PARAM param, const UINT value) {
+ AACENC_ERROR err = AACENC_OK;
+ USER_PARAM *settings = &hAacEncoder->extParam;
+
+ /* check encoder handle */
+ if (hAacEncoder == NULL) {
+ err = AACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ /* apply param value */
+ switch (param) {
+ case AACENC_AOT:
+ if (settings->userAOT != (AUDIO_OBJECT_TYPE)value) {
+ /* check if AOT matches the allocated modules */
+ switch (value) {
+ case AOT_PS:
+ case AOT_DABPLUS_PS:
+ if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_PS))) {
+ err = AACENC_INVALID_CONFIG;
+ goto bail;
+ }
+ FDK_FALLTHROUGH;
+ case AOT_SBR:
+ case AOT_MP2_SBR:
+ case AOT_DABPLUS_SBR:
+ if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_SBR))) {
+ err = AACENC_INVALID_CONFIG;
+ goto bail;
+ }
+ FDK_FALLTHROUGH;
+ case AOT_AAC_LC:
+ case AOT_MP2_AAC_LC:
+ case AOT_DABPLUS_AAC_LC:
+ case AOT_ER_AAC_LD:
+ case AOT_ER_AAC_ELD:
+ if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_AAC))) {
+ err = AACENC_INVALID_CONFIG;
+ goto bail;
+ }
+ break;
+ default:
+ err = AACENC_INVALID_CONFIG;
+ goto bail;
+ } /* switch value */
+ settings->userAOT = (AUDIO_OBJECT_TYPE)value;
+ hAacEncoder->InitFlags |=
+ AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_BITRATE:
+ if (settings->userBitrate != value) {
+ settings->userBitrate = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_BITRATEMODE:
+ if (settings->userBitrateMode != value) {
+ switch (value) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 7:
+ case 8:
+ settings->userBitrateMode = value;
+ hAacEncoder->InitFlags |=
+ AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
+ break;
+ default:
+ err = AACENC_INVALID_CONFIG;
+ break;
+ } /* switch value */
+ }
+ break;
+ case AACENC_SAMPLERATE:
+ if (settings->userSamplerate != value) {
+ if (!((value == 8000) || (value == 11025) || (value == 12000) ||
+ (value == 16000) || (value == 22050) || (value == 24000) ||
+ (value == 32000) || (value == 44100) || (value == 48000) ||
+ (value == 64000) || (value == 88200) || (value == 96000))) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userSamplerate = value;
+ hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */
+ hAacEncoder->InitFlags |=
+ AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_CHANNELMODE:
+ if (settings->userChannelMode != (CHANNEL_MODE)value) {
+ if (((CHANNEL_MODE)value == MODE_212) &&
+ (NULL != hAacEncoder->hMpsEnc)) {
+ settings->userChannelMode = (CHANNEL_MODE)value;
+ settings->nChannels = 2;
+ } else {
+ const CHANNEL_MODE_CONFIG_TAB *pConfig =
+ FDKaacEnc_GetChannelModeConfiguration((CHANNEL_MODE)value);
+ if (pConfig == NULL) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ if ((pConfig->nElements > hAacEncoder->nMaxAacElements) ||
+ (pConfig->nChannelsEff > hAacEncoder->nMaxAacChannels)) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+
+ settings->userChannelMode = (CHANNEL_MODE)value;
+ settings->nChannels = pConfig->nChannels;
+ }
+ hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */
+ hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
+ if (!((value >= 1) && (value <= 6))) {
+ hAacEncoder->InitFlags |= AACENC_INIT_STATES;
+ }
+ }
+ break;
+ case AACENC_BANDWIDTH:
+ if (settings->userBandwidth != value) {
+ settings->userBandwidth = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_CONFIG;
+ }
+ break;
+ case AACENC_CHANNELORDER:
+ if (hAacEncoder->aacConfig.channelOrder != (CHANNEL_ORDER)value) {
+ if (!((value == 0) || (value == 1) || (value == 2))) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ hAacEncoder->aacConfig.channelOrder = (CHANNEL_ORDER)value;
+ hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */
+ hAacEncoder->InitFlags |=
+ AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_AFTERBURNER:
+ if (settings->userAfterburner != value) {
+ if (!((value == 0) || (value == 1))) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userAfterburner = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_CONFIG;
+ }
+ break;
+ case AACENC_GRANULE_LENGTH:
+ if (settings->userFramelength != value) {
+ switch (value) {
+ case 1024:
+ case 960:
+ case 512:
+ case 480:
+ case 256:
+ case 240:
+ case 128:
+ case 120:
+ if ((value << 1) == 480 || (value << 1) == 512) {
+ settings->userDownscaleFactor = 2;
+ } else if ((value << 2) == 480 || (value << 2) == 512) {
+ settings->userDownscaleFactor = 4;
+ }
+ settings->userFramelength = value;
+ hAacEncoder->InitFlags |=
+ AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
+ break;
+ default:
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ }
+ break;
+ case AACENC_SBR_RATIO:
+ if (settings->userSbrRatio != value) {
+ if (!((value == 0) || (value == 1) || (value == 2))) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userSbrRatio = value;
+ hAacEncoder->InitFlags |=
+ AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_SBR_MODE:
+ if ((settings->userSbrEnabled != value) &&
+ (NULL != hAacEncoder->hEnvEnc)) {
+ settings->userSbrEnabled = value;
+ hAacEncoder->InitFlags |=
+ AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_TRANSMUX:
+ if (settings->userTpType != (TRANSPORT_TYPE)value) {
+ TRANSPORT_TYPE type = (TRANSPORT_TYPE)value;
+ UINT flags = hAacEncoder->CAPF_tpEnc;
+
+ if (!(((type == TT_MP4_ADIF) && (flags & CAPF_ADIF)) ||
+ ((type == TT_MP4_ADTS) && (flags & CAPF_ADTS)) ||
+ ((type == TT_MP4_LATM_MCP0) &&
+ ((flags & CAPF_LATM) && (flags & CAPF_RAWPACKETS))) ||
+ ((type == TT_MP4_LATM_MCP1) &&
+ ((flags & CAPF_LATM) && (flags & CAPF_RAWPACKETS))) ||
+ ((type == TT_MP4_LOAS) && (flags & CAPF_LOAS)) ||
+ ((type == TT_MP4_RAW) && (flags & CAPF_RAWPACKETS)) ||
+ ((type == TT_DABPLUS) && ((flags & CAPF_DAB_AAC) && (flags & CAPF_RAWPACKETS))) )) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userTpType = (TRANSPORT_TYPE)value;
+ hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_SIGNALING_MODE:
+ if (settings->userTpSignaling != value) {
+ if (!((value == 0) || (value == 1) || (value == 2))) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userTpSignaling = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_PROTECTION:
+ if (settings->userTpProtection != value) {
+ if (!((value == 0) || (value == 1))) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userTpProtection = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_HEADER_PERIOD:
+ if (settings->userTpHeaderPeriod != value) {
+ if (!(((INT)value >= 0) && (value <= 255))) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userTpHeaderPeriod = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_AUDIOMUXVER:
+ if (settings->userTpAmxv != value) {
+ if (!((value == 0) || (value == 1) || (value == 2))) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userTpAmxv = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_TPSUBFRAMES:
+ if (settings->userTpNsubFrames != value) {
+ if (!((value >= 1) && (value <= 6))) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userTpNsubFrames = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_ANCILLARY_BITRATE:
+ if (settings->userAncDataRate != value) {
+ settings->userAncDataRate = value;
+ }
+ break;
+ case AACENC_CONTROL_STATE:
+ if (hAacEncoder->InitFlags != value) {
+ if (value & AACENC_RESET_INBUFFER) {
+ hAacEncoder->nSamplesRead = 0;
+ }
+ hAacEncoder->InitFlags = value;
+ }
+ break;
+ case AACENC_METADATA_MODE:
+ if ((UINT)settings->userMetaDataMode != value) {
+ if (!(((INT)value >= 0) && ((INT)value <= 3))) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userMetaDataMode = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_CONFIG;
+ }
+ break;
+ case AACENC_PEAK_BITRATE:
+ if (settings->userPeakBitrate != value) {
+ settings->userPeakBitrate = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
+ }
+ break;
+ default:
+ err = AACENC_UNSUPPORTED_PARAMETER;
+ break;
+ } /* switch(param) */
+
+bail:
+ return err;
+}
+
+UINT aacEncoder_GetParam(const HANDLE_AACENCODER hAacEncoder,
+ const AACENC_PARAM param) {
+ UINT value = 0;
+ USER_PARAM *settings = &hAacEncoder->extParam;
+
+ /* check encoder handle */
+ if (hAacEncoder == NULL) {
+ goto bail;
+ }
+
+ /* apply param value */
+ switch (param) {
+ case AACENC_AOT:
+ value = (UINT)hAacEncoder->aacConfig.audioObjectType;
+ break;
+ case AACENC_BITRATE:
+ switch (hAacEncoder->aacConfig.bitrateMode) {
+ case AACENC_BR_MODE_CBR:
+ value = (UINT)hAacEncoder->aacConfig.bitRate;
+ break;
+ default:
+ value = (UINT)-1;
+ }
+ break;
+ case AACENC_BITRATEMODE:
+ value = (UINT)((hAacEncoder->aacConfig.bitrateMode != AACENC_BR_MODE_FF)
+ ? hAacEncoder->aacConfig.bitrateMode
+ : AACENC_BR_MODE_CBR);
+ break;
+ case AACENC_SAMPLERATE:
+ value = (UINT)hAacEncoder->coderConfig.extSamplingRate;
+ break;
+ case AACENC_CHANNELMODE:
+ if ((MODE_1 == hAacEncoder->aacConfig.channelMode) &&
+ (hAacEncoder->aacConfig.syntaxFlags & AC_LD_MPS)) {
+ value = MODE_212;
+ } else {
+ value = (UINT)hAacEncoder->aacConfig.channelMode;
+ }
+ break;
+ case AACENC_BANDWIDTH:
+ value = (UINT)hAacEncoder->aacConfig.bandWidth;
+ break;
+ case AACENC_CHANNELORDER:
+ value = (UINT)hAacEncoder->aacConfig.channelOrder;
+ break;
+ case AACENC_AFTERBURNER:
+ value = (UINT)hAacEncoder->aacConfig.useRequant;
+ break;
+ case AACENC_GRANULE_LENGTH:
+ value = (UINT)hAacEncoder->aacConfig.framelength;
+ break;
+ case AACENC_SBR_RATIO:
+ value = isSbrActive(&hAacEncoder->aacConfig)
+ ? hAacEncoder->aacConfig.sbrRatio
+ : 0;
+ break;
+ case AACENC_SBR_MODE:
+ value =
+ (UINT)(hAacEncoder->aacConfig.syntaxFlags & AC_SBR_PRESENT) ? 1 : 0;
+ break;
+ case AACENC_TRANSMUX:
+ value = (UINT)settings->userTpType;
+ break;
+ case AACENC_SIGNALING_MODE:
+ value = (UINT)getSbrSignalingMode(
+ hAacEncoder->aacConfig.audioObjectType, settings->userTpType,
+ settings->userTpSignaling, hAacEncoder->aacConfig.sbrRatio);
+ break;
+ case AACENC_PROTECTION:
+ value = (UINT)settings->userTpProtection;
+ break;
+ case AACENC_HEADER_PERIOD:
+ value = (UINT)hAacEncoder->coderConfig.headerPeriod;
+ break;
+ case AACENC_AUDIOMUXVER:
+ value = (UINT)hAacEncoder->aacConfig.audioMuxVersion;
+ break;
+ case AACENC_TPSUBFRAMES:
+ value = (UINT)settings->userTpNsubFrames;
+ break;
+ case AACENC_ANCILLARY_BITRATE:
+ value = (UINT)hAacEncoder->aacConfig.anc_Rate;
+ break;
+ case AACENC_CONTROL_STATE:
+ value = (UINT)hAacEncoder->InitFlags;
+ break;
+ case AACENC_METADATA_MODE:
+ value = (hAacEncoder->metaDataAllowed == 0)
+ ? 0
+ : (UINT)settings->userMetaDataMode;
+ break;
+ case AACENC_PEAK_BITRATE:
+ value = (UINT)-1; /* peak bitrate parameter is meaningless */
+ if (((INT)hAacEncoder->extParam.userPeakBitrate != -1)) {
+ value =
+ (UINT)(fMax((INT)hAacEncoder->extParam.userPeakBitrate,
+ hAacEncoder->aacConfig
+ .bitRate)); /* peak bitrate parameter is in use */
+ }
+ break;
+
+ default:
+ // err = MPS_INVALID_PARAMETER;
+ break;
+ } /* switch(param) */
+
+bail:
+ return value;
+}
+
+AACENC_ERROR aacEncInfo(const HANDLE_AACENCODER hAacEncoder,
+ AACENC_InfoStruct *pInfo) {
+ AACENC_ERROR err = AACENC_OK;
+
+ FDKmemclear(pInfo, sizeof(AACENC_InfoStruct));
+ pInfo->confSize = 64; /* pre-initialize */
+
+ pInfo->maxOutBufBytes = ((hAacEncoder->nMaxAacChannels * 6144) + 7) >> 3;
+ pInfo->maxAncBytes = hAacEncoder->aacConfig.maxAncBytesPerAU;
+ pInfo->inBufFillLevel =
+ hAacEncoder->nSamplesRead / hAacEncoder->extParam.nChannels;
+ pInfo->inputChannels = hAacEncoder->extParam.nChannels;
+ pInfo->frameLength =
+ hAacEncoder->nSamplesToRead / hAacEncoder->extParam.nChannels;
+ pInfo->nDelay = hAacEncoder->nDelay;
+ pInfo->nDelayCore = hAacEncoder->nDelayCore;
+
+ /* Get encoder configuration */
+ if (aacEncGetConf(hAacEncoder, &pInfo->confSize, &pInfo->confBuf[0]) !=
+ AAC_ENC_OK) {
+ err = AACENC_INIT_ERROR;
+ goto bail;
+ }
+bail:
+ return err;
+}
diff --git a/fdk-aac/libAACenc/src/aacenc_pns.cpp b/fdk-aac/libAACenc/src/aacenc_pns.cpp
new file mode 100644
index 0000000..f0571d6
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacenc_pns.cpp
@@ -0,0 +1,541 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser
+
+ Description: pns.c
+
+*******************************************************************************/
+
+#include "aacenc_pns.h"
+
+#include "psy_data.h"
+#include "pnsparam.h"
+#include "noisedet.h"
+#include "bit_cnt.h"
+#include "interface.h"
+
+/* minCorrelationEnergy = (1.0e-10f)^2 ~ 2^-67 = 2^-47 * 2^-20 */
+static const FIXP_DBL minCorrelationEnergy =
+ FL2FXCONST_DBL(0.0); /* FL2FXCONST_DBL((float)FDKpow(2.0,-47)); */
+/* noiseCorrelationThresh = 0.6^2 */
+static const FIXP_DBL noiseCorrelationThresh = FL2FXCONST_DBL(0.36);
+
+static void FDKaacEnc_FDKaacEnc_noiseDetection(
+ PNS_CONFIG *pnsConf, PNS_DATA *pnsData, const INT sfbActive,
+ const INT *sfbOffset, INT tnsOrder, INT tnsPredictionGain, INT tnsActive,
+ FIXP_DBL *mdctSpectrum, INT *sfbMaxScaleSpec, FIXP_SGL *sfbtonality);
+
+static void FDKaacEnc_CalcNoiseNrgs(const INT sfbActive, INT *pnsFlag,
+ FIXP_DBL *sfbEnergyLdData, INT *noiseNrg);
+
+/*****************************************************************************
+
+ functionname: initPnsConfiguration
+ description: fill pnsConf with pns parameters
+ returns: error status
+ input: PNS Config struct (modified)
+ bitrate, samplerate, usePns,
+ number of sfb's, pointer to sfb offset
+ output: error code
+
+*****************************************************************************/
+
+AAC_ENCODER_ERROR FDKaacEnc_InitPnsConfiguration(
+ PNS_CONFIG *pnsConf, INT bitRate, INT sampleRate, INT usePns, INT sfbCnt,
+ const INT *sfbOffset, const INT numChan, const INT isLC) {
+ AAC_ENCODER_ERROR ErrorStatus;
+
+ /* init noise detection */
+ ErrorStatus = FDKaacEnc_GetPnsParam(&pnsConf->np, bitRate, sampleRate, sfbCnt,
+ sfbOffset, &usePns, numChan, isLC);
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+
+ pnsConf->minCorrelationEnergy = minCorrelationEnergy;
+ pnsConf->noiseCorrelationThresh = noiseCorrelationThresh;
+
+ pnsConf->usePns = usePns;
+
+ return AAC_ENC_OK;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_PnsDetect
+ description: do decision, if PNS shall used or not
+ returns:
+ input: pns config structure
+ pns data structure (modified),
+ lastWindowSequence (long or short blocks)
+ sfbActive
+ pointer to Sfb Energy, Threshold, Offset
+ pointer to mdct Spectrum
+ length of each group
+ pointer to tonality calculated in chaosmeasure
+ tns order and prediction gain
+ calculated noiseNrg at active PNS
+ output: pnsFlag in pns data structure
+
+*****************************************************************************/
+void FDKaacEnc_PnsDetect(PNS_CONFIG *pnsConf, PNS_DATA *pnsData,
+ const INT lastWindowSequence, const INT sfbActive,
+ const INT maxSfbPerGroup, FIXP_DBL *sfbThresholdLdData,
+ const INT *sfbOffset, FIXP_DBL *mdctSpectrum,
+ INT *sfbMaxScaleSpec, FIXP_SGL *sfbtonality,
+ INT tnsOrder, INT tnsPredictionGain, INT tnsActive,
+ FIXP_DBL *sfbEnergyLdData, INT *noiseNrg)
+
+{
+ int sfb;
+ int startNoiseSfb;
+
+ /* Reset pns info. */
+ FDKmemclear(pnsData->pnsFlag, sizeof(pnsData->pnsFlag));
+ for (sfb = 0; sfb < MAX_GROUPED_SFB; sfb++) {
+ noiseNrg[sfb] = NO_NOISE_PNS;
+ }
+
+ /* Disable PNS and skip detection in certain cases. */
+ if (pnsConf->usePns == 0) {
+ return;
+ } else {
+ /* AAC - LC core encoder */
+ if ((pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMPLEXITY) &&
+ (lastWindowSequence == SHORT_WINDOW)) {
+ return;
+ }
+ /* AAC - (E)LD core encoder */
+ if (!(pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMPLEXITY) &&
+ (pnsConf->np.detectionAlgorithmFlags & JUST_LONG_WINDOW) &&
+ (lastWindowSequence != LONG_WINDOW)) {
+ return;
+ }
+ }
+
+ /*
+ call noise detection
+ */
+ FDKaacEnc_FDKaacEnc_noiseDetection(
+ pnsConf, pnsData, sfbActive, sfbOffset, tnsOrder, tnsPredictionGain,
+ tnsActive, mdctSpectrum, sfbMaxScaleSpec, sfbtonality);
+
+ /* set startNoiseSfb (long) */
+ startNoiseSfb = pnsConf->np.startSfb;
+
+ /* Set noise substitution status */
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ /* No PNS below startNoiseSfb */
+ if (sfb < startNoiseSfb) {
+ pnsData->pnsFlag[sfb] = 0;
+ continue;
+ }
+
+ /*
+ do noise substitution if
+ fuzzy measure is high enough
+ sfb freq > minimum sfb freq
+ signal in coder band is not masked
+ */
+
+ if ((pnsData->noiseFuzzyMeasure[sfb] > FL2FXCONST_SGL(0.5)) &&
+ ((sfbThresholdLdData[sfb] +
+ FL2FXCONST_DBL(0.5849625f /
+ 64.0f)) /* thr * 1.5 = thrLd +ld(1.5)/64 */
+ < sfbEnergyLdData[sfb])) {
+ /*
+ mark in psyout flag array that we will code
+ this band with PNS
+ */
+ pnsData->pnsFlag[sfb] = 1; /* PNS_ON */
+ } else {
+ pnsData->pnsFlag[sfb] = 0; /* PNS_OFF */
+ }
+
+ /* no PNS if LTP is active */
+ }
+
+ /* avoid PNS holes */
+ if ((pnsData->noiseFuzzyMeasure[0] > FL2FXCONST_SGL(0.5f)) &&
+ (pnsData->pnsFlag[1])) {
+ pnsData->pnsFlag[0] = 1;
+ }
+
+ for (sfb = 1; sfb < maxSfbPerGroup - 1; sfb++) {
+ if ((pnsData->noiseFuzzyMeasure[sfb] > pnsConf->np.gapFillThr) &&
+ (pnsData->pnsFlag[sfb - 1]) && (pnsData->pnsFlag[sfb + 1])) {
+ pnsData->pnsFlag[sfb] = 1;
+ }
+ }
+
+ if (maxSfbPerGroup > 0) {
+ /* avoid PNS hole */
+ if ((pnsData->noiseFuzzyMeasure[maxSfbPerGroup - 1] >
+ pnsConf->np.gapFillThr) &&
+ (pnsData->pnsFlag[maxSfbPerGroup - 2])) {
+ pnsData->pnsFlag[maxSfbPerGroup - 1] = 1;
+ }
+ /* avoid single PNS band */
+ if (pnsData->pnsFlag[maxSfbPerGroup - 2] == 0) {
+ pnsData->pnsFlag[maxSfbPerGroup - 1] = 0;
+ }
+ }
+
+ /* avoid single PNS bands */
+ if (pnsData->pnsFlag[1] == 0) {
+ pnsData->pnsFlag[0] = 0;
+ }
+
+ for (sfb = 1; sfb < maxSfbPerGroup - 1; sfb++) {
+ if ((pnsData->pnsFlag[sfb - 1] == 0) && (pnsData->pnsFlag[sfb + 1] == 0)) {
+ pnsData->pnsFlag[sfb] = 0;
+ }
+ }
+
+ /*
+ calculate noiseNrg's
+ */
+ FDKaacEnc_CalcNoiseNrgs(sfbActive, pnsData->pnsFlag, sfbEnergyLdData,
+ noiseNrg);
+}
+
+/*****************************************************************************
+
+ functionname:FDKaacEnc_FDKaacEnc_noiseDetection
+ description: wrapper for noisedet.c
+ returns:
+ input: pns config structure
+ pns data structure (modified),
+ sfbActive
+ tns order and prediction gain
+ pointer to mdct Spectrumand Sfb Energy
+ pointer to Sfb tonality
+ output: noiseFuzzyMeasure in structure pnsData
+ flags tonal / nontonal
+
+*****************************************************************************/
+static void FDKaacEnc_FDKaacEnc_noiseDetection(
+ PNS_CONFIG *pnsConf, PNS_DATA *pnsData, const INT sfbActive,
+ const INT *sfbOffset, int tnsOrder, INT tnsPredictionGain, INT tnsActive,
+ FIXP_DBL *mdctSpectrum, INT *sfbMaxScaleSpec, FIXP_SGL *sfbtonality) {
+ INT condition = TRUE;
+ if (!(pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMPLEXITY)) {
+ condition = (tnsOrder > 3);
+ }
+ /*
+ no PNS if heavy TNS activity
+ clear pnsData->noiseFuzzyMeasure
+ */
+ if ((pnsConf->np.detectionAlgorithmFlags & USE_TNS_GAIN_THR) &&
+ (tnsPredictionGain >= pnsConf->np.tnsGainThreshold) && condition &&
+ !((pnsConf->np.detectionAlgorithmFlags & USE_TNS_PNS) &&
+ (tnsPredictionGain >= pnsConf->np.tnsPNSGainThreshold) &&
+ (tnsActive))) {
+ /* clear all noiseFuzzyMeasure */
+ FDKmemclear(pnsData->noiseFuzzyMeasure, sfbActive * sizeof(FIXP_SGL));
+ } else {
+ /*
+ call noise detection, output in pnsData->noiseFuzzyMeasure,
+ use real mdct spectral data
+ */
+ FDKaacEnc_noiseDetect(mdctSpectrum, sfbMaxScaleSpec, sfbActive, sfbOffset,
+ pnsData->noiseFuzzyMeasure, &pnsConf->np,
+ sfbtonality);
+ }
+}
+
+/*****************************************************************************
+
+ functionname:FDKaacEnc_CalcNoiseNrgs
+ description: Calculate the NoiseNrg's
+ returns:
+ input: sfbActive
+ if pnsFlag calculate NoiseNrg
+ pointer to sfbEnergy and groupLen
+ pointer to noiseNrg (modified)
+ output: noiseNrg's in pnsFlaged sfb's
+
+*****************************************************************************/
+
+static void FDKaacEnc_CalcNoiseNrgs(const INT sfbActive, INT *RESTRICT pnsFlag,
+ FIXP_DBL *RESTRICT sfbEnergyLdData,
+ INT *RESTRICT noiseNrg) {
+ int sfb;
+ INT tmp = (-LOG_NORM_PCM) << 2;
+
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ if (pnsFlag[sfb]) {
+ INT nrg = (-sfbEnergyLdData[sfb] + FL2FXCONST_DBL(0.5f / 64.0f)) >>
+ (DFRACT_BITS - 1 - 7);
+ noiseNrg[sfb] = tmp - nrg;
+ }
+ }
+}
+
+/*****************************************************************************
+
+ functionname:FDKaacEnc_CodePnsChannel
+ description: Execute pns decission
+ returns:
+ input: sfbActive
+ pns config structure
+ use PNS if pnsFlag
+ pointer to Sfb Energy, noiseNrg, Threshold
+ output: set sfbThreshold high to code pe with 0,
+ noiseNrg marks flag for pns coding
+
+*****************************************************************************/
+
+void FDKaacEnc_CodePnsChannel(const INT sfbActive, PNS_CONFIG *pnsConf,
+ INT *RESTRICT pnsFlag,
+ FIXP_DBL *RESTRICT sfbEnergyLdData,
+ INT *RESTRICT noiseNrg,
+ FIXP_DBL *RESTRICT sfbThresholdLdData) {
+ INT sfb;
+ INT lastiNoiseEnergy = 0;
+ INT firstPNSband = 1; /* TRUE for first PNS-coded band */
+
+ /* no PNS */
+ if (!pnsConf->usePns) {
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ /* no PNS coding */
+ noiseNrg[sfb] = NO_NOISE_PNS;
+ }
+ return;
+ }
+
+ /* code PNS */
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ if (pnsFlag[sfb]) {
+ /* high sfbThreshold causes pe = 0 */
+ if (noiseNrg[sfb] != NO_NOISE_PNS)
+ sfbThresholdLdData[sfb] =
+ sfbEnergyLdData[sfb] + FL2FXCONST_DBL(1.0f / LD_DATA_SCALING);
+
+ /* set noiseNrg in valid region */
+ if (!firstPNSband) {
+ INT deltaiNoiseEnergy = noiseNrg[sfb] - lastiNoiseEnergy;
+
+ if (deltaiNoiseEnergy > CODE_BOOK_PNS_LAV)
+ noiseNrg[sfb] -= deltaiNoiseEnergy - CODE_BOOK_PNS_LAV;
+ else if (deltaiNoiseEnergy < -CODE_BOOK_PNS_LAV)
+ noiseNrg[sfb] -= deltaiNoiseEnergy + CODE_BOOK_PNS_LAV;
+ } else {
+ firstPNSband = 0;
+ }
+ lastiNoiseEnergy = noiseNrg[sfb];
+ } else {
+ /* no PNS coding */
+ noiseNrg[sfb] = NO_NOISE_PNS;
+ }
+ }
+}
+
+/*****************************************************************************
+
+ functionname:FDKaacEnc_PreProcessPnsChannelPair
+ description: Calculate the correlation of noise in a channel pair
+
+ returns:
+ input: sfbActive
+ pointer to sfb energies left, right and mid channel
+ pns config structure
+ pns data structure left and right (modified)
+
+ output: noiseEnergyCorrelation in pns data structure
+
+*****************************************************************************/
+
+void FDKaacEnc_PreProcessPnsChannelPair(
+ const INT sfbActive, FIXP_DBL *RESTRICT sfbEnergyLeft,
+ FIXP_DBL *RESTRICT sfbEnergyRight, FIXP_DBL *RESTRICT sfbEnergyLeftLD,
+ FIXP_DBL *RESTRICT sfbEnergyRightLD, FIXP_DBL *RESTRICT sfbEnergyMid,
+ PNS_CONFIG *RESTRICT pnsConf, PNS_DATA *pnsDataLeft,
+ PNS_DATA *pnsDataRight) {
+ INT sfb;
+ FIXP_DBL ccf;
+
+ if (!pnsConf->usePns) return;
+
+ FIXP_DBL *RESTRICT pNoiseEnergyCorrelationL =
+ pnsDataLeft->noiseEnergyCorrelation;
+ FIXP_DBL *RESTRICT pNoiseEnergyCorrelationR =
+ pnsDataRight->noiseEnergyCorrelation;
+
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ FIXP_DBL quot = (sfbEnergyLeftLD[sfb] >> 1) + (sfbEnergyRightLD[sfb] >> 1);
+
+ if (quot < FL2FXCONST_DBL(-32.0f / (float)LD_DATA_SCALING))
+ ccf = FL2FXCONST_DBL(0.0f);
+ else {
+ FIXP_DBL accu =
+ sfbEnergyMid[sfb] -
+ (((sfbEnergyLeft[sfb] >> 1) + (sfbEnergyRight[sfb] >> 1)) >> 1);
+ INT sign = (accu < FL2FXCONST_DBL(0.0f)) ? 1 : 0;
+ accu = fixp_abs(accu);
+
+ ccf = CalcLdData(accu) +
+ FL2FXCONST_DBL((float)1.0f / (float)LD_DATA_SCALING) -
+ quot; /* ld(accu*2) = ld(accu) + 1 */
+ ccf = (ccf >= FL2FXCONST_DBL(0.0))
+ ? ((FIXP_DBL)MAXVAL_DBL)
+ : (sign) ? -CalcInvLdData(ccf) : CalcInvLdData(ccf);
+ }
+
+ pNoiseEnergyCorrelationL[sfb] = ccf;
+ pNoiseEnergyCorrelationR[sfb] = ccf;
+ }
+}
+
+/*****************************************************************************
+
+ functionname:FDKaacEnc_PostProcessPnsChannelPair
+ description: if PNS used at left and right channel,
+ use msMask to flag correlation
+ returns:
+ input: sfbActive
+ pns config structure
+ pns data structure left and right (modified)
+ pointer to msMask, flags correlation by pns coding (modified)
+ Digest of MS coding
+ output: pnsFlag in pns data structure,
+ msFlag in msMask (flags correlation)
+
+*****************************************************************************/
+
+void FDKaacEnc_PostProcessPnsChannelPair(const INT sfbActive,
+ PNS_CONFIG *pnsConf,
+ PNS_DATA *pnsDataLeft,
+ PNS_DATA *pnsDataRight,
+ INT *RESTRICT msMask, INT *msDigest) {
+ INT sfb;
+
+ if (!pnsConf->usePns) return;
+
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ /*
+ MS post processing
+ */
+ if (msMask[sfb]) {
+ if ((pnsDataLeft->pnsFlag[sfb]) && (pnsDataRight->pnsFlag[sfb])) {
+ /* AAC only: Standard */
+ /* do this to avoid ms flags in layers that should not have it */
+ if (pnsDataLeft->noiseEnergyCorrelation[sfb] <=
+ pnsConf->noiseCorrelationThresh) {
+ msMask[sfb] = 0;
+ *msDigest = MS_SOME;
+ }
+ } else {
+ /*
+ No PNS coding
+ */
+ pnsDataLeft->pnsFlag[sfb] = 0;
+ pnsDataRight->pnsFlag[sfb] = 0;
+ }
+ }
+
+ /*
+ Use MS flag to signal noise correlation if
+ pns is active in both channels
+ */
+ if ((pnsDataLeft->pnsFlag[sfb]) && (pnsDataRight->pnsFlag[sfb])) {
+ if (pnsDataLeft->noiseEnergyCorrelation[sfb] >
+ pnsConf->noiseCorrelationThresh) {
+ msMask[sfb] = 1;
+ *msDigest = MS_SOME;
+ }
+ }
+ }
+}
diff --git a/fdk-aac/libAACenc/src/aacenc_pns.h b/fdk-aac/libAACenc/src/aacenc_pns.h
new file mode 100644
index 0000000..4938fcf
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacenc_pns.h
@@ -0,0 +1,124 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser
+
+ Description: pns.h
+
+*******************************************************************************/
+
+#ifndef AACENC_PNS_H
+#define AACENC_PNS_H
+
+#include "common_fix.h"
+#include "pnsparam.h"
+
+#define NO_NOISE_PNS FDK_INT_MIN
+
+typedef struct {
+ NOISEPARAMS np;
+ FIXP_DBL minCorrelationEnergy;
+ FIXP_DBL noiseCorrelationThresh;
+ INT usePns;
+} PNS_CONFIG;
+
+typedef struct {
+ FIXP_SGL noiseFuzzyMeasure[MAX_GROUPED_SFB];
+ FIXP_DBL noiseEnergyCorrelation[MAX_GROUPED_SFB];
+ INT pnsFlag[MAX_GROUPED_SFB];
+} PNS_DATA;
+
+#endif /* AACENC_PNS_H */
diff --git a/fdk-aac/libAACenc/src/aacenc_tns.cpp b/fdk-aac/libAACenc/src/aacenc_tns.cpp
new file mode 100644
index 0000000..3436150
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacenc_tns.cpp
@@ -0,0 +1,1210 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): Alex Groeschel, Tobias Chalupka
+
+ Description: Temporal noise shaping
+
+*******************************************************************************/
+
+#include "aacenc_tns.h"
+#include "psy_const.h"
+#include "psy_configuration.h"
+#include "tns_func.h"
+#include "aacEnc_rom.h"
+#include "aacenc_tns.h"
+#include "FDK_lpc.h"
+
+#define FILTER_DIRECTION 0 /* 0 = up, 1 = down */
+
+static const FIXP_DBL acfWindowLong[12 + 3 + 1] = {
+ 0x7fffffff, 0x7fb80000, 0x7ee00000, 0x7d780000, 0x7b800000, 0x78f80000,
+ 0x75e00000, 0x72380000, 0x6e000000, 0x69380000, 0x63e00000, 0x5df80000,
+ 0x57800000, 0x50780000, 0x48e00000, 0x40b80000};
+
+static const FIXP_DBL acfWindowShort[4 + 3 + 1] = {
+ 0x7fffffff, 0x7e000000, 0x78000000, 0x6e000000,
+ 0x60000000, 0x4e000000, 0x38000000, 0x1e000000};
+
+typedef struct {
+ INT bitRateFrom[2]; /* noneSbr=0, useSbr=1 */
+ INT bitRateTo[2]; /* noneSbr=0, useSbr=1 */
+ TNS_PARAMETER_TABULATED paramTab[2]; /* mono=0, stereo=1 */
+
+} TNS_INFO_TAB;
+
+#define TNS_TIMERES_SCALE (1)
+#define FL2_TIMERES_FIX(a) (FL2FXCONST_DBL(a / (float)(1 << TNS_TIMERES_SCALE)))
+
+static const TNS_INFO_TAB tnsInfoTab[] = {
+ {{16000, 13500},
+ {32000, 28000},
+ {{{1, 1},
+ {1437, 1500},
+ {1400, 600},
+ {12, 12},
+ {FILTER_DIRECTION, FILTER_DIRECTION},
+ {3, 1},
+ {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.2f)},
+ 1},
+ {{1, 1},
+ {1437, 1500},
+ {1400, 600},
+ {12, 12},
+ {FILTER_DIRECTION, FILTER_DIRECTION},
+ {3, 1},
+ {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.2f)},
+ 1}}},
+ {{32001, 28001},
+ {60000, 52000},
+ {{{1, 1},
+ {1437, 1500},
+ {1400, 600},
+ {12, 10},
+ {FILTER_DIRECTION, FILTER_DIRECTION},
+ {3, 1},
+ {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)},
+ 1},
+ {{1, 1},
+ {1437, 1500},
+ {1400, 600},
+ {12, 10},
+ {FILTER_DIRECTION, FILTER_DIRECTION},
+ {3, 1},
+ {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)},
+ 1}}},
+ {{60001, 52001},
+ {384000, 384000},
+ {{{1, 1},
+ {1437, 1500},
+ {1400, 600},
+ {12, 8},
+ {FILTER_DIRECTION, FILTER_DIRECTION},
+ {3, 1},
+ {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)},
+ 1},
+ {{1, 1},
+ {1437, 1500},
+ {1400, 600},
+ {12, 8},
+ {FILTER_DIRECTION, FILTER_DIRECTION},
+ {3, 1},
+ {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)},
+ 1}}}};
+
+typedef struct {
+ INT samplingRate;
+ SCHAR maxBands[2]; /* long=0; short=1 */
+
+} TNS_MAX_TAB_ENTRY;
+
+static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab1024[] = {
+ {96000, {31, 9}}, {88200, {31, 9}}, {64000, {34, 10}}, {48000, {40, 14}},
+ {44100, {42, 14}}, {32000, {51, 14}}, {24000, {46, 14}}, {22050, {46, 14}},
+ {16000, {42, 14}}, {12000, {42, 14}}, {11025, {42, 14}}, {8000, {39, 14}}};
+
+static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab960[] =
+{
+ { 96000, { 31, 9}},
+ { 88200, { 31, 9}},
+ { 64000, { 34, 10}},
+ { 48000, { 49, 14}},
+ { 44100, { 49, 14}},
+ { 32000, { 49, 14}},
+ { 24000, { 46, 15}},
+ { 22050, { 46, 14}},
+ { 16000, { 46, 15}},
+ { 12000, { 42, 15}},
+ { 11025, { 42, 15}},
+ { 8000, { 40, 15}}
+};
+
+static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab120[] = {
+ {48000, {12, -1}}, /* 48000 */
+ {44100, {12, -1}}, /* 44100 */
+ {32000, {15, -1}}, /* 32000 */
+ {24000, {15, -1}}, /* 24000 */
+ {22050, {15, -1}} /* 22050 */
+};
+
+static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab128[] = {
+ {48000, {12, -1}}, /* 48000 */
+ {44100, {12, -1}}, /* 44100 */
+ {32000, {15, -1}}, /* 32000 */
+ {24000, {15, -1}}, /* 24000 */
+ {22050, {15, -1}} /* 22050 */
+};
+
+static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab240[] = {
+ {96000, {22, -1}}, /* 96000 */
+ {48000, {22, -1}}, /* 48000 */
+ {44100, {22, -1}}, /* 44100 */
+ {32000, {21, -1}}, /* 32000 */
+ {24000, {21, -1}}, /* 24000 */
+ {22050, {21, -1}} /* 22050 */
+};
+
+static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab256[] = {
+ {96000, {25, -1}}, /* 96000 */
+ {48000, {25, -1}}, /* 48000 */
+ {44100, {25, -1}}, /* 44100 */
+ {32000, {24, -1}}, /* 32000 */
+ {24000, {24, -1}}, /* 24000 */
+ {22050, {24, -1}} /* 22050 */
+};
+static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab480[] = {{48000, {31, -1}},
+ {44100, {32, -1}},
+ {32000, {37, -1}},
+ {24000, {30, -1}},
+ {22050, {30, -1}}};
+
+static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab512[] = {{48000, {31, -1}},
+ {44100, {32, -1}},
+ {32000, {37, -1}},
+ {24000, {31, -1}},
+ {22050, {31, -1}}};
+
+static void FDKaacEnc_Parcor2Index(const FIXP_LPC *parcor, INT *RESTRICT index,
+ const INT order, const INT bitsPerCoeff);
+
+static void FDKaacEnc_Index2Parcor(const INT *index, FIXP_LPC *RESTRICT parcor,
+ const INT order, const INT bitsPerCoeff);
+
+static void FDKaacEnc_CalcGaussWindow(FIXP_DBL *win, const int winSize,
+ const INT samplingRate,
+ const INT transformResolution,
+ const FIXP_DBL timeResolution,
+ const INT timeResolution_e);
+
+static const TNS_PARAMETER_TABULATED *FDKaacEnc_GetTnsParam(const INT bitRate,
+ const INT channels,
+ const INT sbrLd) {
+ int i;
+ const TNS_PARAMETER_TABULATED *tnsConfigTab = NULL;
+
+ for (i = 0; i < (int)(sizeof(tnsInfoTab) / sizeof(TNS_INFO_TAB)); i++) {
+ if ((bitRate >= tnsInfoTab[i].bitRateFrom[sbrLd ? 1 : 0]) &&
+ bitRate <= tnsInfoTab[i].bitRateTo[sbrLd ? 1 : 0]) {
+ tnsConfigTab = &tnsInfoTab[i].paramTab[(channels == 1) ? 0 : 1];
+ }
+ }
+
+ return tnsConfigTab;
+}
+
+static INT getTnsMaxBands(const INT sampleRate, const INT granuleLength,
+ const INT isShortBlock) {
+ int i;
+ INT numBands = -1;
+ const TNS_MAX_TAB_ENTRY *pMaxBandsTab = NULL;
+ int maxBandsTabSize = 0;
+
+ switch (granuleLength) {
+ case 960:
+ pMaxBandsTab = tnsMaxBandsTab960;
+ maxBandsTabSize = sizeof(tnsMaxBandsTab960) / sizeof(TNS_MAX_TAB_ENTRY);
+ break;
+ case 1024:
+ pMaxBandsTab = tnsMaxBandsTab1024;
+ maxBandsTabSize = sizeof(tnsMaxBandsTab1024) / sizeof(TNS_MAX_TAB_ENTRY);
+ break;
+ case 120:
+ pMaxBandsTab = tnsMaxBandsTab120;
+ maxBandsTabSize = sizeof(tnsMaxBandsTab120) / sizeof(TNS_MAX_TAB_ENTRY);
+ break;
+ case 128:
+ pMaxBandsTab = tnsMaxBandsTab128;
+ maxBandsTabSize = sizeof(tnsMaxBandsTab128) / sizeof(TNS_MAX_TAB_ENTRY);
+ break;
+ case 240:
+ pMaxBandsTab = tnsMaxBandsTab240;
+ maxBandsTabSize = sizeof(tnsMaxBandsTab240) / sizeof(TNS_MAX_TAB_ENTRY);
+ break;
+ case 256:
+ pMaxBandsTab = tnsMaxBandsTab256;
+ maxBandsTabSize = sizeof(tnsMaxBandsTab256) / sizeof(TNS_MAX_TAB_ENTRY);
+ break;
+ case 480:
+ pMaxBandsTab = tnsMaxBandsTab480;
+ maxBandsTabSize = sizeof(tnsMaxBandsTab480) / sizeof(TNS_MAX_TAB_ENTRY);
+ break;
+ case 512:
+ pMaxBandsTab = tnsMaxBandsTab512;
+ maxBandsTabSize = sizeof(tnsMaxBandsTab512) / sizeof(TNS_MAX_TAB_ENTRY);
+ break;
+ default:
+ numBands = -1;
+ }
+
+ if (pMaxBandsTab != NULL) {
+ for (i = 0; i < maxBandsTabSize; i++) {
+ numBands = pMaxBandsTab[i].maxBands[(!isShortBlock) ? 0 : 1];
+ if (sampleRate >= pMaxBandsTab[i].samplingRate) {
+ break;
+ }
+ }
+ }
+
+ return numBands;
+}
+
+/***************************************************************************/
+/*!
+ \brief FDKaacEnc_FreqToBandWidthRounding
+
+ Returns index of nearest band border
+
+ \param frequency
+ \param sampling frequency
+ \param total number of bands
+ \param pointer to table of band borders
+
+ \return band border
+****************************************************************************/
+
+INT FDKaacEnc_FreqToBandWidthRounding(const INT freq, const INT fs,
+ const INT numOfBands,
+ const INT *bandStartOffset) {
+ INT lineNumber, band;
+
+ /* assert(freq >= 0); */
+ lineNumber = (freq * bandStartOffset[numOfBands] * 4 / fs + 1) / 2;
+
+ /* freq > fs/2 */
+ if (lineNumber >= bandStartOffset[numOfBands]) return numOfBands;
+
+ /* find band the line number lies in */
+ for (band = 0; band < numOfBands; band++) {
+ if (bandStartOffset[band + 1] > lineNumber) break;
+ }
+
+ /* round to nearest band border */
+ if (lineNumber - bandStartOffset[band] >
+ bandStartOffset[band + 1] - lineNumber) {
+ band++;
+ }
+
+ return (band);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_InitTnsConfiguration
+ description: fill TNS_CONFIG structure with sensible content
+ returns:
+ input: bitrate, samplerate, number of channels,
+ blocktype (long or short),
+ TNS Config struct (modified),
+ psy config struct,
+ tns active flag
+ output:
+
+*****************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(
+ INT bitRate, INT sampleRate, INT channels, INT blockType, INT granuleLength,
+ INT isLowDelay, INT ldSbrPresent, TNS_CONFIG *tC, PSY_CONFIGURATION *pC,
+ INT active, INT useTnsPeak) {
+ int i;
+ // float acfTimeRes = (blockType == SHORT_WINDOW) ? 0.125f : 0.046875f;
+
+ if (channels <= 0) return (AAC_ENCODER_ERROR)1;
+
+ tC->isLowDelay = isLowDelay;
+
+ /* initialize TNS filter flag, order, and coefficient resolution (in bits per
+ * coeff) */
+ tC->tnsActive = (active) ? TRUE : FALSE;
+ tC->maxOrder = (blockType == SHORT_WINDOW) ? 5 : 12; /* maximum: 7, 20 */
+ if (bitRate < 16000) tC->maxOrder -= 2;
+ tC->coefRes = (blockType == SHORT_WINDOW) ? 3 : 4;
+
+ /* LPC stop line: highest MDCT line to be coded, but do not go beyond
+ * TNS_MAX_BANDS! */
+ tC->lpcStopBand = getTnsMaxBands(sampleRate, granuleLength,
+ (blockType == SHORT_WINDOW) ? 1 : 0);
+
+ if (tC->lpcStopBand < 0) {
+ return (AAC_ENCODER_ERROR)1;
+ }
+
+ tC->lpcStopBand = fMin(tC->lpcStopBand, pC->sfbActive);
+ tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand];
+
+ switch (granuleLength) {
+ case 960:
+ case 1024:
+ /* TNS start line: skip lower MDCT lines to prevent artifacts due to
+ * filter mismatch */
+ if (blockType == SHORT_WINDOW) {
+ tC->lpcStartBand[LOFILT] = 0;
+ } else {
+ tC->lpcStartBand[LOFILT] =
+ (sampleRate < 9391) ? 2 : ((sampleRate < 18783) ? 4 : 8);
+ }
+ tC->lpcStartLine[LOFILT] = pC->sfbOffset[tC->lpcStartBand[LOFILT]];
+
+ i = tC->lpcStopBand;
+ while (pC->sfbOffset[i] >
+ (tC->lpcStartLine[LOFILT] +
+ (tC->lpcStopLine - tC->lpcStartLine[LOFILT]) / 4))
+ i--;
+ tC->lpcStartBand[HIFILT] = i;
+ tC->lpcStartLine[HIFILT] = pC->sfbOffset[i];
+
+ tC->confTab.threshOn[HIFILT] = 1437;
+ tC->confTab.threshOn[LOFILT] = 1500;
+
+ tC->confTab.tnsLimitOrder[HIFILT] = tC->maxOrder;
+ tC->confTab.tnsLimitOrder[LOFILT] = fMax(0, tC->maxOrder - 7);
+
+ tC->confTab.tnsFilterDirection[HIFILT] = FILTER_DIRECTION;
+ tC->confTab.tnsFilterDirection[LOFILT] = FILTER_DIRECTION;
+
+ tC->confTab.acfSplit[HIFILT] =
+ -1; /* signal Merged4to2QuartersAutoCorrelation in
+ FDKaacEnc_MergedAutoCorrelation*/
+ tC->confTab.acfSplit[LOFILT] =
+ -1; /* signal Merged4to2QuartersAutoCorrelation in
+ FDKaacEnc_MergedAutoCorrelation */
+
+ tC->confTab.filterEnabled[HIFILT] = 1;
+ tC->confTab.filterEnabled[LOFILT] = 1;
+ tC->confTab.seperateFiltersAllowed = 1;
+
+ /* compute autocorrelation window based on maximum filter order for given
+ * block type */
+ /* for (i = 0; i <= tC->maxOrder + 3; i++) {
+ float acfWinTemp = acfTimeRes * i;
+ acfWindow[i] = FL2FXCONST_DBL(1.0f - acfWinTemp * acfWinTemp);
+ }
+ */
+ if (blockType == SHORT_WINDOW) {
+ FDKmemcpy(tC->acfWindow[HIFILT], acfWindowShort,
+ fMin((LONG)sizeof(acfWindowShort),
+ (LONG)sizeof(tC->acfWindow[HIFILT])));
+ FDKmemcpy(tC->acfWindow[LOFILT], acfWindowShort,
+ fMin((LONG)sizeof(acfWindowShort),
+ (LONG)sizeof(tC->acfWindow[HIFILT])));
+ } else {
+ FDKmemcpy(tC->acfWindow[HIFILT], acfWindowLong,
+ fMin((LONG)sizeof(acfWindowLong),
+ (LONG)sizeof(tC->acfWindow[HIFILT])));
+ FDKmemcpy(tC->acfWindow[LOFILT], acfWindowLong,
+ fMin((LONG)sizeof(acfWindowLong),
+ (LONG)sizeof(tC->acfWindow[HIFILT])));
+ }
+ break;
+ case 480:
+ case 512: {
+ const TNS_PARAMETER_TABULATED *pCfg =
+ FDKaacEnc_GetTnsParam(bitRate, channels, ldSbrPresent);
+ if (pCfg != NULL) {
+ FDKmemcpy(&(tC->confTab), pCfg, sizeof(tC->confTab));
+
+ tC->lpcStartBand[HIFILT] = FDKaacEnc_FreqToBandWidthRounding(
+ pCfg->filterStartFreq[HIFILT], sampleRate, pC->sfbCnt,
+ pC->sfbOffset);
+ tC->lpcStartLine[HIFILT] = pC->sfbOffset[tC->lpcStartBand[HIFILT]];
+ tC->lpcStartBand[LOFILT] = FDKaacEnc_FreqToBandWidthRounding(
+ pCfg->filterStartFreq[LOFILT], sampleRate, pC->sfbCnt,
+ pC->sfbOffset);
+ tC->lpcStartLine[LOFILT] = pC->sfbOffset[tC->lpcStartBand[LOFILT]];
+
+ FDKaacEnc_CalcGaussWindow(
+ tC->acfWindow[HIFILT], tC->maxOrder + 1, sampleRate, granuleLength,
+ pCfg->tnsTimeResolution[HIFILT], TNS_TIMERES_SCALE);
+ FDKaacEnc_CalcGaussWindow(
+ tC->acfWindow[LOFILT], tC->maxOrder + 1, sampleRate, granuleLength,
+ pCfg->tnsTimeResolution[LOFILT], TNS_TIMERES_SCALE);
+ } else {
+ tC->tnsActive =
+ FALSE; /* no configuration available, disable tns tool */
+ }
+ } break;
+ default:
+ tC->tnsActive = FALSE; /* no configuration available, disable tns tool */
+ }
+
+ return AAC_ENC_OK;
+}
+
+/***************************************************************************/
+/*!
+ \brief FDKaacEnc_ScaleUpSpectrum
+
+ Scales up spectrum lines in a given frequency section
+
+ \param scaled spectrum
+ \param original spectrum
+ \param frequency line to start scaling
+ \param frequency line to enc scaling
+
+ \return scale factor
+
+****************************************************************************/
+static inline INT FDKaacEnc_ScaleUpSpectrum(FIXP_DBL *dest, const FIXP_DBL *src,
+ const INT startLine,
+ const INT stopLine) {
+ INT i, scale;
+
+ FIXP_DBL maxVal = FL2FXCONST_DBL(0.f);
+
+ /* Get highest value in given spectrum */
+ for (i = startLine; i < stopLine; i++) {
+ maxVal = fixMax(maxVal, fixp_abs(src[i]));
+ }
+ scale = CountLeadingBits(maxVal);
+
+ /* Scale spectrum according to highest value */
+ for (i = startLine; i < stopLine; i++) {
+ dest[i] = src[i] << scale;
+ }
+
+ return scale;
+}
+
+/***************************************************************************/
+/*!
+ \brief FDKaacEnc_CalcAutoCorrValue
+
+ Calculate autocorellation value for one lag
+
+ \param pointer to spectrum
+ \param start line
+ \param stop line
+ \param lag to be calculated
+ \param scaling of the lag
+
+****************************************************************************/
+static inline FIXP_DBL FDKaacEnc_CalcAutoCorrValue(const FIXP_DBL *spectrum,
+ const INT startLine,
+ const INT stopLine,
+ const INT lag,
+ const INT scale) {
+ int i;
+ FIXP_DBL result = FL2FXCONST_DBL(0.f);
+
+ /* This versions allows to save memory accesses, when computing pow2 */
+ /* It is of interest for ARM, XTENSA without parallel memory access */
+ if (lag == 0) {
+ for (i = startLine; i < stopLine; i++) {
+ result += (fPow2(spectrum[i]) >> scale);
+ }
+ } else {
+ for (i = startLine; i < (stopLine - lag); i++) {
+ result += (fMult(spectrum[i], spectrum[i + lag]) >> scale);
+ }
+ }
+
+ return result;
+}
+
+/***************************************************************************/
+/*!
+ \brief FDKaacEnc_AutoCorrNormFac
+
+ Autocorrelation function for 1st and 2nd half of the spectrum
+
+ \param pointer to spectrum
+ \param pointer to autocorrelation window
+ \param filter start line
+
+****************************************************************************/
+static inline FIXP_DBL FDKaacEnc_AutoCorrNormFac(const FIXP_DBL value,
+ const INT scale, INT *sc) {
+#define HLM_MIN_NRG 0.0000000037252902984619140625f /* 2^-28 */
+#define MAX_INV_NRGFAC (1.f / HLM_MIN_NRG)
+
+ FIXP_DBL retValue;
+ FIXP_DBL A, B;
+
+ if (scale >= 0) {
+ A = value;
+ B = FL2FXCONST_DBL(HLM_MIN_NRG) >> fixMin(DFRACT_BITS - 1, scale);
+ } else {
+ A = value >> fixMin(DFRACT_BITS - 1, (-scale));
+ B = FL2FXCONST_DBL(HLM_MIN_NRG);
+ }
+
+ if (A > B) {
+ int shift = 0;
+ FIXP_DBL tmp = invSqrtNorm2(value, &shift);
+
+ retValue = fMult(tmp, tmp);
+ *sc += (2 * shift);
+ } else {
+ /* MAX_INV_NRGFAC*FDKpow(2,-28) = 1/2^-28 * 2^-28 = 1.0 */
+ retValue =
+ /*FL2FXCONST_DBL(MAX_INV_NRGFAC*FDKpow(2,-28))*/ (FIXP_DBL)MAXVAL_DBL;
+ *sc += scale + 28;
+ }
+
+ return retValue;
+}
+
+static void FDKaacEnc_MergedAutoCorrelation(
+ const FIXP_DBL *spectrum, const INT isLowDelay,
+ const FIXP_DBL acfWindow[MAX_NUM_OF_FILTERS][TNS_MAX_ORDER + 3 + 1],
+ const INT lpcStartLine[MAX_NUM_OF_FILTERS], const INT lpcStopLine,
+ const INT maxOrder, const INT acfSplit[MAX_NUM_OF_FILTERS], FIXP_DBL *_rxx1,
+ FIXP_DBL *_rxx2) {
+ int i, idx0, idx1, idx2, idx3, idx4, lag;
+ FIXP_DBL rxx1_0, rxx2_0, rxx3_0, rxx4_0;
+
+ /* buffer for temporal spectrum */
+ C_ALLOC_SCRATCH_START(pSpectrum, FIXP_DBL, (1024))
+
+ /* MDCT line indices separating the 1st, 2nd, 3rd, and 4th analysis quarters
+ */
+ if ((acfSplit[LOFILT] == -1) || (acfSplit[HIFILT] == -1)) {
+ /* autocorrelation function for 1st, 2nd, 3rd, and 4th quarter of the
+ * spectrum */
+ idx0 = lpcStartLine[LOFILT];
+ i = lpcStopLine - lpcStartLine[LOFILT];
+ idx1 = idx0 + i / 4;
+ idx2 = idx0 + i / 2;
+ idx3 = idx0 + i * 3 / 4;
+ idx4 = lpcStopLine;
+ } else {
+ FDK_ASSERT(acfSplit[LOFILT] == 1);
+ FDK_ASSERT(acfSplit[HIFILT] == 3);
+ i = (lpcStopLine - lpcStartLine[HIFILT]) / 3;
+ idx0 = lpcStartLine[LOFILT];
+ idx1 = lpcStartLine[HIFILT];
+ idx2 = idx1 + i;
+ idx3 = idx2 + i;
+ idx4 = lpcStopLine;
+ }
+
+ /* copy spectrum to temporal buffer and scale up as much as possible */
+ INT sc1 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx0, idx1);
+ INT sc2 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx1, idx2);
+ INT sc3 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx2, idx3);
+ INT sc4 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx3, idx4);
+
+ /* get scaling values for summation */
+ INT nsc1, nsc2, nsc3, nsc4;
+ for (nsc1 = 1; (1 << nsc1) < (idx1 - idx0); nsc1++)
+ ;
+ for (nsc2 = 1; (1 << nsc2) < (idx2 - idx1); nsc2++)
+ ;
+ for (nsc3 = 1; (1 << nsc3) < (idx3 - idx2); nsc3++)
+ ;
+ for (nsc4 = 1; (1 << nsc4) < (idx4 - idx3); nsc4++)
+ ;
+
+ /* compute autocorrelation value at lag zero, i. e. energy, for each quarter
+ */
+ rxx1_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, 0, nsc1);
+ rxx2_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx1, idx2, 0, nsc2);
+ rxx3_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx2, idx3, 0, nsc3);
+ rxx4_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx3, idx4, 0, nsc4);
+
+ /* compute energy normalization factors, i. e. 1/energy (saves some divisions)
+ */
+ if (rxx1_0 != FL2FXCONST_DBL(0.f)) {
+ INT sc_fac1 = -1;
+ FIXP_DBL fac1 =
+ FDKaacEnc_AutoCorrNormFac(rxx1_0, ((-2 * sc1) + nsc1), &sc_fac1);
+ _rxx1[0] = scaleValue(fMult(rxx1_0, fac1), sc_fac1);
+
+ if (isLowDelay) {
+ for (lag = 1; lag <= maxOrder; lag++) {
+ /* compute energy-normalized and windowed autocorrelation values at this
+ * lag */
+ FIXP_DBL x1 =
+ FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, lag, nsc1);
+ _rxx1[lag] =
+ fMult(scaleValue(fMult(x1, fac1), sc_fac1), acfWindow[LOFILT][lag]);
+ }
+ } else {
+ for (lag = 1; lag <= maxOrder; lag++) {
+ if ((3 * lag) <= maxOrder + 3) {
+ FIXP_DBL x1 =
+ FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, lag, nsc1);
+ _rxx1[lag] = fMult(scaleValue(fMult(x1, fac1), sc_fac1),
+ acfWindow[LOFILT][3 * lag]);
+ }
+ }
+ }
+ }
+
+ /* auto corr over upper 3/4 of spectrum */
+ if (!((rxx2_0 == FL2FXCONST_DBL(0.f)) && (rxx3_0 == FL2FXCONST_DBL(0.f)) &&
+ (rxx4_0 == FL2FXCONST_DBL(0.f)))) {
+ FIXP_DBL fac2, fac3, fac4;
+ fac2 = fac3 = fac4 = FL2FXCONST_DBL(0.f);
+ INT sc_fac2, sc_fac3, sc_fac4;
+ sc_fac2 = sc_fac3 = sc_fac4 = 0;
+
+ if (rxx2_0 != FL2FXCONST_DBL(0.f)) {
+ fac2 = FDKaacEnc_AutoCorrNormFac(rxx2_0, ((-2 * sc2) + nsc2), &sc_fac2);
+ sc_fac2 -= 2;
+ }
+ if (rxx3_0 != FL2FXCONST_DBL(0.f)) {
+ fac3 = FDKaacEnc_AutoCorrNormFac(rxx3_0, ((-2 * sc3) + nsc3), &sc_fac3);
+ sc_fac3 -= 2;
+ }
+ if (rxx4_0 != FL2FXCONST_DBL(0.f)) {
+ fac4 = FDKaacEnc_AutoCorrNormFac(rxx4_0, ((-2 * sc4) + nsc4), &sc_fac4);
+ sc_fac4 -= 2;
+ }
+
+ _rxx2[0] = scaleValue(fMult(rxx2_0, fac2), sc_fac2) +
+ scaleValue(fMult(rxx3_0, fac3), sc_fac3) +
+ scaleValue(fMult(rxx4_0, fac4), sc_fac4);
+
+ for (lag = 1; lag <= maxOrder; lag++) {
+ /* merge quarters 2, 3, 4 into one autocorrelation; quarter 1 stays
+ * separate */
+ FIXP_DBL x2 = scaleValue(fMult(FDKaacEnc_CalcAutoCorrValue(
+ pSpectrum, idx1, idx2, lag, nsc2),
+ fac2),
+ sc_fac2) +
+ scaleValue(fMult(FDKaacEnc_CalcAutoCorrValue(
+ pSpectrum, idx2, idx3, lag, nsc3),
+ fac3),
+ sc_fac3) +
+ scaleValue(fMult(FDKaacEnc_CalcAutoCorrValue(
+ pSpectrum, idx3, idx4, lag, nsc4),
+ fac4),
+ sc_fac4);
+
+ _rxx2[lag] = fMult(x2, acfWindow[HIFILT][lag]);
+ }
+ }
+
+ C_ALLOC_SCRATCH_END(pSpectrum, FIXP_DBL, (1024))
+}
+
+/*****************************************************************************
+ functionname: FDKaacEnc_TnsDetect
+ description: do decision, if TNS shall be used or not
+ returns:
+ input: tns data structure (modified),
+ tns config structure,
+ scalefactor size and table,
+ spectrum,
+ subblock num, blocktype,
+ sfb-wise energy.
+
+*****************************************************************************/
+INT FDKaacEnc_TnsDetect(TNS_DATA *tnsData, const TNS_CONFIG *tC,
+ TNS_INFO *tnsInfo, INT sfbCnt, const FIXP_DBL *spectrum,
+ INT subBlockNumber, INT blockType) {
+ /* autocorrelation function for 1st, 2nd, 3rd, and 4th quarter of the
+ * spectrum. */
+ FIXP_DBL rxx1[TNS_MAX_ORDER + 1]; /* higher part */
+ FIXP_DBL rxx2[TNS_MAX_ORDER + 1]; /* lower part */
+ FIXP_LPC parcor_tmp[TNS_MAX_ORDER];
+
+ int i;
+
+ FDKmemclear(rxx1, sizeof(rxx1));
+ FDKmemclear(rxx2, sizeof(rxx2));
+
+ TNS_SUBBLOCK_INFO *tsbi =
+ (blockType == SHORT_WINDOW)
+ ? &tnsData->dataRaw.Short.subBlockInfo[subBlockNumber]
+ : &tnsData->dataRaw.Long.subBlockInfo;
+
+ tnsData->filtersMerged = FALSE;
+
+ tsbi->tnsActive[HIFILT] = FALSE;
+ tsbi->predictionGain[HIFILT] = 1000;
+ tsbi->tnsActive[LOFILT] = FALSE;
+ tsbi->predictionGain[LOFILT] = 1000;
+
+ tnsInfo->numOfFilters[subBlockNumber] = 0;
+ tnsInfo->coefRes[subBlockNumber] = tC->coefRes;
+ for (i = 0; i < tC->maxOrder; i++) {
+ tnsInfo->coef[subBlockNumber][HIFILT][i] =
+ tnsInfo->coef[subBlockNumber][LOFILT][i] = 0;
+ }
+
+ tnsInfo->length[subBlockNumber][HIFILT] =
+ tnsInfo->length[subBlockNumber][LOFILT] = 0;
+ tnsInfo->order[subBlockNumber][HIFILT] =
+ tnsInfo->order[subBlockNumber][LOFILT] = 0;
+
+ if ((tC->tnsActive) && (tC->maxOrder > 0)) {
+ int sumSqrCoef;
+
+ FDKaacEnc_MergedAutoCorrelation(
+ spectrum, tC->isLowDelay, tC->acfWindow, tC->lpcStartLine,
+ tC->lpcStopLine, tC->maxOrder, tC->confTab.acfSplit, rxx1, rxx2);
+
+ /* compute higher TNS filter coefficients in lattice form (ParCor) with
+ * LeRoux-Gueguen/Schur algorithm */
+ {
+ FIXP_DBL predictionGain_m;
+ INT predictionGain_e;
+
+ CLpc_AutoToParcor(rxx2, 0, parcor_tmp, tC->confTab.tnsLimitOrder[HIFILT],
+ &predictionGain_m, &predictionGain_e);
+ tsbi->predictionGain[HIFILT] =
+ (INT)fMultNorm(predictionGain_m, predictionGain_e, 1000, 31, 31);
+ }
+
+ /* non-linear quantization of TNS lattice coefficients with given resolution
+ */
+ FDKaacEnc_Parcor2Index(parcor_tmp, tnsInfo->coef[subBlockNumber][HIFILT],
+ tC->confTab.tnsLimitOrder[HIFILT], tC->coefRes);
+
+ /* reduce filter order by truncating trailing zeros, compute sum(abs(coefs))
+ */
+ for (i = tC->confTab.tnsLimitOrder[HIFILT] - 1; i >= 0; i--) {
+ if (tnsInfo->coef[subBlockNumber][HIFILT][i] != 0) {
+ break;
+ }
+ }
+
+ tnsInfo->order[subBlockNumber][HIFILT] = i + 1;
+
+ sumSqrCoef = 0;
+ for (; i >= 0; i--) {
+ sumSqrCoef += tnsInfo->coef[subBlockNumber][HIFILT][i] *
+ tnsInfo->coef[subBlockNumber][HIFILT][i];
+ }
+
+ tnsInfo->direction[subBlockNumber][HIFILT] =
+ tC->confTab.tnsFilterDirection[HIFILT];
+ tnsInfo->length[subBlockNumber][HIFILT] = sfbCnt - tC->lpcStartBand[HIFILT];
+
+ /* disable TNS if predictionGain is less than 3dB or sumSqrCoef is too small
+ */
+ if ((tsbi->predictionGain[HIFILT] > tC->confTab.threshOn[HIFILT]) ||
+ (sumSqrCoef > (tC->confTab.tnsLimitOrder[HIFILT] / 2 + 2))) {
+ tsbi->tnsActive[HIFILT] = TRUE;
+ tnsInfo->numOfFilters[subBlockNumber]++;
+
+ /* compute second filter for lower quarter; only allowed for long windows!
+ */
+ if ((blockType != SHORT_WINDOW) && (tC->confTab.filterEnabled[LOFILT]) &&
+ (tC->confTab.seperateFiltersAllowed)) {
+ /* compute second filter for lower frequencies */
+
+ /* compute TNS filter in lattice (ParCor) form with LeRoux-Gueguen
+ * algorithm */
+ INT predGain;
+ {
+ FIXP_DBL predictionGain_m;
+ INT predictionGain_e;
+
+ CLpc_AutoToParcor(rxx1, 0, parcor_tmp,
+ tC->confTab.tnsLimitOrder[LOFILT],
+ &predictionGain_m, &predictionGain_e);
+ predGain =
+ (INT)fMultNorm(predictionGain_m, predictionGain_e, 1000, 31, 31);
+ }
+
+ /* non-linear quantization of TNS lattice coefficients with given
+ * resolution */
+ FDKaacEnc_Parcor2Index(parcor_tmp,
+ tnsInfo->coef[subBlockNumber][LOFILT],
+ tC->confTab.tnsLimitOrder[LOFILT], tC->coefRes);
+
+ /* reduce filter order by truncating trailing zeros, compute
+ * sum(abs(coefs)) */
+ for (i = tC->confTab.tnsLimitOrder[LOFILT] - 1; i >= 0; i--) {
+ if (tnsInfo->coef[subBlockNumber][LOFILT][i] != 0) {
+ break;
+ }
+ }
+ tnsInfo->order[subBlockNumber][LOFILT] = i + 1;
+
+ sumSqrCoef = 0;
+ for (; i >= 0; i--) {
+ sumSqrCoef += tnsInfo->coef[subBlockNumber][LOFILT][i] *
+ tnsInfo->coef[subBlockNumber][LOFILT][i];
+ }
+
+ tnsInfo->direction[subBlockNumber][LOFILT] =
+ tC->confTab.tnsFilterDirection[LOFILT];
+ tnsInfo->length[subBlockNumber][LOFILT] =
+ tC->lpcStartBand[HIFILT] - tC->lpcStartBand[LOFILT];
+
+ /* filter lower quarter if gain is high enough, but not if it's too high
+ */
+ if (((predGain > tC->confTab.threshOn[LOFILT]) &&
+ (predGain < (16000 * tC->confTab.tnsLimitOrder[LOFILT]))) ||
+ ((sumSqrCoef > 9) &&
+ (sumSqrCoef < 22 * tC->confTab.tnsLimitOrder[LOFILT]))) {
+ /* compare lower to upper filter; if they are very similar, merge them
+ */
+ tsbi->tnsActive[LOFILT] = TRUE;
+ sumSqrCoef = 0;
+ for (i = 0; i < tC->confTab.tnsLimitOrder[LOFILT]; i++) {
+ sumSqrCoef += fAbs(tnsInfo->coef[subBlockNumber][HIFILT][i] -
+ tnsInfo->coef[subBlockNumber][LOFILT][i]);
+ }
+ if ((sumSqrCoef < 2) &&
+ (tnsInfo->direction[subBlockNumber][LOFILT] ==
+ tnsInfo->direction[subBlockNumber][HIFILT])) {
+ tnsData->filtersMerged = TRUE;
+ tnsInfo->length[subBlockNumber][HIFILT] =
+ sfbCnt - tC->lpcStartBand[LOFILT];
+ for (; i < tnsInfo->order[subBlockNumber][HIFILT]; i++) {
+ if (fAbs(tnsInfo->coef[subBlockNumber][HIFILT][i]) > 1) {
+ break;
+ }
+ }
+ for (i--; i >= 0; i--) {
+ if (tnsInfo->coef[subBlockNumber][HIFILT][i] != 0) {
+ break;
+ }
+ }
+ if (i < tnsInfo->order[subBlockNumber][HIFILT]) {
+ tnsInfo->order[subBlockNumber][HIFILT] = i + 1;
+ }
+ } else {
+ tnsInfo->numOfFilters[subBlockNumber]++;
+ }
+ } /* filter lower part */
+ tsbi->predictionGain[LOFILT] = predGain;
+
+ } /* second filter allowed */
+ } /* if predictionGain > 1437 ... */
+ } /* maxOrder > 0 && tnsActive */
+
+ return 0;
+}
+
+/***************************************************************************/
+/*!
+ \brief FDKaacLdEnc_TnsSync
+
+ synchronize TNS parameters when TNS gain difference small (relative)
+
+ \param pointer to TNS data structure (destination)
+ \param pointer to TNS data structure (source)
+ \param pointer to TNS config structure
+ \param number of sub-block
+ \param block type
+
+ \return void
+****************************************************************************/
+void FDKaacEnc_TnsSync(TNS_DATA *tnsDataDest, const TNS_DATA *tnsDataSrc,
+ TNS_INFO *tnsInfoDest, TNS_INFO *tnsInfoSrc,
+ const INT blockTypeDest, const INT blockTypeSrc,
+ const TNS_CONFIG *tC) {
+ int i, w, absDiff, nWindows;
+ TNS_SUBBLOCK_INFO *sbInfoDest;
+ const TNS_SUBBLOCK_INFO *sbInfoSrc;
+
+ /* if one channel contains short blocks and the other not, do not synchronize
+ */
+ if ((blockTypeSrc == SHORT_WINDOW && blockTypeDest != SHORT_WINDOW) ||
+ (blockTypeDest == SHORT_WINDOW && blockTypeSrc != SHORT_WINDOW)) {
+ return;
+ }
+
+ if (blockTypeDest != SHORT_WINDOW) {
+ sbInfoDest = &tnsDataDest->dataRaw.Long.subBlockInfo;
+ sbInfoSrc = &tnsDataSrc->dataRaw.Long.subBlockInfo;
+ nWindows = 1;
+ } else {
+ sbInfoDest = &tnsDataDest->dataRaw.Short.subBlockInfo[0];
+ sbInfoSrc = &tnsDataSrc->dataRaw.Short.subBlockInfo[0];
+ nWindows = 8;
+ }
+
+ for (w = 0; w < nWindows; w++) {
+ const TNS_SUBBLOCK_INFO *pSbInfoSrcW = sbInfoSrc + w;
+ TNS_SUBBLOCK_INFO *pSbInfoDestW = sbInfoDest + w;
+ INT doSync = 1, absDiffSum = 0;
+
+ /* if TNS is active in at least one channel, check if ParCor coefficients of
+ * higher filter are similar */
+ if (pSbInfoDestW->tnsActive[HIFILT] || pSbInfoSrcW->tnsActive[HIFILT]) {
+ for (i = 0; i < tC->maxOrder; i++) {
+ absDiff = fAbs(tnsInfoDest->coef[w][HIFILT][i] -
+ tnsInfoSrc->coef[w][HIFILT][i]);
+ absDiffSum += absDiff;
+ /* if coefficients diverge too much between channels, do not synchronize
+ */
+ if ((absDiff > 1) || (absDiffSum > 2)) {
+ doSync = 0;
+ break;
+ }
+ }
+
+ if (doSync) {
+ /* if no significant difference was detected, synchronize coefficient
+ * sets */
+ if (pSbInfoSrcW->tnsActive[HIFILT]) {
+ /* no dest filter, or more dest than source filters: use one dest
+ * filter */
+ if ((!pSbInfoDestW->tnsActive[HIFILT]) ||
+ ((pSbInfoDestW->tnsActive[HIFILT]) &&
+ (tnsInfoDest->numOfFilters[w] > tnsInfoSrc->numOfFilters[w]))) {
+ pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 1;
+ }
+ tnsDataDest->filtersMerged = tnsDataSrc->filtersMerged;
+ tnsInfoDest->order[w][HIFILT] = tnsInfoSrc->order[w][HIFILT];
+ tnsInfoDest->length[w][HIFILT] = tnsInfoSrc->length[w][HIFILT];
+ tnsInfoDest->direction[w][HIFILT] = tnsInfoSrc->direction[w][HIFILT];
+ tnsInfoDest->coefCompress[w][HIFILT] =
+ tnsInfoSrc->coefCompress[w][HIFILT];
+
+ for (i = 0; i < tC->maxOrder; i++) {
+ tnsInfoDest->coef[w][HIFILT][i] = tnsInfoSrc->coef[w][HIFILT][i];
+ }
+ } else
+ pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 0;
+ }
+ }
+ }
+}
+
+/***************************************************************************/
+/*!
+ \brief FDKaacEnc_TnsEncode
+
+ perform TNS encoding
+
+ \param pointer to TNS info structure
+ \param pointer to TNS data structure
+ \param number of sfbs
+ \param pointer to TNS config structure
+ \param low-pass line
+ \param pointer to spectrum
+ \param number of sub-block
+ \param block type
+
+ \return ERROR STATUS
+****************************************************************************/
+INT FDKaacEnc_TnsEncode(TNS_INFO *tnsInfo, TNS_DATA *tnsData,
+ const INT numOfSfb, const TNS_CONFIG *tC,
+ const INT lowPassLine, FIXP_DBL *spectrum,
+ const INT subBlockNumber, const INT blockType) {
+ INT i, startLine, stopLine;
+
+ if (((blockType == SHORT_WINDOW) &&
+ (!tnsData->dataRaw.Short.subBlockInfo[subBlockNumber]
+ .tnsActive[HIFILT])) ||
+ ((blockType != SHORT_WINDOW) &&
+ (!tnsData->dataRaw.Long.subBlockInfo.tnsActive[HIFILT]))) {
+ return 1;
+ }
+
+ startLine = (tnsData->filtersMerged) ? tC->lpcStartLine[LOFILT]
+ : tC->lpcStartLine[HIFILT];
+ stopLine = tC->lpcStopLine;
+
+ for (i = 0; i < tnsInfo->numOfFilters[subBlockNumber]; i++) {
+ INT lpcGainFactor;
+ FIXP_LPC LpcCoeff[TNS_MAX_ORDER];
+ FIXP_DBL workBuffer[TNS_MAX_ORDER];
+ FIXP_LPC parcor_tmp[TNS_MAX_ORDER];
+
+ FDKaacEnc_Index2Parcor(tnsInfo->coef[subBlockNumber][i], parcor_tmp,
+ tnsInfo->order[subBlockNumber][i], tC->coefRes);
+
+ lpcGainFactor = CLpc_ParcorToLpc(
+ parcor_tmp, LpcCoeff, tnsInfo->order[subBlockNumber][i], workBuffer);
+
+ FDKmemclear(workBuffer, TNS_MAX_ORDER * sizeof(FIXP_DBL));
+ CLpc_Analysis(&spectrum[startLine], stopLine - startLine, LpcCoeff,
+ lpcGainFactor, tnsInfo->order[subBlockNumber][i], workBuffer,
+ NULL);
+
+ /* update for second filter */
+ startLine = tC->lpcStartLine[LOFILT];
+ stopLine = tC->lpcStartLine[HIFILT];
+ }
+
+ return (0);
+}
+
+static void FDKaacEnc_CalcGaussWindow(FIXP_DBL *win, const int winSize,
+ const INT samplingRate,
+ const INT transformResolution,
+ const FIXP_DBL timeResolution,
+ const INT timeResolution_e) {
+#define PI_E (2)
+#define PI_M FL2FXCONST_DBL(3.1416f / (float)(1 << PI_E))
+
+#define EULER_E (2)
+#define EULER_M FL2FXCONST_DBL(2.7183 / (float)(1 << EULER_E))
+
+#define COEFF_LOOP_SCALE (4)
+
+ INT i, e1, e2, gaussExp_e;
+ FIXP_DBL gaussExp_m;
+
+ /* calc. window exponent from time resolution:
+ *
+ * gaussExp = PI * samplingRate * 0.001f * timeResolution /
+ * transformResolution; gaussExp = -0.5f * gaussExp * gaussExp;
+ */
+ gaussExp_m = fMultNorm(
+ timeResolution,
+ fMult(PI_M,
+ fDivNorm((FIXP_DBL)(samplingRate),
+ (FIXP_DBL)(LONG)(transformResolution * 1000.f), &e1)),
+ &e2);
+ gaussExp_m = -fPow2Div2(gaussExp_m);
+ gaussExp_e = 2 * (e1 + e2 + timeResolution_e + PI_E);
+
+ FDK_ASSERT(winSize < (1 << COEFF_LOOP_SCALE));
+
+ /* calc. window coefficients
+ * win[i] = (float)exp( gaussExp * (i+0.5) * (i+0.5) );
+ */
+ for (i = 0; i < winSize; i++) {
+ win[i] = fPow(
+ EULER_M, EULER_E,
+ fMult(gaussExp_m,
+ fPow2((i * FL2FXCONST_DBL(1.f / (float)(1 << COEFF_LOOP_SCALE)) +
+ FL2FXCONST_DBL(.5f / (float)(1 << COEFF_LOOP_SCALE))))),
+ gaussExp_e + 2 * COEFF_LOOP_SCALE, &e1);
+
+ win[i] = scaleValueSaturate(win[i], e1);
+ }
+}
+
+static INT FDKaacEnc_Search3(FIXP_LPC parcor) {
+ INT i, index = 0;
+
+ for (i = 0; i < 8; i++) {
+ if (parcor > FDKaacEnc_tnsCoeff3Borders[i]) index = i;
+ }
+ return (index - 4);
+}
+
+static INT FDKaacEnc_Search4(FIXP_LPC parcor) {
+ INT i, index = 0;
+
+ for (i = 0; i < 16; i++) {
+ if (parcor > FDKaacEnc_tnsCoeff4Borders[i]) index = i;
+ }
+ return (index - 8);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_Parcor2Index
+
+*****************************************************************************/
+static void FDKaacEnc_Parcor2Index(const FIXP_LPC *parcor, INT *RESTRICT index,
+ const INT order, const INT bitsPerCoeff) {
+ INT i;
+ for (i = 0; i < order; i++) {
+ if (bitsPerCoeff == 3)
+ index[i] = FDKaacEnc_Search3(parcor[i]);
+ else
+ index[i] = FDKaacEnc_Search4(parcor[i]);
+ }
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_Index2Parcor
+ description: inverse quantization for reflection coefficients
+ returns: -
+ input: quantized values, ptr. to reflection coefficients,
+ no. of coefficients, resolution
+ output: reflection coefficients
+
+*****************************************************************************/
+static void FDKaacEnc_Index2Parcor(const INT *index, FIXP_LPC *RESTRICT parcor,
+ const INT order, const INT bitsPerCoeff) {
+ INT i;
+ for (i = 0; i < order; i++)
+ parcor[i] = bitsPerCoeff == 4 ? FDKaacEnc_tnsEncCoeff4[index[i] + 8]
+ : FDKaacEnc_tnsEncCoeff3[index[i] + 4];
+}
diff --git a/fdk-aac/libAACenc/src/aacenc_tns.h b/fdk-aac/libAACenc/src/aacenc_tns.h
new file mode 100644
index 0000000..a37f978
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacenc_tns.h
@@ -0,0 +1,213 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): Alex Groeschel
+
+ Description: Temporal noise shaping
+
+*******************************************************************************/
+
+#ifndef AACENC_TNS_H
+#define AACENC_TNS_H
+
+#include "common_fix.h"
+
+#include "psy_const.h"
+
+#ifndef PI
+#define PI 3.1415926535897931f
+#endif
+
+/**
+ * TNS_ENABLE_MASK
+ * This bitfield defines which TNS features are enabled
+ * The TNS mask is composed of 4 bits.
+ * tnsMask |= 0x1; activate TNS short blocks
+ * tnsMask |= 0x2; activate TNS for long blocks
+ * tnsMask |= 0x4; activate TNS PEAK tool for short blocks
+ * tnsMask |= 0x8; activate TNS PEAK tool for long blocks
+ */
+#define TNS_ENABLE_MASK 0xf
+
+/* TNS max filter order for Low Complexity MPEG4 profile */
+#define TNS_MAX_ORDER 12
+
+#define MAX_NUM_OF_FILTERS 2
+
+#define HIFILT 0 /* index of higher filter */
+#define LOFILT 1 /* index of lower filter */
+
+typedef struct { /* stuff that is tabulated dependent on bitrate etc. */
+ INT filterEnabled[MAX_NUM_OF_FILTERS];
+ INT threshOn[MAX_NUM_OF_FILTERS]; /* min. prediction gain for using tns
+ TABUL*/
+ INT filterStartFreq[MAX_NUM_OF_FILTERS]; /* lowest freq for lpc TABUL*/
+ INT tnsLimitOrder[MAX_NUM_OF_FILTERS]; /* Limit for TNS order TABUL*/
+ INT tnsFilterDirection[MAX_NUM_OF_FILTERS]; /* Filtering direction, 0=up,
+ 1=down TABUL */
+ INT acfSplit[MAX_NUM_OF_FILTERS];
+ FIXP_DBL tnsTimeResolution[MAX_NUM_OF_FILTERS]; /* TNS max. time resolution
+ TABUL. Should be fract but
+ MSVC won't compile then */
+ INT seperateFiltersAllowed;
+} TNS_PARAMETER_TABULATED;
+
+typedef struct { /*assigned at InitTime*/
+ TNS_PARAMETER_TABULATED confTab;
+ INT isLowDelay;
+ INT tnsActive;
+ INT maxOrder; /* max. order of tns filter */
+ INT coefRes;
+ FIXP_DBL acfWindow[MAX_NUM_OF_FILTERS][TNS_MAX_ORDER + 3 + 1];
+ /* now some things that only probably can be done at Init time;
+ could be they have to be split up for each individual (short) window or
+ even filter. */
+ INT lpcStartBand[MAX_NUM_OF_FILTERS];
+ INT lpcStartLine[MAX_NUM_OF_FILTERS];
+ INT lpcStopBand;
+ INT lpcStopLine;
+
+} TNS_CONFIG;
+
+typedef struct {
+ INT tnsActive[MAX_NUM_OF_FILTERS];
+ INT predictionGain[MAX_NUM_OF_FILTERS];
+} TNS_SUBBLOCK_INFO;
+
+typedef struct { /*changed at runTime*/
+ TNS_SUBBLOCK_INFO subBlockInfo[TRANS_FAC];
+ FIXP_DBL ratioMultTable[TRANS_FAC][MAX_SFB_SHORT];
+} TNS_DATA_SHORT;
+
+typedef struct { /*changed at runTime*/
+ TNS_SUBBLOCK_INFO subBlockInfo;
+ FIXP_DBL ratioMultTable[MAX_SFB_LONG];
+} TNS_DATA_LONG;
+
+/* can be implemented as union */
+typedef shouldBeUnion {
+ TNS_DATA_LONG Long;
+ TNS_DATA_SHORT Short;
+}
+TNS_DATA_RAW;
+
+typedef struct {
+ INT numOfSubblocks;
+ TNS_DATA_RAW dataRaw;
+ INT tnsMaxScaleSpec;
+ INT filtersMerged;
+} TNS_DATA;
+
+typedef struct {
+ INT numOfFilters[TRANS_FAC];
+ INT coefRes[TRANS_FAC];
+ INT length[TRANS_FAC][MAX_NUM_OF_FILTERS];
+ INT order[TRANS_FAC][MAX_NUM_OF_FILTERS];
+ INT direction[TRANS_FAC][MAX_NUM_OF_FILTERS];
+ INT coefCompress[TRANS_FAC][MAX_NUM_OF_FILTERS];
+ /* for Long: length TNS_MAX_ORDER (12 for LC) is required -> 12 */
+ /* for Short: length TRANS_FAC*TNS_MAX_ORDER (only 5 for short LC) is required
+ * -> 8*5=40 */
+ /* Currently TRANS_FAC*TNS_MAX_ORDER = 8*12 = 96 (for LC) is used (per
+ * channel)! Memory could be saved here! */
+ INT coef[TRANS_FAC][MAX_NUM_OF_FILTERS][TNS_MAX_ORDER];
+} TNS_INFO;
+
+INT FDKaacEnc_FreqToBandWidthRounding(const INT freq, const INT fs,
+ const INT numOfBands,
+ const INT *bandStartOffset);
+
+#endif /* AACENC_TNS_H */
diff --git a/fdk-aac/libAACenc/src/adj_thr.cpp b/fdk-aac/libAACenc/src/adj_thr.cpp
new file mode 100644
index 0000000..6e19680
--- /dev/null
+++ b/fdk-aac/libAACenc/src/adj_thr.cpp
@@ -0,0 +1,2924 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Threshold compensation
+
+*******************************************************************************/
+
+#include "adj_thr.h"
+#include "sf_estim.h"
+#include "aacEnc_ram.h"
+
+#define NUM_NRG_LEVS (8)
+#define INV_INT_TAB_SIZE (8)
+static const FIXP_DBL invInt[INV_INT_TAB_SIZE] = {
+ 0x7fffffff, 0x7fffffff, 0x40000000, 0x2aaaaaaa,
+ 0x20000000, 0x19999999, 0x15555555, 0x12492492};
+
+#define INV_SQRT4_TAB_SIZE (8)
+static const FIXP_DBL invSqrt4[INV_SQRT4_TAB_SIZE] = {
+ 0x7fffffff, 0x7fffffff, 0x6ba27e65, 0x61424bb5,
+ 0x5a827999, 0x55994845, 0x51c8e33c, 0x4eb160d1};
+
+/*static const INT invRedExp = 4;*/
+static const FIXP_DBL SnrLdMin1 =
+ (FIXP_DBL)0xfcad0ddf; /*FL2FXCONST_DBL(FDKlog(0.316)/FDKlog(2.0)/LD_DATA_SCALING);*/
+static const FIXP_DBL SnrLdMin2 =
+ (FIXP_DBL)0x0351e1a2; /*FL2FXCONST_DBL(FDKlog(3.16)
+ /FDKlog(2.0)/LD_DATA_SCALING);*/
+static const FIXP_DBL SnrLdFac =
+ (FIXP_DBL)0xff5b2c3e; /*FL2FXCONST_DBL(FDKlog(0.8)
+ /FDKlog(2.0)/LD_DATA_SCALING);*/
+
+static const FIXP_DBL SnrLdMin3 =
+ (FIXP_DBL)0xfe000000; /*FL2FXCONST_DBL(FDKlog(0.5)
+ /FDKlog(2.0)/LD_DATA_SCALING);*/
+static const FIXP_DBL SnrLdMin4 =
+ (FIXP_DBL)0x02000000; /*FL2FXCONST_DBL(FDKlog(2.0)
+ /FDKlog(2.0)/LD_DATA_SCALING);*/
+static const FIXP_DBL SnrLdMin5 =
+ (FIXP_DBL)0xfc000000; /*FL2FXCONST_DBL(FDKlog(0.25)
+ /FDKlog(2.0)/LD_DATA_SCALING);*/
+
+/*
+The bits2Pe factors are choosen for the case that some times
+the crash recovery strategy will be activated once.
+*/
+#define AFTERBURNER_STATI 2
+#define MAX_ALLOWED_EL_CHANNELS 2
+
+typedef struct {
+ INT bitrate;
+ FIXP_DBL bits2PeFactor[AFTERBURNER_STATI][MAX_ALLOWED_EL_CHANNELS];
+} BIT_PE_SFAC;
+
+typedef struct {
+ INT sampleRate;
+ const BIT_PE_SFAC *pPeTab;
+ INT nEntries;
+
+} BITS2PE_CFG_TAB;
+
+#define FL2B2PE(value) FL2FXCONST_DBL((value) / (1 << 2))
+
+static const BIT_PE_SFAC S_Bits2PeTab16000[] = {
+ /* bitrate| afterburner off | afterburner on | | nCh=1
+ | nCh=2 | nCh=1 | nCh=2 */
+ {10000,
+ {{FL2B2PE(1.60f), FL2B2PE(0.00f)}, {FL2B2PE(1.40f), FL2B2PE(0.00f)}}},
+ {24000,
+ {{FL2B2PE(1.80f), FL2B2PE(1.40f)}, {FL2B2PE(1.60f), FL2B2PE(1.20f)}}},
+ {32000,
+ {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}},
+ {48000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.80f)}, {FL2B2PE(1.60f), FL2B2PE(1.60f)}}},
+ {64000,
+ {{FL2B2PE(1.20f), FL2B2PE(1.60f)}, {FL2B2PE(1.20f), FL2B2PE(1.60f)}}},
+ {96000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.80f)}, {FL2B2PE(1.40f), FL2B2PE(1.60f)}}},
+ {128000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.80f)}, {FL2B2PE(1.40f), FL2B2PE(1.80f)}}},
+ {148000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.80f)}, {FL2B2PE(1.40f), FL2B2PE(1.40f)}}}};
+
+static const BIT_PE_SFAC S_Bits2PeTab22050[] = {
+ /* bitrate| afterburner off | afterburner on | | nCh=1
+ | nCh=2 | nCh=1 | nCh=2 */
+ {16000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.40f)}, {FL2B2PE(1.20f), FL2B2PE(0.80f)}}},
+ {24000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.40f)}, {FL2B2PE(1.40f), FL2B2PE(1.00f)}}},
+ {32000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.40f)}, {FL2B2PE(1.40f), FL2B2PE(1.20f)}}},
+ {48000,
+ {{FL2B2PE(1.20f), FL2B2PE(1.60f)}, {FL2B2PE(1.20f), FL2B2PE(1.40f)}}},
+ {64000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}},
+ {96000,
+ {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.60f)}}},
+ {128000,
+ {{FL2B2PE(1.80f), FL2B2PE(1.80f)}, {FL2B2PE(1.60f), FL2B2PE(1.60f)}}},
+ {148000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.80f)}, {FL2B2PE(1.40f), FL2B2PE(1.60f)}}}};
+
+static const BIT_PE_SFAC S_Bits2PeTab24000[] = {
+ /* bitrate| afterburner off | afterburner on | | nCh=1
+ | nCh=2 | nCh=1 | nCh=2 */
+ {16000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.40f)}, {FL2B2PE(1.20f), FL2B2PE(0.80f)}}},
+ {24000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.20f)}, {FL2B2PE(1.40f), FL2B2PE(1.00f)}}},
+ {32000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.20f)}, {FL2B2PE(1.40f), FL2B2PE(0.80f)}}},
+ {48000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.60f)}, {FL2B2PE(1.40f), FL2B2PE(1.40f)}}},
+ {64000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}},
+ {96000,
+ {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.60f)}}},
+ {128000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.80f)}}},
+ {148000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.60f)}, {FL2B2PE(1.40f), FL2B2PE(1.80f)}}}};
+
+static const BIT_PE_SFAC S_Bits2PeTab32000[] = {
+ /* bitrate| afterburner off | afterburner on | | nCh=1
+ | nCh=2 | nCh=1 | nCh=2 */
+ {16000,
+ {{FL2B2PE(1.20f), FL2B2PE(1.40f)}, {FL2B2PE(0.80f), FL2B2PE(0.80f)}}},
+ {24000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.20f)}, {FL2B2PE(1.00f), FL2B2PE(0.60f)}}},
+ {32000,
+ {{FL2B2PE(1.20f), FL2B2PE(1.20f)}, {FL2B2PE(1.00f), FL2B2PE(0.80f)}}},
+ {48000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.40f)}, {FL2B2PE(1.20f), FL2B2PE(1.20f)}}},
+ {64000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.40f)}, {FL2B2PE(1.60f), FL2B2PE(1.20f)}}},
+ {96000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.40f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}},
+ {128000,
+ {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.60f)}}},
+ {148000,
+ {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.60f)}}},
+ {160000,
+ {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.60f)}}},
+ {200000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.60f)}, {FL2B2PE(1.40f), FL2B2PE(1.60f)}}},
+ {320000,
+ {{FL2B2PE(3.20f), FL2B2PE(1.80f)}, {FL2B2PE(3.20f), FL2B2PE(1.80f)}}}};
+
+static const BIT_PE_SFAC S_Bits2PeTab44100[] = {
+ /* bitrate| afterburner off | afterburner on | | nCh=1
+ | nCh=2 | nCh=1 | nCh=2 */
+ {16000,
+ {{FL2B2PE(1.20f), FL2B2PE(1.60f)}, {FL2B2PE(0.80f), FL2B2PE(1.00f)}}},
+ {24000,
+ {{FL2B2PE(1.00f), FL2B2PE(1.20f)}, {FL2B2PE(1.00f), FL2B2PE(0.80f)}}},
+ {32000,
+ {{FL2B2PE(1.20f), FL2B2PE(1.20f)}, {FL2B2PE(0.80f), FL2B2PE(0.60f)}}},
+ {48000,
+ {{FL2B2PE(1.20f), FL2B2PE(1.20f)}, {FL2B2PE(1.20f), FL2B2PE(0.80f)}}},
+ {64000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.20f)}, {FL2B2PE(1.20f), FL2B2PE(1.00f)}}},
+ {96000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.20f)}, {FL2B2PE(1.60f), FL2B2PE(1.20f)}}},
+ {128000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}},
+ {148000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.60f)}}},
+ {160000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.60f)}}},
+ {200000,
+ {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.60f)}}},
+ {320000,
+ {{FL2B2PE(3.20f), FL2B2PE(1.60f)}, {FL2B2PE(3.20f), FL2B2PE(1.60f)}}}};
+
+static const BIT_PE_SFAC S_Bits2PeTab48000[] = {
+ /* bitrate| afterburner off | afterburner on | | nCh=1
+ | nCh=2 | nCh=1 | nCh=2 */
+ {16000,
+ {{FL2B2PE(1.40f), FL2B2PE(0.00f)}, {FL2B2PE(0.80f), FL2B2PE(0.00f)}}},
+ {24000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.20f)}, {FL2B2PE(1.00f), FL2B2PE(0.80f)}}},
+ {32000,
+ {{FL2B2PE(1.00f), FL2B2PE(1.20f)}, {FL2B2PE(0.60f), FL2B2PE(0.80f)}}},
+ {48000,
+ {{FL2B2PE(1.20f), FL2B2PE(1.00f)}, {FL2B2PE(0.80f), FL2B2PE(0.80f)}}},
+ {64000,
+ {{FL2B2PE(1.20f), FL2B2PE(1.20f)}, {FL2B2PE(1.20f), FL2B2PE(1.00f)}}},
+ {96000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.40f)}, {FL2B2PE(1.60f), FL2B2PE(1.20f)}}},
+ {128000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}},
+ {148000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}},
+ {160000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}},
+ {200000,
+ {{FL2B2PE(1.20f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}},
+ {320000,
+ {{FL2B2PE(3.20f), FL2B2PE(1.60f)}, {FL2B2PE(3.20f), FL2B2PE(1.60f)}}}};
+
+static const BITS2PE_CFG_TAB bits2PeConfigTab[] = {
+ {16000, S_Bits2PeTab16000, sizeof(S_Bits2PeTab16000) / sizeof(BIT_PE_SFAC)},
+ {22050, S_Bits2PeTab22050, sizeof(S_Bits2PeTab22050) / sizeof(BIT_PE_SFAC)},
+ {24000, S_Bits2PeTab24000, sizeof(S_Bits2PeTab24000) / sizeof(BIT_PE_SFAC)},
+ {32000, S_Bits2PeTab32000, sizeof(S_Bits2PeTab32000) / sizeof(BIT_PE_SFAC)},
+ {44100, S_Bits2PeTab44100, sizeof(S_Bits2PeTab44100) / sizeof(BIT_PE_SFAC)},
+ {48000, S_Bits2PeTab48000,
+ sizeof(S_Bits2PeTab48000) / sizeof(BIT_PE_SFAC)}};
+
+/* values for avoid hole flag */
+enum _avoid_hole_state { NO_AH = 0, AH_INACTIVE = 1, AH_ACTIVE = 2 };
+
+/* Q format definitions */
+#define Q_BITFAC \
+ (24) /* Q scaling used in FDKaacEnc_bitresCalcBitFac() calculation */
+#define Q_AVGBITS (17) /* scale bit values */
+
+/*****************************************************************************
+ functionname: FDKaacEnc_InitBits2PeFactor
+ description: retrieve bits2PeFactor from table
+*****************************************************************************/
+static void FDKaacEnc_InitBits2PeFactor(
+ FIXP_DBL *bits2PeFactor_m, INT *bits2PeFactor_e, const INT bitRate,
+ const INT nChannels, const INT sampleRate, const INT advancedBitsToPe,
+ const INT dZoneQuantEnable, const INT invQuant) {
+ /**** 1) Set default bits2pe factor ****/
+ FIXP_DBL bit2PE_m = FL2FXCONST_DBL(1.18f / (1 << (1)));
+ INT bit2PE_e = 1;
+
+ /**** 2) For AAC-(E)LD, make use of advanced bits to pe factor table ****/
+ if (advancedBitsToPe && nChannels <= (2)) {
+ int i;
+ const BIT_PE_SFAC *peTab = NULL;
+ INT size = 0;
+
+ /*** 2.1) Get correct table entry ***/
+ for (i = 0; i < (INT)(sizeof(bits2PeConfigTab) / sizeof(BITS2PE_CFG_TAB));
+ i++) {
+ if (sampleRate >= bits2PeConfigTab[i].sampleRate) {
+ peTab = bits2PeConfigTab[i].pPeTab;
+ size = bits2PeConfigTab[i].nEntries;
+ }
+ }
+
+ if ((peTab != NULL) && (size != 0)) {
+ INT startB = -1; /* bitrate entry in table that is the next-lower to
+ actual bitrate */
+ INT stopB = -1; /* bitrate entry in table that is the next-higher to
+ actual bitrate */
+ FIXP_DBL startPF =
+ FL2FXCONST_DBL(0.0f); /* bits2PE factor entry in table that is the
+ next-lower to actual bits2PE factor */
+ FIXP_DBL stopPF = FL2FXCONST_DBL(0.0f); /* bits2PE factor entry in table
+ that is the next-higher to
+ actual bits2PE factor */
+ FIXP_DBL slope = FL2FXCONST_DBL(
+ 0.0f); /* the slope from the start bits2Pe entry to the next one */
+ const int qualityIdx = (invQuant == 0) ? 0 : 1;
+
+ if (bitRate >= peTab[size - 1].bitrate) {
+ /* Chosen bitrate is higher than the highest bitrate in table.
+ The slope for extrapolating the bits2PE factor must be zero.
+ Values are set accordingly. */
+ startB = peTab[size - 1].bitrate;
+ stopB =
+ bitRate +
+ 1; /* Can be an arbitrary value greater than startB and bitrate. */
+ startPF = peTab[size - 1].bits2PeFactor[qualityIdx][nChannels - 1];
+ stopPF = peTab[size - 1].bits2PeFactor[qualityIdx][nChannels - 1];
+ } else {
+ for (i = 0; i < size - 1; i++) {
+ if ((peTab[i].bitrate <= bitRate) &&
+ (peTab[i + 1].bitrate > bitRate)) {
+ startB = peTab[i].bitrate;
+ stopB = peTab[i + 1].bitrate;
+ startPF = peTab[i].bits2PeFactor[qualityIdx][nChannels - 1];
+ stopPF = peTab[i + 1].bits2PeFactor[qualityIdx][nChannels - 1];
+ break;
+ }
+ }
+ }
+
+ /*** 2.2) Configuration available? ***/
+ if (startB != -1) {
+ /** 2.2.1) linear interpolate to actual PEfactor **/
+ FIXP_DBL bit2PE = 0;
+
+ const FIXP_DBL maxBit2PE = FL2FXCONST_DBL(3.f / 4.f);
+
+ /* bit2PE = ((stopPF-startPF)/(stopB-startB))*(bitRate-startB)+startPF;
+ */
+ slope = fDivNorm(bitRate - startB, stopB - startB);
+ bit2PE = fMult(slope, stopPF - startPF) + startPF;
+
+ bit2PE = fMin(maxBit2PE, bit2PE);
+
+ /** 2.2.2) sanity check if bits2pe value is high enough **/
+ if (bit2PE >= (FL2FXCONST_DBL(0.35f) >> 2)) {
+ bit2PE_m = bit2PE;
+ bit2PE_e = 2; /* table is fixed scaled */
+ }
+ } /* br */
+ } /* sr */
+ } /* advancedBitsToPe */
+
+ if (dZoneQuantEnable) {
+ if (bit2PE_m >= (FL2FXCONST_DBL(0.6f)) >> bit2PE_e) {
+ /* Additional headroom for addition */
+ bit2PE_m >>= 1;
+ bit2PE_e += 1;
+ }
+
+ /* the quantTendencyCompensator compensates a lower bit consumption due to
+ * increasing the tendency to quantize low spectral values to the lower
+ * quantizer border for bitrates below a certain bitrate threshold --> see
+ * also function calcSfbDistLD in quantize.c */
+ if ((bitRate / nChannels > 32000) && (bitRate / nChannels <= 40000)) {
+ bit2PE_m += (FL2FXCONST_DBL(0.4f)) >> bit2PE_e;
+ } else if (bitRate / nChannels > 20000) {
+ bit2PE_m += (FL2FXCONST_DBL(0.3f)) >> bit2PE_e;
+ } else if (bitRate / nChannels >= 16000) {
+ bit2PE_m += (FL2FXCONST_DBL(0.3f)) >> bit2PE_e;
+ } else {
+ bit2PE_m += (FL2FXCONST_DBL(0.0f)) >> bit2PE_e;
+ }
+ }
+
+ /***** 3.) Return bits2pe factor *****/
+ *bits2PeFactor_m = bit2PE_m;
+ *bits2PeFactor_e = bit2PE_e;
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_bits2pe2
+description: convert from bits to pe
+*****************************************************************************/
+FDK_INLINE INT FDKaacEnc_bits2pe2(const INT bits, const FIXP_DBL factor_m,
+ const INT factor_e) {
+ return (INT)(fMult(factor_m, (FIXP_DBL)(bits << Q_AVGBITS)) >>
+ (Q_AVGBITS - factor_e));
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_calcThreshExp
+description: loudness calculation (threshold to the power of redExp)
+*****************************************************************************/
+static void FDKaacEnc_calcThreshExp(
+ FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB],
+ const QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)], const INT nChannels) {
+ INT ch, sfb, sfbGrp;
+ FIXP_DBL thrExpLdData;
+
+ for (ch = 0; ch < nChannels; ch++) {
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) {
+ thrExpLdData = psyOutChannel[ch]->sfbThresholdLdData[sfbGrp + sfb] >> 2;
+ thrExp[ch][sfbGrp + sfb] = CalcInvLdData(thrExpLdData);
+ }
+ }
+ }
+}
+
+/*****************************************************************************
+ functionname: FDKaacEnc_adaptMinSnr
+ description: reduce minSnr requirements for bands with relative low
+energies
+*****************************************************************************/
+static void FDKaacEnc_adaptMinSnr(
+ QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)],
+ const MINSNR_ADAPT_PARAM *const msaParam, const INT nChannels) {
+ INT ch, sfb, sfbGrp, nSfb;
+ FIXP_DBL avgEnLD64, dbRatio, minSnrRed;
+ FIXP_DBL minSnrLimitLD64 =
+ FL2FXCONST_DBL(-0.00503012648262f); /* ld64(0.8f) */
+ FIXP_DBL nSfbLD64;
+ FIXP_DBL accu;
+
+ FIXP_DBL msaParam_maxRed = msaParam->maxRed;
+ FIXP_DBL msaParam_startRatio = msaParam->startRatio;
+ FIXP_DBL msaParam_redRatioFac =
+ fMult(msaParam->redRatioFac, FL2FXCONST_DBL(0.3010299956f));
+ FIXP_DBL msaParam_redOffs = msaParam->redOffs;
+
+ for (ch = 0; ch < nChannels; ch++) {
+ /* calc average energy per scalefactor band */
+ nSfb = 0;
+ accu = FL2FXCONST_DBL(0.0f);
+
+ DWORD_ALIGNED(psyOutChannel[ch]->sfbEnergy);
+
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup) {
+ int maxSfbPerGroup = psyOutChannel[ch]->maxSfbPerGroup;
+ nSfb += maxSfbPerGroup;
+ for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+ accu += psyOutChannel[ch]->sfbEnergy[sfbGrp + sfb] >> 6;
+ }
+ }
+
+ if ((accu == FL2FXCONST_DBL(0.0f)) || (nSfb == 0)) {
+ avgEnLD64 = FL2FXCONST_DBL(-1.0f);
+ } else {
+ nSfbLD64 = CalcLdInt(nSfb);
+ avgEnLD64 = CalcLdData(accu);
+ avgEnLD64 = avgEnLD64 + FL2FXCONST_DBL(0.09375f) -
+ nSfbLD64; /* 0.09375f: compensate shift with 6 */
+ }
+
+ /* reduce minSnr requirement by minSnr^minSnrRed dependent on avgEn/sfbEn */
+ int maxSfbPerGroup = psyOutChannel[ch]->maxSfbPerGroup;
+ int sfbCnt = psyOutChannel[ch]->sfbCnt;
+ int sfbPerGroup = psyOutChannel[ch]->sfbPerGroup;
+
+ for (sfbGrp = 0; sfbGrp < sfbCnt; sfbGrp += sfbPerGroup) {
+ FIXP_DBL *RESTRICT psfbEnergyLdData =
+ &qcOutChannel[ch]->sfbEnergyLdData[sfbGrp];
+ FIXP_DBL *RESTRICT psfbMinSnrLdData =
+ &qcOutChannel[ch]->sfbMinSnrLdData[sfbGrp];
+ for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+ FIXP_DBL sfbEnergyLdData = *psfbEnergyLdData++;
+ FIXP_DBL sfbMinSnrLdData = *psfbMinSnrLdData;
+ dbRatio = avgEnLD64 - sfbEnergyLdData;
+ int update = (msaParam_startRatio < dbRatio) ? 1 : 0;
+ minSnrRed = msaParam_redOffs + fMult(msaParam_redRatioFac,
+ dbRatio); /* scaled by 1.0f/64.0f*/
+ minSnrRed =
+ fixMax(minSnrRed, msaParam_maxRed); /* scaled by 1.0f/64.0f*/
+ minSnrRed = (fMult(sfbMinSnrLdData, minSnrRed)) << 6;
+ minSnrRed = fixMin(minSnrLimitLD64, minSnrRed);
+ *psfbMinSnrLdData++ = update ? minSnrRed : sfbMinSnrLdData;
+ }
+ }
+ }
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_initAvoidHoleFlag
+description: determine bands where avoid hole is not necessary resp. possible
+*****************************************************************************/
+static void FDKaacEnc_initAvoidHoleFlag(
+ QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)],
+ UCHAR ahFlag[(2)][MAX_GROUPED_SFB], const struct TOOLSINFO *const toolsInfo,
+ const INT nChannels, const AH_PARAM *const ahParam) {
+ INT ch, sfb, sfbGrp;
+ FIXP_DBL sfbEn, sfbEnm1;
+ FIXP_DBL sfbEnLdData;
+ FIXP_DBL avgEnLdData;
+
+ /* decrease spread energy by 3dB for long blocks, resp. 2dB for shorts
+ (avoid more holes in long blocks) */
+ for (ch = 0; ch < nChannels; ch++) {
+ QC_OUT_CHANNEL *const qcOutChan = qcOutChannel[ch];
+
+ if (psyOutChannel[ch]->lastWindowSequence != SHORT_WINDOW) {
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup)
+ for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++)
+ qcOutChan->sfbSpreadEnergy[sfbGrp + sfb] >>= 1;
+ } else {
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup)
+ for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++)
+ qcOutChan->sfbSpreadEnergy[sfbGrp + sfb] = fMult(
+ FL2FXCONST_DBL(0.63f), qcOutChan->sfbSpreadEnergy[sfbGrp + sfb]);
+ }
+ }
+
+ /* increase minSnr for local peaks, decrease it for valleys */
+ if (ahParam->modifyMinSnr) {
+ for (ch = 0; ch < nChannels; ch++) {
+ QC_OUT_CHANNEL *const qcOutChan = qcOutChannel[ch];
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) {
+ FIXP_DBL sfbEnp1, avgEn;
+ if (sfb > 0)
+ sfbEnm1 = qcOutChan->sfbEnergy[sfbGrp + sfb - 1];
+ else
+ sfbEnm1 = qcOutChan->sfbEnergy[sfbGrp + sfb];
+
+ if (sfb < psyOutChannel[ch]->maxSfbPerGroup - 1)
+ sfbEnp1 = qcOutChan->sfbEnergy[sfbGrp + sfb + 1];
+ else
+ sfbEnp1 = qcOutChan->sfbEnergy[sfbGrp + sfb];
+
+ avgEn = (sfbEnm1 >> 1) + (sfbEnp1 >> 1);
+ avgEnLdData = CalcLdData(avgEn);
+ sfbEn = qcOutChan->sfbEnergy[sfbGrp + sfb];
+ sfbEnLdData = qcOutChan->sfbEnergyLdData[sfbGrp + sfb];
+ /* peak ? */
+ if (sfbEn > avgEn) {
+ FIXP_DBL tmpMinSnrLdData;
+ if (psyOutChannel[ch]->lastWindowSequence == LONG_WINDOW)
+ tmpMinSnrLdData =
+ fixMax(SnrLdFac + (FIXP_DBL)(avgEnLdData - sfbEnLdData),
+ (FIXP_DBL)SnrLdMin1);
+ else
+ tmpMinSnrLdData =
+ fixMax(SnrLdFac + (FIXP_DBL)(avgEnLdData - sfbEnLdData),
+ (FIXP_DBL)SnrLdMin3);
+
+ qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] = fixMin(
+ qcOutChan->sfbMinSnrLdData[sfbGrp + sfb], tmpMinSnrLdData);
+ }
+ /* valley ? */
+ if (((sfbEnLdData + (FIXP_DBL)SnrLdMin4) < (FIXP_DBL)avgEnLdData) &&
+ (sfbEn > FL2FXCONST_DBL(0.0))) {
+ FIXP_DBL tmpMinSnrLdData = avgEnLdData - sfbEnLdData -
+ (FIXP_DBL)SnrLdMin4 +
+ qcOutChan->sfbMinSnrLdData[sfbGrp + sfb];
+ tmpMinSnrLdData = fixMin((FIXP_DBL)SnrLdFac, tmpMinSnrLdData);
+ qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] =
+ fixMin(tmpMinSnrLdData,
+ (FIXP_DBL)(qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] +
+ SnrLdMin2));
+ }
+ }
+ }
+ }
+ }
+
+ /* stereo: adapt the minimum requirements sfbMinSnr of mid and
+ side channels to avoid spending unnoticable bits */
+ if (nChannels == 2) {
+ QC_OUT_CHANNEL *qcOutChanM = qcOutChannel[0];
+ QC_OUT_CHANNEL *qcOutChanS = qcOutChannel[1];
+ const PSY_OUT_CHANNEL *const psyOutChanM = psyOutChannel[0];
+ for (sfbGrp = 0; sfbGrp < psyOutChanM->sfbCnt;
+ sfbGrp += psyOutChanM->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChanM->maxSfbPerGroup; sfb++) {
+ if (toolsInfo->msMask[sfbGrp + sfb]) {
+ FIXP_DBL maxSfbEnLd =
+ fixMax(qcOutChanM->sfbEnergyLdData[sfbGrp + sfb],
+ qcOutChanS->sfbEnergyLdData[sfbGrp + sfb]);
+ FIXP_DBL maxThrLd, sfbMinSnrTmpLd;
+
+ if (((SnrLdMin5 >> 1) + (maxSfbEnLd >> 1) +
+ (qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb] >> 1)) <=
+ FL2FXCONST_DBL(-0.5f))
+ maxThrLd = FL2FXCONST_DBL(-1.0f);
+ else
+ maxThrLd = SnrLdMin5 + maxSfbEnLd +
+ qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb];
+
+ if (qcOutChanM->sfbEnergy[sfbGrp + sfb] > FL2FXCONST_DBL(0.0f))
+ sfbMinSnrTmpLd =
+ maxThrLd - qcOutChanM->sfbEnergyLdData[sfbGrp + sfb];
+ else
+ sfbMinSnrTmpLd = FL2FXCONST_DBL(0.0f);
+
+ qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb] =
+ fixMax(qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb], sfbMinSnrTmpLd);
+
+ if (qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb] <= FL2FXCONST_DBL(0.0f))
+ qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb] = fixMin(
+ qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb], (FIXP_DBL)SnrLdFac);
+
+ if (qcOutChanS->sfbEnergy[sfbGrp + sfb] > FL2FXCONST_DBL(0.0f))
+ sfbMinSnrTmpLd =
+ maxThrLd - qcOutChanS->sfbEnergyLdData[sfbGrp + sfb];
+ else
+ sfbMinSnrTmpLd = FL2FXCONST_DBL(0.0f);
+
+ qcOutChanS->sfbMinSnrLdData[sfbGrp + sfb] =
+ fixMax(qcOutChanS->sfbMinSnrLdData[sfbGrp + sfb], sfbMinSnrTmpLd);
+
+ if (qcOutChanS->sfbMinSnrLdData[sfbGrp + sfb] <= FL2FXCONST_DBL(0.0f))
+ qcOutChanS->sfbMinSnrLdData[sfbGrp + sfb] = fixMin(
+ qcOutChanS->sfbMinSnrLdData[sfbGrp + sfb], (FIXP_DBL)SnrLdFac);
+
+ if (qcOutChanM->sfbEnergy[sfbGrp + sfb] >
+ qcOutChanM->sfbSpreadEnergy[sfbGrp + sfb])
+ qcOutChanS->sfbSpreadEnergy[sfbGrp + sfb] = fMult(
+ qcOutChanS->sfbEnergy[sfbGrp + sfb], FL2FXCONST_DBL(0.9f));
+
+ if (qcOutChanS->sfbEnergy[sfbGrp + sfb] >
+ qcOutChanS->sfbSpreadEnergy[sfbGrp + sfb])
+ qcOutChanM->sfbSpreadEnergy[sfbGrp + sfb] = fMult(
+ qcOutChanM->sfbEnergy[sfbGrp + sfb], FL2FXCONST_DBL(0.9f));
+
+ } /* if (toolsInfo->msMask[sfbGrp+sfb]) */
+ } /* sfb */
+ } /* sfbGrp */
+ } /* nChannels==2 */
+
+ /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */
+ for (ch = 0; ch < nChannels; ch++) {
+ QC_OUT_CHANNEL *qcOutChan = qcOutChannel[ch];
+ const PSY_OUT_CHANNEL *const psyOutChan = psyOutChannel[ch];
+ for (sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt;
+ sfbGrp += psyOutChan->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChan->maxSfbPerGroup; sfb++) {
+ if ((qcOutChan->sfbSpreadEnergy[sfbGrp + sfb] >
+ qcOutChan->sfbEnergy[sfbGrp + sfb]) ||
+ (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] > FL2FXCONST_DBL(0.0f))) {
+ ahFlag[ch][sfbGrp + sfb] = NO_AH;
+ } else {
+ ahFlag[ch][sfbGrp + sfb] = AH_INACTIVE;
+ }
+ }
+ }
+ }
+}
+
+/**
+ * \brief Calculate constants that do not change during successive pe
+ * calculations.
+ *
+ * \param peData Pointer to structure containing PE data of
+ * current element.
+ * \param psyOutChannel Pointer to PSY_OUT_CHANNEL struct holding
+ * nChannels elements.
+ * \param qcOutChannel Pointer to QC_OUT_CHANNEL struct holding
+ * nChannels elements.
+ * \param nChannels Number of channels in element.
+ * \param peOffset Fixed PE offset defined while
+ * FDKaacEnc_AdjThrInit() depending on bitrate.
+ *
+ * \return void
+ */
+static void FDKaacEnc_preparePe(PE_DATA *const peData,
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)],
+ const QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ const INT nChannels, const INT peOffset) {
+ INT ch;
+
+ for (ch = 0; ch < nChannels; ch++) {
+ const PSY_OUT_CHANNEL *const psyOutChan = psyOutChannel[ch];
+ FDKaacEnc_prepareSfbPe(
+ &peData->peChannelData[ch], psyOutChan->sfbEnergyLdData,
+ psyOutChan->sfbThresholdLdData, qcOutChannel[ch]->sfbFormFactorLdData,
+ psyOutChan->sfbOffsets, psyOutChan->sfbCnt, psyOutChan->sfbPerGroup,
+ psyOutChan->maxSfbPerGroup);
+ }
+ peData->offset = peOffset;
+}
+
+/**
+ * \brief Calculate weighting factor for threshold adjustment.
+ *
+ * Calculate weighting factor to be applied at energies and thresholds in ld64
+ * format.
+ *
+ * \param peData, Pointer to PE data in current element.
+ * \param psyOutChannel Pointer to PSY_OUT_CHANNEL struct holding
+ * nChannels elements.
+ * \param qcOutChannel Pointer to QC_OUT_CHANNEL struct holding
+ * nChannels elements.
+ * \param toolsInfo Pointer to tools info struct of current element.
+ * \param adjThrStateElement Pointer to ATS_ELEMENT holding enFacPatch
+ * states.
+ * \param nChannels Number of channels in element.
+ * \param usePatchTool Apply the weighting tool 0 (no) else (yes).
+ *
+ * \return void
+ */
+static void FDKaacEnc_calcWeighting(
+ const PE_DATA *const peData,
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)],
+ QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ const struct TOOLSINFO *const toolsInfo,
+ ATS_ELEMENT *const adjThrStateElement, const INT nChannels,
+ const INT usePatchTool) {
+ int ch, noShortWindowInFrame = TRUE;
+ INT exePatchM = 0;
+
+ for (ch = 0; ch < nChannels; ch++) {
+ if (psyOutChannel[ch]->lastWindowSequence == SHORT_WINDOW) {
+ noShortWindowInFrame = FALSE;
+ }
+ FDKmemclear(qcOutChannel[ch]->sfbEnFacLd,
+ MAX_GROUPED_SFB * sizeof(FIXP_DBL));
+ }
+
+ if (usePatchTool == 0) {
+ return; /* tool is disabled */
+ }
+
+ for (ch = 0; ch < nChannels; ch++) {
+ const PSY_OUT_CHANNEL *const psyOutChan = psyOutChannel[ch];
+
+ if (noShortWindowInFrame) { /* retain energy ratio between blocks of
+ different length */
+
+ FIXP_DBL nrgSum14, nrgSum12, nrgSum34, nrgTotal;
+ FIXP_DBL nrgFacLd_14, nrgFacLd_12, nrgFacLd_34;
+ INT usePatch, exePatch;
+ int sfb, sfbGrp, nLinesSum = 0;
+
+ nrgSum14 = nrgSum12 = nrgSum34 = nrgTotal = FL2FXCONST_DBL(0.f);
+
+ /* calculate flatness of audible spectrum, i.e. spectrum above masking
+ * threshold. */
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) {
+ FIXP_DBL nrgFac12 = CalcInvLdData(
+ psyOutChan->sfbEnergyLdData[sfbGrp + sfb] >> 1); /* nrg^(1/2) */
+ FIXP_DBL nrgFac14 = CalcInvLdData(
+ psyOutChan->sfbEnergyLdData[sfbGrp + sfb] >> 2); /* nrg^(1/4) */
+
+ /* maximal number of bands is 64, results scaling factor 6 */
+ nLinesSum += peData->peChannelData[ch]
+ .sfbNLines[sfbGrp + sfb]; /* relevant lines */
+ nrgTotal +=
+ (psyOutChan->sfbEnergy[sfbGrp + sfb] >> 6); /* sum up nrg */
+ nrgSum12 += (nrgFac12 >> 6); /* sum up nrg^(2/4) */
+ nrgSum14 += (nrgFac14 >> 6); /* sum up nrg^(1/4) */
+ nrgSum34 += (fMult(nrgFac14, nrgFac12) >> 6); /* sum up nrg^(3/4) */
+ }
+ }
+
+ nrgTotal = CalcLdData(nrgTotal); /* get ld64 of total nrg */
+
+ nrgFacLd_14 =
+ CalcLdData(nrgSum14) - nrgTotal; /* ld64(nrgSum14/nrgTotal) */
+ nrgFacLd_12 =
+ CalcLdData(nrgSum12) - nrgTotal; /* ld64(nrgSum12/nrgTotal) */
+ nrgFacLd_34 =
+ CalcLdData(nrgSum34) - nrgTotal; /* ld64(nrgSum34/nrgTotal) */
+
+ /* Note: nLinesSum cannot be larger than the number of total lines, thats
+ * taken care of in line_pe.cpp FDKaacEnc_prepareSfbPe() */
+ adjThrStateElement->chaosMeasureEnFac[ch] =
+ fMax(FL2FXCONST_DBL(0.1875f),
+ fDivNorm(nLinesSum, psyOutChan->sfbOffsets[psyOutChan->sfbCnt]));
+
+ usePatch = (adjThrStateElement->chaosMeasureEnFac[ch] >
+ FL2FXCONST_DBL(0.78125f));
+ exePatch = ((usePatch) && (adjThrStateElement->lastEnFacPatch[ch]));
+
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) {
+ INT sfbExePatch;
+ /* for MS coupled SFBs, also execute patch in side channel if done in
+ * mid channel */
+ if ((ch == 1) && (toolsInfo->msMask[sfbGrp + sfb])) {
+ sfbExePatch = exePatchM;
+ } else {
+ sfbExePatch = exePatch;
+ }
+
+ if ((sfbExePatch) &&
+ (psyOutChan->sfbEnergy[sfbGrp + sfb] > FL2FXCONST_DBL(0.f))) {
+ /* execute patch based on spectral flatness calculated above */
+ if (adjThrStateElement->chaosMeasureEnFac[ch] >
+ FL2FXCONST_DBL(0.8125f)) {
+ qcOutChannel[ch]->sfbEnFacLd[sfbGrp + sfb] =
+ ((nrgFacLd_14 +
+ (psyOutChan->sfbEnergyLdData[sfbGrp + sfb] +
+ (psyOutChan->sfbEnergyLdData[sfbGrp + sfb] >> 1))) >>
+ 1); /* sfbEnergy^(3/4) */
+ } else if (adjThrStateElement->chaosMeasureEnFac[ch] >
+ FL2FXCONST_DBL(0.796875f)) {
+ qcOutChannel[ch]->sfbEnFacLd[sfbGrp + sfb] =
+ ((nrgFacLd_12 + psyOutChan->sfbEnergyLdData[sfbGrp + sfb]) >>
+ 1); /* sfbEnergy^(2/4) */
+ } else {
+ qcOutChannel[ch]->sfbEnFacLd[sfbGrp + sfb] =
+ ((nrgFacLd_34 +
+ (psyOutChan->sfbEnergyLdData[sfbGrp + sfb] >> 1)) >>
+ 1); /* sfbEnergy^(1/4) */
+ }
+ qcOutChannel[ch]->sfbEnFacLd[sfbGrp + sfb] =
+ fixMin(qcOutChannel[ch]->sfbEnFacLd[sfbGrp + sfb], (FIXP_DBL)0);
+ }
+ }
+ } /* sfb loop */
+
+ adjThrStateElement->lastEnFacPatch[ch] = usePatch;
+ exePatchM = exePatch;
+ } else {
+ /* !noShortWindowInFrame */
+ adjThrStateElement->chaosMeasureEnFac[ch] = FL2FXCONST_DBL(0.75f);
+ adjThrStateElement->lastEnFacPatch[ch] =
+ TRUE; /* allow use of sfbEnFac patch in upcoming frame */
+ }
+
+ } /* ch loop */
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_calcPe
+description: calculate pe for both channels
+*****************************************************************************/
+static void FDKaacEnc_calcPe(const PSY_OUT_CHANNEL *const psyOutChannel[(2)],
+ const QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ PE_DATA *const peData, const INT nChannels) {
+ INT ch;
+
+ peData->pe = peData->offset;
+ peData->constPart = 0;
+ peData->nActiveLines = 0;
+ for (ch = 0; ch < nChannels; ch++) {
+ PE_CHANNEL_DATA *peChanData = &peData->peChannelData[ch];
+
+ FDKaacEnc_calcSfbPe(
+ peChanData, qcOutChannel[ch]->sfbWeightedEnergyLdData,
+ qcOutChannel[ch]->sfbThresholdLdData, psyOutChannel[ch]->sfbCnt,
+ psyOutChannel[ch]->sfbPerGroup, psyOutChannel[ch]->maxSfbPerGroup,
+ psyOutChannel[ch]->isBook, psyOutChannel[ch]->isScale);
+
+ peData->pe += peChanData->pe;
+ peData->constPart += peChanData->constPart;
+ peData->nActiveLines += peChanData->nActiveLines;
+ }
+}
+
+void FDKaacEnc_peCalculation(PE_DATA *const peData,
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)],
+ QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ const struct TOOLSINFO *const toolsInfo,
+ ATS_ELEMENT *const adjThrStateElement,
+ const INT nChannels) {
+ /* constants that will not change during successive pe calculations */
+ FDKaacEnc_preparePe(peData, psyOutChannel, qcOutChannel, nChannels,
+ adjThrStateElement->peOffset);
+
+ /* calculate weighting factor for threshold adjustment */
+ FDKaacEnc_calcWeighting(peData, psyOutChannel, qcOutChannel, toolsInfo,
+ adjThrStateElement, nChannels, 1);
+ {
+ /* no weighting of threholds and energies for mlout */
+ /* weight energies and thresholds */
+ int ch;
+ for (ch = 0; ch < nChannels; ch++) {
+ int sfb, sfbGrp;
+ QC_OUT_CHANNEL *pQcOutCh = qcOutChannel[ch];
+
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) {
+ pQcOutCh->sfbWeightedEnergyLdData[sfb + sfbGrp] =
+ pQcOutCh->sfbEnergyLdData[sfb + sfbGrp] -
+ pQcOutCh->sfbEnFacLd[sfb + sfbGrp];
+ pQcOutCh->sfbThresholdLdData[sfb + sfbGrp] -=
+ pQcOutCh->sfbEnFacLd[sfb + sfbGrp];
+ }
+ }
+ }
+ }
+
+ /* pe without reduction */
+ FDKaacEnc_calcPe(psyOutChannel, qcOutChannel, peData, nChannels);
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_FDKaacEnc_calcPeNoAH
+description: sum the pe data only for bands where avoid hole is inactive
+*****************************************************************************/
+#define CONSTPART_HEADROOM 4
+static void FDKaacEnc_FDKaacEnc_calcPeNoAH(
+ INT *const pe, INT *const constPart, INT *const nActiveLines,
+ const PE_DATA *const peData, const UCHAR ahFlag[(2)][MAX_GROUPED_SFB],
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)], const INT nChannels) {
+ INT ch, sfb, sfbGrp;
+
+ INT pe_tmp = peData->offset;
+ INT constPart_tmp = 0;
+ INT nActiveLines_tmp = 0;
+ for (ch = 0; ch < nChannels; ch++) {
+ const PE_CHANNEL_DATA *const peChanData = &peData->peChannelData[ch];
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) {
+ if (ahFlag[ch][sfbGrp + sfb] < AH_ACTIVE) {
+ pe_tmp += peChanData->sfbPe[sfbGrp + sfb];
+ constPart_tmp +=
+ peChanData->sfbConstPart[sfbGrp + sfb] >> CONSTPART_HEADROOM;
+ nActiveLines_tmp += peChanData->sfbNActiveLines[sfbGrp + sfb];
+ }
+ }
+ }
+ }
+ /* correct scaled pe and constPart values */
+ *pe = pe_tmp >> PE_CONSTPART_SHIFT;
+ *constPart = constPart_tmp >> (PE_CONSTPART_SHIFT - CONSTPART_HEADROOM);
+
+ *nActiveLines = nActiveLines_tmp;
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_reduceThresholdsCBR
+description: apply reduction formula
+*****************************************************************************/
+static const FIXP_DBL limitThrReducedLdData =
+ (FIXP_DBL)0x00008000; /*FL2FXCONST_DBL(FDKpow(2.0,-LD_DATA_SCALING/4.0));*/
+
+static void FDKaacEnc_reduceThresholdsCBR(
+ QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)],
+ UCHAR ahFlag[(2)][MAX_GROUPED_SFB],
+ const FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB], const INT nChannels,
+ const FIXP_DBL redVal_m, const SCHAR redVal_e) {
+ INT ch, sfb, sfbGrp;
+ FIXP_DBL sfbEnLdData, sfbThrLdData, sfbThrReducedLdData;
+ FIXP_DBL sfbThrExp;
+
+ for (ch = 0; ch < nChannels; ch++) {
+ QC_OUT_CHANNEL *qcOutChan = qcOutChannel[ch];
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) {
+ sfbEnLdData = qcOutChan->sfbWeightedEnergyLdData[sfbGrp + sfb];
+ sfbThrLdData = qcOutChan->sfbThresholdLdData[sfbGrp + sfb];
+ sfbThrExp = thrExp[ch][sfbGrp + sfb];
+ if ((sfbEnLdData > sfbThrLdData) &&
+ (ahFlag[ch][sfbGrp + sfb] != AH_ACTIVE)) {
+ /* threshold reduction formula:
+ float tmp = thrExp[ch][sfb]+redVal;
+ tmp *= tmp;
+ sfbThrReduced = tmp*tmp;
+ */
+ int minScale = fixMin(CountLeadingBits(sfbThrExp),
+ CountLeadingBits(redVal_m) - redVal_e) -
+ 1;
+
+ /* 4*log( sfbThrExp + redVal ) */
+ sfbThrReducedLdData =
+ CalcLdData(fAbs(scaleValue(sfbThrExp, minScale) +
+ scaleValue(redVal_m, redVal_e + minScale))) -
+ (FIXP_DBL)(minScale << (DFRACT_BITS - 1 - LD_DATA_SHIFT));
+ sfbThrReducedLdData <<= 2;
+
+ /* avoid holes */
+ if ((sfbThrReducedLdData >
+ (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] + sfbEnLdData)) &&
+ (ahFlag[ch][sfbGrp + sfb] != NO_AH)) {
+ if (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] >
+ (FL2FXCONST_DBL(-1.0f) - sfbEnLdData)) {
+ sfbThrReducedLdData = fixMax(
+ (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] + sfbEnLdData),
+ sfbThrLdData);
+ } else
+ sfbThrReducedLdData = sfbThrLdData;
+ ahFlag[ch][sfbGrp + sfb] = AH_ACTIVE;
+ }
+
+ /* minimum of 29 dB Ratio for Thresholds */
+ if ((sfbEnLdData + (FIXP_DBL)MAXVAL_DBL) >
+ FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING)) {
+ sfbThrReducedLdData = fixMax(
+ sfbThrReducedLdData,
+ (sfbEnLdData - FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING)));
+ }
+
+ qcOutChan->sfbThresholdLdData[sfbGrp + sfb] = sfbThrReducedLdData;
+ }
+ }
+ }
+ }
+}
+
+/* similar to prepareSfbPe1() */
+static FIXP_DBL FDKaacEnc_calcChaosMeasure(
+ const PSY_OUT_CHANNEL *const psyOutChannel,
+ const FIXP_DBL *const sfbFormFactorLdData) {
+#define SCALE_FORM_FAC \
+ (4) /* (SCALE_FORM_FAC+FORM_FAC_SHIFT) >= ld(FRAME_LENGTH)*/
+#define SCALE_NRGS (8)
+#define SCALE_NLINES (16)
+#define SCALE_NRGS_SQRT4 (2) /* 0.25 * SCALE_NRGS */
+#define SCALE_NLINES_P34 (12) /* 0.75 * SCALE_NLINES */
+
+ INT sfbGrp, sfb;
+ FIXP_DBL chaosMeasure;
+ INT frameNLines = 0;
+ FIXP_DBL frameFormFactor = FL2FXCONST_DBL(0.f);
+ FIXP_DBL frameEnergy = FL2FXCONST_DBL(0.f);
+
+ for (sfbGrp = 0; sfbGrp < psyOutChannel->sfbCnt;
+ sfbGrp += psyOutChannel->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
+ if (psyOutChannel->sfbEnergyLdData[sfbGrp + sfb] >
+ psyOutChannel->sfbThresholdLdData[sfbGrp + sfb]) {
+ frameFormFactor += (CalcInvLdData(sfbFormFactorLdData[sfbGrp + sfb]) >>
+ SCALE_FORM_FAC);
+ frameNLines += (psyOutChannel->sfbOffsets[sfbGrp + sfb + 1] -
+ psyOutChannel->sfbOffsets[sfbGrp + sfb]);
+ frameEnergy += (psyOutChannel->sfbEnergy[sfbGrp + sfb] >> SCALE_NRGS);
+ }
+ }
+ }
+
+ if (frameNLines > 0) {
+ /* frameNActiveLines = frameFormFactor*2^FORM_FAC_SHIFT * ((frameEnergy
+ *2^SCALE_NRGS)/frameNLines)^-0.25 chaosMeasure = frameNActiveLines /
+ frameNLines */
+ chaosMeasure = CalcInvLdData(
+ (((CalcLdData(frameFormFactor) >> 1) -
+ (CalcLdData(frameEnergy) >> (2 + 1))) -
+ (fMultDiv2(FL2FXCONST_DBL(0.75f),
+ CalcLdData((FIXP_DBL)frameNLines
+ << (DFRACT_BITS - 1 - SCALE_NLINES))) -
+ (((FIXP_DBL)(-((-SCALE_FORM_FAC + SCALE_NRGS_SQRT4 - FORM_FAC_SHIFT +
+ SCALE_NLINES_P34)
+ << (DFRACT_BITS - 1 - LD_DATA_SHIFT)))) >>
+ 1)))
+ << 1);
+ } else {
+ /* assuming total chaos, if no sfb is above thresholds */
+ chaosMeasure = FL2FXCONST_DBL(1.f);
+ }
+
+ return chaosMeasure;
+}
+
+/* apply reduction formula for VBR-mode */
+static void FDKaacEnc_reduceThresholdsVBR(
+ QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)],
+ UCHAR ahFlag[(2)][MAX_GROUPED_SFB],
+ const FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB], const INT nChannels,
+ const FIXP_DBL vbrQualFactor, FIXP_DBL *const chaosMeasureOld) {
+ INT ch, sfbGrp, sfb;
+ FIXP_DBL chGroupEnergy[TRANS_FAC][2]; /*energy for each group and channel*/
+ FIXP_DBL chChaosMeasure[2];
+ FIXP_DBL frameEnergy = FL2FXCONST_DBL(1e-10f);
+ FIXP_DBL chaosMeasure = FL2FXCONST_DBL(0.f);
+ FIXP_DBL sfbEnLdData, sfbThrLdData, sfbThrExp;
+ FIXP_DBL sfbThrReducedLdData;
+ FIXP_DBL chaosMeasureAvg;
+ INT groupCnt; /* loop counter */
+ FIXP_DBL redVal[TRANS_FAC]; /* reduction values; in short-block case one
+ redVal for each group */
+ QC_OUT_CHANNEL *qcOutChan = NULL;
+ const PSY_OUT_CHANNEL *psyOutChan = NULL;
+
+#define SCALE_GROUP_ENERGY (8)
+
+#define CONST_CHAOS_MEAS_AVG_FAC_0 (FL2FXCONST_DBL(0.25f))
+#define CONST_CHAOS_MEAS_AVG_FAC_1 (FL2FXCONST_DBL(1.f - 0.25f))
+
+#define MIN_LDTHRESH (FL2FXCONST_DBL(-0.515625f))
+
+ for (ch = 0; ch < nChannels; ch++) {
+ psyOutChan = psyOutChannel[ch];
+
+ /* adding up energy for each channel and each group separately */
+ FIXP_DBL chEnergy = FL2FXCONST_DBL(0.f);
+ groupCnt = 0;
+
+ for (sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt;
+ sfbGrp += psyOutChan->sfbPerGroup, groupCnt++) {
+ chGroupEnergy[groupCnt][ch] = FL2FXCONST_DBL(0.f);
+ for (sfb = 0; sfb < psyOutChan->maxSfbPerGroup; sfb++) {
+ chGroupEnergy[groupCnt][ch] +=
+ (psyOutChan->sfbEnergy[sfbGrp + sfb] >> SCALE_GROUP_ENERGY);
+ }
+ chEnergy += chGroupEnergy[groupCnt][ch];
+ }
+ frameEnergy += chEnergy;
+
+ /* chaosMeasure */
+ if (psyOutChannel[0]->lastWindowSequence == SHORT_WINDOW) {
+ chChaosMeasure[ch] = FL2FXCONST_DBL(
+ 0.5f); /* assume a constant chaos measure of 0.5f for short blocks */
+ } else {
+ chChaosMeasure[ch] = FDKaacEnc_calcChaosMeasure(
+ psyOutChannel[ch], qcOutChannel[ch]->sfbFormFactorLdData);
+ }
+ chaosMeasure += fMult(chChaosMeasure[ch], chEnergy);
+ }
+
+ if (frameEnergy > chaosMeasure) {
+ INT scale = CntLeadingZeros(frameEnergy) - 1;
+ FIXP_DBL num = chaosMeasure << scale;
+ FIXP_DBL denum = frameEnergy << scale;
+ chaosMeasure = schur_div(num, denum, 16);
+ } else {
+ chaosMeasure = FL2FXCONST_DBL(1.f);
+ }
+
+ chaosMeasureAvg = fMult(CONST_CHAOS_MEAS_AVG_FAC_0, chaosMeasure) +
+ fMult(CONST_CHAOS_MEAS_AVG_FAC_1,
+ *chaosMeasureOld); /* averaging chaos measure */
+ *chaosMeasureOld = chaosMeasure = (fixMin(
+ chaosMeasure, chaosMeasureAvg)); /* use min-value, safe for next frame */
+
+ /* characteristic curve
+ chaosMeasure = 0.2f + 0.7f/0.3f * (chaosMeasure - 0.2f);
+ chaosMeasure = fixMin(1.0f, fixMax(0.1f, chaosMeasure));
+ constants scaled by 4.f
+ */
+ chaosMeasure = ((FL2FXCONST_DBL(0.2f) >> 2) +
+ fMult(FL2FXCONST_DBL(0.7f / (4.f * 0.3f)),
+ (chaosMeasure - FL2FXCONST_DBL(0.2f))));
+ chaosMeasure =
+ (fixMin((FIXP_DBL)(FL2FXCONST_DBL(1.0f) >> 2),
+ fixMax((FIXP_DBL)(FL2FXCONST_DBL(0.1f) >> 2), chaosMeasure)))
+ << 2;
+
+ /* calculation of reduction value */
+ if (psyOutChannel[0]->lastWindowSequence == SHORT_WINDOW) { /* short-blocks */
+ FDK_ASSERT(TRANS_FAC == 8);
+#define WIN_TYPE_SCALE (3)
+
+ groupCnt = 0;
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[0]->sfbCnt;
+ sfbGrp += psyOutChannel[0]->sfbPerGroup, groupCnt++) {
+ FIXP_DBL groupEnergy = FL2FXCONST_DBL(0.f);
+
+ for (ch = 0; ch < nChannels; ch++) {
+ groupEnergy +=
+ chGroupEnergy[groupCnt]
+ [ch]; /* adding up the channels groupEnergy */
+ }
+
+ FDK_ASSERT(psyOutChannel[0]->groupLen[groupCnt] <= INV_INT_TAB_SIZE);
+ groupEnergy = fMult(
+ groupEnergy,
+ invInt[psyOutChannel[0]->groupLen[groupCnt]]); /* correction of
+ group energy */
+ groupEnergy = fixMin(groupEnergy,
+ frameEnergy >> WIN_TYPE_SCALE); /* do not allow an
+ higher redVal as
+ calculated
+ framewise */
+
+ groupEnergy >>=
+ 2; /* 2*WIN_TYPE_SCALE = 6 => 6+2 = 8 ==> 8/4 = int number */
+
+ redVal[groupCnt] =
+ fMult(fMult(vbrQualFactor, chaosMeasure),
+ CalcInvLdData(CalcLdData(groupEnergy) >> 2))
+ << (int)((2 + (2 * WIN_TYPE_SCALE) + SCALE_GROUP_ENERGY) >> 2);
+ }
+ } else { /* long-block */
+
+ redVal[0] = fMult(fMult(vbrQualFactor, chaosMeasure),
+ CalcInvLdData(CalcLdData(frameEnergy) >> 2))
+ << (int)(SCALE_GROUP_ENERGY >> 2);
+ }
+
+ for (ch = 0; ch < nChannels; ch++) {
+ qcOutChan = qcOutChannel[ch];
+ psyOutChan = psyOutChannel[ch];
+
+ for (sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt;
+ sfbGrp += psyOutChan->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChan->maxSfbPerGroup; sfb++) {
+ sfbEnLdData = (qcOutChan->sfbWeightedEnergyLdData[sfbGrp + sfb]);
+ sfbThrLdData = (qcOutChan->sfbThresholdLdData[sfbGrp + sfb]);
+ sfbThrExp = thrExp[ch][sfbGrp + sfb];
+
+ if ((sfbThrLdData >= MIN_LDTHRESH) && (sfbEnLdData > sfbThrLdData) &&
+ (ahFlag[ch][sfbGrp + sfb] != AH_ACTIVE)) {
+ /* Short-Window */
+ if (psyOutChannel[ch]->lastWindowSequence == SHORT_WINDOW) {
+ const int groupNumber = (int)sfb / psyOutChan->sfbPerGroup;
+
+ FDK_ASSERT(INV_SQRT4_TAB_SIZE > psyOutChan->groupLen[groupNumber]);
+
+ sfbThrExp =
+ fMult(sfbThrExp,
+ fMult(FL2FXCONST_DBL(2.82f / 4.f),
+ invSqrt4[psyOutChan->groupLen[groupNumber]]))
+ << 2;
+
+ if (sfbThrExp <= (limitThrReducedLdData - redVal[groupNumber])) {
+ sfbThrReducedLdData = FL2FXCONST_DBL(-1.0f);
+ } else {
+ if ((FIXP_DBL)redVal[groupNumber] >=
+ FL2FXCONST_DBL(1.0f) - sfbThrExp)
+ sfbThrReducedLdData = FL2FXCONST_DBL(0.0f);
+ else {
+ /* threshold reduction formula */
+ sfbThrReducedLdData =
+ CalcLdData(sfbThrExp + redVal[groupNumber]);
+ sfbThrReducedLdData <<= 2;
+ }
+ }
+ sfbThrReducedLdData +=
+ (CalcLdInt(psyOutChan->groupLen[groupNumber]) -
+ ((FIXP_DBL)6 << (DFRACT_BITS - 1 - LD_DATA_SHIFT)));
+ }
+
+ /* Long-Window */
+ else {
+ if ((FIXP_DBL)redVal[0] >= FL2FXCONST_DBL(1.0f) - sfbThrExp) {
+ sfbThrReducedLdData = FL2FXCONST_DBL(0.0f);
+ } else {
+ /* threshold reduction formula */
+ sfbThrReducedLdData = CalcLdData(sfbThrExp + redVal[0]);
+ sfbThrReducedLdData <<= 2;
+ }
+ }
+
+ /* avoid holes */
+ if (((sfbThrReducedLdData - sfbEnLdData) >
+ qcOutChan->sfbMinSnrLdData[sfbGrp + sfb]) &&
+ (ahFlag[ch][sfbGrp + sfb] != NO_AH)) {
+ if (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] >
+ (FL2FXCONST_DBL(-1.0f) - sfbEnLdData)) {
+ sfbThrReducedLdData = fixMax(
+ (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] + sfbEnLdData),
+ sfbThrLdData);
+ } else
+ sfbThrReducedLdData = sfbThrLdData;
+ ahFlag[ch][sfbGrp + sfb] = AH_ACTIVE;
+ }
+
+ if (sfbThrReducedLdData < FL2FXCONST_DBL(-0.5f))
+ sfbThrReducedLdData = FL2FXCONST_DBL(-1.f);
+
+ /* minimum of 29 dB Ratio for Thresholds */
+ if ((sfbEnLdData + FL2FXCONST_DBL(1.0f)) >
+ FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING)) {
+ sfbThrReducedLdData = fixMax(
+ sfbThrReducedLdData,
+ sfbEnLdData - FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING));
+ }
+
+ sfbThrReducedLdData = fixMax(MIN_LDTHRESH, sfbThrReducedLdData);
+
+ qcOutChan->sfbThresholdLdData[sfbGrp + sfb] = sfbThrReducedLdData;
+ }
+ }
+ }
+ }
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_correctThresh
+description: if pe difference deltaPe between desired pe and real pe is small
+enough, the difference can be distributed among the scale factor bands. New
+thresholds can be derived from this pe-difference
+*****************************************************************************/
+static void FDKaacEnc_correctThresh(
+ const CHANNEL_MAPPING *const cm, QC_OUT_ELEMENT *const qcElement[((8))],
+ const PSY_OUT_ELEMENT *const psyOutElement[((8))],
+ UCHAR ahFlag[((8))][(2)][MAX_GROUPED_SFB],
+ const FIXP_DBL thrExp[((8))][(2)][MAX_GROUPED_SFB], const FIXP_DBL redVal_m,
+ const SCHAR redVal_e, const INT deltaPe, const INT processElements,
+ const INT elementOffset) {
+ INT ch, sfb, sfbGrp;
+ QC_OUT_CHANNEL *qcOutChan;
+ PSY_OUT_CHANNEL *psyOutChan;
+ PE_CHANNEL_DATA *peChanData;
+ FIXP_DBL thrFactorLdData;
+ FIXP_DBL sfbEnLdData, sfbThrLdData, sfbThrReducedLdData;
+ FIXP_DBL *sfbPeFactorsLdData[((8))][(2)];
+ FIXP_DBL(*sfbNActiveLinesLdData)[(2)][MAX_GROUPED_SFB];
+
+ INT normFactorInt;
+ FIXP_DBL normFactorLdData;
+
+ INT nElements = elementOffset + processElements;
+ INT elementId;
+
+ /* scratch is empty; use temporal memory from quantSpec in QC_OUT_CHANNEL */
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) {
+ /* The reinterpret_cast is used to suppress a compiler warning. We know
+ * that qcElement[elementId]->qcOutChannel[ch]->quantSpec is sufficiently
+ * aligned, so the cast is safe */
+ sfbPeFactorsLdData[elementId][ch] =
+ reinterpret_cast<FIXP_DBL *>(reinterpret_cast<void *>(
+ qcElement[elementId]->qcOutChannel[ch]->quantSpec));
+ }
+ }
+ /* The reinterpret_cast is used to suppress a compiler warning. We know that
+ * qcElement[0]->dynMem_SfbNActiveLinesLdData is sufficiently aligned, so the
+ * cast is safe */
+ sfbNActiveLinesLdData = reinterpret_cast<FIXP_DBL(*)[(2)][MAX_GROUPED_SFB]>(
+ reinterpret_cast<void *>(qcElement[0]->dynMem_SfbNActiveLinesLdData));
+
+ /* for each sfb calc relative factors for pe changes */
+ normFactorInt = 0;
+
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) {
+ psyOutChan = psyOutElement[elementId]->psyOutChannel[ch];
+ peChanData = &qcElement[elementId]->peData.peChannelData[ch];
+
+ for (sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt;
+ sfbGrp += psyOutChan->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChan->maxSfbPerGroup; sfb++) {
+ if (peChanData->sfbNActiveLines[sfbGrp + sfb] == 0) {
+ sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] =
+ FL2FXCONST_DBL(-1.0f);
+ } else {
+ /* Both CalcLdInt and CalcLdData can be used!
+ * No offset has to be subtracted, because sfbNActiveLinesLdData
+ * is shorted while thrFactor calculation */
+ sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] =
+ CalcLdInt(peChanData->sfbNActiveLines[sfbGrp + sfb]);
+ }
+ if (((ahFlag[elementId][ch][sfbGrp + sfb] < AH_ACTIVE) ||
+ (deltaPe > 0)) &&
+ peChanData->sfbNActiveLines[sfbGrp + sfb] != 0) {
+ if (thrExp[elementId][ch][sfbGrp + sfb] > -redVal_m) {
+ /* sfbPeFactors[ch][sfbGrp+sfb] =
+ peChanData->sfbNActiveLines[sfbGrp+sfb] /
+ (thrExp[elementId][ch][sfbGrp+sfb] +
+ redVal[elementId]); */
+
+ int minScale =
+ fixMin(
+ CountLeadingBits(thrExp[elementId][ch][sfbGrp + sfb]),
+ CountLeadingBits(redVal_m) - redVal_e) -
+ 1;
+
+ /* sumld = ld64( sfbThrExp + redVal ) */
+ FIXP_DBL sumLd =
+ CalcLdData(scaleValue(thrExp[elementId][ch][sfbGrp + sfb],
+ minScale) +
+ scaleValue(redVal_m, redVal_e + minScale)) -
+ (FIXP_DBL)(minScale << (DFRACT_BITS - 1 - LD_DATA_SHIFT));
+
+ if (sumLd < FL2FXCONST_DBL(0.f)) {
+ sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] =
+ sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] -
+ sumLd;
+ } else {
+ if (sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] >
+ (FL2FXCONST_DBL(-1.f) + sumLd)) {
+ sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] =
+ sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] -
+ sumLd;
+ } else {
+ sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] =
+ sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb];
+ }
+ }
+
+ normFactorInt += (INT)CalcInvLdData(
+ sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb]);
+ } else
+ sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] =
+ FL2FXCONST_DBL(1.0f);
+ } else
+ sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] =
+ FL2FXCONST_DBL(-1.0f);
+ }
+ }
+ }
+ }
+ }
+
+ /* normFactorLdData = ld64(deltaPe/normFactorInt) */
+ normFactorLdData =
+ CalcLdData((FIXP_DBL)((deltaPe < 0) ? (-deltaPe) : (deltaPe))) -
+ CalcLdData((FIXP_DBL)normFactorInt);
+
+ /* distribute the pe difference to the scalefactors
+ and calculate the according thresholds */
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) {
+ qcOutChan = qcElement[elementId]->qcOutChannel[ch];
+ psyOutChan = psyOutElement[elementId]->psyOutChannel[ch];
+ peChanData = &qcElement[elementId]->peData.peChannelData[ch];
+
+ for (sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt;
+ sfbGrp += psyOutChan->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChan->maxSfbPerGroup; sfb++) {
+ if (peChanData->sfbNActiveLines[sfbGrp + sfb] > 0) {
+ /* pe difference for this sfb */
+ if ((sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] ==
+ FL2FXCONST_DBL(-1.0f)) ||
+ (deltaPe == 0)) {
+ thrFactorLdData = FL2FXCONST_DBL(0.f);
+ } else {
+ /* new threshold */
+ FIXP_DBL tmp = CalcInvLdData(
+ sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] +
+ normFactorLdData -
+ sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] -
+ FL2FXCONST_DBL((float)LD_DATA_SHIFT / LD_DATA_SCALING));
+
+ /* limit thrFactor to 60dB */
+ tmp = (deltaPe < 0) ? tmp : (-tmp);
+ thrFactorLdData =
+ fMin(tmp, FL2FXCONST_DBL(20.f / LD_DATA_SCALING));
+ }
+
+ /* new threshold */
+ sfbThrLdData = qcOutChan->sfbThresholdLdData[sfbGrp + sfb];
+ sfbEnLdData = qcOutChan->sfbWeightedEnergyLdData[sfbGrp + sfb];
+
+ if (thrFactorLdData < FL2FXCONST_DBL(0.f)) {
+ if (sfbThrLdData > (FL2FXCONST_DBL(-1.f) - thrFactorLdData)) {
+ sfbThrReducedLdData = sfbThrLdData + thrFactorLdData;
+ } else {
+ sfbThrReducedLdData = FL2FXCONST_DBL(-1.f);
+ }
+ } else {
+ sfbThrReducedLdData = sfbThrLdData + thrFactorLdData;
+ }
+
+ /* avoid hole */
+ if ((sfbThrReducedLdData - sfbEnLdData >
+ qcOutChan->sfbMinSnrLdData[sfbGrp + sfb]) &&
+ (ahFlag[elementId][ch][sfbGrp + sfb] == AH_INACTIVE)) {
+ /* sfbThrReduced = max(psyOutChan[ch]->sfbMinSnr[i] * sfbEn,
+ * sfbThr); */
+ if (sfbEnLdData >
+ (sfbThrLdData - qcOutChan->sfbMinSnrLdData[sfbGrp + sfb])) {
+ sfbThrReducedLdData =
+ qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] + sfbEnLdData;
+ } else {
+ sfbThrReducedLdData = sfbThrLdData;
+ }
+ ahFlag[elementId][ch][sfbGrp + sfb] = AH_ACTIVE;
+ }
+
+ qcOutChan->sfbThresholdLdData[sfbGrp + sfb] = sfbThrReducedLdData;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/*****************************************************************************
+ functionname: FDKaacEnc_reduceMinSnr
+ description: if the desired pe can not be reached, reduce pe by
+ reducing minSnr
+*****************************************************************************/
+static void FDKaacEnc_reduceMinSnr(
+ const CHANNEL_MAPPING *const cm, QC_OUT_ELEMENT *const qcElement[((8))],
+ const PSY_OUT_ELEMENT *const psyOutElement[((8))],
+ const UCHAR ahFlag[((8))][(2)][MAX_GROUPED_SFB], const INT desiredPe,
+ INT *const redPeGlobal, const INT processElements, const INT elementOffset)
+
+{
+ INT ch, elementId, globalMaxSfb = 0;
+ const INT nElements = elementOffset + processElements;
+ INT newGlobalPe = *redPeGlobal;
+
+ if (newGlobalPe <= desiredPe) {
+ goto bail;
+ }
+
+ /* global maximum of maxSfbPerGroup */
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) {
+ globalMaxSfb =
+ fMax(globalMaxSfb,
+ psyOutElement[elementId]->psyOutChannel[ch]->maxSfbPerGroup);
+ }
+ }
+ }
+
+ /* as long as globalPE is above desirePE reduce SNR to 1.0 dB, starting at
+ * highest SFB */
+ while ((newGlobalPe > desiredPe) && (--globalMaxSfb >= 0)) {
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ PE_DATA *peData = &qcElement[elementId]->peData;
+
+ for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) {
+ QC_OUT_CHANNEL *qcOutChan = qcElement[elementId]->qcOutChannel[ch];
+ PSY_OUT_CHANNEL *psyOutChan =
+ psyOutElement[elementId]->psyOutChannel[ch];
+
+ /* try to reduce SNR of channel's uppermost SFB(s) */
+ if (globalMaxSfb < psyOutChan->maxSfbPerGroup) {
+ INT sfb, deltaPe = 0;
+
+ for (sfb = globalMaxSfb; sfb < psyOutChan->sfbCnt;
+ sfb += psyOutChan->sfbPerGroup) {
+ if (ahFlag[elementId][ch][sfb] != NO_AH &&
+ qcOutChan->sfbMinSnrLdData[sfb] < SnrLdFac &&
+ (qcOutChan->sfbWeightedEnergyLdData[sfb] >
+ qcOutChan->sfbThresholdLdData[sfb] - SnrLdFac)) {
+ /* increase threshold to new minSnr of 1dB */
+ qcOutChan->sfbMinSnrLdData[sfb] = SnrLdFac;
+ qcOutChan->sfbThresholdLdData[sfb] =
+ qcOutChan->sfbWeightedEnergyLdData[sfb] + SnrLdFac;
+
+ /* calc new pe */
+ /* C2 + C3*ld(1/0.8) = 1.5 */
+ deltaPe -= peData->peChannelData[ch].sfbPe[sfb];
+
+ /* sfbPe = 1.5 * sfbNLines */
+ peData->peChannelData[ch].sfbPe[sfb] =
+ (3 * peData->peChannelData[ch].sfbNLines[sfb])
+ << (PE_CONSTPART_SHIFT - 1);
+ deltaPe += peData->peChannelData[ch].sfbPe[sfb];
+ }
+
+ } /* sfb loop */
+
+ deltaPe >>= PE_CONSTPART_SHIFT;
+ peData->pe += deltaPe;
+ peData->peChannelData[ch].pe += deltaPe;
+ newGlobalPe += deltaPe;
+
+ } /* if globalMaxSfb < maxSfbPerGroup */
+
+ /* stop if enough has been saved */
+ if (newGlobalPe <= desiredPe) {
+ goto bail;
+ }
+
+ } /* ch loop */
+ } /* != ID_DSE */
+ } /* elementId loop */
+ } /* while ( newGlobalPe > desiredPe) && (--globalMaxSfb >= 0) ) */
+
+bail:
+ /* update global PE */
+ *redPeGlobal = newGlobalPe;
+}
+
+/*****************************************************************************
+ functionname: FDKaacEnc_allowMoreHoles
+ description: if the desired pe can not be reached, some more scalefactor
+ bands have to be quantized to zero
+*****************************************************************************/
+static void FDKaacEnc_allowMoreHoles(
+ const CHANNEL_MAPPING *const cm, QC_OUT_ELEMENT *const qcElement[((8))],
+ const PSY_OUT_ELEMENT *const psyOutElement[((8))],
+ const ATS_ELEMENT *const AdjThrStateElement[((8))],
+ UCHAR ahFlag[((8))][(2)][MAX_GROUPED_SFB], const INT desiredPe,
+ const INT currentPe, const int processElements, const int elementOffset) {
+ INT elementId;
+ INT nElements = elementOffset + processElements;
+ INT actPe = currentPe;
+
+ if (actPe <= desiredPe) {
+ return; /* nothing to do */
+ }
+
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ INT ch, sfb, sfbGrp;
+
+ PE_DATA *peData = &qcElement[elementId]->peData;
+ const INT nChannels = cm->elInfo[elementId].nChannelsInEl;
+
+ QC_OUT_CHANNEL *qcOutChannel[(2)] = {NULL};
+ PSY_OUT_CHANNEL *psyOutChannel[(2)] = {NULL};
+
+ for (ch = 0; ch < nChannels; ch++) {
+ /* init pointers */
+ qcOutChannel[ch] = qcElement[elementId]->qcOutChannel[ch];
+ psyOutChannel[ch] = psyOutElement[elementId]->psyOutChannel[ch];
+
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup) {
+ for (sfb = psyOutChannel[ch]->maxSfbPerGroup;
+ sfb < psyOutChannel[ch]->sfbPerGroup; sfb++) {
+ peData->peChannelData[ch].sfbPe[sfbGrp + sfb] = 0;
+ }
+ }
+ }
+
+ /* for MS allow hole in the channel with less energy */
+ if (nChannels == 2 && psyOutChannel[0]->lastWindowSequence ==
+ psyOutChannel[1]->lastWindowSequence) {
+ for (sfb = psyOutChannel[0]->maxSfbPerGroup - 1; sfb >= 0; sfb--) {
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[0]->sfbCnt;
+ sfbGrp += psyOutChannel[0]->sfbPerGroup) {
+ if (psyOutElement[elementId]->toolsInfo.msMask[sfbGrp + sfb]) {
+ FIXP_DBL EnergyLd_L =
+ qcOutChannel[0]->sfbWeightedEnergyLdData[sfbGrp + sfb];
+ FIXP_DBL EnergyLd_R =
+ qcOutChannel[1]->sfbWeightedEnergyLdData[sfbGrp + sfb];
+
+ /* allow hole in side channel ? */
+ if ((ahFlag[elementId][1][sfbGrp + sfb] != NO_AH) &&
+ (((FL2FXCONST_DBL(-0.02065512648f) >> 1) +
+ (qcOutChannel[0]->sfbMinSnrLdData[sfbGrp + sfb] >> 1)) >
+ ((EnergyLd_R >> 1) - (EnergyLd_L >> 1)))) {
+ ahFlag[elementId][1][sfbGrp + sfb] = NO_AH;
+ qcOutChannel[1]->sfbThresholdLdData[sfbGrp + sfb] =
+ FL2FXCONST_DBL(0.015625f) + EnergyLd_R;
+ actPe -= peData->peChannelData[1].sfbPe[sfbGrp + sfb] >>
+ PE_CONSTPART_SHIFT;
+ }
+ /* allow hole in mid channel ? */
+ else if ((ahFlag[elementId][0][sfbGrp + sfb] != NO_AH) &&
+ (((FL2FXCONST_DBL(-0.02065512648f) >> 1) +
+ (qcOutChannel[1]->sfbMinSnrLdData[sfbGrp + sfb] >>
+ 1)) > ((EnergyLd_L >> 1) - (EnergyLd_R >> 1)))) {
+ ahFlag[elementId][0][sfbGrp + sfb] = NO_AH;
+ qcOutChannel[0]->sfbThresholdLdData[sfbGrp + sfb] =
+ FL2FXCONST_DBL(0.015625f) + EnergyLd_L;
+ actPe -= peData->peChannelData[0].sfbPe[sfbGrp + sfb] >>
+ PE_CONSTPART_SHIFT;
+ } /* if (ahFlag) */
+ } /* if MS */
+ } /* sfbGrp */
+ if (actPe <= desiredPe) {
+ return; /* stop if enough has been saved */
+ }
+ } /* sfb */
+ } /* MS possible ? */
+
+ } /* EOF DSE-suppression */
+ } /* EOF for all elements... */
+
+ if (actPe > desiredPe) {
+ /* more holes necessary? subsequently erase bands starting with low energies
+ */
+ INT ch, sfb, sfbGrp;
+ INT minSfb, maxSfb;
+ INT enIdx, ahCnt, done;
+ INT startSfb[(8)];
+ INT sfbCnt[(8)];
+ INT sfbPerGroup[(8)];
+ INT maxSfbPerGroup[(8)];
+ FIXP_DBL avgEn;
+ FIXP_DBL minEnLD64;
+ FIXP_DBL avgEnLD64;
+ FIXP_DBL enLD64[NUM_NRG_LEVS];
+ INT avgEn_e;
+
+ /* get the scaling factor over all audio elements and channels */
+ maxSfb = 0;
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) {
+ for (sfbGrp = 0;
+ sfbGrp < psyOutElement[elementId]->psyOutChannel[ch]->sfbCnt;
+ sfbGrp +=
+ psyOutElement[elementId]->psyOutChannel[ch]->sfbPerGroup) {
+ maxSfb +=
+ psyOutElement[elementId]->psyOutChannel[ch]->maxSfbPerGroup;
+ }
+ }
+ }
+ }
+ avgEn_e =
+ (DFRACT_BITS - fixnormz_D((LONG)fMax(0, maxSfb - 1))); /* ilog2() */
+
+ ahCnt = 0;
+ maxSfb = 0;
+ minSfb = MAX_SFB;
+ avgEn = FL2FXCONST_DBL(0.0f);
+ minEnLD64 = FL2FXCONST_DBL(0.0f);
+
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) {
+ const INT chIdx = cm->elInfo[elementId].ChannelIndex[ch];
+ QC_OUT_CHANNEL *qcOutChannel = qcElement[elementId]->qcOutChannel[ch];
+ PSY_OUT_CHANNEL *psyOutChannel =
+ psyOutElement[elementId]->psyOutChannel[ch];
+
+ maxSfbPerGroup[chIdx] = psyOutChannel->maxSfbPerGroup;
+ sfbCnt[chIdx] = psyOutChannel->sfbCnt;
+ sfbPerGroup[chIdx] = psyOutChannel->sfbPerGroup;
+
+ maxSfb = fMax(maxSfb, psyOutChannel->maxSfbPerGroup);
+
+ if (psyOutChannel->lastWindowSequence != SHORT_WINDOW) {
+ startSfb[chIdx] = AdjThrStateElement[elementId]->ahParam.startSfbL;
+ } else {
+ startSfb[chIdx] = AdjThrStateElement[elementId]->ahParam.startSfbS;
+ }
+
+ minSfb = fMin(minSfb, startSfb[chIdx]);
+
+ sfbGrp = 0;
+ sfb = startSfb[chIdx];
+
+ do {
+ for (; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
+ if ((ahFlag[elementId][ch][sfbGrp + sfb] != NO_AH) &&
+ (qcOutChannel->sfbWeightedEnergyLdData[sfbGrp + sfb] >
+ qcOutChannel->sfbThresholdLdData[sfbGrp + sfb])) {
+ minEnLD64 = fixMin(minEnLD64,
+ qcOutChannel->sfbEnergyLdData[sfbGrp + sfb]);
+ avgEn += qcOutChannel->sfbEnergy[sfbGrp + sfb] >> avgEn_e;
+ ahCnt++;
+ }
+ }
+
+ sfbGrp += psyOutChannel->sfbPerGroup;
+ sfb = startSfb[chIdx];
+
+ } while (sfbGrp < psyOutChannel->sfbCnt);
+ }
+ } /* (cm->elInfo[elementId].elType != ID_DSE) */
+ } /* (elementId = elementOffset;elementId<nElements;elementId++) */
+
+ if ((avgEn == FL2FXCONST_DBL(0.0f)) || (ahCnt == 0)) {
+ avgEnLD64 = FL2FXCONST_DBL(0.0f);
+ } else {
+ avgEnLD64 = CalcLdData(avgEn) +
+ (FIXP_DBL)(avgEn_e << (DFRACT_BITS - 1 - LD_DATA_SHIFT)) -
+ CalcLdInt(ahCnt);
+ }
+
+ /* calc some energy borders between minEn and avgEn */
+
+ /* for (enIdx = 0; enIdx < NUM_NRG_LEVS; enIdx++) {
+ en[enIdx] = (2.0f*enIdx+1.0f)/(2.0f*NUM_NRG_LEVS-1.0f);
+ } */
+ enLD64[0] =
+ minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.06666667f));
+ enLD64[1] =
+ minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.20000000f));
+ enLD64[2] =
+ minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.33333334f));
+ enLD64[3] =
+ minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.46666667f));
+ enLD64[4] =
+ minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.60000002f));
+ enLD64[5] =
+ minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.73333335f));
+ enLD64[6] =
+ minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.86666667f));
+ enLD64[7] = minEnLD64 + (avgEnLD64 - minEnLD64);
+
+ done = 0;
+ enIdx = 0;
+ sfb = maxSfb - 1;
+
+ while (!done) {
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ PE_DATA *peData = &qcElement[elementId]->peData;
+ for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) {
+ const INT chIdx = cm->elInfo[elementId].ChannelIndex[ch];
+ QC_OUT_CHANNEL *qcOutChannel =
+ qcElement[elementId]->qcOutChannel[ch];
+ if (sfb >= startSfb[chIdx] && sfb < maxSfbPerGroup[chIdx]) {
+ for (sfbGrp = 0; sfbGrp < sfbCnt[chIdx];
+ sfbGrp += sfbPerGroup[chIdx]) {
+ /* sfb energy below border ? */
+ if (ahFlag[elementId][ch][sfbGrp + sfb] != NO_AH &&
+ qcOutChannel->sfbEnergyLdData[sfbGrp + sfb] <
+ enLD64[enIdx]) {
+ /* allow hole */
+ ahFlag[elementId][ch][sfbGrp + sfb] = NO_AH;
+ qcOutChannel->sfbThresholdLdData[sfbGrp + sfb] =
+ FL2FXCONST_DBL(0.015625f) +
+ qcOutChannel->sfbWeightedEnergyLdData[sfbGrp + sfb];
+ actPe -= peData->peChannelData[ch].sfbPe[sfbGrp + sfb] >>
+ PE_CONSTPART_SHIFT;
+ }
+ if (actPe <= desiredPe) {
+ return; /* stop if enough has been saved */
+ }
+ } /* sfbGrp */
+ } /* sfb */
+ } /* nChannelsInEl */
+ } /* ID_DSE */
+ } /* elementID */
+
+ sfb--;
+ if (sfb < minSfb) {
+ /* restart with next energy border */
+ sfb = maxSfb;
+ enIdx++;
+ if (enIdx >= NUM_NRG_LEVS) {
+ done = 1;
+ }
+ }
+ } /* done */
+ } /* (actPe <= desiredPe) */
+}
+
+/* reset avoid hole flags from AH_ACTIVE to AH_INACTIVE */
+static void FDKaacEnc_resetAHFlags(
+ UCHAR ahFlag[(2)][MAX_GROUPED_SFB], const INT nChannels,
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)]) {
+ int ch, sfb, sfbGrp;
+
+ for (ch = 0; ch < nChannels; ch++) {
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) {
+ if (ahFlag[ch][sfbGrp + sfb] == AH_ACTIVE) {
+ ahFlag[ch][sfbGrp + sfb] = AH_INACTIVE;
+ }
+ }
+ }
+ }
+}
+
+static FIXP_DBL CalcRedValPower(FIXP_DBL num, FIXP_DBL denum, INT *scaling) {
+ FIXP_DBL value = FL2FXCONST_DBL(0.f);
+
+ if (num >= FL2FXCONST_DBL(0.f)) {
+ value = fDivNorm(num, denum, scaling);
+ } else {
+ value = -fDivNorm(-num, denum, scaling);
+ }
+ value = f2Pow(value, *scaling, scaling);
+
+ return value;
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_adaptThresholdsToPe
+description: two guesses for the reduction value and one final correction of
+the thresholds
+*****************************************************************************/
+static void FDKaacEnc_adaptThresholdsToPe(
+ const CHANNEL_MAPPING *const cm,
+ ATS_ELEMENT *const AdjThrStateElement[((8))],
+ QC_OUT_ELEMENT *const qcElement[((8))],
+ const PSY_OUT_ELEMENT *const psyOutElement[((8))], const INT desiredPe,
+ const INT maxIter2ndGuess, const INT processElements,
+ const INT elementOffset) {
+ FIXP_DBL reductionValue_m;
+ SCHAR reductionValue_e;
+ UCHAR(*pAhFlag)[(2)][MAX_GROUPED_SFB];
+ FIXP_DBL(*pThrExp)[(2)][MAX_GROUPED_SFB];
+ int iter;
+
+ INT constPartGlobal, noRedPeGlobal, nActiveLinesGlobal, redPeGlobal;
+ constPartGlobal = noRedPeGlobal = nActiveLinesGlobal = redPeGlobal = 0;
+
+ int elementId;
+
+ int nElements = elementOffset + processElements;
+ if (nElements > cm->nElements) {
+ nElements = cm->nElements;
+ }
+
+ /* The reinterpret_cast is used to suppress a compiler warning. We know that
+ * qcElement[0]->dynMem_Ah_Flag is sufficiently aligned, so the cast is safe
+ */
+ pAhFlag = reinterpret_cast<UCHAR(*)[(2)][MAX_GROUPED_SFB]>(
+ reinterpret_cast<void *>(qcElement[0]->dynMem_Ah_Flag));
+ /* The reinterpret_cast is used to suppress a compiler warning. We know that
+ * qcElement[0]->dynMem_Thr_Exp is sufficiently aligned, so the cast is safe
+ */
+ pThrExp = reinterpret_cast<FIXP_DBL(*)[(2)][MAX_GROUPED_SFB]>(
+ reinterpret_cast<void *>(qcElement[0]->dynMem_Thr_Exp));
+
+ /* ------------------------------------------------------- */
+ /* Part I: Initialize data structures and variables... */
+ /* ------------------------------------------------------- */
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ INT nChannels = cm->elInfo[elementId].nChannelsInEl;
+ PE_DATA *peData = &qcElement[elementId]->peData;
+
+ /* thresholds to the power of redExp */
+ FDKaacEnc_calcThreshExp(
+ pThrExp[elementId], qcElement[elementId]->qcOutChannel,
+ psyOutElement[elementId]->psyOutChannel, nChannels);
+
+ /* lower the minSnr requirements for low energies compared to the average
+ energy in this frame */
+ FDKaacEnc_adaptMinSnr(qcElement[elementId]->qcOutChannel,
+ psyOutElement[elementId]->psyOutChannel,
+ &AdjThrStateElement[elementId]->minSnrAdaptParam,
+ nChannels);
+
+ /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */
+ FDKaacEnc_initAvoidHoleFlag(
+ qcElement[elementId]->qcOutChannel,
+ psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId],
+ &psyOutElement[elementId]->toolsInfo, nChannels,
+ &AdjThrStateElement[elementId]->ahParam);
+
+ /* sum up */
+ constPartGlobal += peData->constPart;
+ noRedPeGlobal += peData->pe;
+ nActiveLinesGlobal += fixMax((INT)peData->nActiveLines, 1);
+
+ } /* EOF DSE-suppression */
+ } /* EOF for all elements... */
+
+ /*
+ First guess of reduction value:
+ avgThrExp = (float)pow(2.0f, (constPartGlobal - noRedPeGlobal)/(4.0f *
+ nActiveLinesGlobal)); redVal = (float)pow(2.0f, (constPartGlobal -
+ desiredPe)/(4.0f * nActiveLinesGlobal)) - avgThrExp; redVal = max(0.f,
+ redVal);
+ */
+ int redVal_e, avgThrExp_e, result_e;
+ FIXP_DBL redVal_m, avgThrExp_m;
+
+ redVal_m = CalcRedValPower(constPartGlobal - desiredPe,
+ 4 * nActiveLinesGlobal, &redVal_e);
+ avgThrExp_m = CalcRedValPower(constPartGlobal - noRedPeGlobal,
+ 4 * nActiveLinesGlobal, &avgThrExp_e);
+ result_e = fMax(redVal_e, avgThrExp_e) + 1;
+
+ reductionValue_m = fMax(FL2FXCONST_DBL(0.f),
+ scaleValue(redVal_m, redVal_e - result_e) -
+ scaleValue(avgThrExp_m, avgThrExp_e - result_e));
+ reductionValue_e = result_e;
+
+ /* ----------------------------------------------------------------------- */
+ /* Part II: Calculate bit consumption of initial bit constraints setup */
+ /* ----------------------------------------------------------------------- */
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ INT nChannels = cm->elInfo[elementId].nChannelsInEl;
+ PE_DATA *peData = &qcElement[elementId]->peData;
+
+ /* reduce thresholds */
+ FDKaacEnc_reduceThresholdsCBR(
+ qcElement[elementId]->qcOutChannel,
+ psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId],
+ pThrExp[elementId], nChannels, reductionValue_m, reductionValue_e);
+
+ /* pe after first guess */
+ FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel,
+ qcElement[elementId]->qcOutChannel, peData, nChannels);
+
+ redPeGlobal += peData->pe;
+ } /* EOF DSE-suppression */
+ } /* EOF for all elements... */
+
+ /* -------------------------------------------------- */
+ /* Part III: Iterate until bit constraints are met */
+ /* -------------------------------------------------- */
+ iter = 0;
+ while ((fixp_abs(redPeGlobal - desiredPe) >
+ fMultI(FL2FXCONST_DBL(0.05f), desiredPe)) &&
+ (iter < maxIter2ndGuess)) {
+ INT desiredPeNoAHGlobal;
+ INT redPeNoAHGlobal = 0;
+ INT constPartNoAHGlobal = 0;
+ INT nActiveLinesNoAHGlobal = 0;
+
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ INT redPeNoAH, constPartNoAH, nActiveLinesNoAH;
+ INT nChannels = cm->elInfo[elementId].nChannelsInEl;
+ PE_DATA *peData = &qcElement[elementId]->peData;
+
+ /* pe for bands where avoid hole is inactive */
+ FDKaacEnc_FDKaacEnc_calcPeNoAH(
+ &redPeNoAH, &constPartNoAH, &nActiveLinesNoAH, peData,
+ pAhFlag[elementId], psyOutElement[elementId]->psyOutChannel,
+ nChannels);
+
+ redPeNoAHGlobal += redPeNoAH;
+ constPartNoAHGlobal += constPartNoAH;
+ nActiveLinesNoAHGlobal += nActiveLinesNoAH;
+ } /* EOF DSE-suppression */
+ } /* EOF for all elements... */
+
+ /* Calculate new redVal ... */
+ if (desiredPe < redPeGlobal) {
+ /* new desired pe without bands where avoid hole is active */
+ desiredPeNoAHGlobal = desiredPe - (redPeGlobal - redPeNoAHGlobal);
+
+ /* limit desiredPeNoAH to positive values, as the PE can not become
+ * negative */
+ desiredPeNoAHGlobal = fMax(0, desiredPeNoAHGlobal);
+
+ /* second guess (only if there are bands left where avoid hole is
+ * inactive)*/
+ if (nActiveLinesNoAHGlobal > 0) {
+ /*
+ avgThrExp = (float)pow(2.0f, (constPartNoAHGlobal - redPeNoAHGlobal) /
+ (4.0f * nActiveLinesNoAHGlobal)); redVal += (float)pow(2.0f,
+ (constPartNoAHGlobal - desiredPeNoAHGlobal) / (4.0f *
+ nActiveLinesNoAHGlobal)) - avgThrExp; redVal = max(0.0f, redVal);
+ */
+
+ redVal_m = CalcRedValPower(constPartNoAHGlobal - desiredPeNoAHGlobal,
+ 4 * nActiveLinesNoAHGlobal, &redVal_e);
+ avgThrExp_m = CalcRedValPower(constPartNoAHGlobal - redPeNoAHGlobal,
+ 4 * nActiveLinesNoAHGlobal, &avgThrExp_e);
+ result_e = fMax(reductionValue_e, fMax(redVal_e, avgThrExp_e) + 1) + 1;
+
+ reductionValue_m =
+ fMax(FL2FXCONST_DBL(0.f),
+ scaleValue(reductionValue_m, reductionValue_e - result_e) +
+ scaleValue(redVal_m, redVal_e - result_e) -
+ scaleValue(avgThrExp_m, avgThrExp_e - result_e));
+ reductionValue_e = result_e;
+
+ } /* nActiveLinesNoAHGlobal > 0 */
+ } else {
+ /* redVal *= redPeGlobal/desiredPe; */
+ int sc0, sc1;
+ reductionValue_m = fMultNorm(
+ reductionValue_m,
+ fDivNorm((FIXP_DBL)redPeGlobal, (FIXP_DBL)desiredPe, &sc0), &sc1);
+ reductionValue_e += sc0 + sc1;
+
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ FDKaacEnc_resetAHFlags(pAhFlag[elementId],
+ cm->elInfo[elementId].nChannelsInEl,
+ psyOutElement[elementId]->psyOutChannel);
+ } /* EOF DSE-suppression */
+ } /* EOF for all elements... */
+ }
+
+ redPeGlobal = 0;
+ /* Calculate new redVal's PE... */
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ INT nChannels = cm->elInfo[elementId].nChannelsInEl;
+ PE_DATA *peData = &qcElement[elementId]->peData;
+
+ /* reduce thresholds */
+ FDKaacEnc_reduceThresholdsCBR(
+ qcElement[elementId]->qcOutChannel,
+ psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId],
+ pThrExp[elementId], nChannels, reductionValue_m, reductionValue_e);
+
+ /* pe after second guess */
+ FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel,
+ qcElement[elementId]->qcOutChannel, peData, nChannels);
+ redPeGlobal += peData->pe;
+
+ } /* EOF DSE-suppression */
+ } /* EOF for all elements... */
+
+ iter++;
+ } /* EOF while */
+
+ /* ------------------------------------------------------- */
+ /* Part IV: if still required, further reduce constraints */
+ /* ------------------------------------------------------- */
+ /* 1.0* 1.15* 1.20*
+ * desiredPe desiredPe desiredPe
+ * | | |
+ * ...XXXXXXXXXXXXXXXXXXXXXXXXXXX| |
+ * | | |XXXXXXXXXXX...
+ * | |XXXXXXXXXXX|
+ * --- A --- | --- B --- | --- C ---
+ *
+ * (X): redPeGlobal
+ * (A): FDKaacEnc_correctThresh()
+ * (B): FDKaacEnc_allowMoreHoles()
+ * (C): FDKaacEnc_reduceMinSnr()
+ */
+
+ /* correct thresholds to get closer to the desired pe */
+ if (redPeGlobal > desiredPe) {
+ FDKaacEnc_correctThresh(cm, qcElement, psyOutElement, pAhFlag, pThrExp,
+ reductionValue_m, reductionValue_e,
+ desiredPe - redPeGlobal, processElements,
+ elementOffset);
+
+ /* update PE */
+ redPeGlobal = 0;
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ INT nChannels = cm->elInfo[elementId].nChannelsInEl;
+ PE_DATA *peData = &qcElement[elementId]->peData;
+
+ /* pe after correctThresh */
+ FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel,
+ qcElement[elementId]->qcOutChannel, peData, nChannels);
+ redPeGlobal += peData->pe;
+
+ } /* EOF DSE-suppression */
+ } /* EOF for all elements... */
+ }
+
+ if (redPeGlobal > desiredPe) {
+ /* reduce pe by reducing minSnr requirements */
+ FDKaacEnc_reduceMinSnr(
+ cm, qcElement, psyOutElement, pAhFlag,
+ (fMultI(FL2FXCONST_DBL(0.15f), desiredPe) + desiredPe), &redPeGlobal,
+ processElements, elementOffset);
+
+ /* reduce pe by allowing additional spectral holes */
+ FDKaacEnc_allowMoreHoles(cm, qcElement, psyOutElement, AdjThrStateElement,
+ pAhFlag, desiredPe, redPeGlobal, processElements,
+ elementOffset);
+ }
+}
+
+/* similar to FDKaacEnc_adaptThresholdsToPe(), for VBR-mode */
+static void FDKaacEnc_AdaptThresholdsVBR(
+ QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)],
+ ATS_ELEMENT *const AdjThrStateElement,
+ const struct TOOLSINFO *const toolsInfo, const INT nChannels) {
+ UCHAR(*pAhFlag)[MAX_GROUPED_SFB];
+ FIXP_DBL(*pThrExp)[MAX_GROUPED_SFB];
+
+ /* allocate scratch memory */
+ C_ALLOC_SCRATCH_START(_pAhFlag, UCHAR, (2) * MAX_GROUPED_SFB)
+ C_ALLOC_SCRATCH_START(_pThrExp, FIXP_DBL, (2) * MAX_GROUPED_SFB)
+ pAhFlag = (UCHAR(*)[MAX_GROUPED_SFB])_pAhFlag;
+ pThrExp = (FIXP_DBL(*)[MAX_GROUPED_SFB])_pThrExp;
+
+ /* thresholds to the power of redExp */
+ FDKaacEnc_calcThreshExp(pThrExp, qcOutChannel, psyOutChannel, nChannels);
+
+ /* lower the minSnr requirements for low energies compared to the average
+ energy in this frame */
+ FDKaacEnc_adaptMinSnr(qcOutChannel, psyOutChannel,
+ &AdjThrStateElement->minSnrAdaptParam, nChannels);
+
+ /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */
+ FDKaacEnc_initAvoidHoleFlag(qcOutChannel, psyOutChannel, pAhFlag, toolsInfo,
+ nChannels, &AdjThrStateElement->ahParam);
+
+ /* reduce thresholds */
+ FDKaacEnc_reduceThresholdsVBR(qcOutChannel, psyOutChannel, pAhFlag, pThrExp,
+ nChannels, AdjThrStateElement->vbrQualFactor,
+ &AdjThrStateElement->chaosMeasureOld);
+
+ /* free scratch memory */
+ C_ALLOC_SCRATCH_END(_pThrExp, FIXP_DBL, (2) * MAX_GROUPED_SFB)
+ C_ALLOC_SCRATCH_END(_pAhFlag, UCHAR, (2) * MAX_GROUPED_SFB)
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_calcBitSave
+ description: Calculates percentage of bit save, see figure below
+ returns:
+ input: parameters and bitres-fullness
+ output: percentage of bit save
+
+*****************************************************************************/
+/*
+ bitsave
+ maxBitSave(%)| clipLow
+ |---\
+ | \
+ | \
+ | \
+ | \
+ |--------\--------------> bitres
+ | \
+ minBitSave(%)| \------------
+ clipHigh maxBitres
+*/
+static FIXP_DBL FDKaacEnc_calcBitSave(FIXP_DBL fillLevel,
+ const FIXP_DBL clipLow,
+ const FIXP_DBL clipHigh,
+ const FIXP_DBL minBitSave,
+ const FIXP_DBL maxBitSave,
+ const FIXP_DBL bitsave_slope) {
+ FIXP_DBL bitsave;
+
+ fillLevel = fixMax(fillLevel, clipLow);
+ fillLevel = fixMin(fillLevel, clipHigh);
+
+ bitsave = maxBitSave - fMult((fillLevel - clipLow), bitsave_slope);
+
+ return (bitsave);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_calcBitSpend
+ description: Calculates percentage of bit spend, see figure below
+ returns:
+ input: parameters and bitres-fullness
+ output: percentage of bit spend
+
+*****************************************************************************/
+/*
+ bitspend clipHigh
+ maxBitSpend(%)| /-----------maxBitres
+ | /
+ | /
+ | /
+ | /
+ | /
+ |----/-----------------> bitres
+ | /
+ minBitSpend(%)|--/
+ clipLow
+*/
+static FIXP_DBL FDKaacEnc_calcBitSpend(FIXP_DBL fillLevel,
+ const FIXP_DBL clipLow,
+ const FIXP_DBL clipHigh,
+ const FIXP_DBL minBitSpend,
+ const FIXP_DBL maxBitSpend,
+ const FIXP_DBL bitspend_slope) {
+ FIXP_DBL bitspend;
+
+ fillLevel = fixMax(fillLevel, clipLow);
+ fillLevel = fixMin(fillLevel, clipHigh);
+
+ bitspend = minBitSpend + fMult(fillLevel - clipLow, bitspend_slope);
+
+ return (bitspend);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_adjustPeMinMax()
+ description: adjusts peMin and peMax parameters over time
+ returns:
+ input: current pe, peMin, peMax, bitres size
+ output: adjusted peMin/peMax
+
+*****************************************************************************/
+static void FDKaacEnc_adjustPeMinMax(const INT currPe, INT *peMin, INT *peMax) {
+ FIXP_DBL minFacHi = FL2FXCONST_DBL(0.3f), maxFacHi = (FIXP_DBL)MAXVAL_DBL,
+ minFacLo = FL2FXCONST_DBL(0.14f), maxFacLo = FL2FXCONST_DBL(0.07f);
+ INT diff;
+
+ INT minDiff_fix = fMultI(FL2FXCONST_DBL(0.1666666667f), currPe);
+
+ if (currPe > *peMax) {
+ diff = (currPe - *peMax);
+ *peMin += fMultI(minFacHi, diff);
+ *peMax += fMultI(maxFacHi, diff);
+ } else if (currPe < *peMin) {
+ diff = (*peMin - currPe);
+ *peMin -= fMultI(minFacLo, diff);
+ *peMax -= fMultI(maxFacLo, diff);
+ } else {
+ *peMin += fMultI(minFacHi, (currPe - *peMin));
+ *peMax -= fMultI(maxFacLo, (*peMax - currPe));
+ }
+
+ if ((*peMax - *peMin) < minDiff_fix) {
+ INT peMax_fix = *peMax, peMin_fix = *peMin;
+ FIXP_DBL partLo_fix, partHi_fix;
+
+ partLo_fix = (FIXP_DBL)fixMax(0, currPe - peMin_fix);
+ partHi_fix = (FIXP_DBL)fixMax(0, peMax_fix - currPe);
+
+ peMax_fix =
+ (INT)(currPe + fMultI(fDivNorm(partHi_fix, (partLo_fix + partHi_fix)),
+ minDiff_fix));
+ peMin_fix =
+ (INT)(currPe - fMultI(fDivNorm(partLo_fix, (partLo_fix + partHi_fix)),
+ minDiff_fix));
+ peMin_fix = fixMax(0, peMin_fix);
+
+ *peMax = peMax_fix;
+ *peMin = peMin_fix;
+ }
+}
+
+/*****************************************************************************
+
+ functionname: BitresCalcBitFac
+ description: calculates factor of spending bits for one frame
+ 1.0 : take all frame dynpart bits
+ >1.0 : take all frame dynpart bits + bitres
+ <1.0 : put bits in bitreservoir
+ returns: BitFac
+ input: bitres-fullness, pe, blockType, parameter-settings
+ output:
+
+*****************************************************************************/
+/*
+ bitfac(%) pemax
+ bitspend(%) | /-----------maxBitres
+ | /
+ | /
+ | /
+ | /
+ | /
+ |----/-----------------> pe
+ | /
+ bitsave(%) |--/
+ pemin
+*/
+
+void FDKaacEnc_bitresCalcBitFac(const INT bitresBits, const INT maxBitresBits,
+ const INT pe, const INT lastWindowSequence,
+ const INT avgBits, const FIXP_DBL maxBitFac,
+ const ADJ_THR_STATE *const AdjThr,
+ ATS_ELEMENT *const adjThrChan,
+ FIXP_DBL *const pBitresFac,
+ INT *const pBitresFac_e) {
+ const BRES_PARAM *bresParam;
+ INT pex;
+ FIXP_DBL fillLevel;
+ INT fillLevel_e = 0;
+
+ FIXP_DBL bitresFac;
+ INT bitresFac_e;
+
+ FIXP_DBL bitSave, bitSpend;
+ FIXP_DBL bitsave_slope, bitspend_slope;
+ FIXP_DBL fillLevel_fix = MAXVAL_DBL;
+
+ FIXP_DBL slope = MAXVAL_DBL;
+
+ if (lastWindowSequence != SHORT_WINDOW) {
+ bresParam = &(AdjThr->bresParamLong);
+ bitsave_slope = FL2FXCONST_DBL(0.466666666);
+ bitspend_slope = FL2FXCONST_DBL(0.666666666);
+ } else {
+ bresParam = &(AdjThr->bresParamShort);
+ bitsave_slope = (FIXP_DBL)0x2E8BA2E9;
+ bitspend_slope = (FIXP_DBL)0x7fffffff;
+ }
+
+ // fillLevel = (float)(bitresBits+avgBits) / (float)(maxBitresBits + avgBits);
+ if (bitresBits < maxBitresBits) {
+ fillLevel_fix = fDivNorm(bitresBits, maxBitresBits);
+ }
+
+ pex = fMax(pe, adjThrChan->peMin);
+ pex = fMin(pex, adjThrChan->peMax);
+
+ bitSave = FDKaacEnc_calcBitSave(
+ fillLevel_fix, bresParam->clipSaveLow, bresParam->clipSaveHigh,
+ bresParam->minBitSave, bresParam->maxBitSave, bitsave_slope);
+
+ bitSpend = FDKaacEnc_calcBitSpend(
+ fillLevel_fix, bresParam->clipSpendLow, bresParam->clipSpendHigh,
+ bresParam->minBitSpend, bresParam->maxBitSpend, bitspend_slope);
+
+ slope = schur_div((pex - adjThrChan->peMin),
+ (adjThrChan->peMax - adjThrChan->peMin), 31);
+
+ /* scale down by 1 bit because the result of the following addition can be
+ * bigger than 1 (though smaller than 2) */
+ bitresFac = ((FIXP_DBL)(MAXVAL_DBL >> 1) - (bitSave >> 1));
+ bitresFac_e = 1; /* exp=1 */
+ bitresFac = fMultAddDiv2(bitresFac, slope, bitSpend + bitSave); /* exp=1 */
+
+ /*** limit bitresFac for small bitreservoir ***/
+ fillLevel = fDivNorm(bitresBits, avgBits, &fillLevel_e);
+ if (fillLevel_e < 0) {
+ fillLevel = scaleValue(fillLevel, fillLevel_e);
+ fillLevel_e = 0;
+ }
+ /* shift down value by 1 because of summation, ... */
+ fillLevel >>= 1;
+ fillLevel_e += 1;
+ /* ..., this summation: */
+ fillLevel += scaleValue(FL2FXCONST_DBL(0.7f), -fillLevel_e);
+ /* set bitresfactor to same exponent as fillLevel */
+ if (scaleValue(bitresFac, -fillLevel_e + 1) > fillLevel) {
+ bitresFac = fillLevel;
+ bitresFac_e = fillLevel_e;
+ }
+
+ /* limit bitresFac for high bitrates */
+ if (scaleValue(bitresFac, bitresFac_e - (DFRACT_BITS - 1 - 24)) > maxBitFac) {
+ bitresFac = maxBitFac;
+ bitresFac_e = (DFRACT_BITS - 1 - 24);
+ }
+
+ FDKaacEnc_adjustPeMinMax(pe, &adjThrChan->peMin, &adjThrChan->peMax);
+
+ /* output values */
+ *pBitresFac = bitresFac;
+ *pBitresFac_e = bitresFac_e;
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_AdjThrNew
+description: allocate ADJ_THR_STATE
+*****************************************************************************/
+INT FDKaacEnc_AdjThrNew(ADJ_THR_STATE **phAdjThr, INT nElements) {
+ INT err = 0;
+ INT i;
+ ADJ_THR_STATE *hAdjThr = GetRam_aacEnc_AdjustThreshold();
+ if (hAdjThr == NULL) {
+ err = 1;
+ goto bail;
+ }
+
+ for (i = 0; i < nElements; i++) {
+ hAdjThr->adjThrStateElem[i] = GetRam_aacEnc_AdjThrStateElement(i);
+ if (hAdjThr->adjThrStateElem[i] == NULL) {
+ err = 1;
+ goto bail;
+ }
+ }
+
+bail:
+ *phAdjThr = hAdjThr;
+ return err;
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_AdjThrInit
+description: initialize ADJ_THR_STATE
+*****************************************************************************/
+void FDKaacEnc_AdjThrInit(
+ ADJ_THR_STATE *const hAdjThr, const INT meanPe, const INT invQuant,
+ const CHANNEL_MAPPING *const channelMapping, const INT sampleRate,
+ const INT totalBitrate, const INT isLowDelay,
+ const AACENC_BITRES_MODE bitResMode, const INT dZoneQuantEnable,
+ const INT bitDistributionMode, const FIXP_DBL vbrQualFactor) {
+ INT i;
+
+ FIXP_DBL POINT8 = FL2FXCONST_DBL(0.8f);
+ FIXP_DBL POINT6 = FL2FXCONST_DBL(0.6f);
+
+ if (bitDistributionMode == 1) {
+ hAdjThr->bitDistributionMode = AACENC_BD_MODE_INTRA_ELEMENT;
+ } else {
+ hAdjThr->bitDistributionMode = AACENC_BD_MODE_INTER_ELEMENT;
+ }
+
+ /* Max number of iterations in second guess is 3 for lowdelay aot and for
+ configurations with multiple audio elements in general, otherwise iteration
+ value is always 1. */
+ hAdjThr->maxIter2ndGuess =
+ (isLowDelay != 0 || channelMapping->nElements > 1) ? 3 : 1;
+
+ /* common for all elements: */
+ /* parameters for bitres control */
+ hAdjThr->bresParamLong.clipSaveLow =
+ (FIXP_DBL)0x1999999a; /* FL2FXCONST_DBL(0.2f); */
+ hAdjThr->bresParamLong.clipSaveHigh =
+ (FIXP_DBL)0x7999999a; /* FL2FXCONST_DBL(0.95f); */
+ hAdjThr->bresParamLong.minBitSave =
+ (FIXP_DBL)0xf999999a; /* FL2FXCONST_DBL(-0.05f); */
+ hAdjThr->bresParamLong.maxBitSave =
+ (FIXP_DBL)0x26666666; /* FL2FXCONST_DBL(0.3f); */
+ hAdjThr->bresParamLong.clipSpendLow =
+ (FIXP_DBL)0x1999999a; /* FL2FXCONST_DBL(0.2f); */
+ hAdjThr->bresParamLong.clipSpendHigh =
+ (FIXP_DBL)0x7999999a; /* FL2FXCONST_DBL(0.95f); */
+ hAdjThr->bresParamLong.minBitSpend =
+ (FIXP_DBL)0xf3333333; /* FL2FXCONST_DBL(-0.10f); */
+ hAdjThr->bresParamLong.maxBitSpend =
+ (FIXP_DBL)0x33333333; /* FL2FXCONST_DBL(0.4f); */
+
+ hAdjThr->bresParamShort.clipSaveLow =
+ (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */
+ hAdjThr->bresParamShort.clipSaveHigh =
+ (FIXP_DBL)0x5fffffff; /* FL2FXCONST_DBL(0.75f); */
+ hAdjThr->bresParamShort.minBitSave =
+ (FIXP_DBL)0x00000000; /* FL2FXCONST_DBL(0.0f); */
+ hAdjThr->bresParamShort.maxBitSave =
+ (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */
+ hAdjThr->bresParamShort.clipSpendLow =
+ (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */
+ hAdjThr->bresParamShort.clipSpendHigh =
+ (FIXP_DBL)0x5fffffff; /* FL2FXCONST_DBL(0.75f); */
+ hAdjThr->bresParamShort.minBitSpend =
+ (FIXP_DBL)0xf9999998; /* FL2FXCONST_DBL(-0.05f); */
+ hAdjThr->bresParamShort.maxBitSpend =
+ (FIXP_DBL)0x40000000; /* FL2FXCONST_DBL(0.5f); */
+
+ /* specific for each element: */
+ for (i = 0; i < channelMapping->nElements; i++) {
+ const FIXP_DBL relativeBits = channelMapping->elInfo[i].relativeBits;
+ const INT nChannelsInElement = channelMapping->elInfo[i].nChannelsInEl;
+ const INT bitrateInElement =
+ (relativeBits != (FIXP_DBL)MAXVAL_DBL)
+ ? (INT)fMultNorm(relativeBits, (FIXP_DBL)totalBitrate)
+ : totalBitrate;
+ const INT chBitrate = bitrateInElement >> (nChannelsInElement == 1 ? 0 : 1);
+
+ ATS_ELEMENT *atsElem = hAdjThr->adjThrStateElem[i];
+ MINSNR_ADAPT_PARAM *msaParam = &atsElem->minSnrAdaptParam;
+
+ /* parameters for bitres control */
+ if (isLowDelay) {
+ atsElem->peMin = fMultI(POINT8, meanPe);
+ atsElem->peMax = fMultI(POINT6, meanPe) << 1;
+ } else {
+ atsElem->peMin = fMultI(POINT8, meanPe) >> 1;
+ atsElem->peMax = fMultI(POINT6, meanPe);
+ }
+
+ /* for use in FDKaacEnc_reduceThresholdsVBR */
+ atsElem->chaosMeasureOld = FL2FXCONST_DBL(0.3f);
+
+ /* additional pe offset to correct pe2bits for low bitrates */
+ /* ---- no longer necessary, set by table ----- */
+ atsElem->peOffset = 0;
+
+ /* vbr initialisation */
+ atsElem->vbrQualFactor = vbrQualFactor;
+ if (chBitrate < 32000) {
+ atsElem->peOffset =
+ fixMax(50, 100 - fMultI((FIXP_DBL)0x666667, chBitrate));
+ }
+
+ /* avoid hole parameters */
+ if (chBitrate >= 20000) {
+ atsElem->ahParam.modifyMinSnr = TRUE;
+ atsElem->ahParam.startSfbL = 15;
+ atsElem->ahParam.startSfbS = 3;
+ } else {
+ atsElem->ahParam.modifyMinSnr = FALSE;
+ atsElem->ahParam.startSfbL = 0;
+ atsElem->ahParam.startSfbS = 0;
+ }
+
+ /* minSnr adaptation */
+ msaParam->maxRed = FL2FXCONST_DBL(0.00390625f); /* 0.25f/64.0f */
+ /* start adaptation of minSnr for avgEn/sfbEn > startRatio */
+ msaParam->startRatio = FL2FXCONST_DBL(0.05190512648f); /* ld64(10.0f) */
+ /* maximum minSnr reduction to minSnr^maxRed is reached for
+ avgEn/sfbEn >= maxRatio */
+ /* msaParam->maxRatio = 1000.0f; */
+ /*msaParam->redRatioFac = ((float)1.0f - msaParam->maxRed) /
+ * ((float)10.0f*log10(msaParam->startRatio/msaParam->maxRatio)/log10(2.0f)*(float)0.3010299956f);*/
+ msaParam->redRatioFac = FL2FXCONST_DBL(-0.375f); /* -0.0375f * 10.0f */
+ /*msaParam->redOffs = (float)1.0f - msaParam->redRatioFac * (float)10.0f *
+ * log10(msaParam->startRatio)/log10(2.0f) * (float)0.3010299956f;*/
+ msaParam->redOffs = FL2FXCONST_DBL(0.021484375); /* 1.375f/64.0f */
+
+ /* init pe correction */
+ atsElem->peCorrectionFactor_m = FL2FXCONST_DBL(0.5f); /* 1.0 */
+ atsElem->peCorrectionFactor_e = 1;
+
+ atsElem->dynBitsLast = -1;
+ atsElem->peLast = 0;
+
+ /* init bits to pe factor */
+
+ /* init bits2PeFactor */
+ FDKaacEnc_InitBits2PeFactor(
+ &atsElem->bits2PeFactor_m, &atsElem->bits2PeFactor_e, bitrateInElement,
+ nChannelsInElement, sampleRate, isLowDelay, dZoneQuantEnable, invQuant);
+
+ } /* for nElements */
+}
+
+/*****************************************************************************
+ functionname: FDKaacEnc_FDKaacEnc_calcPeCorrection
+ description: calc desired pe
+*****************************************************************************/
+static void FDKaacEnc_FDKaacEnc_calcPeCorrection(
+ FIXP_DBL *const correctionFac_m, INT *const correctionFac_e,
+ const INT peAct, const INT peLast, const INT bitsLast,
+ const FIXP_DBL bits2PeFactor_m, const INT bits2PeFactor_e) {
+ if ((bitsLast > 0) && (peAct < 1.5f * peLast) && (peAct > 0.7f * peLast) &&
+ (FDKaacEnc_bits2pe2(bitsLast,
+ fMult(FL2FXCONST_DBL(1.2f / 2.f), bits2PeFactor_m),
+ bits2PeFactor_e + 1) > peLast) &&
+ (FDKaacEnc_bits2pe2(bitsLast,
+ fMult(FL2FXCONST_DBL(0.65f), bits2PeFactor_m),
+ bits2PeFactor_e) < peLast)) {
+ FIXP_DBL corrFac = *correctionFac_m;
+
+ int scaling = 0;
+ FIXP_DBL denum = (FIXP_DBL)FDKaacEnc_bits2pe2(bitsLast, bits2PeFactor_m,
+ bits2PeFactor_e);
+ FIXP_DBL newFac = fDivNorm((FIXP_DBL)peLast, denum, &scaling);
+
+ /* dead zone, newFac and corrFac are scaled by 0.5 */
+ if ((FIXP_DBL)peLast <= denum) { /* ratio <= 1.f */
+ newFac = fixMax(
+ scaleValue(fixMin(fMult(FL2FXCONST_DBL(1.1f / 2.f), newFac),
+ scaleValue(FL2FXCONST_DBL(1.f / 2.f), -scaling)),
+ scaling),
+ FL2FXCONST_DBL(0.85f / 2.f));
+ } else { /* ratio < 1.f */
+ newFac = fixMax(
+ fixMin(scaleValue(fMult(FL2FXCONST_DBL(0.9f / 2.f), newFac), scaling),
+ FL2FXCONST_DBL(1.15f / 2.f)),
+ FL2FXCONST_DBL(1.f / 2.f));
+ }
+
+ if (((newFac > FL2FXCONST_DBL(1.f / 2.f)) &&
+ (corrFac < FL2FXCONST_DBL(1.f / 2.f))) ||
+ ((newFac < FL2FXCONST_DBL(1.f / 2.f)) &&
+ (corrFac > FL2FXCONST_DBL(1.f / 2.f)))) {
+ corrFac = FL2FXCONST_DBL(1.f / 2.f);
+ }
+
+ /* faster adaptation towards 1.0, slower in the other direction */
+ if ((corrFac < FL2FXCONST_DBL(1.f / 2.f) && newFac < corrFac) ||
+ (corrFac > FL2FXCONST_DBL(1.f / 2.f) && newFac > corrFac)) {
+ corrFac = fMult(FL2FXCONST_DBL(0.85f), corrFac) +
+ fMult(FL2FXCONST_DBL(0.15f), newFac);
+ } else {
+ corrFac = fMult(FL2FXCONST_DBL(0.7f), corrFac) +
+ fMult(FL2FXCONST_DBL(0.3f), newFac);
+ }
+
+ corrFac = fixMax(fixMin(corrFac, FL2FXCONST_DBL(1.15f / 2.f)),
+ FL2FXCONST_DBL(0.85 / 2.f));
+
+ *correctionFac_m = corrFac;
+ *correctionFac_e = 1;
+ } else {
+ *correctionFac_m = FL2FXCONST_DBL(1.f / 2.f);
+ *correctionFac_e = 1;
+ }
+}
+
+static void FDKaacEnc_calcPeCorrectionLowBitRes(
+ FIXP_DBL *const correctionFac_m, INT *const correctionFac_e,
+ const INT peLast, const INT bitsLast, const INT bitresLevel,
+ const INT nChannels, const FIXP_DBL bits2PeFactor_m,
+ const INT bits2PeFactor_e) {
+ /* tuning params */
+ const FIXP_DBL amp = FL2FXCONST_DBL(0.005);
+ const FIXP_DBL maxDiff = FL2FXCONST_DBL(0.25f);
+
+ if (bitsLast > 0) {
+ /* Estimate deviation of granted and used dynamic bits in previous frame, in
+ * PE units */
+ const int bitsBalLast =
+ peLast - FDKaacEnc_bits2pe2(bitsLast, bits2PeFactor_m, bits2PeFactor_e);
+
+ /* reserve n bits per channel */
+ int headroom = (bitresLevel >= 50 * nChannels) ? 0 : (100 * nChannels);
+
+ /* in PE units */
+ headroom = FDKaacEnc_bits2pe2(headroom, bits2PeFactor_m, bits2PeFactor_e);
+
+ /*
+ * diff = amp * ((bitsBalLast - headroom) / (bitresLevel + headroom)
+ * diff = max ( min ( diff, maxDiff, -maxDiff)) / 2
+ */
+ FIXP_DBL denominator = (FIXP_DBL)FDKaacEnc_bits2pe2(
+ bitresLevel, bits2PeFactor_m, bits2PeFactor_e) +
+ (FIXP_DBL)headroom;
+
+ int scaling = 0;
+ FIXP_DBL diff =
+ (bitsBalLast >= headroom)
+ ? fMult(amp, fDivNorm((FIXP_DBL)(bitsBalLast - headroom),
+ denominator, &scaling))
+ : -fMult(amp, fDivNorm(-(FIXP_DBL)(bitsBalLast - headroom),
+ denominator, &scaling));
+
+ scaling -= 1; /* divide by 2 */
+
+ diff = (scaling <= 0)
+ ? fMax(fMin(diff >> (-scaling), maxDiff >> 1), -maxDiff >> 1)
+ : fMax(fMin(diff, maxDiff >> (1 + scaling)),
+ -maxDiff >> (1 + scaling))
+ << scaling;
+
+ /*
+ * corrFac += diff
+ * corrFac = max ( min ( corrFac/2.f, 1.f/2.f, 0.75f/2.f ) )
+ */
+ *correctionFac_m =
+ fMax(fMin((*correctionFac_m) + diff, FL2FXCONST_DBL(1.0f / 2.f)),
+ FL2FXCONST_DBL(0.75f / 2.f));
+ *correctionFac_e = 1;
+ } else {
+ *correctionFac_m = FL2FXCONST_DBL(0.75 / 2.f);
+ *correctionFac_e = 1;
+ }
+}
+
+void FDKaacEnc_DistributeBits(
+ ADJ_THR_STATE *adjThrState, ATS_ELEMENT *AdjThrStateElement,
+ PSY_OUT_CHANNEL *psyOutChannel[(2)], PE_DATA *peData, INT *grantedPe,
+ INT *grantedPeCorr, const INT nChannels, const INT commonWindow,
+ const INT grantedDynBits, const INT bitresBits, const INT maxBitresBits,
+ const FIXP_DBL maxBitFac, const AACENC_BITRES_MODE bitResMode) {
+ FIXP_DBL bitFactor;
+ INT bitFactor_e;
+ INT noRedPe = peData->pe;
+
+ /* prefer short windows for calculation of bitFactor */
+ INT curWindowSequence = LONG_WINDOW;
+ if (nChannels == 2) {
+ if ((psyOutChannel[0]->lastWindowSequence == SHORT_WINDOW) ||
+ (psyOutChannel[1]->lastWindowSequence == SHORT_WINDOW)) {
+ curWindowSequence = SHORT_WINDOW;
+ }
+ } else {
+ curWindowSequence = psyOutChannel[0]->lastWindowSequence;
+ }
+
+ if (grantedDynBits >= 1) {
+ if (bitResMode != AACENC_BR_MODE_FULL) {
+ /* small or disabled bitreservoir */
+ *grantedPe = FDKaacEnc_bits2pe2(grantedDynBits,
+ AdjThrStateElement->bits2PeFactor_m,
+ AdjThrStateElement->bits2PeFactor_e);
+ } else {
+ /* factor dependend on current fill level and pe */
+ FDKaacEnc_bitresCalcBitFac(
+ bitresBits, maxBitresBits, noRedPe, curWindowSequence, grantedDynBits,
+ maxBitFac, adjThrState, AdjThrStateElement, &bitFactor, &bitFactor_e);
+
+ /* desired pe for actual frame */
+ /* Worst case max of grantedDynBits is = 1024 * 5.27 * 2 */
+ *grantedPe = FDKaacEnc_bits2pe2(
+ grantedDynBits, fMult(bitFactor, AdjThrStateElement->bits2PeFactor_m),
+ AdjThrStateElement->bits2PeFactor_e + bitFactor_e);
+ }
+ } else {
+ *grantedPe = 0; /* prevent divsion by 0 */
+ }
+
+ /* correction of pe value */
+ switch (bitResMode) {
+ case AACENC_BR_MODE_DISABLED:
+ case AACENC_BR_MODE_REDUCED:
+ /* correction of pe value for low bitres */
+ FDKaacEnc_calcPeCorrectionLowBitRes(
+ &AdjThrStateElement->peCorrectionFactor_m,
+ &AdjThrStateElement->peCorrectionFactor_e, AdjThrStateElement->peLast,
+ AdjThrStateElement->dynBitsLast, bitresBits, nChannels,
+ AdjThrStateElement->bits2PeFactor_m,
+ AdjThrStateElement->bits2PeFactor_e);
+ break;
+ case AACENC_BR_MODE_FULL:
+ default:
+ /* correction of pe value for high bitres */
+ FDKaacEnc_FDKaacEnc_calcPeCorrection(
+ &AdjThrStateElement->peCorrectionFactor_m,
+ &AdjThrStateElement->peCorrectionFactor_e,
+ fixMin(*grantedPe, noRedPe), AdjThrStateElement->peLast,
+ AdjThrStateElement->dynBitsLast, AdjThrStateElement->bits2PeFactor_m,
+ AdjThrStateElement->bits2PeFactor_e);
+ break;
+ }
+
+ *grantedPeCorr =
+ (INT)(fMult((FIXP_DBL)(*grantedPe << Q_AVGBITS),
+ AdjThrStateElement->peCorrectionFactor_m) >>
+ (Q_AVGBITS - AdjThrStateElement->peCorrectionFactor_e));
+
+ /* update last pe */
+ AdjThrStateElement->peLast = *grantedPe;
+ AdjThrStateElement->dynBitsLast = -1;
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_AdjustThresholds
+description: adjust thresholds
+*****************************************************************************/
+void FDKaacEnc_AdjustThresholds(
+ ADJ_THR_STATE *const hAdjThr, QC_OUT_ELEMENT *const qcElement[((8))],
+ QC_OUT *const qcOut, const PSY_OUT_ELEMENT *const psyOutElement[((8))],
+ const INT CBRbitrateMode, const CHANNEL_MAPPING *const cm) {
+ int i;
+
+ if (CBRbitrateMode) {
+ /* In case, no bits must be shifted between different elements, */
+ /* an element-wise execution of the pe-dependent threshold- */
+ /* adaption becomes necessary... */
+ if (hAdjThr->bitDistributionMode == AACENC_BD_MODE_INTRA_ELEMENT) {
+ for (i = 0; i < cm->nElements; i++) {
+ ELEMENT_INFO elInfo = cm->elInfo[i];
+
+ if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
+ (elInfo.elType == ID_LFE)) {
+ /* qcElement[i]->grantedPe = 2000; */ /* Use this only for debugging
+ */
+ // if (totalGrantedPeCorr < totalNoRedPe) {
+ if (qcElement[i]->grantedPeCorr < qcElement[i]->peData.pe) {
+ /* calc threshold necessary for desired pe */
+ FDKaacEnc_adaptThresholdsToPe(
+ cm, hAdjThr->adjThrStateElem, qcElement, psyOutElement,
+ qcElement[i]->grantedPeCorr, hAdjThr->maxIter2ndGuess,
+ 1, /* Process only 1 element */
+ i /* Process exactly THIS element */
+ );
+ }
+ } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */
+ } /* -end- element loop */
+ } /* AACENC_BD_MODE_INTRA_ELEMENT */
+ else if (hAdjThr->bitDistributionMode == AACENC_BD_MODE_INTER_ELEMENT) {
+ /* Use global Pe to obtain the thresholds? */
+ if (qcOut->totalGrantedPeCorr < qcOut->totalNoRedPe) {
+ /* add equal loadness quantization noise to match the */
+ /* desired pe calc threshold necessary for desired pe */
+ /* Now carried out globally to cover all(!) channels. */
+ FDKaacEnc_adaptThresholdsToPe(cm, hAdjThr->adjThrStateElem, qcElement,
+ psyOutElement, qcOut->totalGrantedPeCorr,
+ hAdjThr->maxIter2ndGuess,
+ cm->nElements, /* Process all elements */
+ 0); /* Process exactly THIS element */
+ } else {
+ /* In case global pe doesn't need to be reduced check each element to
+ hold estimated bitrate below maximum element bitrate. */
+ for (i = 0; i < cm->nElements; i++) {
+ if ((cm->elInfo[i].elType == ID_SCE) ||
+ (cm->elInfo[i].elType == ID_CPE) ||
+ (cm->elInfo[i].elType == ID_LFE)) {
+ /* Element pe applies to dynamic bits of maximum element bitrate. */
+ const int maxElementPe = FDKaacEnc_bits2pe2(
+ (cm->elInfo[i].nChannelsInEl * MIN_BUFSIZE_PER_EFF_CHAN) -
+ qcElement[i]->staticBitsUsed - qcElement[i]->extBitsUsed,
+ hAdjThr->adjThrStateElem[i]->bits2PeFactor_m,
+ hAdjThr->adjThrStateElem[i]->bits2PeFactor_e);
+
+ if (maxElementPe < qcElement[i]->peData.pe) {
+ FDKaacEnc_adaptThresholdsToPe(
+ cm, hAdjThr->adjThrStateElem, qcElement, psyOutElement,
+ maxElementPe, hAdjThr->maxIter2ndGuess, 1, i);
+ }
+ } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */
+ } /* -end- element loop */
+ } /* (qcOut->totalGrantedPeCorr < qcOut->totalNoRedPe) */
+ } /* AACENC_BD_MODE_INTER_ELEMENT */
+ } else {
+ for (i = 0; i < cm->nElements; i++) {
+ ELEMENT_INFO elInfo = cm->elInfo[i];
+
+ if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
+ (elInfo.elType == ID_LFE)) {
+ /* for VBR-mode */
+ FDKaacEnc_AdaptThresholdsVBR(
+ qcElement[i]->qcOutChannel, psyOutElement[i]->psyOutChannel,
+ hAdjThr->adjThrStateElem[i], &psyOutElement[i]->toolsInfo,
+ cm->elInfo[i].nChannelsInEl);
+ } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */
+
+ } /* -end- element loop */
+ }
+ for (i = 0; i < cm->nElements; i++) {
+ int ch, sfb, sfbGrp;
+ /* no weighting of threholds and energies for mlout */
+ /* weight energies and thresholds */
+ for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) {
+ QC_OUT_CHANNEL *pQcOutCh = qcElement[i]->qcOutChannel[ch];
+ for (sfbGrp = 0; sfbGrp < psyOutElement[i]->psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutElement[i]->psyOutChannel[ch]->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutElement[i]->psyOutChannel[ch]->maxSfbPerGroup;
+ sfb++) {
+ pQcOutCh->sfbThresholdLdData[sfb + sfbGrp] +=
+ pQcOutCh->sfbEnFacLd[sfb + sfbGrp];
+ }
+ }
+ }
+ }
+}
+
+void FDKaacEnc_AdjThrClose(ADJ_THR_STATE **phAdjThr) {
+ INT i;
+ ADJ_THR_STATE *hAdjThr = *phAdjThr;
+
+ if (hAdjThr != NULL) {
+ for (i = 0; i < ((8)); i++) {
+ if (hAdjThr->adjThrStateElem[i] != NULL) {
+ FreeRam_aacEnc_AdjThrStateElement(&hAdjThr->adjThrStateElem[i]);
+ }
+ }
+ FreeRam_aacEnc_AdjustThreshold(phAdjThr);
+ }
+}
diff --git a/fdk-aac/libAACenc/src/adj_thr.h b/fdk-aac/libAACenc/src/adj_thr.h
new file mode 100644
index 0000000..1f5f998
--- /dev/null
+++ b/fdk-aac/libAACenc/src/adj_thr.h
@@ -0,0 +1,166 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Threshold compensation
+
+*******************************************************************************/
+
+#ifndef ADJ_THR_H
+#define ADJ_THR_H
+
+#include "common_fix.h"
+#include "adj_thr_data.h"
+#include "qc_data.h"
+#include "line_pe.h"
+#include "interface.h"
+
+/*****************************************************************************
+ functionname: FDKaacEnc_peCalculation
+ description:
+*****************************************************************************/
+void FDKaacEnc_peCalculation(PE_DATA *const peData,
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)],
+ QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ const struct TOOLSINFO *const toolsInfo,
+ ATS_ELEMENT *const adjThrStateElement,
+ const INT nChannels);
+
+/*****************************************************************************
+functionname: FDKaacEnc_AdjThrNew
+description: allocate ADJ_THR_STATE
+*****************************************************************************/
+INT FDKaacEnc_AdjThrNew(ADJ_THR_STATE **phAdjThr, INT nElements);
+
+/*****************************************************************************
+functionname: FDKaacEnc_AdjThrInit
+description: initialize ADJ_THR_STATE
+*****************************************************************************/
+void FDKaacEnc_AdjThrInit(
+ ADJ_THR_STATE *const hAdjThr, const INT meanPe, const INT invQuant,
+ const CHANNEL_MAPPING *const channelMapping, const INT sampleRate,
+ const INT totalBitrate, const INT isLowDelay,
+ const AACENC_BITRES_MODE bitResMode, const INT dZoneQuantEnable,
+ const INT bitDistributionMode, const FIXP_DBL vbrQualFactor);
+
+/*****************************************************************************
+functionname: FDKaacEnc_DistributeBits
+description:
+*****************************************************************************/
+void FDKaacEnc_DistributeBits(
+ ADJ_THR_STATE *adjThrState, ATS_ELEMENT *AdjThrStateElement,
+ PSY_OUT_CHANNEL *psyOutChannel[(2)], PE_DATA *peData, INT *grantedPe,
+ INT *grantedPeCorr, const INT nChannels, const INT commonWindow,
+ const INT avgBits, const INT bitresBits, const INT maxBitresBits,
+ const FIXP_DBL maxBitFac, const AACENC_BITRES_MODE bitResMode);
+
+/*****************************************************************************
+functionname: FDKaacEnc_AdjustThresholds
+description: adjust thresholds
+*****************************************************************************/
+void FDKaacEnc_AdjustThresholds(
+ ADJ_THR_STATE *const hAdjThr, QC_OUT_ELEMENT *const qcElement[((8))],
+ QC_OUT *const qcOut, const PSY_OUT_ELEMENT *const psyOutElement[((8))],
+ const INT CBRbitrateMode, const CHANNEL_MAPPING *const cm);
+
+/*****************************************************************************
+functionname: FDKaacEnc_AdjThrClose
+description:
+*****************************************************************************/
+void FDKaacEnc_AdjThrClose(ADJ_THR_STATE **hAdjThr);
+
+#endif
diff --git a/fdk-aac/libAACenc/src/adj_thr_data.h b/fdk-aac/libAACenc/src/adj_thr_data.h
new file mode 100644
index 0000000..4cd1299
--- /dev/null
+++ b/fdk-aac/libAACenc/src/adj_thr_data.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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Schug / A. Groeschel
+
+ Description: threshold calculations
+
+*******************************************************************************/
+
+#ifndef ADJ_THR_DATA_H
+#define ADJ_THR_DATA_H
+
+#include "psy_const.h"
+
+typedef enum {
+ AACENC_BD_MODE_INTER_ELEMENT = 0,
+ AACENC_BD_MODE_INTRA_ELEMENT = 1
+} AACENC_BIT_DISTRIBUTION_MODE;
+
+typedef enum {
+ AACENC_BR_MODE_FULL = 0,
+ AACENC_BR_MODE_REDUCED = 1,
+ AACENC_BR_MODE_DISABLED = 2
+} AACENC_BITRES_MODE;
+
+typedef struct {
+ FIXP_DBL clipSaveLow, clipSaveHigh;
+ FIXP_DBL minBitSave, maxBitSave;
+ FIXP_DBL clipSpendLow, clipSpendHigh;
+ FIXP_DBL minBitSpend, maxBitSpend;
+} BRES_PARAM;
+
+typedef struct {
+ INT modifyMinSnr;
+ INT startSfbL, startSfbS;
+} AH_PARAM;
+
+typedef struct {
+ FIXP_DBL maxRed;
+ FIXP_DBL startRatio;
+ FIXP_DBL maxRatio;
+ FIXP_DBL redRatioFac;
+ FIXP_DBL redOffs;
+} MINSNR_ADAPT_PARAM;
+
+typedef struct {
+ /* parameters for bitreservoir control */
+ INT peMin, peMax;
+ /* constant offset to pe */
+ INT peOffset;
+ /* constant PeFactor */
+ FIXP_DBL bits2PeFactor_m;
+ INT bits2PeFactor_e;
+ /* avoid hole parameters */
+ AH_PARAM ahParam;
+ /* parameters for adaptation of minSnr */
+ MINSNR_ADAPT_PARAM minSnrAdaptParam;
+
+ /* values for correction of pe */
+ INT peLast;
+ INT dynBitsLast;
+ FIXP_DBL peCorrectionFactor_m;
+ INT peCorrectionFactor_e;
+
+ /* vbr encoding */
+ FIXP_DBL vbrQualFactor;
+ FIXP_DBL chaosMeasureOld;
+
+ /* threshold weighting */
+ FIXP_DBL chaosMeasureEnFac[(2)];
+ INT lastEnFacPatch[(2)];
+
+} ATS_ELEMENT;
+
+typedef struct {
+ BRES_PARAM bresParamLong, bresParamShort;
+ ATS_ELEMENT* adjThrStateElem[((8))];
+ AACENC_BIT_DISTRIBUTION_MODE bitDistributionMode;
+ INT maxIter2ndGuess;
+} ADJ_THR_STATE;
+
+#endif
diff --git a/fdk-aac/libAACenc/src/band_nrg.cpp b/fdk-aac/libAACenc/src/band_nrg.cpp
new file mode 100644
index 0000000..fb22dbb
--- /dev/null
+++ b/fdk-aac/libAACenc/src/band_nrg.cpp
@@ -0,0 +1,361 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Band/Line energy calculations
+
+*******************************************************************************/
+
+#include "band_nrg.h"
+
+/*****************************************************************************
+ functionname: FDKaacEnc_CalcSfbMaxScaleSpec
+ description:
+ input:
+ output:
+*****************************************************************************/
+void FDKaacEnc_CalcSfbMaxScaleSpec(const FIXP_DBL *RESTRICT mdctSpectrum,
+ const INT *RESTRICT bandOffset,
+ INT *RESTRICT sfbMaxScaleSpec,
+ const INT numBands) {
+ INT i, j;
+ FIXP_DBL maxSpc, tmp;
+
+ for (i = 0; i < numBands; i++) {
+ maxSpc = (FIXP_DBL)0;
+
+ DWORD_ALIGNED(mdctSpectrum);
+
+ for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
+ tmp = fixp_abs(mdctSpectrum[j]);
+ maxSpc = fixMax(maxSpc, tmp);
+ }
+ j = CntLeadingZeros(maxSpc) - 1;
+ sfbMaxScaleSpec[i] = fixMin((DFRACT_BITS - 2), j);
+ /* CountLeadingBits() is not necessary here since test value is always > 0
+ */
+ }
+}
+
+/*****************************************************************************
+ functionname: FDKaacEnc_CheckBandEnergyOptim
+ description:
+ input:
+ output:
+*****************************************************************************/
+FIXP_DBL
+FDKaacEnc_CheckBandEnergyOptim(const FIXP_DBL *const RESTRICT mdctSpectrum,
+ const INT *const RESTRICT sfbMaxScaleSpec,
+ const INT *const RESTRICT bandOffset,
+ const INT numBands,
+ FIXP_DBL *RESTRICT bandEnergy,
+ FIXP_DBL *RESTRICT bandEnergyLdData,
+ const INT minSpecShift) {
+ INT i, j, scale, nr = 0;
+ FIXP_DBL maxNrgLd = FL2FXCONST_DBL(-1.0f);
+ FIXP_DBL maxNrg = 0;
+ FIXP_DBL spec;
+
+ for (i = 0; i < numBands; i++) {
+ scale = fixMax(0, sfbMaxScaleSpec[i] - 4);
+ FIXP_DBL tmp = 0;
+
+ DWORD_ALIGNED(mdctSpectrum);
+
+ for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
+ spec = mdctSpectrum[j] << scale;
+ tmp = fPow2AddDiv2(tmp, spec);
+ }
+ bandEnergy[i] = tmp << 1;
+
+ /* calculate ld of bandNrg, subtract scaling */
+ bandEnergyLdData[i] = CalcLdData(bandEnergy[i]);
+ if (bandEnergyLdData[i] != FL2FXCONST_DBL(-1.0f)) {
+ bandEnergyLdData[i] -= scale * FL2FXCONST_DBL(2.0 / 64);
+ }
+ /* find index of maxNrg */
+ if (bandEnergyLdData[i] > maxNrgLd) {
+ maxNrgLd = bandEnergyLdData[i];
+ nr = i;
+ }
+ }
+
+ /* return unscaled maxNrg*/
+ scale = fixMax(0, sfbMaxScaleSpec[nr] - 4);
+ scale = fixMax(2 * (minSpecShift - scale), -(DFRACT_BITS - 1));
+
+ maxNrg = scaleValue(bandEnergy[nr], scale);
+
+ return maxNrg;
+}
+
+/*****************************************************************************
+ functionname: FDKaacEnc_CalcBandEnergyOptimLong
+ description:
+ input:
+ output:
+*****************************************************************************/
+INT FDKaacEnc_CalcBandEnergyOptimLong(const FIXP_DBL *RESTRICT mdctSpectrum,
+ INT *RESTRICT sfbMaxScaleSpec,
+ const INT *RESTRICT bandOffset,
+ const INT numBands,
+ FIXP_DBL *RESTRICT bandEnergy,
+ FIXP_DBL *RESTRICT bandEnergyLdData) {
+ INT i, j, shiftBits = 0;
+ FIXP_DBL maxNrgLd = FL2FXCONST_DBL(0.0f);
+
+ FIXP_DBL spec;
+
+ for (i = 0; i < numBands; i++) {
+ INT leadingBits = sfbMaxScaleSpec[i] -
+ 4; /* max sfbWidth = 96 ; 2^7=128 => 7/2 = 4 (spc*spc) */
+ FIXP_DBL tmp = FL2FXCONST_DBL(0.0);
+ /* don't use scaleValue() here, it increases workload quite sufficiently...
+ */
+ if (leadingBits >= 0) {
+ for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
+ spec = mdctSpectrum[j] << leadingBits;
+ tmp = fPow2AddDiv2(tmp, spec);
+ }
+ } else {
+ INT shift = -leadingBits;
+ for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
+ spec = mdctSpectrum[j] >> shift;
+ tmp = fPow2AddDiv2(tmp, spec);
+ }
+ }
+ bandEnergy[i] = tmp << 1;
+ }
+
+ /* calculate ld of bandNrg, subtract scaling */
+ LdDataVector(bandEnergy, bandEnergyLdData, numBands);
+ for (i = numBands; i-- != 0;) {
+ FIXP_DBL scaleDiff = (sfbMaxScaleSpec[i] - 4) * FL2FXCONST_DBL(2.0 / 64);
+
+ bandEnergyLdData[i] = (bandEnergyLdData[i] >=
+ ((FL2FXCONST_DBL(-1.f) >> 1) + (scaleDiff >> 1)))
+ ? bandEnergyLdData[i] - scaleDiff
+ : FL2FXCONST_DBL(-1.f);
+ /* find maxNrgLd */
+ maxNrgLd = fixMax(maxNrgLd, bandEnergyLdData[i]);
+ }
+
+ if (maxNrgLd <= (FIXP_DBL)0) {
+ for (i = numBands; i-- != 0;) {
+ INT scale = fixMin((sfbMaxScaleSpec[i] - 4) << 1, (DFRACT_BITS - 1));
+ bandEnergy[i] = scaleValue(bandEnergy[i], -scale);
+ }
+ return 0;
+ } else { /* scale down NRGs */
+ while (maxNrgLd > FL2FXCONST_DBL(0.0f)) {
+ maxNrgLd -= FL2FXCONST_DBL(2.0 / 64);
+ shiftBits++;
+ }
+ for (i = numBands; i-- != 0;) {
+ INT scale = fixMin(((sfbMaxScaleSpec[i] - 4) + shiftBits) << 1,
+ (DFRACT_BITS - 1));
+ bandEnergyLdData[i] -= shiftBits * FL2FXCONST_DBL(2.0 / 64);
+ bandEnergy[i] = scaleValue(bandEnergy[i], -scale);
+ }
+ return shiftBits;
+ }
+}
+
+/*****************************************************************************
+ functionname: FDKaacEnc_CalcBandEnergyOptimShort
+ description:
+ input:
+ output:
+*****************************************************************************/
+void FDKaacEnc_CalcBandEnergyOptimShort(const FIXP_DBL *RESTRICT mdctSpectrum,
+ INT *RESTRICT sfbMaxScaleSpec,
+ const INT *RESTRICT bandOffset,
+ const INT numBands,
+ FIXP_DBL *RESTRICT bandEnergy) {
+ INT i, j;
+
+ for (i = 0; i < numBands; i++) {
+ int leadingBits = sfbMaxScaleSpec[i] -
+ 3; /* max sfbWidth = 36 ; 2^6=64 => 6/2 = 3 (spc*spc) */
+ FIXP_DBL tmp = FL2FXCONST_DBL(0.0);
+ for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
+ FIXP_DBL spec = scaleValue(mdctSpectrum[j], leadingBits);
+ tmp = fPow2AddDiv2(tmp, spec);
+ }
+ bandEnergy[i] = tmp;
+ }
+
+ for (i = 0; i < numBands; i++) {
+ INT scale = (2 * (sfbMaxScaleSpec[i] - 3)) -
+ 1; /* max sfbWidth = 36 ; 2^6=64 => 6/2 = 3 (spc*spc) */
+ scale = fixMax(fixMin(scale, (DFRACT_BITS - 1)), -(DFRACT_BITS - 1));
+ bandEnergy[i] = scaleValueSaturate(bandEnergy[i], -scale);
+ }
+}
+
+/*****************************************************************************
+ functionname: FDKaacEnc_CalcBandNrgMSOpt
+ description:
+ input:
+ output:
+*****************************************************************************/
+void FDKaacEnc_CalcBandNrgMSOpt(
+ const FIXP_DBL *RESTRICT mdctSpectrumLeft,
+ const FIXP_DBL *RESTRICT mdctSpectrumRight,
+ INT *RESTRICT sfbMaxScaleSpecLeft, INT *RESTRICT sfbMaxScaleSpecRight,
+ const INT *RESTRICT bandOffset, const INT numBands,
+ FIXP_DBL *RESTRICT bandEnergyMid, FIXP_DBL *RESTRICT bandEnergySide,
+ INT calcLdData, FIXP_DBL *RESTRICT bandEnergyMidLdData,
+ FIXP_DBL *RESTRICT bandEnergySideLdData) {
+ INT i, j, minScale;
+ FIXP_DBL NrgMid, NrgSide, specm, specs;
+
+ for (i = 0; i < numBands; i++) {
+ NrgMid = NrgSide = FL2FXCONST_DBL(0.0);
+ minScale = fixMin(sfbMaxScaleSpecLeft[i], sfbMaxScaleSpecRight[i]) - 4;
+ minScale = fixMax(0, minScale);
+
+ if (minScale > 0) {
+ for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
+ FIXP_DBL specL = mdctSpectrumLeft[j] << (minScale - 1);
+ FIXP_DBL specR = mdctSpectrumRight[j] << (minScale - 1);
+ specm = specL + specR;
+ specs = specL - specR;
+ NrgMid = fPow2AddDiv2(NrgMid, specm);
+ NrgSide = fPow2AddDiv2(NrgSide, specs);
+ }
+ } else {
+ for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
+ FIXP_DBL specL = mdctSpectrumLeft[j] >> 1;
+ FIXP_DBL specR = mdctSpectrumRight[j] >> 1;
+ specm = specL + specR;
+ specs = specL - specR;
+ NrgMid = fPow2AddDiv2(NrgMid, specm);
+ NrgSide = fPow2AddDiv2(NrgSide, specs);
+ }
+ }
+ bandEnergyMid[i] = fMin(NrgMid, (FIXP_DBL)MAXVAL_DBL >> 1) << 1;
+ bandEnergySide[i] = fMin(NrgSide, (FIXP_DBL)MAXVAL_DBL >> 1) << 1;
+ }
+
+ if (calcLdData) {
+ LdDataVector(bandEnergyMid, bandEnergyMidLdData, numBands);
+ LdDataVector(bandEnergySide, bandEnergySideLdData, numBands);
+ }
+
+ for (i = 0; i < numBands; i++) {
+ minScale = fixMin(sfbMaxScaleSpecLeft[i], sfbMaxScaleSpecRight[i]);
+ INT scale = fixMax(0, 2 * (minScale - 4));
+
+ if (calcLdData) {
+ /* using the minimal scaling of left and right channel can cause very
+ small energies; check ldNrg before subtract scaling multiplication:
+ fract*INT we don't need fMult */
+
+ int minus = scale * FL2FXCONST_DBL(1.0 / 64);
+
+ if (bandEnergyMidLdData[i] != FL2FXCONST_DBL(-1.0f))
+ bandEnergyMidLdData[i] -= minus;
+
+ if (bandEnergySideLdData[i] != FL2FXCONST_DBL(-1.0f))
+ bandEnergySideLdData[i] -= minus;
+ }
+ scale = fixMin(scale, (DFRACT_BITS - 1));
+ bandEnergyMid[i] >>= scale;
+ bandEnergySide[i] >>= scale;
+ }
+}
diff --git a/fdk-aac/libAACenc/src/band_nrg.h b/fdk-aac/libAACenc/src/band_nrg.h
new file mode 100644
index 0000000..4137565
--- /dev/null
+++ b/fdk-aac/libAACenc/src/band_nrg.h
@@ -0,0 +1,142 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Band/Line energy calculation
+
+*******************************************************************************/
+
+#ifndef BAND_NRG_H
+#define BAND_NRG_H
+
+#include "common_fix.h"
+
+void FDKaacEnc_CalcSfbMaxScaleSpec(const FIXP_DBL *mdctSpectrum,
+ const INT *bandOffset, INT *sfbMaxScaleSpec,
+ const INT numBands);
+
+FIXP_DBL
+FDKaacEnc_CheckBandEnergyOptim(const FIXP_DBL *const RESTRICT mdctSpectrum,
+ const INT *const RESTRICT sfbMaxScaleSpec,
+ const INT *const RESTRICT bandOffset,
+ const INT numBands,
+ FIXP_DBL *RESTRICT bandEnergy,
+ FIXP_DBL *RESTRICT bandEnergyLdData,
+ const INT minSpecShift);
+
+INT FDKaacEnc_CalcBandEnergyOptimLong(const FIXP_DBL *mdctSpectrum,
+ INT *sfbMaxScaleSpec,
+ const INT *bandOffset, const INT numBands,
+ FIXP_DBL *bandEnergy,
+ FIXP_DBL *bandEnergyLdData);
+
+void FDKaacEnc_CalcBandEnergyOptimShort(const FIXP_DBL *mdctSpectrum,
+ INT *sfbMaxScaleSpec,
+ const INT *bandOffset,
+ const INT numBands,
+ FIXP_DBL *bandEnergy);
+
+void FDKaacEnc_CalcBandNrgMSOpt(
+ const FIXP_DBL *RESTRICT mdctSpectrumLeft,
+ const FIXP_DBL *RESTRICT mdctSpectrumRight,
+ INT *RESTRICT sfbMaxScaleSpecLeft, INT *RESTRICT sfbMaxScaleSpecRight,
+ const INT *RESTRICT bandOffset, const INT numBands,
+ FIXP_DBL *RESTRICT bandEnergyMid, FIXP_DBL *RESTRICT bandEnergySide,
+ INT calcLdData, FIXP_DBL *RESTRICT bandEnergyMidLdData,
+ FIXP_DBL *RESTRICT bandEnergySideLdData);
+
+#endif
diff --git a/fdk-aac/libAACenc/src/bandwidth.cpp b/fdk-aac/libAACenc/src/bandwidth.cpp
new file mode 100644
index 0000000..36cd64d
--- /dev/null
+++ b/fdk-aac/libAACenc/src/bandwidth.cpp
@@ -0,0 +1,360 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Schug / A. Groeschel
+
+ Description: bandwidth expert
+
+*******************************************************************************/
+
+#include "channel_map.h"
+#include "bandwidth.h"
+#include "aacEnc_ram.h"
+
+typedef struct {
+ INT chanBitRate;
+ INT bandWidthMono;
+ INT bandWidth2AndMoreChan;
+
+} BANDWIDTH_TAB;
+
+static const BANDWIDTH_TAB bandWidthTable[] = {
+ {0, 3700, 5000}, {12000, 5000, 6400}, {20000, 6900, 9640},
+ {28000, 9600, 13050}, {40000, 12060, 14260}, {56000, 13950, 15500},
+ {72000, 14200, 16120}, {96000, 17000, 17000}, {576001, 17000, 17000}};
+
+static const BANDWIDTH_TAB bandWidthTable_LD_22050[] = {
+ {8000, 2000, 2400}, {12000, 2500, 2700}, {16000, 3300, 3100},
+ {24000, 6250, 7200}, {32000, 9200, 10500}, {40000, 16000, 16000},
+ {48000, 16000, 16000}, {282241, 16000, 16000}};
+
+static const BANDWIDTH_TAB bandWidthTable_LD_24000[] = {
+ {8000, 2000, 2000}, {12000, 2000, 2300}, {16000, 2200, 2500},
+ {24000, 5650, 7200}, {32000, 11600, 12000}, {40000, 12000, 16000},
+ {48000, 16000, 16000}, {64000, 16000, 16000}, {307201, 16000, 16000}};
+
+static const BANDWIDTH_TAB bandWidthTable_LD_32000[] = {
+ {8000, 2000, 2000}, {12000, 2000, 2000}, {24000, 4250, 7200},
+ {32000, 8400, 9000}, {40000, 9400, 11300}, {48000, 11900, 14700},
+ {64000, 14800, 16000}, {76000, 16000, 16000}, {409601, 16000, 16000}};
+
+static const BANDWIDTH_TAB bandWidthTable_LD_44100[] = {
+ {8000, 2000, 2000}, {24000, 2000, 2000}, {32000, 4400, 5700},
+ {40000, 7400, 8800}, {48000, 9000, 10700}, {56000, 11000, 12900},
+ {64000, 14400, 15500}, {80000, 16000, 16200}, {96000, 16500, 16000},
+ {128000, 16000, 16000}, {564481, 16000, 16000}};
+
+static const BANDWIDTH_TAB bandWidthTable_LD_48000[] = {
+ {8000, 2000, 2000}, {24000, 2000, 2000}, {32000, 4400, 5700},
+ {40000, 7400, 8800}, {48000, 9000, 10700}, {56000, 11000, 12800},
+ {64000, 14300, 15400}, {80000, 16000, 16200}, {96000, 16500, 16000},
+ {128000, 16000, 16000}, {614401, 16000, 16000}};
+
+typedef struct {
+ AACENC_BITRATE_MODE bitrateMode;
+ int bandWidthMono;
+ int bandWidth2AndMoreChan;
+} BANDWIDTH_TAB_VBR;
+
+static const BANDWIDTH_TAB_VBR bandWidthTableVBR[] = {
+ {AACENC_BR_MODE_CBR, 0, 0},
+ {AACENC_BR_MODE_VBR_1, 13050, 13050},
+ {AACENC_BR_MODE_VBR_2, 13050, 13050},
+ {AACENC_BR_MODE_VBR_3, 14260, 14260},
+ {AACENC_BR_MODE_VBR_4, 15500, 15500},
+ {AACENC_BR_MODE_VBR_5, 48000, 48000},
+ {AACENC_BR_MODE_SFR, 0, 0},
+ {AACENC_BR_MODE_FF, 0, 0}
+
+};
+
+static INT GetBandwidthEntry(const INT frameLength, const INT sampleRate,
+ const INT chanBitRate, const INT entryNo) {
+ INT bandwidth = -1;
+ const BANDWIDTH_TAB *pBwTab = NULL;
+ INT bwTabSize = 0;
+
+ switch (frameLength) {
+ case 960:
+ case 1024:
+ pBwTab = bandWidthTable;
+ bwTabSize = sizeof(bandWidthTable) / sizeof(BANDWIDTH_TAB);
+ break;
+ case 120:
+ case 128:
+ case 240:
+ case 256:
+ case 480:
+ case 512:
+ switch (sampleRate) {
+ case 8000:
+ case 11025:
+ case 12000:
+ case 16000:
+ case 22050:
+ pBwTab = bandWidthTable_LD_22050;
+ bwTabSize = sizeof(bandWidthTable_LD_22050) / sizeof(BANDWIDTH_TAB);
+ break;
+ case 24000:
+ pBwTab = bandWidthTable_LD_24000;
+ bwTabSize = sizeof(bandWidthTable_LD_24000) / sizeof(BANDWIDTH_TAB);
+ break;
+ case 32000:
+ pBwTab = bandWidthTable_LD_32000;
+ bwTabSize = sizeof(bandWidthTable_LD_32000) / sizeof(BANDWIDTH_TAB);
+ break;
+ case 44100:
+ pBwTab = bandWidthTable_LD_44100;
+ bwTabSize = sizeof(bandWidthTable_LD_44100) / sizeof(BANDWIDTH_TAB);
+ break;
+ case 48000:
+ case 64000:
+ case 88200:
+ case 96000:
+ pBwTab = bandWidthTable_LD_48000;
+ bwTabSize = sizeof(bandWidthTable_LD_48000) / sizeof(BANDWIDTH_TAB);
+ break;
+ }
+ break;
+ default:
+ pBwTab = NULL;
+ bwTabSize = 0;
+ }
+
+ if (pBwTab != NULL) {
+ int i;
+ for (i = 0; i < bwTabSize - 1; i++) {
+ if (chanBitRate >= pBwTab[i].chanBitRate &&
+ chanBitRate < pBwTab[i + 1].chanBitRate) {
+ switch (frameLength) {
+ case 960:
+ case 1024:
+ bandwidth = (entryNo == 0) ? pBwTab[i].bandWidthMono
+ : pBwTab[i].bandWidth2AndMoreChan;
+ break;
+ case 120:
+ case 128:
+ case 240:
+ case 256:
+ case 480:
+ case 512: {
+ INT q_res = 0;
+ INT startBw = (entryNo == 0) ? pBwTab[i].bandWidthMono
+ : pBwTab[i].bandWidth2AndMoreChan;
+ INT endBw = (entryNo == 0) ? pBwTab[i + 1].bandWidthMono
+ : pBwTab[i + 1].bandWidth2AndMoreChan;
+ INT startBr = pBwTab[i].chanBitRate;
+ INT endBr = pBwTab[i + 1].chanBitRate;
+
+ FIXP_DBL bwFac_fix =
+ fDivNorm(chanBitRate - startBr, endBr - startBr, &q_res);
+ bandwidth =
+ (INT)scaleValue(fMult(bwFac_fix, (FIXP_DBL)(endBw - startBw)),
+ q_res) +
+ startBw;
+ } break;
+ default:
+ bandwidth = -1;
+ }
+ break;
+ } /* within bitrate range */
+ }
+ } /* pBwTab!=NULL */
+
+ return bandwidth;
+}
+
+AAC_ENCODER_ERROR FDKaacEnc_DetermineBandWidth(
+ const INT proposedBandWidth, const INT bitrate,
+ const AACENC_BITRATE_MODE bitrateMode, const INT sampleRate,
+ const INT frameLength, const CHANNEL_MAPPING *const cm,
+ const CHANNEL_MODE encoderMode, INT *const bandWidth) {
+ AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
+ INT chanBitRate = bitrate / cm->nChannelsEff;
+
+ switch (bitrateMode) {
+ case AACENC_BR_MODE_VBR_1:
+ case AACENC_BR_MODE_VBR_2:
+ case AACENC_BR_MODE_VBR_3:
+ case AACENC_BR_MODE_VBR_4:
+ case AACENC_BR_MODE_VBR_5:
+ if (proposedBandWidth != 0) {
+ /* use given bw */
+ *bandWidth = proposedBandWidth;
+ } else {
+ /* take bw from table */
+ switch (encoderMode) {
+ case MODE_1:
+ *bandWidth = bandWidthTableVBR[bitrateMode].bandWidthMono;
+ break;
+ case MODE_2:
+ case MODE_1_2:
+ case MODE_1_2_1:
+ case MODE_1_2_2:
+ case MODE_1_2_2_1:
+ case MODE_6_1:
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_REAR_SURROUND:
+ case MODE_7_1_FRONT_CENTER:
+ case MODE_7_1_BACK:
+ case MODE_7_1_TOP_FRONT:
+ *bandWidth = bandWidthTableVBR[bitrateMode].bandWidth2AndMoreChan;
+ break;
+ default:
+ return AAC_ENC_UNSUPPORTED_CHANNELCONFIG;
+ }
+ }
+ break;
+ case AACENC_BR_MODE_CBR:
+ case AACENC_BR_MODE_SFR:
+ case AACENC_BR_MODE_FF:
+
+ /* bandwidth limiting */
+ if (proposedBandWidth != 0) {
+ *bandWidth = fMin(proposedBandWidth, fMin(20000, sampleRate >> 1));
+ } else { /* search reasonable bandwidth */
+
+ int entryNo = 0;
+
+ switch (encoderMode) {
+ case MODE_1: /* mono */
+ entryNo = 0; /* use mono bandwidth settings */
+ break;
+
+ case MODE_2: /* stereo */
+ case MODE_1_2: /* sce + cpe */
+ case MODE_1_2_1: /* sce + cpe + sce */
+ case MODE_1_2_2: /* sce + cpe + cpe */
+ case MODE_1_2_2_1: /* (5.1) sce + cpe + cpe + lfe */
+ case MODE_6_1:
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_REAR_SURROUND:
+ case MODE_7_1_FRONT_CENTER:
+ case MODE_7_1_BACK:
+ case MODE_7_1_TOP_FRONT:
+ entryNo = 1; /* use stereo bandwidth settings */
+ break;
+
+ default:
+ return AAC_ENC_UNSUPPORTED_CHANNELCONFIG;
+ }
+
+ *bandWidth =
+ GetBandwidthEntry(frameLength, sampleRate, chanBitRate, entryNo);
+
+ if (*bandWidth == -1) {
+ switch (frameLength) {
+ case 120:
+ case 128:
+ case 240:
+ case 256:
+ *bandWidth = 16000;
+ break;
+ default:
+ ErrorStatus = AAC_ENC_INVALID_CHANNEL_BITRATE;
+ }
+ }
+ }
+ break;
+ default:
+ *bandWidth = 0;
+ return AAC_ENC_UNSUPPORTED_BITRATE_MODE;
+ }
+
+ *bandWidth = fMin(*bandWidth, sampleRate / 2);
+
+ return ErrorStatus;
+}
diff --git a/fdk-aac/libAACenc/src/bandwidth.h b/fdk-aac/libAACenc/src/bandwidth.h
new file mode 100644
index 0000000..088e829
--- /dev/null
+++ b/fdk-aac/libAACenc/src/bandwidth.h
@@ -0,0 +1,114 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Schug / A. Groeschel
+
+ Description: bandwidth expert
+
+*******************************************************************************/
+
+#ifndef BANDWIDTH_H
+#define BANDWIDTH_H
+
+#include "qc_data.h"
+
+AAC_ENCODER_ERROR FDKaacEnc_DetermineBandWidth(
+ const INT proposedBandWidth, const INT bitrate,
+ const AACENC_BITRATE_MODE bitrateMode, const INT sampleRate,
+ const INT frameLength, const CHANNEL_MAPPING *const cm,
+ const CHANNEL_MODE encoderMode, INT *const bandWidth);
+
+#endif /* BANDWIDTH_H */
diff --git a/fdk-aac/libAACenc/src/bit_cnt.cpp b/fdk-aac/libAACenc/src/bit_cnt.cpp
new file mode 100644
index 0000000..579df8c
--- /dev/null
+++ b/fdk-aac/libAACenc/src/bit_cnt.cpp
@@ -0,0 +1,950 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Huffman Bitcounter & coder
+
+*******************************************************************************/
+
+#include "bit_cnt.h"
+
+#include "aacEnc_ram.h"
+
+#define HI_LTAB(a) (a >> 16)
+#define LO_LTAB(a) (a & 0xffff)
+
+/*****************************************************************************
+
+
+ functionname: FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11
+ description: counts tables 1-11
+ returns:
+ input: quantized spectrum
+ output: bitCount for tables 1-11
+
+*****************************************************************************/
+
+static void FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11(const SHORT *const values,
+ const INT width,
+ INT *RESTRICT bitCount) {
+ INT i;
+ INT bc1_2, bc3_4, bc5_6, bc7_8, bc9_10, bc11, sc;
+ INT t0, t1, t2, t3;
+ bc1_2 = 0;
+ bc3_4 = 0;
+ bc5_6 = 0;
+ bc7_8 = 0;
+ bc9_10 = 0;
+ bc11 = 0;
+ sc = 0;
+
+ DWORD_ALIGNED(values);
+
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0];
+ t1 = values[i + 1];
+ t2 = values[i + 2];
+ t3 = values[i + 3];
+
+ bc1_2 += (INT)FDKaacEnc_huff_ltab1_2[t0 + 1][t1 + 1][t2 + 1][t3 + 1];
+ bc5_6 += (INT)FDKaacEnc_huff_ltab5_6[t0 + 4][t1 + 4] +
+ (INT)FDKaacEnc_huff_ltab5_6[t2 + 4][t3 + 4];
+
+ t0 = fixp_abs(t0);
+ sc += (t0 > 0);
+ t1 = fixp_abs(t1);
+ sc += (t1 > 0);
+ t2 = fixp_abs(t2);
+ sc += (t2 > 0);
+ t3 = fixp_abs(t3);
+ sc += (t3 > 0);
+
+ bc3_4 += (INT)FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3];
+ bc7_8 += (INT)FDKaacEnc_huff_ltab7_8[t0][t1] +
+ (INT)FDKaacEnc_huff_ltab7_8[t2][t3];
+ bc9_10 += (INT)FDKaacEnc_huff_ltab9_10[t0][t1] +
+ (INT)FDKaacEnc_huff_ltab9_10[t2][t3];
+ bc11 +=
+ (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3];
+ }
+ bitCount[1] = HI_LTAB(bc1_2);
+ bitCount[2] = LO_LTAB(bc1_2);
+ bitCount[3] = HI_LTAB(bc3_4) + sc;
+ bitCount[4] = LO_LTAB(bc3_4) + sc;
+ bitCount[5] = HI_LTAB(bc5_6);
+ bitCount[6] = LO_LTAB(bc5_6);
+ bitCount[7] = HI_LTAB(bc7_8) + sc;
+ bitCount[8] = LO_LTAB(bc7_8) + sc;
+ bitCount[9] = HI_LTAB(bc9_10) + sc;
+ bitCount[10] = LO_LTAB(bc9_10) + sc;
+ bitCount[11] = bc11 + sc;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_count3_4_5_6_7_8_9_10_11
+ description: counts tables 3-11
+ returns:
+ input: quantized spectrum
+ output: bitCount for tables 3-11
+
+*****************************************************************************/
+
+static void FDKaacEnc_count3_4_5_6_7_8_9_10_11(const SHORT *const values,
+ const INT width,
+ INT *RESTRICT bitCount) {
+ INT i;
+ INT bc3_4, bc5_6, bc7_8, bc9_10, bc11, sc;
+ INT t0, t1, t2, t3;
+
+ bc3_4 = 0;
+ bc5_6 = 0;
+ bc7_8 = 0;
+ bc9_10 = 0;
+ bc11 = 0;
+ sc = 0;
+
+ DWORD_ALIGNED(values);
+
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0];
+ t1 = values[i + 1];
+ t2 = values[i + 2];
+ t3 = values[i + 3];
+
+ bc5_6 += (INT)FDKaacEnc_huff_ltab5_6[t0 + 4][t1 + 4] +
+ (INT)FDKaacEnc_huff_ltab5_6[t2 + 4][t3 + 4];
+
+ t0 = fixp_abs(t0);
+ sc += (t0 > 0);
+ t1 = fixp_abs(t1);
+ sc += (t1 > 0);
+ t2 = fixp_abs(t2);
+ sc += (t2 > 0);
+ t3 = fixp_abs(t3);
+ sc += (t3 > 0);
+
+ bc3_4 += (INT)FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3];
+ bc7_8 += (INT)FDKaacEnc_huff_ltab7_8[t0][t1] +
+ (INT)FDKaacEnc_huff_ltab7_8[t2][t3];
+ bc9_10 += (INT)FDKaacEnc_huff_ltab9_10[t0][t1] +
+ (INT)FDKaacEnc_huff_ltab9_10[t2][t3];
+ bc11 +=
+ (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3];
+ }
+
+ bitCount[1] = INVALID_BITCOUNT;
+ bitCount[2] = INVALID_BITCOUNT;
+ bitCount[3] = HI_LTAB(bc3_4) + sc;
+ bitCount[4] = LO_LTAB(bc3_4) + sc;
+ bitCount[5] = HI_LTAB(bc5_6);
+ bitCount[6] = LO_LTAB(bc5_6);
+ bitCount[7] = HI_LTAB(bc7_8) + sc;
+ bitCount[8] = LO_LTAB(bc7_8) + sc;
+ bitCount[9] = HI_LTAB(bc9_10) + sc;
+ bitCount[10] = LO_LTAB(bc9_10) + sc;
+ bitCount[11] = bc11 + sc;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_count5_6_7_8_9_10_11
+ description: counts tables 5-11
+ returns:
+ input: quantized spectrum
+ output: bitCount for tables 5-11
+
+*****************************************************************************/
+
+static void FDKaacEnc_count5_6_7_8_9_10_11(const SHORT *const values,
+ const INT width,
+ INT *RESTRICT bitCount) {
+ INT i;
+ INT bc5_6, bc7_8, bc9_10, bc11, sc;
+ INT t0, t1, t2, t3;
+ bc5_6 = 0;
+ bc7_8 = 0;
+ bc9_10 = 0;
+ bc11 = 0;
+ sc = 0;
+
+ DWORD_ALIGNED(values);
+
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0];
+ t1 = values[i + 1];
+ t2 = values[i + 2];
+ t3 = values[i + 3];
+
+ bc5_6 += (INT)FDKaacEnc_huff_ltab5_6[t0 + 4][t1 + 4] +
+ (INT)FDKaacEnc_huff_ltab5_6[t2 + 4][t3 + 4];
+
+ t0 = fixp_abs(t0);
+ sc += (t0 > 0);
+ t1 = fixp_abs(t1);
+ sc += (t1 > 0);
+ t2 = fixp_abs(t2);
+ sc += (t2 > 0);
+ t3 = fixp_abs(t3);
+ sc += (t3 > 0);
+
+ bc7_8 += (INT)FDKaacEnc_huff_ltab7_8[t0][t1] +
+ (INT)FDKaacEnc_huff_ltab7_8[t2][t3];
+ bc9_10 += (INT)FDKaacEnc_huff_ltab9_10[t0][t1] +
+ (INT)FDKaacEnc_huff_ltab9_10[t2][t3];
+ bc11 +=
+ (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3];
+ }
+ bitCount[1] = INVALID_BITCOUNT;
+ bitCount[2] = INVALID_BITCOUNT;
+ bitCount[3] = INVALID_BITCOUNT;
+ bitCount[4] = INVALID_BITCOUNT;
+ bitCount[5] = HI_LTAB(bc5_6);
+ bitCount[6] = LO_LTAB(bc5_6);
+ bitCount[7] = HI_LTAB(bc7_8) + sc;
+ bitCount[8] = LO_LTAB(bc7_8) + sc;
+ bitCount[9] = HI_LTAB(bc9_10) + sc;
+ bitCount[10] = LO_LTAB(bc9_10) + sc;
+ bitCount[11] = bc11 + sc;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_count7_8_9_10_11
+ description: counts tables 7-11
+ returns:
+ input: quantized spectrum
+ output: bitCount for tables 7-11
+
+*****************************************************************************/
+
+static void FDKaacEnc_count7_8_9_10_11(const SHORT *const values,
+ const INT width,
+ INT *RESTRICT bitCount) {
+ INT i;
+ INT bc7_8, bc9_10, bc11, sc;
+ INT t0, t1, t2, t3;
+
+ bc7_8 = 0;
+ bc9_10 = 0;
+ bc11 = 0;
+ sc = 0;
+
+ DWORD_ALIGNED(values);
+
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0];
+ t1 = values[i + 1];
+ t2 = values[i + 2];
+ t3 = values[i + 3];
+
+ t0 = fixp_abs(t0);
+ sc += (t0 > 0);
+ t1 = fixp_abs(t1);
+ sc += (t1 > 0);
+ t2 = fixp_abs(t2);
+ sc += (t2 > 0);
+ t3 = fixp_abs(t3);
+ sc += (t3 > 0);
+
+ bc7_8 += (INT)FDKaacEnc_huff_ltab7_8[t0][t1] +
+ (INT)FDKaacEnc_huff_ltab7_8[t2][t3];
+ bc9_10 += (INT)FDKaacEnc_huff_ltab9_10[t0][t1] +
+ (INT)FDKaacEnc_huff_ltab9_10[t2][t3];
+ bc11 +=
+ (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3];
+ }
+
+ bitCount[1] = INVALID_BITCOUNT;
+ bitCount[2] = INVALID_BITCOUNT;
+ bitCount[3] = INVALID_BITCOUNT;
+ bitCount[4] = INVALID_BITCOUNT;
+ bitCount[5] = INVALID_BITCOUNT;
+ bitCount[6] = INVALID_BITCOUNT;
+ bitCount[7] = HI_LTAB(bc7_8) + sc;
+ bitCount[8] = LO_LTAB(bc7_8) + sc;
+ bitCount[9] = HI_LTAB(bc9_10) + sc;
+ bitCount[10] = LO_LTAB(bc9_10) + sc;
+ bitCount[11] = bc11 + sc;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_count9_10_11
+ description: counts tables 9-11
+ returns:
+ input: quantized spectrum
+ output: bitCount for tables 9-11
+
+*****************************************************************************/
+
+static void FDKaacEnc_count9_10_11(const SHORT *const values, const INT width,
+ INT *RESTRICT bitCount) {
+ INT i;
+ INT bc9_10, bc11, sc;
+ INT t0, t1, t2, t3;
+
+ bc9_10 = 0;
+ bc11 = 0;
+ sc = 0;
+
+ DWORD_ALIGNED(values);
+
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0];
+ t1 = values[i + 1];
+ t2 = values[i + 2];
+ t3 = values[i + 3];
+
+ t0 = fixp_abs(t0);
+ sc += (t0 > 0);
+ t1 = fixp_abs(t1);
+ sc += (t1 > 0);
+ t2 = fixp_abs(t2);
+ sc += (t2 > 0);
+ t3 = fixp_abs(t3);
+ sc += (t3 > 0);
+
+ bc9_10 += (INT)FDKaacEnc_huff_ltab9_10[t0][t1] +
+ (INT)FDKaacEnc_huff_ltab9_10[t2][t3];
+ bc11 +=
+ (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3];
+ }
+
+ bitCount[1] = INVALID_BITCOUNT;
+ bitCount[2] = INVALID_BITCOUNT;
+ bitCount[3] = INVALID_BITCOUNT;
+ bitCount[4] = INVALID_BITCOUNT;
+ bitCount[5] = INVALID_BITCOUNT;
+ bitCount[6] = INVALID_BITCOUNT;
+ bitCount[7] = INVALID_BITCOUNT;
+ bitCount[8] = INVALID_BITCOUNT;
+ bitCount[9] = HI_LTAB(bc9_10) + sc;
+ bitCount[10] = LO_LTAB(bc9_10) + sc;
+ bitCount[11] = bc11 + sc;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_count11
+ description: counts table 11
+ returns:
+ input: quantized spectrum
+ output: bitCount for table 11
+
+*****************************************************************************/
+
+static void FDKaacEnc_count11(const SHORT *const values, const INT width,
+ INT *RESTRICT bitCount) {
+ INT i;
+ INT bc11, sc;
+ INT t0, t1, t2, t3;
+
+ bc11 = 0;
+ sc = 0;
+
+ DWORD_ALIGNED(values);
+
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0];
+ t1 = values[i + 1];
+ t2 = values[i + 2];
+ t3 = values[i + 3];
+
+ t0 = fixp_abs(t0);
+ sc += (t0 > 0);
+ t1 = fixp_abs(t1);
+ sc += (t1 > 0);
+ t2 = fixp_abs(t2);
+ sc += (t2 > 0);
+ t3 = fixp_abs(t3);
+ sc += (t3 > 0);
+
+ bc11 +=
+ (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3];
+ }
+
+ bitCount[1] = INVALID_BITCOUNT;
+ bitCount[2] = INVALID_BITCOUNT;
+ bitCount[3] = INVALID_BITCOUNT;
+ bitCount[4] = INVALID_BITCOUNT;
+ bitCount[5] = INVALID_BITCOUNT;
+ bitCount[6] = INVALID_BITCOUNT;
+ bitCount[7] = INVALID_BITCOUNT;
+ bitCount[8] = INVALID_BITCOUNT;
+ bitCount[9] = INVALID_BITCOUNT;
+ bitCount[10] = INVALID_BITCOUNT;
+ bitCount[11] = bc11 + sc;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_countEsc
+ description: counts table 11 (with Esc)
+ returns:
+ input: quantized spectrum
+ output: bitCount for tables 11 (with Esc)
+
+*****************************************************************************/
+
+static void FDKaacEnc_countEsc(const SHORT *const values, const INT width,
+ INT *RESTRICT bitCount) {
+ INT i;
+ INT bc11, ec, sc;
+ INT t0, t1, t00, t01;
+
+ bc11 = 0;
+ sc = 0;
+ ec = 0;
+ for (i = 0; i < width; i += 2) {
+ t0 = fixp_abs(values[i + 0]);
+ t1 = fixp_abs(values[i + 1]);
+
+ sc += (t0 > 0) + (t1 > 0);
+
+ t00 = fixMin(t0, 16);
+ t01 = fixMin(t1, 16);
+ bc11 += (INT)FDKaacEnc_huff_ltab11[t00][t01];
+
+ if (t0 >= 16) {
+ ec += 5;
+ while ((t0 >>= 1) >= 16) ec += 2;
+ }
+
+ if (t1 >= 16) {
+ ec += 5;
+ while ((t1 >>= 1) >= 16) ec += 2;
+ }
+ }
+
+ for (i = 0; i < 11; i++) bitCount[i] = INVALID_BITCOUNT;
+
+ bitCount[11] = bc11 + sc + ec;
+}
+
+typedef void (*COUNT_FUNCTION)(const SHORT *const values, const INT width,
+ INT *RESTRICT bitCount);
+
+static const COUNT_FUNCTION countFuncTable[CODE_BOOK_ESC_LAV + 1] = {
+
+ FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11, /* 0 */
+ FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11, /* 1 */
+ FDKaacEnc_count3_4_5_6_7_8_9_10_11, /* 2 */
+ FDKaacEnc_count5_6_7_8_9_10_11, /* 3 */
+ FDKaacEnc_count5_6_7_8_9_10_11, /* 4 */
+ FDKaacEnc_count7_8_9_10_11, /* 5 */
+ FDKaacEnc_count7_8_9_10_11, /* 6 */
+ FDKaacEnc_count7_8_9_10_11, /* 7 */
+ FDKaacEnc_count9_10_11, /* 8 */
+ FDKaacEnc_count9_10_11, /* 9 */
+ FDKaacEnc_count9_10_11, /* 10 */
+ FDKaacEnc_count9_10_11, /* 11 */
+ FDKaacEnc_count9_10_11, /* 12 */
+ FDKaacEnc_count11, /* 13 */
+ FDKaacEnc_count11, /* 14 */
+ FDKaacEnc_count11, /* 15 */
+ FDKaacEnc_countEsc /* 16 */
+};
+
+INT FDKaacEnc_bitCount(const SHORT *const values, const INT width,
+ const INT maxVal, INT *const RESTRICT bitCount) {
+ /*
+ check if we can use codebook 0
+ */
+
+ bitCount[0] = (maxVal == 0) ? 0 : INVALID_BITCOUNT;
+
+ countFuncTable[fixMin(maxVal, (INT)CODE_BOOK_ESC_LAV)](values, width,
+ bitCount);
+
+ return (0);
+}
+
+/*
+ count difference between actual and zeroed lines
+*/
+INT FDKaacEnc_countValues(SHORT *RESTRICT values, INT width, INT codeBook) {
+ INT i, t0, t1, t2, t3;
+ INT bitCnt = 0;
+
+ switch (codeBook) {
+ case CODE_BOOK_ZERO_NO:
+ break;
+
+ case CODE_BOOK_1_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0];
+ t1 = values[i + 1];
+ t2 = values[i + 2];
+ t3 = values[i + 3];
+ bitCnt +=
+ HI_LTAB(FDKaacEnc_huff_ltab1_2[t0 + 1][t1 + 1][t2 + 1][t3 + 1]);
+ }
+ break;
+
+ case CODE_BOOK_2_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0];
+ t1 = values[i + 1];
+ t2 = values[i + 2];
+ t3 = values[i + 3];
+ bitCnt +=
+ LO_LTAB(FDKaacEnc_huff_ltab1_2[t0 + 1][t1 + 1][t2 + 1][t3 + 1]);
+ }
+ break;
+
+ case CODE_BOOK_3_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = fixp_abs(values[i + 0]);
+ bitCnt += (t0 > 0);
+ t1 = fixp_abs(values[i + 1]);
+ bitCnt += (t1 > 0);
+ t2 = fixp_abs(values[i + 2]);
+ bitCnt += (t2 > 0);
+ t3 = fixp_abs(values[i + 3]);
+ bitCnt += (t3 > 0);
+ bitCnt += HI_LTAB(FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3]);
+ }
+ break;
+
+ case CODE_BOOK_4_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = fixp_abs(values[i + 0]);
+ bitCnt += (t0 > 0);
+ t1 = fixp_abs(values[i + 1]);
+ bitCnt += (t1 > 0);
+ t2 = fixp_abs(values[i + 2]);
+ bitCnt += (t2 > 0);
+ t3 = fixp_abs(values[i + 3]);
+ bitCnt += (t3 > 0);
+ bitCnt += LO_LTAB(FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3]);
+ }
+ break;
+
+ case CODE_BOOK_5_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0];
+ t1 = values[i + 1];
+ t2 = values[i + 2];
+ t3 = values[i + 3];
+ bitCnt += HI_LTAB(FDKaacEnc_huff_ltab5_6[t0 + 4][t1 + 4]) +
+ HI_LTAB(FDKaacEnc_huff_ltab5_6[t2 + 4][t3 + 4]);
+ }
+ break;
+
+ case CODE_BOOK_6_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0];
+ t1 = values[i + 1];
+ t2 = values[i + 2];
+ t3 = values[i + 3];
+ bitCnt += LO_LTAB(FDKaacEnc_huff_ltab5_6[t0 + 4][t1 + 4]) +
+ LO_LTAB(FDKaacEnc_huff_ltab5_6[t2 + 4][t3 + 4]);
+ }
+ break;
+
+ case CODE_BOOK_7_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = fixp_abs(values[i + 0]);
+ bitCnt += (t0 > 0);
+ t1 = fixp_abs(values[i + 1]);
+ bitCnt += (t1 > 0);
+ t2 = fixp_abs(values[i + 2]);
+ bitCnt += (t2 > 0);
+ t3 = fixp_abs(values[i + 3]);
+ bitCnt += (t3 > 0);
+ bitCnt += HI_LTAB(FDKaacEnc_huff_ltab7_8[t0][t1]) +
+ HI_LTAB(FDKaacEnc_huff_ltab7_8[t2][t3]);
+ }
+ break;
+
+ case CODE_BOOK_8_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = fixp_abs(values[i + 0]);
+ bitCnt += (t0 > 0);
+ t1 = fixp_abs(values[i + 1]);
+ bitCnt += (t1 > 0);
+ t2 = fixp_abs(values[i + 2]);
+ bitCnt += (t2 > 0);
+ t3 = fixp_abs(values[i + 3]);
+ bitCnt += (t3 > 0);
+ bitCnt += LO_LTAB(FDKaacEnc_huff_ltab7_8[t0][t1]) +
+ LO_LTAB(FDKaacEnc_huff_ltab7_8[t2][t3]);
+ }
+ break;
+
+ case CODE_BOOK_9_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = fixp_abs(values[i + 0]);
+ bitCnt += (t0 > 0);
+ t1 = fixp_abs(values[i + 1]);
+ bitCnt += (t1 > 0);
+ t2 = fixp_abs(values[i + 2]);
+ bitCnt += (t2 > 0);
+ t3 = fixp_abs(values[i + 3]);
+ bitCnt += (t3 > 0);
+ bitCnt += HI_LTAB(FDKaacEnc_huff_ltab9_10[t0][t1]) +
+ HI_LTAB(FDKaacEnc_huff_ltab9_10[t2][t3]);
+ }
+ break;
+
+ case CODE_BOOK_10_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = fixp_abs(values[i + 0]);
+ bitCnt += (t0 > 0);
+ t1 = fixp_abs(values[i + 1]);
+ bitCnt += (t1 > 0);
+ t2 = fixp_abs(values[i + 2]);
+ bitCnt += (t2 > 0);
+ t3 = fixp_abs(values[i + 3]);
+ bitCnt += (t3 > 0);
+ bitCnt += LO_LTAB(FDKaacEnc_huff_ltab9_10[t0][t1]) +
+ LO_LTAB(FDKaacEnc_huff_ltab9_10[t2][t3]);
+ }
+ break;
+
+ case CODE_BOOK_ESC_NO:
+ for (i = 0; i < width; i += 2) {
+ t0 = fixp_abs(values[i + 0]);
+ bitCnt += (t0 > 0);
+ t1 = fixp_abs(values[i + 1]);
+ bitCnt += (t1 > 0);
+ bitCnt += (INT)FDKaacEnc_huff_ltab11[fixMin(t0, 16)][fixMin(t1, 16)];
+ if (t0 >= 16) {
+ bitCnt += 5;
+ while ((t0 >>= 1) >= 16) bitCnt += 2;
+ }
+ if (t1 >= 16) {
+ bitCnt += 5;
+ while ((t1 >>= 1) >= 16) bitCnt += 2;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return (bitCnt);
+}
+
+INT FDKaacEnc_codeValues(SHORT *RESTRICT values, INT width, INT codeBook,
+ HANDLE_FDK_BITSTREAM hBitstream) {
+ INT i, t0, t1, t2, t3, t00, t01;
+ INT codeWord, codeLength;
+ INT sign, signLength;
+
+ DWORD_ALIGNED(values);
+
+ switch (codeBook) {
+ case CODE_BOOK_ZERO_NO:
+ break;
+
+ case CODE_BOOK_1_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0] + 1;
+ t1 = values[i + 1] + 1;
+ t2 = values[i + 2] + 1;
+ t3 = values[i + 3] + 1;
+ codeWord = FDKaacEnc_huff_ctab1[t0][t1][t2][t3];
+ codeLength = HI_LTAB(FDKaacEnc_huff_ltab1_2[t0][t1][t2][t3]);
+ FDKwriteBits(hBitstream, codeWord, codeLength);
+ }
+ break;
+
+ case CODE_BOOK_2_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0] + 1;
+ t1 = values[i + 1] + 1;
+ t2 = values[i + 2] + 1;
+ t3 = values[i + 3] + 1;
+ codeWord = FDKaacEnc_huff_ctab2[t0][t1][t2][t3];
+ codeLength = LO_LTAB(FDKaacEnc_huff_ltab1_2[t0][t1][t2][t3]);
+ FDKwriteBits(hBitstream, codeWord, codeLength);
+ }
+ break;
+
+ case CODE_BOOK_3_NO:
+ for (i = 0; i < (width >> 2); i++) {
+ sign = 0;
+ signLength = 0;
+ int index[4];
+ for (int j = 0; j < 4; j++) {
+ int ti = *values++;
+ int zero = (ti == 0) ? 0 : 1;
+ signLength += zero;
+ sign = (sign << zero) + ((UINT)ti >> 31);
+ index[j] = fixp_abs(ti);
+ }
+ codeWord = FDKaacEnc_huff_ctab3[index[0]][index[1]][index[2]][index[3]];
+ codeLength = HI_LTAB(
+ FDKaacEnc_huff_ltab3_4[index[0]][index[1]][index[2]][index[3]]);
+ FDKwriteBits(hBitstream, (codeWord << signLength) | sign,
+ codeLength + signLength);
+ }
+ break;
+
+ case CODE_BOOK_4_NO:
+ for (i = 0; i < width; i += 4) {
+ sign = 0;
+ signLength = 0;
+ int index[4];
+ for (int j = 0; j < 4; j++) {
+ int ti = *values++;
+ int zero = (ti == 0) ? 0 : 1;
+ signLength += zero;
+ sign = (sign << zero) + ((UINT)ti >> 31);
+ index[j] = fixp_abs(ti);
+ }
+ codeWord = FDKaacEnc_huff_ctab4[index[0]][index[1]][index[2]][index[3]];
+ codeLength = LO_LTAB(
+ FDKaacEnc_huff_ltab3_4[index[0]][index[1]][index[2]][index[3]]);
+ FDKwriteBits(hBitstream, (codeWord << signLength) | sign,
+ codeLength + signLength);
+ }
+ break;
+
+ case CODE_BOOK_5_NO:
+ for (i = 0; i < (width >> 2); i++) {
+ t0 = *values++ + 4;
+ t1 = *values++ + 4;
+ t2 = *values++ + 4;
+ t3 = *values++ + 4;
+ codeWord = FDKaacEnc_huff_ctab5[t0][t1];
+ codeLength =
+ HI_LTAB(FDKaacEnc_huff_ltab5_6[t2][t3]); /* length of 2nd cw */
+ codeWord = (codeWord << codeLength) + FDKaacEnc_huff_ctab5[t2][t3];
+ codeLength += HI_LTAB(FDKaacEnc_huff_ltab5_6[t0][t1]);
+ FDKwriteBits(hBitstream, codeWord, codeLength);
+ }
+ break;
+
+ case CODE_BOOK_6_NO:
+ for (i = 0; i < (width >> 2); i++) {
+ t0 = *values++ + 4;
+ t1 = *values++ + 4;
+ t2 = *values++ + 4;
+ t3 = *values++ + 4;
+ codeWord = FDKaacEnc_huff_ctab6[t0][t1];
+ codeLength =
+ LO_LTAB(FDKaacEnc_huff_ltab5_6[t2][t3]); /* length of 2nd cw */
+ codeWord = (codeWord << codeLength) + FDKaacEnc_huff_ctab6[t2][t3];
+ codeLength += LO_LTAB(FDKaacEnc_huff_ltab5_6[t0][t1]);
+ FDKwriteBits(hBitstream, codeWord, codeLength);
+ }
+ break;
+
+ case CODE_BOOK_7_NO:
+ for (i = 0; i < (width >> 1); i++) {
+ t0 = *values++;
+ sign = ((UINT)t0 >> 31);
+ t0 = fixp_abs(t0);
+ signLength = (t0 == 0) ? 0 : 1;
+ t1 = *values++;
+ INT zero = (t1 == 0) ? 0 : 1;
+ signLength += zero;
+ sign = (sign << zero) + ((UINT)t1 >> 31);
+ t1 = fixp_abs(t1);
+ codeWord = FDKaacEnc_huff_ctab7[t0][t1];
+ codeLength = HI_LTAB(FDKaacEnc_huff_ltab7_8[t0][t1]);
+ FDKwriteBits(hBitstream, (codeWord << signLength) | sign,
+ codeLength + signLength);
+ }
+ break;
+
+ case CODE_BOOK_8_NO:
+ for (i = 0; i < (width >> 1); i++) {
+ t0 = *values++;
+ sign = ((UINT)t0 >> 31);
+ t0 = fixp_abs(t0);
+ signLength = (t0 == 0) ? 0 : 1;
+ t1 = *values++;
+ INT zero = (t1 == 0) ? 0 : 1;
+ signLength += zero;
+ sign = (sign << zero) + ((UINT)t1 >> 31);
+ t1 = fixp_abs(t1);
+ codeWord = FDKaacEnc_huff_ctab8[t0][t1];
+ codeLength = LO_LTAB(FDKaacEnc_huff_ltab7_8[t0][t1]);
+ FDKwriteBits(hBitstream, (codeWord << signLength) | sign,
+ codeLength + signLength);
+ }
+ break;
+
+ case CODE_BOOK_9_NO:
+ for (i = 0; i < (width >> 1); i++) {
+ t0 = *values++;
+ sign = ((UINT)t0 >> 31);
+ t0 = fixp_abs(t0);
+ signLength = (t0 == 0) ? 0 : 1;
+ t1 = *values++;
+ INT zero = (t1 == 0) ? 0 : 1;
+ signLength += zero;
+ sign = (sign << zero) + ((UINT)t1 >> 31);
+ t1 = fixp_abs(t1);
+ codeWord = FDKaacEnc_huff_ctab9[t0][t1];
+ codeLength = HI_LTAB(FDKaacEnc_huff_ltab9_10[t0][t1]);
+ FDKwriteBits(hBitstream, (codeWord << signLength) | sign,
+ codeLength + signLength);
+ }
+ break;
+
+ case CODE_BOOK_10_NO:
+ for (i = 0; i < (width >> 1); i++) {
+ t0 = *values++;
+ sign = ((UINT)t0 >> 31);
+ t0 = fixp_abs(t0);
+ signLength = (t0 == 0) ? 0 : 1;
+ t1 = *values++;
+ INT zero = (t1 == 0) ? 0 : 1;
+ signLength += zero;
+ sign = (sign << zero) + ((UINT)t1 >> 31);
+ t1 = fixp_abs(t1);
+ codeWord = FDKaacEnc_huff_ctab10[t0][t1];
+ codeLength = LO_LTAB(FDKaacEnc_huff_ltab9_10[t0][t1]);
+ FDKwriteBits(hBitstream, (codeWord << signLength) | sign,
+ codeLength + signLength);
+ }
+ break;
+
+ case CODE_BOOK_ESC_NO:
+ for (i = 0; i < (width >> 1); i++) {
+ t0 = *values++;
+ sign = ((UINT)t0 >> 31);
+ t0 = fixp_abs(t0);
+ signLength = (t0 == 0) ? 0 : 1;
+ t1 = *values++;
+ INT zero = (t1 == 0) ? 0 : 1;
+ signLength += zero;
+ sign = (sign << zero) + ((UINT)t1 >> 31);
+ t1 = fixp_abs(t1);
+
+ t00 = fixMin(t0, 16);
+ t01 = fixMin(t1, 16);
+
+ codeWord = FDKaacEnc_huff_ctab11[t00][t01];
+ codeLength = (INT)FDKaacEnc_huff_ltab11[t00][t01];
+ FDKwriteBits(hBitstream, (codeWord << signLength) | sign,
+ codeLength + signLength);
+ for (int j = 0; j < 2; j++) {
+ if (t0 >= 16) {
+ INT n = 4, p = t0;
+ for (; (p >>= 1) >= 16;) n++;
+ FDKwriteBits(hBitstream,
+ (((1 << (n - 3)) - 2) << n) | (t0 - (1 << n)),
+ n + n - 3);
+ }
+ t0 = t1;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return (0);
+}
+
+INT FDKaacEnc_codeScalefactorDelta(INT delta, HANDLE_FDK_BITSTREAM hBitstream) {
+ INT codeWord, codeLength;
+
+ if (fixp_abs(delta) > CODE_BOOK_SCF_LAV) return (1);
+
+ codeWord = FDKaacEnc_huff_ctabscf[delta + CODE_BOOK_SCF_LAV];
+ codeLength = (INT)FDKaacEnc_huff_ltabscf[delta + CODE_BOOK_SCF_LAV];
+ FDKwriteBits(hBitstream, codeWord, codeLength);
+ return (0);
+}
diff --git a/fdk-aac/libAACenc/src/bit_cnt.h b/fdk-aac/libAACenc/src/bit_cnt.h
new file mode 100644
index 0000000..7f4c450
--- /dev/null
+++ b/fdk-aac/libAACenc/src/bit_cnt.h
@@ -0,0 +1,200 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Huffman Bitcounter & coder
+
+*******************************************************************************/
+
+#ifndef BIT_CNT_H
+#define BIT_CNT_H
+
+#include "common_fix.h"
+#include "FDK_bitstream.h"
+#include "aacEnc_rom.h"
+
+#define INVALID_BITCOUNT (FDK_INT_MAX / 4)
+
+/*
+ code book number table
+*/
+
+enum codeBookNo {
+ CODE_BOOK_ZERO_NO = 0,
+ CODE_BOOK_1_NO = 1,
+ CODE_BOOK_2_NO = 2,
+ CODE_BOOK_3_NO = 3,
+ CODE_BOOK_4_NO = 4,
+ CODE_BOOK_5_NO = 5,
+ CODE_BOOK_6_NO = 6,
+ CODE_BOOK_7_NO = 7,
+ CODE_BOOK_8_NO = 8,
+ CODE_BOOK_9_NO = 9,
+ CODE_BOOK_10_NO = 10,
+ CODE_BOOK_ESC_NO = 11,
+ CODE_BOOK_RES_NO = 12,
+ CODE_BOOK_PNS_NO = 13,
+ CODE_BOOK_IS_OUT_OF_PHASE_NO = 14,
+ CODE_BOOK_IS_IN_PHASE_NO = 15
+
+};
+
+/*
+ code book index table
+*/
+
+enum codeBookNdx {
+ CODE_BOOK_ZERO_NDX,
+ CODE_BOOK_1_NDX,
+ CODE_BOOK_2_NDX,
+ CODE_BOOK_3_NDX,
+ CODE_BOOK_4_NDX,
+ CODE_BOOK_5_NDX,
+ CODE_BOOK_6_NDX,
+ CODE_BOOK_7_NDX,
+ CODE_BOOK_8_NDX,
+ CODE_BOOK_9_NDX,
+ CODE_BOOK_10_NDX,
+ CODE_BOOK_ESC_NDX,
+ CODE_BOOK_RES_NDX,
+ CODE_BOOK_PNS_NDX,
+ CODE_BOOK_IS_OUT_OF_PHASE_NDX,
+ CODE_BOOK_IS_IN_PHASE_NDX,
+ NUMBER_OF_CODE_BOOKS
+};
+
+/*
+ code book lav table
+*/
+
+enum codeBookLav {
+ CODE_BOOK_ZERO_LAV = 0,
+ CODE_BOOK_1_LAV = 1,
+ CODE_BOOK_2_LAV = 1,
+ CODE_BOOK_3_LAV = 2,
+ CODE_BOOK_4_LAV = 2,
+ CODE_BOOK_5_LAV = 4,
+ CODE_BOOK_6_LAV = 4,
+ CODE_BOOK_7_LAV = 7,
+ CODE_BOOK_8_LAV = 7,
+ CODE_BOOK_9_LAV = 12,
+ CODE_BOOK_10_LAV = 12,
+ CODE_BOOK_ESC_LAV = 16,
+ CODE_BOOK_SCF_LAV = 60,
+ CODE_BOOK_PNS_LAV = 60
+};
+
+INT FDKaacEnc_bitCount(const SHORT *aQuantSpectrum, const INT noOfSpecLines,
+ INT maxVal, INT *bitCountLut);
+
+INT FDKaacEnc_countValues(SHORT *values, INT width, INT codeBook);
+
+INT FDKaacEnc_codeValues(SHORT *values, INT width, INT codeBook,
+ HANDLE_FDK_BITSTREAM hBitstream);
+
+INT FDKaacEnc_codeScalefactorDelta(INT scalefactor,
+ HANDLE_FDK_BITSTREAM hBitstream);
+
+inline INT FDKaacEnc_bitCountScalefactorDelta(const INT delta) {
+ FDK_ASSERT((0 <= (delta + CODE_BOOK_SCF_LAV)) &&
+ ((delta + CODE_BOOK_SCF_LAV) <
+ (int)(sizeof(FDKaacEnc_huff_ltabscf) /
+ sizeof((FDKaacEnc_huff_ltabscf[0])))));
+ return ((INT)FDKaacEnc_huff_ltabscf[delta + CODE_BOOK_SCF_LAV]);
+}
+
+#endif
diff --git a/fdk-aac/libAACenc/src/bitenc.cpp b/fdk-aac/libAACenc/src/bitenc.cpp
new file mode 100644
index 0000000..512d596
--- /dev/null
+++ b/fdk-aac/libAACenc/src/bitenc.cpp
@@ -0,0 +1,1362 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Bitstream encoder
+
+*******************************************************************************/
+
+#include <stdio.h>
+#include "bitenc.h"
+#include "bit_cnt.h"
+#include "dyn_bits.h"
+#include "qc_data.h"
+#include "interface.h"
+#include "aacEnc_ram.h"
+
+#include "tpenc_lib.h"
+
+#include "FDK_tools_rom.h" /* needed for the bitstream syntax tables */
+
+static const int globalGainOffset = 100;
+static const int icsReservedBit = 0;
+static const int noiseOffset = 90;
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_encodeSpectralData
+ description: encode spectral data
+ returns: the number of written bits
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_encodeSpectralData(INT *sfbOffset,
+ SECTION_DATA *sectionData,
+ SHORT *quantSpectrum,
+ HANDLE_FDK_BITSTREAM hBitStream) {
+ INT i, sfb;
+ INT dbgVal = FDKgetValidBits(hBitStream);
+
+ for (i = 0; i < sectionData->noOfSections; i++) {
+ if (sectionData->huffsection[i].codeBook != CODE_BOOK_PNS_NO) {
+ /* huffencode spectral data for this huffsection */
+ INT tmp = sectionData->huffsection[i].sfbStart +
+ sectionData->huffsection[i].sfbCnt;
+ for (sfb = sectionData->huffsection[i].sfbStart; sfb < tmp; sfb++) {
+ FDKaacEnc_codeValues(quantSpectrum + sfbOffset[sfb],
+ sfbOffset[sfb + 1] - sfbOffset[sfb],
+ sectionData->huffsection[i].codeBook, hBitStream);
+ }
+ }
+ }
+ return (FDKgetValidBits(hBitStream) - dbgVal);
+}
+
+/*****************************************************************************
+
+ functionname:FDKaacEnc_encodeGlobalGain
+ description: encodes Global Gain (common scale factor)
+ returns: the number of static bits
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_encodeGlobalGain(INT globalGain, INT scalefac,
+ HANDLE_FDK_BITSTREAM hBitStream,
+ INT mdctScale) {
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream,
+ globalGain - scalefac + globalGainOffset -
+ 4 * (LOG_NORM_PCM - mdctScale),
+ 8);
+ }
+ return (8);
+}
+
+/*****************************************************************************
+
+ functionname:FDKaacEnc_encodeIcsInfo
+ description: encodes Ics Info
+ returns: the number of static bits
+ input:
+ output:
+
+*****************************************************************************/
+
+static INT FDKaacEnc_encodeIcsInfo(INT blockType, INT windowShape,
+ INT groupingMask, INT maxSfbPerGroup,
+ HANDLE_FDK_BITSTREAM hBitStream,
+ UINT syntaxFlags) {
+ INT statBits;
+
+ if (blockType == SHORT_WINDOW) {
+ statBits = 8 + TRANS_FAC - 1;
+ } else {
+ if (syntaxFlags & AC_ELD) {
+ statBits = 6;
+ } else {
+ statBits = (!(syntaxFlags & AC_SCALABLE)) ? 11 : 10;
+ }
+ }
+
+ if (hBitStream != NULL) {
+ if (!(syntaxFlags & AC_ELD)) {
+ FDKwriteBits(hBitStream, icsReservedBit, 1);
+ FDKwriteBits(hBitStream, blockType, 2);
+ FDKwriteBits(hBitStream,
+ (windowShape == LOL_WINDOW) ? KBD_WINDOW : windowShape, 1);
+ }
+
+ switch (blockType) {
+ case LONG_WINDOW:
+ case START_WINDOW:
+ case STOP_WINDOW:
+ FDKwriteBits(hBitStream, maxSfbPerGroup, 6);
+
+ if (!(syntaxFlags &
+ (AC_SCALABLE | AC_ELD))) { /* If not scalable syntax then ... */
+ /* No predictor data present */
+ FDKwriteBits(hBitStream, 0, 1);
+ }
+ break;
+
+ case SHORT_WINDOW:
+ FDKwriteBits(hBitStream, maxSfbPerGroup, 4);
+
+ /* Write grouping bits */
+ FDKwriteBits(hBitStream, groupingMask, TRANS_FAC - 1);
+ break;
+ }
+ }
+
+ return (statBits);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_encodeSectionData
+ description: encode section data (common Huffman codebooks for adjacent
+ SFB's)
+ returns: none
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_encodeSectionData(SECTION_DATA *sectionData,
+ HANDLE_FDK_BITSTREAM hBitStream,
+ UINT useVCB11) {
+ if (hBitStream != NULL) {
+ INT sectEscapeVal = 0, sectLenBits = 0;
+ INT sectLen;
+ INT i;
+ INT dbgVal = FDKgetValidBits(hBitStream);
+ INT sectCbBits = 4;
+
+ switch (sectionData->blockType) {
+ case LONG_WINDOW:
+ case START_WINDOW:
+ case STOP_WINDOW:
+ sectEscapeVal = SECT_ESC_VAL_LONG;
+ sectLenBits = SECT_BITS_LONG;
+ break;
+
+ case SHORT_WINDOW:
+ sectEscapeVal = SECT_ESC_VAL_SHORT;
+ sectLenBits = SECT_BITS_SHORT;
+ break;
+ }
+
+ for (i = 0; i < sectionData->noOfSections; i++) {
+ INT codeBook = sectionData->huffsection[i].codeBook;
+
+ FDKwriteBits(hBitStream, codeBook, sectCbBits);
+
+ {
+ sectLen = sectionData->huffsection[i].sfbCnt;
+
+ while (sectLen >= sectEscapeVal) {
+ FDKwriteBits(hBitStream, sectEscapeVal, sectLenBits);
+ sectLen -= sectEscapeVal;
+ }
+ FDKwriteBits(hBitStream, sectLen, sectLenBits);
+ }
+ }
+ return (FDKgetValidBits(hBitStream) - dbgVal);
+ }
+ return (0);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_encodeScaleFactorData
+ description: encode DPCM coded scale factors
+ returns: none
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_encodeScaleFactorData(UINT *maxValueInSfb,
+ SECTION_DATA *sectionData,
+ INT *scalefac,
+ HANDLE_FDK_BITSTREAM hBitStream,
+ INT *RESTRICT noiseNrg,
+ const INT *isScale, INT globalGain) {
+ if (hBitStream != NULL) {
+ INT i, j, lastValScf, deltaScf;
+ INT deltaPns;
+ INT lastValPns = 0;
+ INT noisePCMFlag = TRUE;
+ INT lastValIs;
+
+ INT dbgVal = FDKgetValidBits(hBitStream);
+
+ lastValScf = scalefac[sectionData->firstScf];
+ lastValPns = globalGain - scalefac[sectionData->firstScf] +
+ globalGainOffset - 4 * LOG_NORM_PCM - noiseOffset;
+ lastValIs = 0;
+
+ for (i = 0; i < sectionData->noOfSections; i++) {
+ if (sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) {
+ if ((sectionData->huffsection[i].codeBook ==
+ CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
+ (sectionData->huffsection[i].codeBook ==
+ CODE_BOOK_IS_IN_PHASE_NO)) {
+ INT sfbStart = sectionData->huffsection[i].sfbStart;
+ INT tmp = sfbStart + sectionData->huffsection[i].sfbCnt;
+ for (j = sfbStart; j < tmp; j++) {
+ INT deltaIs = isScale[j] - lastValIs;
+ lastValIs = isScale[j];
+ if (FDKaacEnc_codeScalefactorDelta(deltaIs, hBitStream)) {
+ return (1);
+ }
+ } /* sfb */
+ } else if (sectionData->huffsection[i].codeBook == CODE_BOOK_PNS_NO) {
+ INT sfbStart = sectionData->huffsection[i].sfbStart;
+ INT tmp = sfbStart + sectionData->huffsection[i].sfbCnt;
+ for (j = sfbStart; j < tmp; j++) {
+ deltaPns = noiseNrg[j] - lastValPns;
+ lastValPns = noiseNrg[j];
+
+ if (noisePCMFlag) {
+ FDKwriteBits(hBitStream, deltaPns + (1 << (PNS_PCM_BITS - 1)),
+ PNS_PCM_BITS);
+ noisePCMFlag = FALSE;
+ } else {
+ if (FDKaacEnc_codeScalefactorDelta(deltaPns, hBitStream)) {
+ return (1);
+ }
+ }
+ } /* sfb */
+ } else {
+ INT tmp = sectionData->huffsection[i].sfbStart +
+ sectionData->huffsection[i].sfbCnt;
+ for (j = sectionData->huffsection[i].sfbStart; j < tmp; j++) {
+ /*
+ check if we can repeat the last value to save bits
+ */
+ if (maxValueInSfb[j] == 0)
+ deltaScf = 0;
+ else {
+ deltaScf = -(scalefac[j] - lastValScf);
+ lastValScf = scalefac[j];
+ }
+ if (FDKaacEnc_codeScalefactorDelta(deltaScf, hBitStream)) {
+ return (1);
+ }
+ } /* sfb */
+ } /* code scalefactor */
+ } /* sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO */
+ } /* section loop */
+
+ return (FDKgetValidBits(hBitStream) - dbgVal);
+ } /* if (hBitStream != NULL) */
+
+ return (0);
+}
+
+/*****************************************************************************
+
+ functionname:encodeMsInfo
+ description: encodes MS-Stereo Info
+ returns: the number of static bits
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_encodeMSInfo(INT sfbCnt, INT grpSfb, INT maxSfb,
+ INT msDigest, INT *jsFlags,
+ HANDLE_FDK_BITSTREAM hBitStream) {
+ INT sfb, sfbOff, msBits = 0;
+
+ if (hBitStream != NULL) {
+ switch (msDigest) {
+ case MS_NONE:
+ FDKwriteBits(hBitStream, SI_MS_MASK_NONE, 2);
+ msBits += 2;
+ break;
+
+ case MS_ALL:
+ FDKwriteBits(hBitStream, SI_MS_MASK_ALL, 2);
+ msBits += 2;
+ break;
+
+ case MS_SOME:
+ FDKwriteBits(hBitStream, SI_MS_MASK_SOME, 2);
+ msBits += 2;
+ for (sfbOff = 0; sfbOff < sfbCnt; sfbOff += grpSfb) {
+ for (sfb = 0; sfb < maxSfb; sfb++) {
+ if (jsFlags[sfbOff + sfb] & MS_ON) {
+ FDKwriteBits(hBitStream, 1, 1);
+ } else {
+ FDKwriteBits(hBitStream, 0, 1);
+ }
+ msBits += 1;
+ }
+ }
+ break;
+ }
+ } else {
+ msBits += 2;
+ if (msDigest == MS_SOME) {
+ for (sfbOff = 0; sfbOff < sfbCnt; sfbOff += grpSfb) {
+ for (sfb = 0; sfb < maxSfb; sfb++) {
+ msBits += 1;
+ }
+ }
+ }
+ }
+ return (msBits);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_encodeTnsDataPresent
+ description: encode TNS data (filter order, coeffs, ..)
+ returns: the number of static bits
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_encodeTnsDataPresent(TNS_INFO *tnsInfo, INT blockType,
+ HANDLE_FDK_BITSTREAM hBitStream) {
+ if ((hBitStream != NULL) && (tnsInfo != NULL)) {
+ INT i, tnsPresent = 0;
+ INT numOfWindows = (blockType == SHORT_WINDOW ? TRANS_FAC : 1);
+
+ for (i = 0; i < numOfWindows; i++) {
+ if (tnsInfo->numOfFilters[i] != 0) {
+ tnsPresent = 1;
+ break;
+ }
+ }
+
+ if (tnsPresent == 0) {
+ FDKwriteBits(hBitStream, 0, 1);
+ } else {
+ FDKwriteBits(hBitStream, 1, 1);
+ }
+ }
+ return (1);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_encodeTnsData
+ description: encode TNS data (filter order, coeffs, ..)
+ returns: the number of static bits
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_encodeTnsData(TNS_INFO *tnsInfo, INT blockType,
+ HANDLE_FDK_BITSTREAM hBitStream) {
+ INT tnsBits = 0;
+
+ if (tnsInfo != NULL) {
+ INT i, j, k;
+ INT tnsPresent = 0;
+ INT coefBits;
+ INT numOfWindows = (blockType == SHORT_WINDOW ? TRANS_FAC : 1);
+
+ for (i = 0; i < numOfWindows; i++) {
+ if (tnsInfo->numOfFilters[i] != 0) {
+ tnsPresent = 1;
+ }
+ }
+
+ if (hBitStream != NULL) {
+ if (tnsPresent == 1) { /* there is data to be written*/
+ for (i = 0; i < numOfWindows; i++) {
+ FDKwriteBits(hBitStream, tnsInfo->numOfFilters[i],
+ (blockType == SHORT_WINDOW ? 1 : 2));
+ tnsBits += (blockType == SHORT_WINDOW ? 1 : 2);
+ if (tnsInfo->numOfFilters[i]) {
+ FDKwriteBits(hBitStream, (tnsInfo->coefRes[i] == 4 ? 1 : 0), 1);
+ tnsBits += 1;
+ }
+ for (j = 0; j < tnsInfo->numOfFilters[i]; j++) {
+ FDKwriteBits(hBitStream, tnsInfo->length[i][j],
+ (blockType == SHORT_WINDOW ? 4 : 6));
+ tnsBits += (blockType == SHORT_WINDOW ? 4 : 6);
+ FDK_ASSERT(tnsInfo->order[i][j] <= 12);
+ FDKwriteBits(hBitStream, tnsInfo->order[i][j],
+ (blockType == SHORT_WINDOW ? 3 : 5));
+ tnsBits += (blockType == SHORT_WINDOW ? 3 : 5);
+ if (tnsInfo->order[i][j]) {
+ FDKwriteBits(hBitStream, tnsInfo->direction[i][j], 1);
+ tnsBits += 1; /*direction*/
+ if (tnsInfo->coefRes[i] == 4) {
+ coefBits = 3;
+ for (k = 0; k < tnsInfo->order[i][j]; k++) {
+ if (tnsInfo->coef[i][j][k] > 3 ||
+ tnsInfo->coef[i][j][k] < -4) {
+ coefBits = 4;
+ break;
+ }
+ }
+ } else {
+ coefBits = 2;
+ for (k = 0; k < tnsInfo->order[i][j]; k++) {
+ if (tnsInfo->coef[i][j][k] > 1 ||
+ tnsInfo->coef[i][j][k] < -2) {
+ coefBits = 3;
+ break;
+ }
+ }
+ }
+ FDKwriteBits(hBitStream, -(coefBits - tnsInfo->coefRes[i]),
+ 1); /*coef_compres*/
+ tnsBits += 1; /*coef_compression */
+ for (k = 0; k < tnsInfo->order[i][j]; k++) {
+ static const INT rmask[] = {0, 1, 3, 7, 15};
+ FDKwriteBits(hBitStream,
+ tnsInfo->coef[i][j][k] & rmask[coefBits],
+ coefBits);
+ tnsBits += coefBits;
+ }
+ }
+ }
+ }
+ }
+ } else {
+ if (tnsPresent != 0) {
+ for (i = 0; i < numOfWindows; i++) {
+ tnsBits += (blockType == SHORT_WINDOW ? 1 : 2);
+ if (tnsInfo->numOfFilters[i]) {
+ tnsBits += 1;
+ for (j = 0; j < tnsInfo->numOfFilters[i]; j++) {
+ tnsBits += (blockType == SHORT_WINDOW ? 4 : 6);
+ tnsBits += (blockType == SHORT_WINDOW ? 3 : 5);
+ if (tnsInfo->order[i][j]) {
+ tnsBits += 1; /*direction*/
+ tnsBits += 1; /*coef_compression */
+ if (tnsInfo->coefRes[i] == 4) {
+ coefBits = 3;
+ for (k = 0; k < tnsInfo->order[i][j]; k++) {
+ if (tnsInfo->coef[i][j][k] > 3 ||
+ tnsInfo->coef[i][j][k] < -4) {
+ coefBits = 4;
+ break;
+ }
+ }
+ } else {
+ coefBits = 2;
+ for (k = 0; k < tnsInfo->order[i][j]; k++) {
+ if (tnsInfo->coef[i][j][k] > 1 ||
+ tnsInfo->coef[i][j][k] < -2) {
+ coefBits = 3;
+ break;
+ }
+ }
+ }
+ for (k = 0; k < tnsInfo->order[i][j]; k++) {
+ tnsBits += coefBits;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } /* (tnsInfo!=NULL) */
+
+ return (tnsBits);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_encodeGainControlData
+ description: unsupported
+ returns: none
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_encodeGainControlData(HANDLE_FDK_BITSTREAM hBitStream) {
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream, 0, 1);
+ }
+ return (1);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_encodePulseData
+ description: not supported yet (dummy)
+ returns: none
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_encodePulseData(HANDLE_FDK_BITSTREAM hBitStream) {
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream, 0, 1);
+ }
+ return (1);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_writeExtensionPayload
+ description: write extension payload to bitstream
+ returns: number of written bits
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_writeExtensionPayload(HANDLE_FDK_BITSTREAM hBitStream,
+ EXT_PAYLOAD_TYPE extPayloadType,
+ const UCHAR *extPayloadData,
+ INT extPayloadBits) {
+#define EXT_TYPE_BITS (4)
+#define DATA_EL_VERSION_BITS (4)
+#define FILL_NIBBLE_BITS (4)
+
+ INT extBitsUsed = 0;
+
+ if (extPayloadBits >= EXT_TYPE_BITS) {
+ UCHAR fillByte = 0x00; /* for EXT_FIL and EXT_FILL_DATA */
+
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream, extPayloadType, EXT_TYPE_BITS);
+ }
+ extBitsUsed += EXT_TYPE_BITS;
+
+ switch (extPayloadType) {
+ /* case EXT_SAC_DATA: */
+ case EXT_LDSAC_DATA:
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream, *extPayloadData++, 4); /* nibble */
+ }
+ extBitsUsed += 4;
+ FDK_FALLTHROUGH;
+ case EXT_DYNAMIC_RANGE:
+ case EXT_SBR_DATA:
+ case EXT_SBR_DATA_CRC:
+ if (hBitStream != NULL) {
+ int i, writeBits = extPayloadBits;
+ for (i = 0; writeBits >= 8; i++) {
+ FDKwriteBits(hBitStream, *extPayloadData++, 8);
+ writeBits -= 8;
+ }
+ if (writeBits > 0) {
+ FDKwriteBits(hBitStream, (*extPayloadData) >> (8 - writeBits),
+ writeBits);
+ }
+ }
+ extBitsUsed += extPayloadBits;
+ break;
+
+ case EXT_DATA_ELEMENT: {
+ INT dataElementLength = (extPayloadBits + 7) >> 3;
+ INT cnt = dataElementLength;
+ int loopCounter = 1;
+
+ while (dataElementLength >= 255) {
+ loopCounter++;
+ dataElementLength -= 255;
+ }
+
+ if (hBitStream != NULL) {
+ int i;
+ FDKwriteBits(
+ hBitStream, 0x00,
+ DATA_EL_VERSION_BITS); /* data_element_version = ANC_DATA */
+
+ for (i = 1; i < loopCounter; i++) {
+ FDKwriteBits(hBitStream, 255, 8);
+ }
+ FDKwriteBits(hBitStream, dataElementLength, 8);
+
+ for (i = 0; i < cnt; i++) {
+ FDKwriteBits(hBitStream, extPayloadData[i], 8);
+ }
+ }
+ extBitsUsed += DATA_EL_VERSION_BITS + (loopCounter * 8) + (cnt * 8);
+ } break;
+
+ case EXT_FILL_DATA:
+ fillByte = 0xA5;
+ FDK_FALLTHROUGH;
+ case EXT_FIL:
+ default:
+ if (hBitStream != NULL) {
+ int writeBits = extPayloadBits;
+ FDKwriteBits(hBitStream, 0x00, FILL_NIBBLE_BITS);
+ writeBits -=
+ 8; /* acount for the extension type and the fill nibble */
+ while (writeBits >= 8) {
+ FDKwriteBits(hBitStream, fillByte, 8);
+ writeBits -= 8;
+ }
+ }
+ extBitsUsed += FILL_NIBBLE_BITS + (extPayloadBits & ~0x7) - 8;
+ break;
+ }
+ }
+
+ return (extBitsUsed);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_writeDataStreamElement
+ description: write data stream elements like ancillary data ...
+ returns: the amount of used bits
+ input:
+ output:
+
+******************************************************************************/
+static INT FDKaacEnc_writeDataStreamElement(HANDLE_TRANSPORTENC hTpEnc,
+ INT elementInstanceTag,
+ INT dataPayloadBytes,
+ UCHAR *dataBuffer,
+ UINT alignAnchor) {
+#define DATA_BYTE_ALIGN_FLAG (0)
+
+#define EL_INSTANCE_TAG_BITS (4)
+#define DATA_BYTE_ALIGN_FLAG_BITS (1)
+#define DATA_LEN_COUNT_BITS (8)
+#define DATA_LEN_ESC_COUNT_BITS (8)
+
+#define MAX_DATA_ALIGN_BITS (7)
+#define MAX_DSE_DATA_BYTES (510)
+
+ INT dseBitsUsed = 0;
+
+ while (dataPayloadBytes > 0) {
+ int esc_count = -1;
+ int cnt = 0;
+ INT crcReg = -1;
+
+ dseBitsUsed += EL_ID_BITS + EL_INSTANCE_TAG_BITS +
+ DATA_BYTE_ALIGN_FLAG_BITS + DATA_LEN_COUNT_BITS;
+
+ if (DATA_BYTE_ALIGN_FLAG) {
+ dseBitsUsed += MAX_DATA_ALIGN_BITS;
+ }
+
+ cnt = fixMin(MAX_DSE_DATA_BYTES, dataPayloadBytes);
+ if (cnt >= 255) {
+ esc_count = cnt - 255;
+ dseBitsUsed += DATA_LEN_ESC_COUNT_BITS;
+ }
+
+ dataPayloadBytes -= cnt;
+ dseBitsUsed += cnt * 8;
+
+ if (hTpEnc != NULL) {
+ HANDLE_FDK_BITSTREAM hBitStream = transportEnc_GetBitstream(hTpEnc);
+ int i;
+
+ FDKwriteBits(hBitStream, ID_DSE, EL_ID_BITS);
+
+ crcReg = transportEnc_CrcStartReg(hTpEnc, 0);
+
+ FDKwriteBits(hBitStream, elementInstanceTag, EL_INSTANCE_TAG_BITS);
+ FDKwriteBits(hBitStream, DATA_BYTE_ALIGN_FLAG, DATA_BYTE_ALIGN_FLAG_BITS);
+
+ /* write length field(s) */
+ if (esc_count >= 0) {
+ FDKwriteBits(hBitStream, 255, DATA_LEN_COUNT_BITS);
+ FDKwriteBits(hBitStream, esc_count, DATA_LEN_ESC_COUNT_BITS);
+ } else {
+ FDKwriteBits(hBitStream, cnt, DATA_LEN_COUNT_BITS);
+ }
+
+ if (DATA_BYTE_ALIGN_FLAG) {
+ INT tmp = (INT)FDKgetValidBits(hBitStream);
+ FDKbyteAlign(hBitStream, alignAnchor);
+ /* count actual bits */
+ dseBitsUsed +=
+ (INT)FDKgetValidBits(hBitStream) - tmp - MAX_DATA_ALIGN_BITS;
+ }
+
+ /* write payload */
+ for (i = 0; i < cnt; i++) {
+ FDKwriteBits(hBitStream, dataBuffer[i], 8);
+ }
+ transportEnc_CrcEndReg(hTpEnc, crcReg);
+ }
+ }
+
+ return (dseBitsUsed);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_writeExtensionData
+ description: write extension payload to bitstream
+ returns: number of written bits
+ input:
+ output:
+
+*****************************************************************************/
+INT FDKaacEnc_writeExtensionData(HANDLE_TRANSPORTENC hTpEnc,
+ QC_OUT_EXTENSION *pExtension,
+ INT elInstanceTag, /* for DSE only */
+ UINT alignAnchor, /* for DSE only */
+ UINT syntaxFlags, AUDIO_OBJECT_TYPE aot,
+ SCHAR epConfig) {
+#define FILL_EL_COUNT_BITS (4)
+#define FILL_EL_ESC_COUNT_BITS (8)
+#define MAX_FILL_DATA_BYTES (269)
+
+ HANDLE_FDK_BITSTREAM hBitStream = NULL;
+ INT payloadBits = pExtension->nPayloadBits;
+ INT extBitsUsed = 0;
+
+ if (hTpEnc != NULL) {
+ hBitStream = transportEnc_GetBitstream(hTpEnc);
+ }
+
+ if (syntaxFlags & (AC_SCALABLE | AC_ER)) {
+ {
+ if ((syntaxFlags & AC_ELD) && ((pExtension->type == EXT_SBR_DATA) ||
+ (pExtension->type == EXT_SBR_DATA_CRC))) {
+ if (hBitStream != NULL) {
+ int i, writeBits = payloadBits;
+ UCHAR *extPayloadData = pExtension->pPayload;
+
+ for (i = 0; writeBits >= 8; i++) {
+ FDKwriteBits(hBitStream, extPayloadData[i], 8);
+ writeBits -= 8;
+ }
+ if (writeBits > 0) {
+ FDKwriteBits(hBitStream, extPayloadData[i] >> (8 - writeBits),
+ writeBits);
+ }
+ }
+ extBitsUsed += payloadBits;
+ } else {
+ /* ER or scalable syntax -> write extension en bloc */
+ extBitsUsed += FDKaacEnc_writeExtensionPayload(
+ hBitStream, pExtension->type, pExtension->pPayload, payloadBits);
+ }
+ }
+ } else {
+ /* We have normal GA bitstream payload (AOT 2,5,29) so pack
+ the data into a fill elements or DSEs */
+
+ if (pExtension->type == EXT_DATA_ELEMENT) {
+ extBitsUsed += FDKaacEnc_writeDataStreamElement(
+ hTpEnc, elInstanceTag, pExtension->nPayloadBits >> 3,
+ pExtension->pPayload, alignAnchor);
+ } else {
+ while (payloadBits >= (EL_ID_BITS + FILL_EL_COUNT_BITS)) {
+ INT cnt, esc_count = -1, alignBits = 7;
+
+ if ((pExtension->type == EXT_FILL_DATA) ||
+ (pExtension->type == EXT_FIL)) {
+ payloadBits -= EL_ID_BITS + FILL_EL_COUNT_BITS;
+ if (payloadBits >= 15 * 8) {
+ payloadBits -= FILL_EL_ESC_COUNT_BITS;
+ esc_count = 0; /* write esc_count even if cnt becomes smaller 15 */
+ }
+ alignBits = 0;
+ }
+
+ cnt = fixMin(MAX_FILL_DATA_BYTES, (payloadBits + alignBits) >> 3);
+
+ if (cnt >= 15) {
+ esc_count = cnt - 15 + 1;
+ }
+
+ if (hBitStream != NULL) {
+ /* write bitstream */
+ FDKwriteBits(hBitStream, ID_FIL, EL_ID_BITS);
+ if (esc_count >= 0) {
+ FDKwriteBits(hBitStream, 15, FILL_EL_COUNT_BITS);
+ FDKwriteBits(hBitStream, esc_count, FILL_EL_ESC_COUNT_BITS);
+ } else {
+ FDKwriteBits(hBitStream, cnt, FILL_EL_COUNT_BITS);
+ }
+ }
+
+ extBitsUsed += EL_ID_BITS + FILL_EL_COUNT_BITS +
+ ((esc_count >= 0) ? FILL_EL_ESC_COUNT_BITS : 0);
+
+ cnt = fixMin(cnt * 8, payloadBits); /* convert back to bits */
+ extBitsUsed += FDKaacEnc_writeExtensionPayload(
+ hBitStream, pExtension->type, pExtension->pPayload, cnt);
+ payloadBits -= cnt;
+ }
+ }
+ }
+
+ return (extBitsUsed);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_ByteAlignment
+ description:
+ returns:
+ input:
+ output:
+
+*****************************************************************************/
+static void FDKaacEnc_ByteAlignment(HANDLE_FDK_BITSTREAM hBitStream,
+ int alignBits) {
+ FDKwriteBits(hBitStream, 0, alignBits);
+}
+
+AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite(
+ HANDLE_TRANSPORTENC hTpEnc, ELEMENT_INFO *pElInfo,
+ QC_OUT_CHANNEL *qcOutChannel[(2)], PSY_OUT_ELEMENT *psyOutElement,
+ PSY_OUT_CHANNEL *psyOutChannel[(2)], UINT syntaxFlags,
+ AUDIO_OBJECT_TYPE aot, SCHAR epConfig, INT *pBitDemand, UCHAR minCnt) {
+ AAC_ENCODER_ERROR error = AAC_ENC_OK;
+ HANDLE_FDK_BITSTREAM hBitStream = NULL;
+ INT bitDemand = 0;
+ const element_list_t *list;
+ int i, ch, decision_bit;
+ INT crcReg1 = -1, crcReg2 = -1;
+ UCHAR numberOfChannels;
+
+ if (hTpEnc != NULL) {
+ /* Get bitstream handle */
+ hBitStream = transportEnc_GetBitstream(hTpEnc);
+ }
+
+ if ((pElInfo->elType == ID_SCE) || (pElInfo->elType == ID_LFE)) {
+ numberOfChannels = 1;
+ } else {
+ numberOfChannels = 2;
+ }
+
+ /* Get channel element sequence table */
+ list = getBitstreamElementList(aot, epConfig, numberOfChannels, 0, 0);
+ if (list == NULL) {
+ error = AAC_ENC_UNSUPPORTED_AOT;
+ goto bail;
+ }
+
+ if (!(syntaxFlags & (AC_SCALABLE | AC_ER))) {
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream, pElInfo->elType, EL_ID_BITS);
+ }
+ bitDemand += EL_ID_BITS;
+ }
+
+ /* Iterate through sequence table */
+ i = 0;
+ ch = 0;
+ decision_bit = 0;
+ do {
+ /* some tmp values */
+ SECTION_DATA *pChSectionData = NULL;
+ INT *pChScf = NULL;
+ UINT *pChMaxValueInSfb = NULL;
+ TNS_INFO *pTnsInfo = NULL;
+ INT chGlobalGain = 0;
+ INT chBlockType = 0;
+ INT chMaxSfbPerGrp = 0;
+ INT chSfbPerGrp = 0;
+ INT chSfbCnt = 0;
+ INT chFirstScf = 0;
+
+ if (minCnt == 0) {
+ if (qcOutChannel != NULL) {
+ pChSectionData = &(qcOutChannel[ch]->sectionData);
+ pChScf = qcOutChannel[ch]->scf;
+ chGlobalGain = qcOutChannel[ch]->globalGain;
+ pChMaxValueInSfb = qcOutChannel[ch]->maxValueInSfb;
+ chBlockType = pChSectionData->blockType;
+ chMaxSfbPerGrp = pChSectionData->maxSfbPerGroup;
+ chSfbPerGrp = pChSectionData->sfbPerGroup;
+ chSfbCnt = pChSectionData->sfbCnt;
+ chFirstScf = pChScf[pChSectionData->firstScf];
+ } else {
+ /* get values from PSY */
+ chSfbCnt = psyOutChannel[ch]->sfbCnt;
+ chSfbPerGrp = psyOutChannel[ch]->sfbPerGroup;
+ chMaxSfbPerGrp = psyOutChannel[ch]->maxSfbPerGroup;
+ }
+ pTnsInfo = &psyOutChannel[ch]->tnsInfo;
+ } /* minCnt==0 */
+
+ if (qcOutChannel == NULL) {
+ chBlockType = psyOutChannel[ch]->lastWindowSequence;
+ }
+
+ switch (list->id[i]) {
+ case element_instance_tag:
+ /* Write element instance tag */
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream, pElInfo->instanceTag, 4);
+ }
+ bitDemand += 4;
+ break;
+
+ case common_window:
+ /* Write common window flag */
+ decision_bit = psyOutElement->commonWindow;
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream, psyOutElement->commonWindow, 1);
+ }
+ bitDemand += 1;
+ break;
+
+ case ics_info:
+ /* Write individual channel info */
+ bitDemand +=
+ FDKaacEnc_encodeIcsInfo(chBlockType, psyOutChannel[ch]->windowShape,
+ psyOutChannel[ch]->groupingMask,
+ chMaxSfbPerGrp, hBitStream, syntaxFlags);
+ break;
+
+ case ltp_data_present:
+ /* Write LTP data present flag */
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream, 0, 1);
+ }
+ bitDemand += 1;
+ break;
+
+ case ltp_data:
+ /* Predictor data not supported.
+ Nothing to do here. */
+ break;
+
+ case ms:
+ /* Write MS info */
+ bitDemand += FDKaacEnc_encodeMSInfo(
+ chSfbCnt, chSfbPerGrp, chMaxSfbPerGrp,
+ (minCnt == 0) ? psyOutElement->toolsInfo.msDigest : MS_NONE,
+ psyOutElement->toolsInfo.msMask, hBitStream);
+ break;
+
+ case global_gain:
+ bitDemand += FDKaacEnc_encodeGlobalGain(
+ chGlobalGain, chFirstScf, hBitStream, psyOutChannel[ch]->mdctScale);
+ break;
+
+ case section_data: {
+ INT siBits = FDKaacEnc_encodeSectionData(
+ pChSectionData, hBitStream, (syntaxFlags & AC_ER_VCB11) ? 1 : 0);
+ if (hBitStream != NULL) {
+ if (siBits != qcOutChannel[ch]->sectionData.sideInfoBits) {
+ error = AAC_ENC_WRITE_SEC_ERROR;
+ }
+ }
+ bitDemand += siBits;
+ } break;
+
+ case scale_factor_data: {
+ INT sfDataBits = FDKaacEnc_encodeScaleFactorData(
+ pChMaxValueInSfb, pChSectionData, pChScf, hBitStream,
+ psyOutChannel[ch]->noiseNrg, psyOutChannel[ch]->isScale,
+ chGlobalGain);
+ if ((hBitStream != NULL) &&
+ (sfDataBits != (qcOutChannel[ch]->sectionData.scalefacBits +
+ qcOutChannel[ch]->sectionData.noiseNrgBits))) {
+ error = AAC_ENC_WRITE_SCAL_ERROR;
+ }
+ bitDemand += sfDataBits;
+ } break;
+
+ case esc2_rvlc:
+ if (syntaxFlags & AC_ER_RVLC) {
+ /* write RVLC data into bitstream (error sens. cat. 2) */
+ error = AAC_ENC_UNSUPPORTED_AOT;
+ }
+ break;
+
+ case pulse:
+ /* Write pulse data */
+ bitDemand += FDKaacEnc_encodePulseData(hBitStream);
+ break;
+
+ case tns_data_present:
+ /* Write TNS data present flag */
+ bitDemand +=
+ FDKaacEnc_encodeTnsDataPresent(pTnsInfo, chBlockType, hBitStream);
+ break;
+ case tns_data:
+ /* Write TNS data */
+ bitDemand += FDKaacEnc_encodeTnsData(pTnsInfo, chBlockType, hBitStream);
+ break;
+
+ case gain_control_data:
+ /* Nothing to do here */
+ break;
+
+ case gain_control_data_present:
+ bitDemand += FDKaacEnc_encodeGainControlData(hBitStream);
+ break;
+
+ case esc1_hcr:
+ if (syntaxFlags & AC_ER_HCR) {
+ error = AAC_ENC_UNKNOWN;
+ }
+ break;
+
+ case spectral_data:
+ if (hBitStream != NULL) {
+ INT spectralBits = 0;
+
+ spectralBits = FDKaacEnc_encodeSpectralData(
+ psyOutChannel[ch]->sfbOffsets, pChSectionData,
+ qcOutChannel[ch]->quantSpec, hBitStream);
+
+ if (spectralBits != qcOutChannel[ch]->sectionData.huffmanBits) {
+ return AAC_ENC_WRITE_SPEC_ERROR;
+ }
+ bitDemand += spectralBits;
+ }
+ break;
+
+ /* Non data cases */
+ case adtscrc_start_reg1:
+ if (hTpEnc != NULL) {
+ crcReg1 = transportEnc_CrcStartReg(hTpEnc, 192);
+ }
+ break;
+ case adtscrc_start_reg2:
+ if (hTpEnc != NULL) {
+ crcReg2 = transportEnc_CrcStartReg(hTpEnc, 128);
+ }
+ break;
+ case adtscrc_end_reg1:
+ case drmcrc_end_reg:
+ if (hTpEnc != NULL) {
+ transportEnc_CrcEndReg(hTpEnc, crcReg1);
+ }
+ break;
+ case adtscrc_end_reg2:
+ if (hTpEnc != NULL) {
+ transportEnc_CrcEndReg(hTpEnc, crcReg2);
+ }
+ break;
+ case drmcrc_start_reg:
+ if (hTpEnc != NULL) {
+ crcReg1 = transportEnc_CrcStartReg(hTpEnc, 0);
+ }
+ break;
+ case next_channel:
+ ch = (ch + 1) % numberOfChannels;
+ break;
+ case link_sequence:
+ list = list->next[decision_bit];
+ i = -1;
+ break;
+
+ default:
+ error = AAC_ENC_UNKNOWN;
+ break;
+ }
+
+ if (error != AAC_ENC_OK) {
+ return error;
+ }
+
+ i++;
+
+ } while (list->id[i] != end_of_sequence);
+
+bail:
+ if (pBitDemand != NULL) {
+ *pBitDemand = bitDemand;
+ }
+
+ return error;
+}
+
+//-----------------------------------------------------------------------------------------------
+
+AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc,
+ CHANNEL_MAPPING *channelMapping,
+ QC_OUT *qcOut, PSY_OUT *psyOut,
+ QC_STATE *qcKernel,
+ AUDIO_OBJECT_TYPE aot,
+ UINT syntaxFlags, SCHAR epConfig) {
+ HANDLE_FDK_BITSTREAM hBs = transportEnc_GetBitstream(hTpEnc);
+ AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
+ int i, n, doByteAlign = 1;
+ INT bitMarkUp;
+ INT frameBits;
+ /* Get first bit of raw data block.
+ In case of ADTS+PCE, AU would start at PCE.
+ This is okay because PCE assures alignment. */
+ UINT alignAnchor = FDKgetValidBits(hBs);
+
+ frameBits = bitMarkUp = alignAnchor;
+
+
+ /* Write DSEs first in case of DAB */
+ for (n = 0; (n < qcOut->nExtensions) && (n < (2+2)); n++) {
+ if ( (syntaxFlags & AC_DAB) &&
+ (qcOut->extension[n].type == EXT_DATA_ELEMENT) ) {
+ FDKaacEnc_writeExtensionData( hTpEnc,
+ &qcOut->extension[n],
+ 0,
+ alignAnchor,
+ syntaxFlags,
+ aot,
+ epConfig );
+ }
+
+ /* For EXT_FIL or EXT_FILL_DATA we could do an additional sanity check here */
+ }
+
+ /* Channel element loop */
+ for (i = 0; i < channelMapping->nElements; i++) {
+ ELEMENT_INFO elInfo = channelMapping->elInfo[i];
+ INT elementUsedBits = 0;
+
+ switch (elInfo.elType) {
+ case ID_SCE: /* single channel */
+ case ID_CPE: /* channel pair */
+ case ID_LFE: /* low freq effects channel */
+ {
+ if (AAC_ENC_OK !=
+ (ErrorStatus = FDKaacEnc_ChannelElementWrite(
+ hTpEnc, &elInfo, qcOut->qcElement[i]->qcOutChannel,
+ psyOut->psyOutElement[i],
+ psyOut->psyOutElement[i]->psyOutChannel,
+ syntaxFlags, /* syntaxFlags (ER tools ...) */
+ aot, /* aot: AOT_AAC_LC, AOT_SBR, AOT_PS */
+ epConfig, /* epConfig -1, 0, 1 */
+ NULL, 0))) {
+ return ErrorStatus;
+ }
+
+ if (!(syntaxFlags & AC_ER)) {
+ /* Write associated extension payload */
+ for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
+ FDKaacEnc_writeExtensionData(
+ hTpEnc, &qcOut->qcElement[i]->extension[n], 0, alignAnchor,
+ syntaxFlags, aot, epConfig);
+ }
+ }
+ } break;
+
+ /* In FDK, DSE signalling explicit done in elDSE. See channel_map.cpp */
+ default:
+ return AAC_ENC_INVALID_ELEMENTINFO_TYPE;
+
+ } /* switch */
+
+ if (elInfo.elType != ID_DSE) {
+ elementUsedBits -= bitMarkUp;
+ bitMarkUp = FDKgetValidBits(hBs);
+ elementUsedBits += bitMarkUp;
+ frameBits += elementUsedBits;
+ }
+
+ } /* for (i=0; i<channelMapping.nElements; i++) */
+
+ if ((syntaxFlags & AC_ER) && !(syntaxFlags & AC_DRM)) {
+ UCHAR channelElementExtensionWritten[((8))][(
+ 1)]; /* 0: extension not touched, 1: extension already written */
+
+ FDKmemclear(channelElementExtensionWritten,
+ sizeof(channelElementExtensionWritten));
+
+ if (syntaxFlags & AC_ELD) {
+ for (i = 0; i < channelMapping->nElements; i++) {
+ for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
+ if ((qcOut->qcElement[i]->extension[n].type == EXT_SBR_DATA) ||
+ (qcOut->qcElement[i]->extension[n].type == EXT_SBR_DATA_CRC)) {
+ /* Write sbr extension payload */
+ FDKaacEnc_writeExtensionData(
+ hTpEnc, &qcOut->qcElement[i]->extension[n], 0, alignAnchor,
+ syntaxFlags, aot, epConfig);
+
+ channelElementExtensionWritten[i][n] = 1;
+ } /* SBR */
+ } /* n */
+ } /* i */
+ } /* AC_ELD */
+
+ for (i = 0; i < channelMapping->nElements; i++) {
+ for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
+ if (channelElementExtensionWritten[i][n] == 0) {
+ /* Write all ramaining extension payloads in element */
+ FDKaacEnc_writeExtensionData(hTpEnc,
+ &qcOut->qcElement[i]->extension[n], 0,
+ alignAnchor, syntaxFlags, aot, epConfig);
+ }
+ } /* n */
+ } /* i */
+ } /* if AC_ER */
+
+ /* Extend global extension payload table with fill bits */
+ n = qcOut->nExtensions;
+
+ /* Add fill data / stuffing bits */
+ n = qcOut->nExtensions;
+
+// if (!(syntaxFlags & AC_DAB)) {
+ qcOut->extension[n].type = EXT_FILL_DATA;
+ qcOut->extension[n].nPayloadBits = qcOut->totFillBits;
+ qcOut->nExtensions++;
+// } else {
+// doByteAlign = 0;
+// }
+ if (syntaxFlags & AC_DAB)
+ doByteAlign = 0;
+
+ /* Write global extension payload and fill data */
+ for (n = 0; (n < qcOut->nExtensions) && (n < (2+2)); n++)
+ {
+ if ( !(syntaxFlags & AC_DAB) ||
+ ( (syntaxFlags & AC_DAB) &&
+ (qcOut->extension[n].type != EXT_DATA_ELEMENT)
+ )
+ ) {
+ FDKaacEnc_writeExtensionData( hTpEnc,
+ &qcOut->extension[n],
+ 0,
+ alignAnchor,
+ syntaxFlags,
+ aot,
+ epConfig );
+ }
+
+ /* For EXT_FIL or EXT_FILL_DATA we could do an additional sanity check here
+ */
+ }
+
+ if (!(syntaxFlags & (AC_SCALABLE | AC_ER | AC_DAB))) {
+ FDKwriteBits(hBs, ID_END, EL_ID_BITS);
+ }
+
+ if (doByteAlign) {
+ /* Assure byte alignment*/
+ if (((FDKgetValidBits(hBs) - alignAnchor + qcOut->alignBits) & 0x7) != 0) {
+ return AAC_ENC_WRITTEN_BITS_ERROR;
+ }
+
+ FDKaacEnc_ByteAlignment(hBs, qcOut->alignBits);
+ }
+
+ frameBits -= bitMarkUp;
+ frameBits += FDKgetValidBits(hBs);
+
+ transportEnc_EndAccessUnit(hTpEnc, &frameBits);
+
+ if (frameBits != qcOut->totalBits + qcKernel->globHdrBits){
+ fprintf(stderr, "frameBits != qcOut->totalBits + qcKernel->globHdrBits: %d != %d + %d", frameBits, qcOut->totalBits, qcKernel->globHdrBits);
+ return AAC_ENC_WRITTEN_BITS_ERROR;
+ }
+
+ //fprintf(stderr, "ErrorStatus=%d", ErrorStatus);
+ return ErrorStatus;
+}
diff --git a/fdk-aac/libAACenc/src/bitenc.h b/fdk-aac/libAACenc/src/bitenc.h
new file mode 100644
index 0000000..75dc068
--- /dev/null
+++ b/fdk-aac/libAACenc/src/bitenc.h
@@ -0,0 +1,184 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Bitstream encoder
+
+*******************************************************************************/
+
+#ifndef BITENC_H
+#define BITENC_H
+
+#include "qc_data.h"
+#include "aacenc_tns.h"
+#include "channel_map.h"
+#include "interface.h" /* obsolete, when PSY_OUT is thrown out of the WritBS-call! */
+#include "FDK_audio.h"
+#include "aacenc.h"
+
+#include "tpenc_lib.h"
+
+typedef enum {
+ MAX_ENCODER_CHANNELS = 9,
+ MAX_BLOCK_TYPES = 4,
+ MAX_AAC_LAYERS = 9,
+ MAX_LAYERS = MAX_AAC_LAYERS, /* only one core layer if present */
+ FIRST_LAY = 1 /* default layer number for AAC nonscalable */
+} _MAX_CONST;
+
+#define BUFFER_MX_HUFFCB_SIZE \
+ (32 * sizeof(INT)) /* our FDK_bitbuffer needs size of power 2 */
+
+#define EL_ID_BITS (3)
+
+/**
+ * \brief Arbitrary order bitstream writer. This function can either assemble a
+ * bit stream and write into the bit buffer of hTpEnc or calculate the number of
+ * static bits (signal independent) TpEnc handle must be NULL in this
+ * case. Or also Calculate the minimum possible number of static bits
+ * which by disabling all tools e.g. MS, TNS and sbfCnt=0. The minCnt
+ * parameter has to be 1 in this latter case.
+ * \param hTpEnc Transport encoder handle. If NULL, the number of static bits
+ * will be returned into *pBitDemand.
+ * \param pElInfo
+ * \param qcOutChannel
+ * \param hReorderInfo
+ * \param psyOutElement
+ * \param psyOutChannel
+ * \param syntaxFlags Bit stream syntax flags as defined in FDK_audio.h (Audio
+ * Codec flags).
+ * \param aot
+ * \param epConfig
+ * \param pBitDemand Pointer to an int where the amount of bits is returned
+ * into. The returned value depends on if hTpEnc is NULL and minCnt.
+ * \param minCnt If non-zero the value returned into *pBitDemand is the absolute
+ * minimum required amount of static bits in order to write a valid bit stream.
+ * \return AAC_ENCODER_ERROR error code
+ */
+AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite(
+ HANDLE_TRANSPORTENC hTpEnc, ELEMENT_INFO *pElInfo,
+ QC_OUT_CHANNEL *qcOutChannel[(2)], PSY_OUT_ELEMENT *psyOutElement,
+ PSY_OUT_CHANNEL *psyOutChannel[(2)], UINT syntaxFlags,
+ AUDIO_OBJECT_TYPE aot, SCHAR epConfig, INT *pBitDemand, UCHAR minCnt);
+/**
+ * \brief Write bit stream or account static bits
+ * \param hTpEnc transport encoder handle. If NULL, the function will
+ * not write any bit stream data but only count the amount
+ * of static (signal independent) bits
+ * \param channelMapping Channel mapping info
+ * \param qcOut
+ * \param psyOut
+ * \param qcKernel
+ * \param hBSE
+ * \param aot Audio Object Type being encoded
+ * \param syntaxFlags Flags indicating format specific detail
+ * \param epConfig Error protection config
+ */
+AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc,
+ CHANNEL_MAPPING *channelMapping,
+ QC_OUT *qcOut, PSY_OUT *psyOut,
+ QC_STATE *qcKernel,
+ AUDIO_OBJECT_TYPE aot,
+ UINT syntaxFlags, SCHAR epConfig);
+
+INT FDKaacEnc_writeExtensionData(HANDLE_TRANSPORTENC hTpEnc,
+ QC_OUT_EXTENSION *pExtension,
+ INT elInstanceTag, UINT alignAnchor,
+ UINT syntaxFlags, AUDIO_OBJECT_TYPE aot,
+ SCHAR epConfig);
+
+#endif /* BITENC_H */
diff --git a/fdk-aac/libAACenc/src/block_switch.cpp b/fdk-aac/libAACenc/src/block_switch.cpp
new file mode 100644
index 0000000..c132253
--- /dev/null
+++ b/fdk-aac/libAACenc/src/block_switch.cpp
@@ -0,0 +1,582 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner, Tobias Chalupka
+
+ Description: Block switching
+
+*******************************************************************************/
+
+/****************** Includes *****************************/
+
+#include "block_switch.h"
+#include "genericStds.h"
+
+#define LOWOV_WINDOW _LOWOV_WINDOW
+
+/**************** internal function prototypes ***********/
+
+static FIXP_DBL FDKaacEnc_GetWindowEnergy(const FIXP_DBL in[],
+ const INT blSwWndIdx);
+
+static void FDKaacEnc_CalcWindowEnergy(
+ BLOCK_SWITCHING_CONTROL *RESTRICT blockSwitchingControl, INT windowLen,
+ const INT_PCM *pTimeSignal);
+
+/****************** Constants *****************************/
+/* LONG START
+ * SHORT STOP LOWOV */
+static const INT blockType2windowShape[2][5] = {
+ {SINE_WINDOW, KBD_WINDOW, WRONG_WINDOW, SINE_WINDOW, KBD_WINDOW}, /* LD */
+ {KBD_WINDOW, SINE_WINDOW, SINE_WINDOW, KBD_WINDOW, WRONG_WINDOW}}; /* LC */
+
+/* IIR high pass coeffs */
+
+#ifndef SINETABLE_16BIT
+
+static const FIXP_DBL hiPassCoeff[BLOCK_SWITCHING_IIR_LEN] = {
+ FL2FXCONST_DBL(-0.5095), FL2FXCONST_DBL(0.7548)};
+
+static const FIXP_DBL accWindowNrgFac =
+ FL2FXCONST_DBL(0.3f); /* factor for accumulating filtered window energies */
+static const FIXP_DBL oneMinusAccWindowNrgFac = FL2FXCONST_DBL(0.7f);
+/* static const float attackRatio = 10.0; */ /* lower ratio limit for attacks */
+static const FIXP_DBL invAttackRatio =
+ FL2FXCONST_DBL(0.1f); /* inverted lower ratio limit for attacks */
+
+/* The next constants are scaled, because they are used for comparison with
+ * scaled values*/
+/* minimum energy for attacks */
+static const FIXP_DBL minAttackNrg =
+ (FL2FXCONST_DBL(1e+6f * NORM_PCM_ENERGY) >>
+ BLOCK_SWITCH_ENERGY_SHIFT); /* minimum energy for attacks */
+
+#else
+
+static const FIXP_SGL hiPassCoeff[BLOCK_SWITCHING_IIR_LEN] = {
+ FL2FXCONST_SGL(-0.5095), FL2FXCONST_SGL(0.7548)};
+
+static const FIXP_DBL accWindowNrgFac =
+ FL2FXCONST_DBL(0.3f); /* factor for accumulating filtered window energies */
+static const FIXP_SGL oneMinusAccWindowNrgFac = FL2FXCONST_SGL(0.7f);
+/* static const float attackRatio = 10.0; */ /* lower ratio limit for attacks */
+static const FIXP_SGL invAttackRatio =
+ FL2FXCONST_SGL(0.1f); /* inverted lower ratio limit for attacks */
+/* minimum energy for attacks */
+static const FIXP_DBL minAttackNrg =
+ (FL2FXCONST_DBL(1e+6f * NORM_PCM_ENERGY) >>
+ BLOCK_SWITCH_ENERGY_SHIFT); /* minimum energy for attacks */
+
+#endif
+
+/**************** internal function prototypes ***********/
+
+/****************** Routines ****************************/
+void FDKaacEnc_InitBlockSwitching(
+ BLOCK_SWITCHING_CONTROL *blockSwitchingControl, INT isLowDelay) {
+ FDKmemclear(blockSwitchingControl, sizeof(BLOCK_SWITCHING_CONTROL));
+
+ if (isLowDelay) {
+ blockSwitchingControl->nBlockSwitchWindows = 4;
+ blockSwitchingControl->allowShortFrames = 0;
+ blockSwitchingControl->allowLookAhead = 0;
+ } else {
+ blockSwitchingControl->nBlockSwitchWindows = 8;
+ blockSwitchingControl->allowShortFrames = 1;
+ blockSwitchingControl->allowLookAhead = 1;
+ }
+
+ blockSwitchingControl->noOfGroups = MAX_NO_OF_GROUPS;
+
+ /* Initialize startvalue for blocktype */
+ blockSwitchingControl->lastWindowSequence = LONG_WINDOW;
+ blockSwitchingControl->windowShape =
+ blockType2windowShape[blockSwitchingControl->allowShortFrames]
+ [blockSwitchingControl->lastWindowSequence];
+}
+
+static const INT suggestedGroupingTable[TRANS_FAC][MAX_NO_OF_GROUPS] = {
+ /* Attack in Window 0 */ {1, 3, 3, 1},
+ /* Attack in Window 1 */ {1, 1, 3, 3},
+ /* Attack in Window 2 */ {2, 1, 3, 2},
+ /* Attack in Window 3 */ {3, 1, 3, 1},
+ /* Attack in Window 4 */ {3, 1, 1, 3},
+ /* Attack in Window 5 */ {3, 2, 1, 2},
+ /* Attack in Window 6 */ {3, 3, 1, 1},
+ /* Attack in Window 7 */ {3, 3, 1, 1}};
+
+/* change block type depending on current blocktype and whether there's an
+ * attack */
+/* assume no look-ahead */
+static const INT chgWndSq[2][N_BLOCKTYPES] = {
+ /* LONG WINDOW START_WINDOW SHORT_WINDOW STOP_WINDOW,
+ LOWOV_WINDOW, WRONG_WINDOW */
+ /*no attack*/ {LONG_WINDOW, STOP_WINDOW, WRONG_WINDOW, LONG_WINDOW,
+ STOP_WINDOW, WRONG_WINDOW},
+ /*attack */ {START_WINDOW, LOWOV_WINDOW, WRONG_WINDOW, START_WINDOW,
+ LOWOV_WINDOW, WRONG_WINDOW}};
+
+/* change block type depending on current blocktype and whether there's an
+ * attack */
+/* assume look-ahead */
+static const INT chgWndSqLkAhd[2][2][N_BLOCKTYPES] = {
+ /*attack LONG WINDOW START_WINDOW SHORT_WINDOW STOP_WINDOW LOWOV_WINDOW, WRONG_WINDOW */ /* last attack */
+ /*no attack*/ {
+ {LONG_WINDOW, SHORT_WINDOW, STOP_WINDOW, LONG_WINDOW, WRONG_WINDOW,
+ WRONG_WINDOW}, /* no attack */
+ /*attack */ {START_WINDOW, SHORT_WINDOW, SHORT_WINDOW, START_WINDOW,
+ WRONG_WINDOW, WRONG_WINDOW}}, /* no attack */
+ /*no attack*/ {{LONG_WINDOW, SHORT_WINDOW, SHORT_WINDOW, LONG_WINDOW,
+ WRONG_WINDOW, WRONG_WINDOW}, /* attack */
+ /*attack */ {START_WINDOW, SHORT_WINDOW, SHORT_WINDOW,
+ START_WINDOW, WRONG_WINDOW,
+ WRONG_WINDOW}} /* attack */
+};
+
+int FDKaacEnc_BlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,
+ const INT granuleLength, const int isLFE,
+ const INT_PCM *pTimeSignal) {
+ UINT i;
+ FIXP_DBL enM1, enMax;
+
+ UINT nBlockSwitchWindows = blockSwitchingControl->nBlockSwitchWindows;
+
+ /* for LFE : only LONG window allowed */
+ if (isLFE) {
+ /* case LFE: */
+ /* only long blocks, always use sine windows (MPEG2 AAC, MPEG4 AAC) */
+ blockSwitchingControl->lastWindowSequence = LONG_WINDOW;
+ blockSwitchingControl->windowShape = SINE_WINDOW;
+ blockSwitchingControl->noOfGroups = 1;
+ blockSwitchingControl->groupLen[0] = 1;
+
+ return (0);
+ };
+
+ /* Save current attack index as last attack index */
+ blockSwitchingControl->lastattack = blockSwitchingControl->attack;
+ blockSwitchingControl->lastAttackIndex = blockSwitchingControl->attackIndex;
+
+ /* Save current window energy as last window energy */
+ FDKmemcpy(blockSwitchingControl->windowNrg[0],
+ blockSwitchingControl->windowNrg[1],
+ sizeof(blockSwitchingControl->windowNrg[0]));
+ FDKmemcpy(blockSwitchingControl->windowNrgF[0],
+ blockSwitchingControl->windowNrgF[1],
+ sizeof(blockSwitchingControl->windowNrgF[0]));
+
+ if (blockSwitchingControl->allowShortFrames) {
+ /* Calculate suggested grouping info for the last frame */
+
+ /* Reset grouping info */
+ FDKmemclear(blockSwitchingControl->groupLen,
+ sizeof(blockSwitchingControl->groupLen));
+
+ /* Set grouping info */
+ blockSwitchingControl->noOfGroups = MAX_NO_OF_GROUPS;
+
+ FDKmemcpy(blockSwitchingControl->groupLen,
+ suggestedGroupingTable[blockSwitchingControl->lastAttackIndex],
+ sizeof(blockSwitchingControl->groupLen));
+
+ if (blockSwitchingControl->attack == TRUE)
+ blockSwitchingControl->maxWindowNrg =
+ FDKaacEnc_GetWindowEnergy(blockSwitchingControl->windowNrg[0],
+ blockSwitchingControl->lastAttackIndex);
+ else
+ blockSwitchingControl->maxWindowNrg = FL2FXCONST_DBL(0.0);
+ }
+
+ /* Calculate unfiltered and filtered energies in subwindows and combine to
+ * segments */
+ FDKaacEnc_CalcWindowEnergy(
+ blockSwitchingControl,
+ granuleLength >> (nBlockSwitchWindows == 4 ? 2 : 3), pTimeSignal);
+
+ /* now calculate if there is an attack */
+
+ /* reset attack */
+ blockSwitchingControl->attack = FALSE;
+
+ /* look for attack */
+ enMax = FL2FXCONST_DBL(0.0f);
+ enM1 = blockSwitchingControl->windowNrgF[0][nBlockSwitchWindows - 1];
+
+ for (i = 0; i < nBlockSwitchWindows; i++) {
+ FIXP_DBL tmp =
+ fMultDiv2(oneMinusAccWindowNrgFac, blockSwitchingControl->accWindowNrg);
+ blockSwitchingControl->accWindowNrg = fMultAdd(tmp, accWindowNrgFac, enM1);
+
+ if (fMult(blockSwitchingControl->windowNrgF[1][i], invAttackRatio) >
+ blockSwitchingControl->accWindowNrg) {
+ blockSwitchingControl->attack = TRUE;
+ blockSwitchingControl->attackIndex = i;
+ }
+ enM1 = blockSwitchingControl->windowNrgF[1][i];
+ enMax = fixMax(enMax, enM1);
+ }
+
+ if (enMax < minAttackNrg) blockSwitchingControl->attack = FALSE;
+
+ /* Check if attack spreads over frame border */
+ if ((blockSwitchingControl->attack == FALSE) &&
+ (blockSwitchingControl->lastattack == TRUE)) {
+ /* if attack is in last window repeat SHORT_WINDOW */
+ if (((blockSwitchingControl->windowNrgF[0][nBlockSwitchWindows - 1] >> 4) >
+ fMult((FIXP_DBL)(10 << (DFRACT_BITS - 1 - 4)),
+ blockSwitchingControl->windowNrgF[1][1])) &&
+ (blockSwitchingControl->lastAttackIndex ==
+ (INT)nBlockSwitchWindows - 1)) {
+ blockSwitchingControl->attack = TRUE;
+ blockSwitchingControl->attackIndex = 0;
+ }
+ }
+
+ if (blockSwitchingControl->allowLookAhead) {
+ blockSwitchingControl->lastWindowSequence =
+ chgWndSqLkAhd[blockSwitchingControl->lastattack]
+ [blockSwitchingControl->attack]
+ [blockSwitchingControl->lastWindowSequence];
+ } else {
+ /* Low Delay */
+ blockSwitchingControl->lastWindowSequence =
+ chgWndSq[blockSwitchingControl->attack]
+ [blockSwitchingControl->lastWindowSequence];
+ }
+
+ /* update window shape */
+ blockSwitchingControl->windowShape =
+ blockType2windowShape[blockSwitchingControl->allowShortFrames]
+ [blockSwitchingControl->lastWindowSequence];
+
+ return (0);
+}
+
+static FIXP_DBL FDKaacEnc_GetWindowEnergy(const FIXP_DBL in[],
+ const INT blSwWndIdx) {
+ /* For coherency, change FDKaacEnc_GetWindowEnergy() to calcluate the energy
+ for a block switching analysis windows, not for a short block. The same is
+ done FDKaacEnc_CalcWindowEnergy(). The result of
+ FDKaacEnc_GetWindowEnergy() is used for a comparision of the max energy of
+ left/right channel. */
+
+ return in[blSwWndIdx];
+}
+
+static void FDKaacEnc_CalcWindowEnergy(
+ BLOCK_SWITCHING_CONTROL *RESTRICT blockSwitchingControl, INT windowLen,
+ const INT_PCM *pTimeSignal) {
+ INT i;
+ UINT w;
+
+#ifndef SINETABLE_16BIT
+ const FIXP_DBL hiPassCoeff0 = hiPassCoeff[0];
+ const FIXP_DBL hiPassCoeff1 = hiPassCoeff[1];
+#else
+ const FIXP_SGL hiPassCoeff0 = hiPassCoeff[0];
+ const FIXP_SGL hiPassCoeff1 = hiPassCoeff[1];
+#endif
+
+ FIXP_DBL temp_iirState0 = blockSwitchingControl->iirStates[0];
+ FIXP_DBL temp_iirState1 = blockSwitchingControl->iirStates[1];
+
+ /* sum up scalarproduct of timesignal as windowed Energies */
+ for (w = 0; w < blockSwitchingControl->nBlockSwitchWindows; w++) {
+ ULONG temp_windowNrg = 0x0;
+ ULONG temp_windowNrgF = 0x0;
+
+ /* windowNrg = sum(timesample^2) */
+ for (i = 0; i < windowLen; i++) {
+ FIXP_DBL tempUnfiltered, t1, t2;
+ /* tempUnfiltered is scaled with 1 to prevent overflows during calculation
+ * of tempFiltred */
+#if SAMPLE_BITS == DFRACT_BITS
+ tempUnfiltered = (FIXP_DBL)*pTimeSignal++ >> 1;
+#else
+ tempUnfiltered = (FIXP_DBL)*pTimeSignal++
+ << (DFRACT_BITS - SAMPLE_BITS - 1);
+#endif
+ t1 = fMultDiv2(hiPassCoeff1, tempUnfiltered - temp_iirState0);
+ t2 = fMultDiv2(hiPassCoeff0, temp_iirState1);
+ temp_iirState0 = tempUnfiltered;
+ temp_iirState1 = (t1 - t2) << 1;
+
+ temp_windowNrg += (LONG)fPow2Div2(temp_iirState0) >>
+ (BLOCK_SWITCH_ENERGY_SHIFT - 1 - 2);
+ temp_windowNrgF += (LONG)fPow2Div2(temp_iirState1) >>
+ (BLOCK_SWITCH_ENERGY_SHIFT - 1 - 2);
+ }
+ blockSwitchingControl->windowNrg[1][w] =
+ (LONG)fMin(temp_windowNrg, (UINT)MAXVAL_DBL);
+ blockSwitchingControl->windowNrgF[1][w] =
+ (LONG)fMin(temp_windowNrgF, (UINT)MAXVAL_DBL);
+ }
+ blockSwitchingControl->iirStates[0] = temp_iirState0;
+ blockSwitchingControl->iirStates[1] = temp_iirState1;
+}
+
+static const UCHAR synchronizedBlockTypeTable[5][5] = {
+ /* LONG_WINDOW START_WINDOW SHORT_WINDOW STOP_WINDOW
+ LOWOV_WINDOW*/
+ /* LONG_WINDOW */ {LONG_WINDOW, START_WINDOW, SHORT_WINDOW, STOP_WINDOW,
+ LOWOV_WINDOW},
+ /* START_WINDOW */
+ {START_WINDOW, START_WINDOW, SHORT_WINDOW, SHORT_WINDOW, LOWOV_WINDOW},
+ /* SHORT_WINDOW */
+ {SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW, WRONG_WINDOW},
+ /* STOP_WINDOW */
+ {STOP_WINDOW, SHORT_WINDOW, SHORT_WINDOW, STOP_WINDOW, LOWOV_WINDOW},
+ /* LOWOV_WINDOW */
+ {LOWOV_WINDOW, LOWOV_WINDOW, WRONG_WINDOW, LOWOV_WINDOW, LOWOV_WINDOW},
+};
+
+int FDKaacEnc_SyncBlockSwitching(
+ BLOCK_SWITCHING_CONTROL *blockSwitchingControlLeft,
+ BLOCK_SWITCHING_CONTROL *blockSwitchingControlRight, const INT nChannels,
+ const INT commonWindow) {
+ UCHAR patchType = LONG_WINDOW;
+
+ if (nChannels == 2 && commonWindow == TRUE) {
+ /* could be better with a channel loop (need a handle to psy_data) */
+ /* get suggested Block Types and synchronize */
+ patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlLeft
+ ->lastWindowSequence];
+ patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlRight
+ ->lastWindowSequence];
+
+ /* sanity check (no change from low overlap window to short winow and vice
+ * versa) */
+ if (patchType == WRONG_WINDOW) return -1; /* mixed up AAC-LC and AAC-LD */
+
+ /* Set synchronized Blocktype */
+ blockSwitchingControlLeft->lastWindowSequence = patchType;
+ blockSwitchingControlRight->lastWindowSequence = patchType;
+
+ /* update window shape */
+ blockSwitchingControlLeft->windowShape =
+ blockType2windowShape[blockSwitchingControlLeft->allowShortFrames]
+ [blockSwitchingControlLeft->lastWindowSequence];
+ blockSwitchingControlRight->windowShape =
+ blockType2windowShape[blockSwitchingControlLeft->allowShortFrames]
+ [blockSwitchingControlRight->lastWindowSequence];
+ }
+
+ if (blockSwitchingControlLeft->allowShortFrames) {
+ int i;
+
+ if (nChannels == 2) {
+ if (commonWindow == TRUE) {
+ /* Synchronize grouping info */
+ int windowSequenceLeftOld =
+ blockSwitchingControlLeft->lastWindowSequence;
+ int windowSequenceRightOld =
+ blockSwitchingControlRight->lastWindowSequence;
+
+ /* Long Blocks */
+ if (patchType != SHORT_WINDOW) {
+ /* Set grouping info */
+ blockSwitchingControlLeft->noOfGroups = 1;
+ blockSwitchingControlRight->noOfGroups = 1;
+ blockSwitchingControlLeft->groupLen[0] = 1;
+ blockSwitchingControlRight->groupLen[0] = 1;
+
+ for (i = 1; i < MAX_NO_OF_GROUPS; i++) {
+ blockSwitchingControlLeft->groupLen[i] = 0;
+ blockSwitchingControlRight->groupLen[i] = 0;
+ }
+ }
+
+ /* Short Blocks */
+ else {
+ /* in case all two channels were detected as short-blocks before
+ * syncing, use the grouping of channel with higher maxWindowNrg */
+ if ((windowSequenceLeftOld == SHORT_WINDOW) &&
+ (windowSequenceRightOld == SHORT_WINDOW)) {
+ if (blockSwitchingControlLeft->maxWindowNrg >
+ blockSwitchingControlRight->maxWindowNrg) {
+ /* Left Channel wins */
+ blockSwitchingControlRight->noOfGroups =
+ blockSwitchingControlLeft->noOfGroups;
+ for (i = 0; i < MAX_NO_OF_GROUPS; i++) {
+ blockSwitchingControlRight->groupLen[i] =
+ blockSwitchingControlLeft->groupLen[i];
+ }
+ } else {
+ /* Right Channel wins */
+ blockSwitchingControlLeft->noOfGroups =
+ blockSwitchingControlRight->noOfGroups;
+ for (i = 0; i < MAX_NO_OF_GROUPS; i++) {
+ blockSwitchingControlLeft->groupLen[i] =
+ blockSwitchingControlRight->groupLen[i];
+ }
+ }
+ } else if ((windowSequenceLeftOld == SHORT_WINDOW) &&
+ (windowSequenceRightOld != SHORT_WINDOW)) {
+ /* else use grouping of short-block channel */
+ blockSwitchingControlRight->noOfGroups =
+ blockSwitchingControlLeft->noOfGroups;
+ for (i = 0; i < MAX_NO_OF_GROUPS; i++) {
+ blockSwitchingControlRight->groupLen[i] =
+ blockSwitchingControlLeft->groupLen[i];
+ }
+ } else if ((windowSequenceRightOld == SHORT_WINDOW) &&
+ (windowSequenceLeftOld != SHORT_WINDOW)) {
+ blockSwitchingControlLeft->noOfGroups =
+ blockSwitchingControlRight->noOfGroups;
+ for (i = 0; i < MAX_NO_OF_GROUPS; i++) {
+ blockSwitchingControlLeft->groupLen[i] =
+ blockSwitchingControlRight->groupLen[i];
+ }
+ } else {
+ /* syncing a start and stop window ... */
+ blockSwitchingControlLeft->noOfGroups =
+ blockSwitchingControlRight->noOfGroups = 2;
+ blockSwitchingControlLeft->groupLen[0] =
+ blockSwitchingControlRight->groupLen[0] = 4;
+ blockSwitchingControlLeft->groupLen[1] =
+ blockSwitchingControlRight->groupLen[1] = 4;
+ }
+ } /* Short Blocks */
+ } else {
+ /* stereo, no common window */
+ if (blockSwitchingControlLeft->lastWindowSequence != SHORT_WINDOW) {
+ blockSwitchingControlLeft->noOfGroups = 1;
+ blockSwitchingControlLeft->groupLen[0] = 1;
+ for (i = 1; i < MAX_NO_OF_GROUPS; i++) {
+ blockSwitchingControlLeft->groupLen[i] = 0;
+ }
+ }
+ if (blockSwitchingControlRight->lastWindowSequence != SHORT_WINDOW) {
+ blockSwitchingControlRight->noOfGroups = 1;
+ blockSwitchingControlRight->groupLen[0] = 1;
+ for (i = 1; i < MAX_NO_OF_GROUPS; i++) {
+ blockSwitchingControlRight->groupLen[i] = 0;
+ }
+ }
+ } /* common window */
+ } else {
+ /* Mono */
+ if (blockSwitchingControlLeft->lastWindowSequence != SHORT_WINDOW) {
+ blockSwitchingControlLeft->noOfGroups = 1;
+ blockSwitchingControlLeft->groupLen[0] = 1;
+
+ for (i = 1; i < MAX_NO_OF_GROUPS; i++) {
+ blockSwitchingControlLeft->groupLen[i] = 0;
+ }
+ }
+ }
+ } /* allowShortFrames */
+
+ /* Translate LOWOV_WINDOW block type to a meaningful window shape. */
+ if (!blockSwitchingControlLeft->allowShortFrames) {
+ if (blockSwitchingControlLeft->lastWindowSequence != LONG_WINDOW &&
+ blockSwitchingControlLeft->lastWindowSequence != STOP_WINDOW) {
+ blockSwitchingControlLeft->lastWindowSequence = LONG_WINDOW;
+ blockSwitchingControlLeft->windowShape = LOL_WINDOW;
+ }
+ }
+ if (nChannels == 2) {
+ if (!blockSwitchingControlRight->allowShortFrames) {
+ if (blockSwitchingControlRight->lastWindowSequence != LONG_WINDOW &&
+ blockSwitchingControlRight->lastWindowSequence != STOP_WINDOW) {
+ blockSwitchingControlRight->lastWindowSequence = LONG_WINDOW;
+ blockSwitchingControlRight->windowShape = LOL_WINDOW;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/fdk-aac/libAACenc/src/block_switch.h b/fdk-aac/libAACenc/src/block_switch.h
new file mode 100644
index 0000000..ff20f84
--- /dev/null
+++ b/fdk-aac/libAACenc/src/block_switch.h
@@ -0,0 +1,162 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Block switching
+
+*******************************************************************************/
+
+#ifndef BLOCK_SWITCH_H
+#define BLOCK_SWITCH_H
+
+#include "common_fix.h"
+
+#include "psy_const.h"
+
+/****************** Defines ******************************/
+#define BLOCK_SWITCH_WINDOWS 8 /* number of windows for energy calculation */
+
+#define BLOCK_SWITCHING_IIR_LEN \
+ 2 /* Length of HighPass-IIR-Filter for Attack-Detection */
+#define BLOCK_SWITCH_ENERGY_SHIFT \
+ 7 /* should be logDualis(BLOCK_SWITCH_WINDOW_LEN) to avoid overflow in \
+ windowNrgs. */
+
+#define LAST_WINDOW 0
+#define THIS_WINDOW 1
+
+/****************** Structures ***************************/
+typedef struct {
+ INT lastWindowSequence;
+ INT windowShape;
+ INT lastWindowShape;
+ UINT nBlockSwitchWindows; /* number of windows for energy calculation */
+ INT attack;
+ INT lastattack;
+ INT attackIndex;
+ INT lastAttackIndex;
+ INT allowShortFrames; /* for Low Delay, don't allow short frames */
+ INT allowLookAhead; /* for Low Delay, don't do look-ahead */
+ INT noOfGroups;
+ INT groupLen[MAX_NO_OF_GROUPS];
+ FIXP_DBL maxWindowNrg; /* max energy in subwindows */
+
+ FIXP_DBL
+ windowNrg[2][BLOCK_SWITCH_WINDOWS]; /* time signal energy in Subwindows
+ (last and current) */
+ FIXP_DBL windowNrgF[2][BLOCK_SWITCH_WINDOWS]; /* filtered time signal energy
+ in segments (last and
+ current) */
+ FIXP_DBL accWindowNrg; /* recursively accumulated windowNrgF */
+
+ FIXP_DBL iirStates[BLOCK_SWITCHING_IIR_LEN]; /* filter delay-line */
+
+} BLOCK_SWITCHING_CONTROL;
+
+void FDKaacEnc_InitBlockSwitching(
+ BLOCK_SWITCHING_CONTROL *blockSwitchingControl, INT isLowDelay);
+
+int FDKaacEnc_BlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,
+ const INT granuleLength, const int isLFE,
+ const INT_PCM *pTimeSignal);
+
+int FDKaacEnc_SyncBlockSwitching(
+ BLOCK_SWITCHING_CONTROL *blockSwitchingControlLeft,
+ BLOCK_SWITCHING_CONTROL *blockSwitchingControlRight, const INT noOfChannels,
+ const INT commonWindow);
+
+#endif /* #ifndef BLOCK_SWITCH_H */
diff --git a/fdk-aac/libAACenc/src/channel_map.cpp b/fdk-aac/libAACenc/src/channel_map.cpp
new file mode 100644
index 0000000..6ee91d5
--- /dev/null
+++ b/fdk-aac/libAACenc/src/channel_map.cpp
@@ -0,0 +1,664 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): A. Groeschel
+
+ Description: channel mapping functionality
+
+*******************************************************************************/
+
+#include "channel_map.h"
+#include "bitenc.h"
+#include "psy_const.h"
+#include "qc_data.h"
+#include "aacEnc_ram.h"
+#include "FDK_tools_rom.h"
+
+/* channel_assignment treats the relationship of Input file channels
+ to the encoder channels.
+ This is necessary because the usual order in RIFF files (.wav)
+ is different from the elements order in the coder given
+ by Table 8.1 (implicit speaker mapping) of the AAC standard.
+
+ In mono and stereo case, this is trivial.
+ In mc case, it looks like this:
+
+ Channel Input file coder chan
+5ch:
+ front center 2 0 (SCE channel)
+ left center 0 1 (1st of 1st CPE)
+ right center 1 2 (2nd of 1st CPE)
+ left surround 3 3 (1st of 2nd CPE)
+ right surround 4 4 (2nd of 2nd CPE)
+
+5.1ch:
+ front center 2 0 (SCE channel)
+ left center 0 1 (1st of 1st CPE)
+ right center 1 2 (2nd of 1st CPE)
+ left surround 4 3 (1st of 2nd CPE)
+ right surround 5 4 (2nd of 2nd CPE)
+ LFE 3 5 (LFE)
+*/
+
+/* Channel mode configuration tab provides,
+ corresponding number of channels and elements
+*/
+static const CHANNEL_MODE_CONFIG_TAB channelModeConfig[] = {
+ {MODE_1, 1, 1, 1}, /* chCfg 1, SCE */
+ {MODE_2, 2, 2, 1}, /* chCfg 2, CPE */
+ {MODE_1_2, 3, 3, 2}, /* chCfg 3, SCE,CPE */
+ {MODE_1_2_1, 4, 4, 3}, /* chCfg 4, SCE,CPE,SCE */
+ {MODE_1_2_2, 5, 5, 3}, /* chCfg 5, SCE,CPE,CPE */
+ {MODE_1_2_2_1, 6, 5, 4}, /* chCfg 6, SCE,CPE,CPE,LFE */
+ {MODE_1_2_2_2_1, 8, 7, 5}, /* chCfg 7, SCE,CPE,CPE,CPE,LFE */
+ {MODE_6_1, 7, 6, 5}, /* chCfg 11, SCE,CPE,CPE,SCE,LFE */
+ {MODE_7_1_BACK, 8, 7, 5}, /* chCfg 12, SCE,CPE,CPE,CPE,LFE */
+ {MODE_7_1_TOP_FRONT, 8, 7, 5}, /* chCfg 14, SCE,CPE,CPE,LFE,CPE */
+ {MODE_7_1_REAR_SURROUND, 8, 7,
+ 5}, /* same as MODE_7_1_BACK, SCE,CPE,CPE,CPE,LFE */
+ {MODE_7_1_FRONT_CENTER, 8, 7,
+ 5}, /* same as MODE_1_2_2_2_1, SCE,CPE,CPE,CPE,LFE */
+
+};
+
+AAC_ENCODER_ERROR FDKaacEnc_DetermineEncoderMode(CHANNEL_MODE* mode,
+ INT nChannels) {
+ INT i;
+ CHANNEL_MODE encMode = MODE_INVALID;
+
+ if (*mode == MODE_UNKNOWN) {
+ for (i = 0; i < (INT)sizeof(channelModeConfig) /
+ (INT)sizeof(CHANNEL_MODE_CONFIG_TAB);
+ i++) {
+ if (channelModeConfig[i].nChannels == nChannels) {
+ encMode = channelModeConfig[i].encMode;
+ break;
+ }
+ }
+ *mode = encMode;
+ } else {
+ /* check if valid channel configuration */
+ if (FDKaacEnc_GetChannelModeConfiguration(*mode)->nChannels == nChannels) {
+ encMode = *mode;
+ }
+ }
+
+ if (encMode == MODE_INVALID) {
+ return AAC_ENC_UNSUPPORTED_CHANNELCONFIG;
+ }
+
+ return AAC_ENC_OK;
+}
+
+static INT FDKaacEnc_initElement(ELEMENT_INFO* elInfo, MP4_ELEMENT_ID elType,
+ INT* cnt, FDK_channelMapDescr* mapDescr,
+ UINT mapIdx, INT* it_cnt,
+ const FIXP_DBL relBits) {
+ INT error = 0;
+ INT counter = *cnt;
+
+ elInfo->elType = elType;
+ elInfo->relativeBits = relBits;
+
+ switch (elInfo->elType) {
+ case ID_SCE:
+ case ID_LFE:
+ case ID_CCE:
+ elInfo->nChannelsInEl = 1;
+ elInfo->ChannelIndex[0] =
+ FDK_chMapDescr_getMapValue(mapDescr, counter++, mapIdx);
+ elInfo->instanceTag = it_cnt[elType]++;
+ break;
+ case ID_CPE:
+ elInfo->nChannelsInEl = 2;
+ elInfo->ChannelIndex[0] =
+ FDK_chMapDescr_getMapValue(mapDescr, counter++, mapIdx);
+ elInfo->ChannelIndex[1] =
+ FDK_chMapDescr_getMapValue(mapDescr, counter++, mapIdx);
+ elInfo->instanceTag = it_cnt[elType]++;
+ break;
+ case ID_DSE:
+ elInfo->nChannelsInEl = 0;
+ elInfo->ChannelIndex[0] = 0;
+ elInfo->ChannelIndex[1] = 0;
+ elInfo->instanceTag = it_cnt[elType]++;
+ break;
+ default:
+ error = 1;
+ };
+ *cnt = counter;
+ return error;
+}
+
+AAC_ENCODER_ERROR FDKaacEnc_InitChannelMapping(CHANNEL_MODE mode,
+ CHANNEL_ORDER co,
+ CHANNEL_MAPPING* cm) {
+ INT count = 0; /* count through coder channels */
+ INT it_cnt[ID_END + 1];
+ INT i;
+ UINT mapIdx;
+ FDK_channelMapDescr mapDescr;
+
+ for (i = 0; i < ID_END; i++) it_cnt[i] = 0;
+
+ FDKmemclear(cm, sizeof(CHANNEL_MAPPING));
+
+ /* init channel mapping*/
+ for (i = 0; i < (INT)sizeof(channelModeConfig) /
+ (INT)sizeof(CHANNEL_MODE_CONFIG_TAB);
+ i++) {
+ if (channelModeConfig[i].encMode == mode) {
+ cm->encMode = channelModeConfig[i].encMode;
+ cm->nChannels = channelModeConfig[i].nChannels;
+ cm->nChannelsEff = channelModeConfig[i].nChannelsEff;
+ cm->nElements = channelModeConfig[i].nElements;
+
+ break;
+ }
+ }
+
+ /* init map descriptor */
+ FDK_chMapDescr_init(&mapDescr, NULL, 0, (co == CH_ORDER_MPEG) ? 1 : 0);
+ switch (mode) {
+ case MODE_7_1_REAR_SURROUND: /* MODE_7_1_REAR_SURROUND is equivalent to
+ MODE_7_1_BACK */
+ mapIdx = (INT)MODE_7_1_BACK;
+ break;
+ case MODE_7_1_FRONT_CENTER: /* MODE_7_1_FRONT_CENTER is equivalent to
+ MODE_1_2_2_2_1 */
+ mapIdx = (INT)MODE_1_2_2_2_1;
+ break;
+ default:
+ mapIdx =
+ (INT)mode > 14
+ ? 0
+ : (INT)
+ mode; /* if channel config > 14 MPEG mapping will be used */
+ }
+
+ /* init element info struct */
+ switch (mode) {
+ case MODE_1:
+ /* (mono) sce */
+ FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx,
+ it_cnt, (FIXP_DBL)MAXVAL_DBL);
+ break;
+ case MODE_2:
+ /* (stereo) cpe */
+ FDKaacEnc_initElement(&cm->elInfo[0], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, (FIXP_DBL)MAXVAL_DBL);
+ break;
+
+ case MODE_1_2:
+ /* sce + cpe */
+ FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.4f));
+ FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.6f));
+ break;
+
+ case MODE_1_2_1:
+ /* sce + cpe + sce */
+ FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.3f));
+ FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.4f));
+ FDKaacEnc_initElement(&cm->elInfo[2], ID_SCE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.3f));
+ break;
+
+ case MODE_1_2_2:
+ /* sce + cpe + cpe */
+ FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.26f));
+ FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.37f));
+ FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.37f));
+ break;
+
+ case MODE_1_2_2_1:
+ /* (5.1) sce + cpe + cpe + lfe */
+ FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.24f));
+ FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.35f));
+ FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.35f));
+ FDKaacEnc_initElement(&cm->elInfo[3], ID_LFE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.06f));
+ break;
+
+ case MODE_6_1:
+ /* (6.1) sce + cpe + cpe + sce + lfe */
+ FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.2f));
+ FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.275f));
+ FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.275f));
+ FDKaacEnc_initElement(&cm->elInfo[3], ID_SCE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.2f));
+ FDKaacEnc_initElement(&cm->elInfo[4], ID_LFE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.05f));
+ break;
+
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_BACK:
+ case MODE_7_1_TOP_FRONT:
+ case MODE_7_1_REAR_SURROUND:
+ case MODE_7_1_FRONT_CENTER: {
+ /* (7.1) sce + cpe + cpe + cpe + lfe */
+ /* (7.1 top) sce + cpe + cpe + lfe + cpe */
+
+ FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.18f));
+ FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.26f));
+ FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.26f));
+ if (mode != MODE_7_1_TOP_FRONT) {
+ FDKaacEnc_initElement(&cm->elInfo[3], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.26f));
+ FDKaacEnc_initElement(&cm->elInfo[4], ID_LFE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.04f));
+ } else {
+ FDKaacEnc_initElement(&cm->elInfo[3], ID_LFE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.04f));
+ FDKaacEnc_initElement(&cm->elInfo[4], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.26f));
+ }
+ break;
+ }
+
+ default:
+ //*chMap=0;
+ return AAC_ENC_UNSUPPORTED_CHANNELCONFIG;
+ };
+
+ FDK_ASSERT(cm->nElements <= ((8)));
+
+ return AAC_ENC_OK;
+}
+
+AAC_ENCODER_ERROR FDKaacEnc_InitElementBits(QC_STATE* hQC, CHANNEL_MAPPING* cm,
+ INT bitrateTot, INT averageBitsTot,
+ INT maxChannelBits) {
+ int sc_brTot = CountLeadingBits(bitrateTot);
+
+ switch (cm->encMode) {
+ case MODE_1:
+ hQC->elementBits[0]->chBitrateEl = bitrateTot;
+
+ hQC->elementBits[0]->maxBitsEl = maxChannelBits;
+
+ hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits;
+ break;
+
+ case MODE_2:
+ hQC->elementBits[0]->chBitrateEl = bitrateTot >> 1;
+
+ hQC->elementBits[0]->maxBitsEl = 2 * maxChannelBits;
+
+ hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits;
+ break;
+ case MODE_1_2: {
+ hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits;
+ hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits;
+ FIXP_DBL sceRate = cm->elInfo[0].relativeBits;
+ FIXP_DBL cpeRate = cm->elInfo[1].relativeBits;
+
+ hQC->elementBits[0]->chBitrateEl =
+ fMult(sceRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot;
+ hQC->elementBits[1]->chBitrateEl =
+ fMult(cpeRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+
+ hQC->elementBits[0]->maxBitsEl = maxChannelBits;
+ hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits;
+ break;
+ }
+ case MODE_1_2_1: {
+ /* sce + cpe + sce */
+ hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits;
+ hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits;
+ hQC->elementBits[2]->relativeBitsEl = cm->elInfo[2].relativeBits;
+ FIXP_DBL sce1Rate = cm->elInfo[0].relativeBits;
+ FIXP_DBL cpeRate = cm->elInfo[1].relativeBits;
+ FIXP_DBL sce2Rate = cm->elInfo[2].relativeBits;
+
+ hQC->elementBits[0]->chBitrateEl =
+ fMult(sce1Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot;
+ hQC->elementBits[1]->chBitrateEl =
+ fMult(cpeRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+ hQC->elementBits[2]->chBitrateEl =
+ fMult(sce2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot;
+
+ hQC->elementBits[0]->maxBitsEl = maxChannelBits;
+ hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits;
+ hQC->elementBits[2]->maxBitsEl = maxChannelBits;
+ break;
+ }
+ case MODE_1_2_2: {
+ /* sce + cpe + cpe */
+ hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits;
+ hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits;
+ hQC->elementBits[2]->relativeBitsEl = cm->elInfo[2].relativeBits;
+ FIXP_DBL sceRate = cm->elInfo[0].relativeBits;
+ FIXP_DBL cpe1Rate = cm->elInfo[1].relativeBits;
+ FIXP_DBL cpe2Rate = cm->elInfo[2].relativeBits;
+
+ hQC->elementBits[0]->chBitrateEl =
+ fMult(sceRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot;
+ hQC->elementBits[1]->chBitrateEl =
+ fMult(cpe1Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+ hQC->elementBits[2]->chBitrateEl =
+ fMult(cpe2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+
+ hQC->elementBits[0]->maxBitsEl = maxChannelBits;
+ hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits;
+ hQC->elementBits[2]->maxBitsEl = 2 * maxChannelBits;
+ break;
+ }
+ case MODE_1_2_2_1: {
+ /* (5.1) sce + cpe + cpe + lfe */
+ hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits;
+ hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits;
+ hQC->elementBits[2]->relativeBitsEl = cm->elInfo[2].relativeBits;
+ hQC->elementBits[3]->relativeBitsEl = cm->elInfo[3].relativeBits;
+ FIXP_DBL sceRate = cm->elInfo[0].relativeBits;
+ FIXP_DBL cpe1Rate = cm->elInfo[1].relativeBits;
+ FIXP_DBL cpe2Rate = cm->elInfo[2].relativeBits;
+ FIXP_DBL lfeRate = cm->elInfo[3].relativeBits;
+
+ int maxBitsTot =
+ maxChannelBits * 5; /* LFE does not add to bit reservoir */
+ int sc = CountLeadingBits(fixMax(maxChannelBits, averageBitsTot));
+ int maxLfeBits = (int)fMax(
+ (INT)((fMult(lfeRate, (FIXP_DBL)(maxChannelBits << sc)) >> sc) << 1),
+ (INT)((fMult(FL2FXCONST_DBL(1.1f / 2.f),
+ fMult(lfeRate, (FIXP_DBL)(averageBitsTot << sc)))
+ << 1) >>
+ sc));
+
+ maxChannelBits = (maxBitsTot - maxLfeBits);
+ sc = CountLeadingBits(maxChannelBits);
+
+ maxChannelBits =
+ fMult((FIXP_DBL)maxChannelBits << sc, GetInvInt(5)) >> sc;
+
+ hQC->elementBits[0]->chBitrateEl =
+ fMult(sceRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot;
+ hQC->elementBits[1]->chBitrateEl =
+ fMult(cpe1Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+ hQC->elementBits[2]->chBitrateEl =
+ fMult(cpe2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+ hQC->elementBits[3]->chBitrateEl =
+ fMult(lfeRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot;
+
+ hQC->elementBits[0]->maxBitsEl = maxChannelBits;
+ hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits;
+ hQC->elementBits[2]->maxBitsEl = 2 * maxChannelBits;
+ hQC->elementBits[3]->maxBitsEl = maxLfeBits;
+
+ break;
+ }
+ case MODE_6_1: {
+ /* (6.1) sce + cpe + cpe + sce + lfe */
+ FIXP_DBL sceRate = hQC->elementBits[0]->relativeBitsEl =
+ cm->elInfo[0].relativeBits;
+ FIXP_DBL cpe1Rate = hQC->elementBits[1]->relativeBitsEl =
+ cm->elInfo[1].relativeBits;
+ FIXP_DBL cpe2Rate = hQC->elementBits[2]->relativeBitsEl =
+ cm->elInfo[2].relativeBits;
+ FIXP_DBL sce2Rate = hQC->elementBits[3]->relativeBitsEl =
+ cm->elInfo[3].relativeBits;
+ FIXP_DBL lfeRate = hQC->elementBits[4]->relativeBitsEl =
+ cm->elInfo[4].relativeBits;
+
+ int maxBitsTot =
+ maxChannelBits * 6; /* LFE does not add to bit reservoir */
+ int sc = CountLeadingBits(fixMax(maxChannelBits, averageBitsTot));
+ int maxLfeBits = (int)fMax(
+ (INT)((fMult(lfeRate, (FIXP_DBL)(maxChannelBits << sc)) >> sc) << 1),
+ (INT)((fMult(FL2FXCONST_DBL(1.1f / 2.f),
+ fMult(lfeRate, (FIXP_DBL)(averageBitsTot << sc)))
+ << 1) >>
+ sc));
+
+ maxChannelBits = (maxBitsTot - maxLfeBits) / 6;
+
+ hQC->elementBits[0]->chBitrateEl =
+ fMult(sceRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot;
+ hQC->elementBits[1]->chBitrateEl =
+ fMult(cpe1Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+ hQC->elementBits[2]->chBitrateEl =
+ fMult(cpe2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+ hQC->elementBits[3]->chBitrateEl =
+ fMult(sce2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+ hQC->elementBits[4]->chBitrateEl =
+ fMult(lfeRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot;
+
+ hQC->elementBits[0]->maxBitsEl = maxChannelBits;
+ hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits;
+ hQC->elementBits[2]->maxBitsEl = 2 * maxChannelBits;
+ hQC->elementBits[3]->maxBitsEl = maxChannelBits;
+ hQC->elementBits[4]->maxBitsEl = maxLfeBits;
+ break;
+ }
+ case MODE_7_1_TOP_FRONT:
+ case MODE_7_1_BACK:
+ case MODE_7_1_REAR_SURROUND:
+ case MODE_7_1_FRONT_CENTER:
+ case MODE_1_2_2_2_1: {
+ int cpe3Idx = (cm->encMode != MODE_7_1_TOP_FRONT) ? 3 : 4;
+ int lfeIdx = (cm->encMode != MODE_7_1_TOP_FRONT) ? 4 : 3;
+
+ /* (7.1) sce + cpe + cpe + cpe + lfe */
+ FIXP_DBL sceRate = hQC->elementBits[0]->relativeBitsEl =
+ cm->elInfo[0].relativeBits;
+ FIXP_DBL cpe1Rate = hQC->elementBits[1]->relativeBitsEl =
+ cm->elInfo[1].relativeBits;
+ FIXP_DBL cpe2Rate = hQC->elementBits[2]->relativeBitsEl =
+ cm->elInfo[2].relativeBits;
+ FIXP_DBL cpe3Rate = hQC->elementBits[cpe3Idx]->relativeBitsEl =
+ cm->elInfo[cpe3Idx].relativeBits;
+ FIXP_DBL lfeRate = hQC->elementBits[lfeIdx]->relativeBitsEl =
+ cm->elInfo[lfeIdx].relativeBits;
+
+ int maxBitsTot =
+ maxChannelBits * 7; /* LFE does not add to bit reservoir */
+ int sc = CountLeadingBits(fixMax(maxChannelBits, averageBitsTot));
+ int maxLfeBits = (int)fMax(
+ (INT)((fMult(lfeRate, (FIXP_DBL)(maxChannelBits << sc)) >> sc) << 1),
+ (INT)((fMult(FL2FXCONST_DBL(1.1f / 2.f),
+ fMult(lfeRate, (FIXP_DBL)(averageBitsTot << sc)))
+ << 1) >>
+ sc));
+
+ maxChannelBits = (maxBitsTot - maxLfeBits) / 7;
+
+ hQC->elementBits[0]->chBitrateEl =
+ fMult(sceRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot;
+ hQC->elementBits[1]->chBitrateEl =
+ fMult(cpe1Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+ hQC->elementBits[2]->chBitrateEl =
+ fMult(cpe2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+ hQC->elementBits[cpe3Idx]->chBitrateEl =
+ fMult(cpe3Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+ hQC->elementBits[lfeIdx]->chBitrateEl =
+ fMult(lfeRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot;
+
+ hQC->elementBits[0]->maxBitsEl = maxChannelBits;
+ hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits;
+ hQC->elementBits[2]->maxBitsEl = 2 * maxChannelBits;
+ hQC->elementBits[cpe3Idx]->maxBitsEl = 2 * maxChannelBits;
+ hQC->elementBits[lfeIdx]->maxBitsEl = maxLfeBits;
+ break;
+ }
+
+ default:
+ return AAC_ENC_UNSUPPORTED_CHANNELCONFIG;
+ }
+
+ return AAC_ENC_OK;
+}
+
+/********************************************************************************/
+/* */
+/* function: GetMonoStereoMODE(const CHANNEL_MODE mode) */
+/* */
+/* description: Determines encoder setting from channel mode. */
+/* Multichannel modes are mapped to mono or stereo modes */
+/* returns MODE_MONO in case of mono, */
+/* MODE_STEREO in case of stereo */
+/* MODE_INVALID in case of error */
+/* */
+/* input: CHANNEL_MODE mode: Encoder mode (see qc_data.h). */
+/* output: return: CM_STEREO_MODE monoStereoSetting */
+/* (MODE_INVALID: error, */
+/* MODE_MONO: mono */
+/* MODE_STEREO: stereo). */
+/* */
+/* misc: No memory is allocated. */
+/* */
+/********************************************************************************/
+
+ELEMENT_MODE FDKaacEnc_GetMonoStereoMode(const CHANNEL_MODE mode) {
+ ELEMENT_MODE monoStereoSetting = EL_MODE_INVALID;
+
+ switch (mode) {
+ case MODE_1: /* mono setups */
+ monoStereoSetting = EL_MODE_MONO;
+ break;
+
+ case MODE_2: /* stereo setups */
+ case MODE_1_2:
+ case MODE_1_2_1:
+ case MODE_1_2_2:
+ case MODE_1_2_2_1:
+ case MODE_6_1:
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_REAR_SURROUND:
+ case MODE_7_1_FRONT_CENTER:
+ case MODE_7_1_BACK:
+ case MODE_7_1_TOP_FRONT:
+ monoStereoSetting = EL_MODE_STEREO;
+ break;
+
+ default: /* error */
+ monoStereoSetting = EL_MODE_INVALID;
+ break;
+ }
+
+ return monoStereoSetting;
+}
+
+const CHANNEL_MODE_CONFIG_TAB* FDKaacEnc_GetChannelModeConfiguration(
+ const CHANNEL_MODE mode) {
+ INT i;
+ const CHANNEL_MODE_CONFIG_TAB* cm_config = NULL;
+
+ /* get channel mode config */
+ for (i = 0; i < (INT)sizeof(channelModeConfig) /
+ (INT)sizeof(CHANNEL_MODE_CONFIG_TAB);
+ i++) {
+ if (channelModeConfig[i].encMode == mode) {
+ cm_config = &channelModeConfig[i];
+ break;
+ }
+ }
+ return cm_config;
+}
diff --git a/fdk-aac/libAACenc/src/channel_map.h b/fdk-aac/libAACenc/src/channel_map.h
new file mode 100644
index 0000000..f9154cd
--- /dev/null
+++ b/fdk-aac/libAACenc/src/channel_map.h
@@ -0,0 +1,136 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): A. Groeschel
+
+ Description: channel mapping functionality
+
+*******************************************************************************/
+
+#ifndef CHANNEL_MAP_H
+#define CHANNEL_MAP_H
+
+#include "aacenc.h"
+#include "psy_const.h"
+#include "qc_data.h"
+
+typedef struct {
+ CHANNEL_MODE encMode;
+ INT nChannels;
+ INT nChannelsEff;
+ INT nElements;
+} CHANNEL_MODE_CONFIG_TAB;
+
+/* Element mode */
+typedef enum { EL_MODE_INVALID = 0, EL_MODE_MONO, EL_MODE_STEREO } ELEMENT_MODE;
+
+AAC_ENCODER_ERROR FDKaacEnc_DetermineEncoderMode(CHANNEL_MODE* mode,
+ INT nChannels);
+
+AAC_ENCODER_ERROR FDKaacEnc_InitChannelMapping(CHANNEL_MODE mode,
+ CHANNEL_ORDER co,
+ CHANNEL_MAPPING* chMap);
+
+AAC_ENCODER_ERROR FDKaacEnc_InitElementBits(QC_STATE* hQC, CHANNEL_MAPPING* cm,
+ INT bitrateTot, INT averageBitsTot,
+ INT maxChannelBits);
+
+ELEMENT_MODE FDKaacEnc_GetMonoStereoMode(const CHANNEL_MODE mode);
+
+const CHANNEL_MODE_CONFIG_TAB* FDKaacEnc_GetChannelModeConfiguration(
+ const CHANNEL_MODE mode);
+
+#endif /* CHANNEL_MAP_H */
diff --git a/fdk-aac/libAACenc/src/chaosmeasure.cpp b/fdk-aac/libAACenc/src/chaosmeasure.cpp
new file mode 100644
index 0000000..664284b
--- /dev/null
+++ b/fdk-aac/libAACenc/src/chaosmeasure.cpp
@@ -0,0 +1,191 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Chaos measure calculation
+
+*******************************************************************************/
+
+#include "chaosmeasure.h"
+
+/*****************************************************************************
+ functionname: FDKaacEnc_FDKaacEnc_CalculateChaosMeasurePeakFast
+ description: Eberlein method of chaos measure calculation by high-pass
+ filtering amplitude spectrum
+ A special case of FDKaacEnc_CalculateChaosMeasureTonalGeneric
+-- highly optimized
+*****************************************************************************/
+static void FDKaacEnc_FDKaacEnc_CalculateChaosMeasurePeakFast(
+ FIXP_DBL *RESTRICT paMDCTDataNM0, INT numberOfLines,
+ FIXP_DBL *RESTRICT chaosMeasure) {
+ INT i, j;
+
+ /* calculate chaos measure by "peak filter" */
+ /* make even and odd pass through data */
+ FIXP_DBL left_0_div2,
+ center_0; /* left, center tap of filter, even numbered */
+ FIXP_DBL left_1_div2, center_1; /* left, center tap of filter, odd numbered */
+
+ left_0_div2 = (FIXP_DBL)(((LONG)paMDCTDataNM0[0] ^
+ ((LONG)paMDCTDataNM0[0] >> (DFRACT_BITS - 1))) >>
+ 1);
+ left_1_div2 = (FIXP_DBL)(((LONG)paMDCTDataNM0[1] ^
+ ((LONG)paMDCTDataNM0[1] >> (DFRACT_BITS - 1))) >>
+ 1);
+ center_0 = (FIXP_DBL)((LONG)paMDCTDataNM0[2] ^
+ ((LONG)paMDCTDataNM0[2] >> (DFRACT_BITS - 1)));
+ center_1 = (FIXP_DBL)((LONG)paMDCTDataNM0[3] ^
+ ((LONG)paMDCTDataNM0[3] >> (DFRACT_BITS - 1)));
+
+ for (j = 2; j < numberOfLines - 2; j += 2) {
+ FIXP_DBL right_0 =
+ (FIXP_DBL)((LONG)paMDCTDataNM0[j + 2] ^
+ ((LONG)paMDCTDataNM0[j + 2] >> (DFRACT_BITS - 1)));
+ FIXP_DBL tmp_0 = left_0_div2 + (right_0 >> 1);
+ FIXP_DBL right_1 =
+ (FIXP_DBL)((LONG)paMDCTDataNM0[j + 3] ^
+ ((LONG)paMDCTDataNM0[j + 3] >> (DFRACT_BITS - 1)));
+ FIXP_DBL tmp_1 = left_1_div2 + (right_1 >> 1);
+
+ if (tmp_0 < center_0) {
+ INT leadingBits = CntLeadingZeros(center_0) - 1;
+ tmp_0 = schur_div(tmp_0 << leadingBits, center_0 << leadingBits, 8);
+ tmp_0 = fMult(tmp_0, tmp_0);
+ } else {
+ tmp_0 = (FIXP_DBL)MAXVAL_DBL;
+ }
+ chaosMeasure[j + 0] = tmp_0;
+ left_0_div2 = center_0 >> 1;
+ center_0 = right_0;
+
+ if (tmp_1 < center_1) {
+ INT leadingBits = CntLeadingZeros(center_1) - 1;
+ tmp_1 = schur_div(tmp_1 << leadingBits, center_1 << leadingBits, 8);
+ tmp_1 = fMult(tmp_1, tmp_1);
+ } else {
+ tmp_1 = (FIXP_DBL)MAXVAL_DBL;
+ }
+
+ left_1_div2 = center_1 >> 1;
+ center_1 = right_1;
+ chaosMeasure[j + 1] = tmp_1;
+ }
+
+ /* provide chaos measure for first few lines */
+ chaosMeasure[0] = chaosMeasure[2];
+ chaosMeasure[1] = chaosMeasure[2];
+
+ /* provide chaos measure for last few lines */
+ for (i = (numberOfLines - 3); i < numberOfLines; i++)
+ chaosMeasure[i] = FL2FXCONST_DBL(0.5);
+}
+
+/*****************************************************************************
+ functionname: FDKaacEnc_CalculateChaosMeasure
+ description: calculates a chaosmeasure for every line, different methods
+ are available. 0 means tonal, 1 means noiselike
+ returns:
+ input: MDCT data, number of lines
+ output: chaosMeasure
+*****************************************************************************/
+void FDKaacEnc_CalculateChaosMeasure(FIXP_DBL *paMDCTDataNM0, INT numberOfLines,
+ FIXP_DBL *chaosMeasure)
+
+{
+ FDKaacEnc_FDKaacEnc_CalculateChaosMeasurePeakFast(
+ paMDCTDataNM0, numberOfLines, chaosMeasure);
+}
diff --git a/fdk-aac/libAACenc/src/chaosmeasure.h b/fdk-aac/libAACenc/src/chaosmeasure.h
new file mode 100644
index 0000000..60d4137
--- /dev/null
+++ b/fdk-aac/libAACenc/src/chaosmeasure.h
@@ -0,0 +1,112 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Chaos measure calculation
+
+*******************************************************************************/
+
+#ifndef CHAOSMEASURE_H
+#define CHAOSMEASURE_H
+
+#include "common_fix.h"
+#include "psy_const.h"
+
+void FDKaacEnc_CalculateChaosMeasure(FIXP_DBL *paMDCTDataNM0, INT numberOfLines,
+ FIXP_DBL *chaosMeasure);
+
+#endif /* CHAOSMEASURE_H */
diff --git a/fdk-aac/libAACenc/src/dyn_bits.cpp b/fdk-aac/libAACenc/src/dyn_bits.cpp
new file mode 100644
index 0000000..b52dc2e
--- /dev/null
+++ b/fdk-aac/libAACenc/src/dyn_bits.cpp
@@ -0,0 +1,665 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Noiseless coder module
+
+*******************************************************************************/
+
+#include "dyn_bits.h"
+#include "bit_cnt.h"
+#include "psy_const.h"
+#include "aacenc_pns.h"
+#include "aacEnc_ram.h"
+#include "aacEnc_rom.h"
+
+typedef INT (*lookUpTable)[CODE_BOOK_ESC_NDX + 1];
+
+static INT FDKaacEnc_getSideInfoBits(const SECTION_INFO* const huffsection,
+ const SHORT* const sideInfoTab,
+ const INT useHCR) {
+ INT sideInfoBits;
+
+ if (useHCR &&
+ ((huffsection->codeBook == 11) || (huffsection->codeBook >= 16))) {
+ sideInfoBits = 5;
+ } else {
+ sideInfoBits = sideInfoTab[huffsection->sfbCnt];
+ }
+
+ return (sideInfoBits);
+}
+
+/* count bits using all possible tables */
+static void FDKaacEnc_buildBitLookUp(
+ const SHORT* const quantSpectrum, const INT maxSfb,
+ const INT* const sfbOffset, const UINT* const sfbMax,
+ INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
+ SECTION_INFO* const huffsection) {
+ INT i, sfbWidth;
+
+ for (i = 0; i < maxSfb; i++) {
+ huffsection[i].sfbCnt = 1;
+ huffsection[i].sfbStart = i;
+ huffsection[i].sectionBits = INVALID_BITCOUNT;
+ huffsection[i].codeBook = -1;
+ sfbWidth = sfbOffset[i + 1] - sfbOffset[i];
+ FDKaacEnc_bitCount(quantSpectrum + sfbOffset[i], sfbWidth, sfbMax[i],
+ bitLookUp[i]);
+ }
+}
+
+/* essential helper functions */
+static inline INT FDKaacEnc_findBestBook(const INT* const bc, INT* const book,
+ const INT useVCB11) {
+ INT minBits = INVALID_BITCOUNT, j;
+
+ int end = CODE_BOOK_ESC_NDX;
+
+ for (j = 0; j <= end; j++) {
+ if (bc[j] < minBits) {
+ minBits = bc[j];
+ *book = j;
+ }
+ }
+ return (minBits);
+}
+
+static inline INT FDKaacEnc_findMinMergeBits(const INT* const bc1,
+ const INT* const bc2,
+ const INT useVCB11) {
+ INT minBits = INVALID_BITCOUNT, j;
+
+ DWORD_ALIGNED(bc1);
+ DWORD_ALIGNED(bc2);
+
+ for (j = 0; j <= CODE_BOOK_ESC_NDX; j++) {
+ minBits = fixMin(minBits, bc1[j] + bc2[j]);
+ }
+ return (minBits);
+}
+
+static inline void FDKaacEnc_mergeBitLookUp(INT* const RESTRICT bc1,
+ const INT* const RESTRICT bc2) {
+ int j;
+
+ for (j = 0; j <= CODE_BOOK_ESC_NDX; j++) {
+ FDK_ASSERT(INVALID_BITCOUNT == 0x1FFFFFFF);
+ bc1[j] = fixMin(bc1[j] + bc2[j], INVALID_BITCOUNT);
+ }
+}
+
+static inline INT FDKaacEnc_findMaxMerge(const INT* const mergeGainLookUp,
+ const SECTION_INFO* const huffsection,
+ const INT maxSfb, INT* const maxNdx) {
+ INT i, maxMergeGain = 0;
+ int lastMaxNdx = 0;
+
+ for (i = 0; i + huffsection[i].sfbCnt < maxSfb; i += huffsection[i].sfbCnt) {
+ if (mergeGainLookUp[i] > maxMergeGain) {
+ maxMergeGain = mergeGainLookUp[i];
+ lastMaxNdx = i;
+ }
+ }
+ *maxNdx = lastMaxNdx;
+ return (maxMergeGain);
+}
+
+static inline INT FDKaacEnc_CalcMergeGain(
+ const SECTION_INFO* const huffsection,
+ const INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
+ const SHORT* const sideInfoTab, const INT ndx1, const INT ndx2,
+ const INT useVCB11) {
+ INT MergeGain, MergeBits, SplitBits;
+
+ MergeBits =
+ sideInfoTab[huffsection[ndx1].sfbCnt + huffsection[ndx2].sfbCnt] +
+ FDKaacEnc_findMinMergeBits(bitLookUp[ndx1], bitLookUp[ndx2], useVCB11);
+ SplitBits =
+ huffsection[ndx1].sectionBits +
+ huffsection[ndx2].sectionBits; /* Bit amount for splitted huffsections */
+ MergeGain = SplitBits - MergeBits;
+
+ if ((huffsection[ndx1].codeBook == CODE_BOOK_PNS_NO) ||
+ (huffsection[ndx2].codeBook == CODE_BOOK_PNS_NO) ||
+ (huffsection[ndx1].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
+ (huffsection[ndx2].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
+ (huffsection[ndx1].codeBook == CODE_BOOK_IS_IN_PHASE_NO) ||
+ (huffsection[ndx2].codeBook == CODE_BOOK_IS_IN_PHASE_NO)) {
+ MergeGain = -1;
+ }
+
+ return (MergeGain);
+}
+
+/* sectioning Stage 0:find minimum codbooks */
+static void FDKaacEnc_gmStage0(
+ SECTION_INFO* const RESTRICT huffsection,
+ const INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], const INT maxSfb,
+ const INT* const noiseNrg, const INT* const isBook) {
+ INT i;
+
+ for (i = 0; i < maxSfb; i++) {
+ /* Side-Info bits will be calculated in Stage 1! */
+ if (huffsection[i].sectionBits == INVALID_BITCOUNT) {
+ /* intensity and pns codebooks are already allocated in bitcount.c */
+ if (noiseNrg[i] != NO_NOISE_PNS) {
+ huffsection[i].codeBook = CODE_BOOK_PNS_NO;
+ huffsection[i].sectionBits = 0;
+ } else if (isBook[i]) {
+ huffsection[i].codeBook = isBook[i];
+ huffsection[i].sectionBits = 0;
+ } else {
+ huffsection[i].sectionBits =
+ FDKaacEnc_findBestBook(bitLookUp[i], &(huffsection[i].codeBook),
+ 0); /* useVCB11 must be 0!!! */
+ }
+ }
+ }
+}
+
+/*
+ sectioning Stage 1:merge all connected regions with the same code book and
+ calculate side info
+ */
+static void FDKaacEnc_gmStage1(
+ SECTION_INFO* const RESTRICT huffsection,
+ INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], const INT maxSfb,
+ const SHORT* const sideInfoTab, const INT useVCB11) {
+ INT mergeStart = 0, mergeEnd;
+
+ do {
+ for (mergeEnd = mergeStart + 1; mergeEnd < maxSfb; mergeEnd++) {
+ if (huffsection[mergeStart].codeBook != huffsection[mergeEnd].codeBook)
+ break;
+
+ /* we can merge. update tables, side info bits will be updated outside of
+ * this loop */
+ huffsection[mergeStart].sfbCnt++;
+ huffsection[mergeStart].sectionBits += huffsection[mergeEnd].sectionBits;
+
+ /* update bit look up for all code books */
+ FDKaacEnc_mergeBitLookUp(bitLookUp[mergeStart], bitLookUp[mergeEnd]);
+ }
+
+ /* add side info info bits */
+ huffsection[mergeStart].sectionBits += FDKaacEnc_getSideInfoBits(
+ &huffsection[mergeStart], sideInfoTab, useVCB11);
+ huffsection[mergeEnd - 1].sfbStart =
+ huffsection[mergeStart].sfbStart; /* speed up prev search */
+
+ mergeStart = mergeEnd;
+
+ } while (mergeStart < maxSfb);
+}
+
+/*
+ sectioning Stage 2:greedy merge algorithm, merge connected sections with
+ maximum bit gain until no more gain is possible
+ */
+static inline void FDKaacEnc_gmStage2(
+ SECTION_INFO* const RESTRICT huffsection,
+ INT* const RESTRICT mergeGainLookUp,
+ INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], const INT maxSfb,
+ const SHORT* const sideInfoTab, const INT useVCB11) {
+ INT i;
+
+ for (i = 0; i + huffsection[i].sfbCnt < maxSfb; i += huffsection[i].sfbCnt) {
+ mergeGainLookUp[i] =
+ FDKaacEnc_CalcMergeGain(huffsection, bitLookUp, sideInfoTab, i,
+ i + huffsection[i].sfbCnt, useVCB11);
+ }
+
+ while (TRUE) {
+ INT maxMergeGain, maxNdx, maxNdxNext, maxNdxLast;
+
+ maxMergeGain =
+ FDKaacEnc_findMaxMerge(mergeGainLookUp, huffsection, maxSfb, &maxNdx);
+
+ /* exit while loop if no more gain is possible */
+ if (maxMergeGain <= 0) break;
+
+ maxNdxNext = maxNdx + huffsection[maxNdx].sfbCnt;
+
+ /* merge sections with maximum bit gain */
+ huffsection[maxNdx].sfbCnt += huffsection[maxNdxNext].sfbCnt;
+ huffsection[maxNdx].sectionBits +=
+ huffsection[maxNdxNext].sectionBits - maxMergeGain;
+
+ /* update bit look up table for merged huffsection */
+ FDKaacEnc_mergeBitLookUp(bitLookUp[maxNdx], bitLookUp[maxNdxNext]);
+
+ /* update mergeLookUpTable */
+ if (maxNdx != 0) {
+ maxNdxLast = huffsection[maxNdx - 1].sfbStart;
+ mergeGainLookUp[maxNdxLast] = FDKaacEnc_CalcMergeGain(
+ huffsection, bitLookUp, sideInfoTab, maxNdxLast, maxNdx, useVCB11);
+ }
+ maxNdxNext = maxNdx + huffsection[maxNdx].sfbCnt;
+
+ huffsection[maxNdxNext - 1].sfbStart = huffsection[maxNdx].sfbStart;
+
+ if (maxNdxNext < maxSfb)
+ mergeGainLookUp[maxNdx] = FDKaacEnc_CalcMergeGain(
+ huffsection, bitLookUp, sideInfoTab, maxNdx, maxNdxNext, useVCB11);
+ }
+}
+
+/* count bits used by the noiseless coder */
+static void FDKaacEnc_noiselessCounter(
+ SECTION_DATA* const RESTRICT sectionData, INT mergeGainLookUp[MAX_SFB_LONG],
+ INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
+ const SHORT* const quantSpectrum, const UINT* const maxValueInSfb,
+ const INT* const sfbOffset, const INT blockType, const INT* const noiseNrg,
+ const INT* const isBook, const INT useVCB11) {
+ INT grpNdx, i;
+ const SHORT* sideInfoTab = NULL;
+ SECTION_INFO* huffsection;
+
+ /* use appropriate side info table */
+ switch (blockType) {
+ case LONG_WINDOW:
+ case START_WINDOW:
+ case STOP_WINDOW:
+ default:
+ sideInfoTab = FDKaacEnc_sideInfoTabLong;
+ break;
+ case SHORT_WINDOW:
+ sideInfoTab = FDKaacEnc_sideInfoTabShort;
+ break;
+ }
+
+ FDK_ASSERT(sideInfoTab != NULL);
+
+ sectionData->noOfSections = 0;
+ sectionData->huffmanBits = 0;
+ sectionData->sideInfoBits = 0;
+
+ if (sectionData->maxSfbPerGroup == 0) return;
+
+ /* loop trough groups */
+ for (grpNdx = 0; grpNdx < sectionData->sfbCnt;
+ grpNdx += sectionData->sfbPerGroup) {
+ huffsection = sectionData->huffsection + sectionData->noOfSections;
+
+ /* count bits in this group */
+ FDKaacEnc_buildBitLookUp(quantSpectrum, sectionData->maxSfbPerGroup,
+ sfbOffset + grpNdx, maxValueInSfb + grpNdx,
+ bitLookUp, huffsection);
+
+ /* 0.Stage :Find minimum Codebooks */
+ FDKaacEnc_gmStage0(huffsection, bitLookUp, sectionData->maxSfbPerGroup,
+ noiseNrg + grpNdx, isBook + grpNdx);
+
+ /* 1.Stage :Merge all connected regions with the same code book */
+ FDKaacEnc_gmStage1(huffsection, bitLookUp, sectionData->maxSfbPerGroup,
+ sideInfoTab, useVCB11);
+
+ /*
+ 2.Stage
+ greedy merge algorithm, merge connected huffsections with maximum bit
+ gain until no more gain is possible
+ */
+
+ FDKaacEnc_gmStage2(huffsection, mergeGainLookUp, bitLookUp,
+ sectionData->maxSfbPerGroup, sideInfoTab, useVCB11);
+
+ /*
+ compress output, calculate total huff and side bits
+ since we did not update the actual codebook in stage 2
+ to save time, we must set it here for later use in bitenc
+ */
+
+ for (i = 0; i < sectionData->maxSfbPerGroup; i += huffsection[i].sfbCnt) {
+ if ((huffsection[i].codeBook == CODE_BOOK_PNS_NO) ||
+ (huffsection[i].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
+ (huffsection[i].codeBook == CODE_BOOK_IS_IN_PHASE_NO)) {
+ huffsection[i].sectionBits = 0;
+ } else {
+ /* the sections in the sectionData are now marked with the optimal code
+ * book */
+
+ FDKaacEnc_findBestBook(bitLookUp[i], &(huffsection[i].codeBook),
+ useVCB11);
+
+ sectionData->huffmanBits +=
+ huffsection[i].sectionBits -
+ FDKaacEnc_getSideInfoBits(&huffsection[i], sideInfoTab, useVCB11);
+ }
+
+ huffsection[i].sfbStart += grpNdx;
+
+ /* sum up side info bits (section data bits) */
+ sectionData->sideInfoBits +=
+ FDKaacEnc_getSideInfoBits(&huffsection[i], sideInfoTab, useVCB11);
+ sectionData->huffsection[sectionData->noOfSections++] = huffsection[i];
+ }
+ }
+}
+
+/*******************************************************************************
+
+ functionname: FDKaacEnc_scfCount
+ returns : ---
+ description : count bits used by scalefactors.
+
+ not in all cases if maxValueInSfb[] == 0 we set deltaScf
+ to zero. only if the difference of the last and future
+ scalefacGain is not greater then CODE_BOOK_SCF_LAV (60).
+
+ example:
+ ^
+ scalefacGain |
+ |
+ | last 75
+ | |
+ | |
+ | |
+ | | current 50
+ | | |
+ | | |
+ | | |
+ | | |
+ | | | future 5
+ | | | |
+ --- ... ---------------------------- ... --------->
+ sfb
+
+
+ if maxValueInSfb[] of current is zero because of a
+ notfallstrategie, we do not save bits and transmit a
+ deltaScf of 25. otherwise the deltaScf between the last
+ scalfacGain (75) and the future scalefacGain (5) is 70.
+
+********************************************************************************/
+static void FDKaacEnc_scfCount(const INT* const scalefacGain,
+ const UINT* const maxValueInSfb,
+ SECTION_DATA* const RESTRICT sectionData,
+ const INT* const isScale) {
+ INT i, j, k, m, n;
+
+ INT lastValScf = 0;
+ INT deltaScf = 0;
+ INT found = 0;
+ INT scfSkipCounter = 0;
+ INT lastValIs = 0;
+
+ sectionData->scalefacBits = 0;
+
+ if (scalefacGain == NULL) return;
+
+ sectionData->firstScf = 0;
+
+ for (i = 0; i < sectionData->noOfSections; i++) {
+ if (sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) {
+ sectionData->firstScf = sectionData->huffsection[i].sfbStart;
+ lastValScf = scalefacGain[sectionData->firstScf];
+ break;
+ }
+ }
+
+ for (i = 0; i < sectionData->noOfSections; i++) {
+ if ((sectionData->huffsection[i].codeBook ==
+ CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
+ (sectionData->huffsection[i].codeBook == CODE_BOOK_IS_IN_PHASE_NO)) {
+ for (j = sectionData->huffsection[i].sfbStart;
+ j < sectionData->huffsection[i].sfbStart +
+ sectionData->huffsection[i].sfbCnt;
+ j++) {
+ INT deltaIs = isScale[j] - lastValIs;
+ lastValIs = isScale[j];
+ sectionData->scalefacBits +=
+ FDKaacEnc_bitCountScalefactorDelta(deltaIs);
+ }
+ } /* Intensity */
+ else if ((sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) &&
+ (sectionData->huffsection[i].codeBook != CODE_BOOK_PNS_NO)) {
+ INT tmp = sectionData->huffsection[i].sfbStart +
+ sectionData->huffsection[i].sfbCnt;
+ for (j = sectionData->huffsection[i].sfbStart; j < tmp; j++) {
+ /* check if we can repeat the last value to save bits */
+ if (maxValueInSfb[j] == 0) {
+ found = 0;
+ /* are scalefactors skipped? */
+ if (scfSkipCounter == 0) {
+ /* end of section */
+ if (j == (tmp - 1))
+ found = 0; /* search in other sections for maxValueInSfb != 0 */
+ else {
+ /* search in this section for the next maxValueInSfb[] != 0 */
+ for (k = (j + 1); k < tmp; k++) {
+ if (maxValueInSfb[k] != 0) {
+ found = 1;
+ if ((fixp_abs(scalefacGain[k] - lastValScf)) <=
+ CODE_BOOK_SCF_LAV)
+ deltaScf = 0; /* save bits */
+ else {
+ /* do not save bits */
+ deltaScf = lastValScf - scalefacGain[j];
+ lastValScf = scalefacGain[j];
+ scfSkipCounter = 0;
+ }
+ break;
+ }
+ /* count scalefactor skip */
+ scfSkipCounter++;
+ }
+ }
+
+ /* search for the next maxValueInSfb[] != 0 in all other sections */
+ for (m = (i + 1); (m < sectionData->noOfSections) && (found == 0);
+ m++) {
+ if ((sectionData->huffsection[m].codeBook != CODE_BOOK_ZERO_NO) &&
+ (sectionData->huffsection[m].codeBook != CODE_BOOK_PNS_NO)) {
+ INT end = sectionData->huffsection[m].sfbStart +
+ sectionData->huffsection[m].sfbCnt;
+ for (n = sectionData->huffsection[m].sfbStart; n < end; n++) {
+ if (maxValueInSfb[n] != 0) {
+ found = 1;
+ if (fixp_abs(scalefacGain[n] - lastValScf) <=
+ CODE_BOOK_SCF_LAV)
+ deltaScf = 0; /* save bits */
+ else {
+ /* do not save bits */
+ deltaScf = lastValScf - scalefacGain[j];
+ lastValScf = scalefacGain[j];
+ scfSkipCounter = 0;
+ }
+ break;
+ }
+ /* count scalefactor skip */
+ scfSkipCounter++;
+ }
+ }
+ }
+ /* no maxValueInSfb[] != 0 found */
+ if (found == 0) {
+ deltaScf = 0;
+ scfSkipCounter = 0;
+ }
+ } else {
+ /* consider skipped scalefactors */
+ deltaScf = 0;
+ scfSkipCounter--;
+ }
+ } else {
+ deltaScf = lastValScf - scalefacGain[j];
+ lastValScf = scalefacGain[j];
+ }
+ sectionData->scalefacBits +=
+ FDKaacEnc_bitCountScalefactorDelta(deltaScf);
+ }
+ }
+ } /* for (i=0; i<sectionData->noOfSections; i++) */
+}
+
+/* count bits used by pns */
+static void FDKaacEnc_noiseCount(SECTION_DATA* const RESTRICT sectionData,
+ const INT* const noiseNrg) {
+ INT noisePCMFlag = TRUE;
+ INT lastValPns = 0, deltaPns;
+ int i, j;
+
+ sectionData->noiseNrgBits = 0;
+
+ for (i = 0; i < sectionData->noOfSections; i++) {
+ if (sectionData->huffsection[i].codeBook == CODE_BOOK_PNS_NO) {
+ int sfbStart = sectionData->huffsection[i].sfbStart;
+ int sfbEnd = sfbStart + sectionData->huffsection[i].sfbCnt;
+ for (j = sfbStart; j < sfbEnd; j++) {
+ if (noisePCMFlag) {
+ sectionData->noiseNrgBits += PNS_PCM_BITS;
+ lastValPns = noiseNrg[j];
+ noisePCMFlag = FALSE;
+ } else {
+ deltaPns = noiseNrg[j] - lastValPns;
+ lastValPns = noiseNrg[j];
+ sectionData->noiseNrgBits +=
+ FDKaacEnc_bitCountScalefactorDelta(deltaPns);
+ }
+ }
+ }
+ }
+}
+
+INT FDKaacEnc_dynBitCount(BITCNTR_STATE* const hBC,
+ const SHORT* const quantSpectrum,
+ const UINT* const maxValueInSfb,
+ const INT* const scalefac, const INT blockType,
+ const INT sfbCnt, const INT maxSfbPerGroup,
+ const INT sfbPerGroup, const INT* const sfbOffset,
+ SECTION_DATA* const RESTRICT sectionData,
+ const INT* const noiseNrg, const INT* const isBook,
+ const INT* const isScale, const UINT syntaxFlags) {
+ sectionData->blockType = blockType;
+ sectionData->sfbCnt = sfbCnt;
+ sectionData->sfbPerGroup = sfbPerGroup;
+ sectionData->noOfGroups = sfbCnt / sfbPerGroup;
+ sectionData->maxSfbPerGroup = maxSfbPerGroup;
+
+ FDKaacEnc_noiselessCounter(sectionData, hBC->mergeGainLookUp,
+ (lookUpTable)hBC->bitLookUp, quantSpectrum,
+ maxValueInSfb, sfbOffset, blockType, noiseNrg,
+ isBook, (syntaxFlags & AC_ER_VCB11) ? 1 : 0);
+
+ FDKaacEnc_scfCount(scalefac, maxValueInSfb, sectionData, isScale);
+
+ FDKaacEnc_noiseCount(sectionData, noiseNrg);
+
+ return (sectionData->huffmanBits + sectionData->sideInfoBits +
+ sectionData->scalefacBits + sectionData->noiseNrgBits);
+}
+
+INT FDKaacEnc_BCNew(BITCNTR_STATE** phBC, UCHAR* dynamic_RAM) {
+ BITCNTR_STATE* hBC = GetRam_aacEnc_BitCntrState();
+
+ if (hBC) {
+ *phBC = hBC;
+ hBC->bitLookUp = GetRam_aacEnc_BitLookUp(0, dynamic_RAM);
+ hBC->mergeGainLookUp = GetRam_aacEnc_MergeGainLookUp(0, dynamic_RAM);
+ if (hBC->bitLookUp == 0 || hBC->mergeGainLookUp == 0) {
+ return 1;
+ }
+ }
+ return (hBC == 0) ? 1 : 0;
+}
+
+void FDKaacEnc_BCClose(BITCNTR_STATE** phBC) {
+ if (*phBC != NULL) {
+ FreeRam_aacEnc_BitCntrState(phBC);
+ }
+}
diff --git a/fdk-aac/libAACenc/src/dyn_bits.h b/fdk-aac/libAACenc/src/dyn_bits.h
new file mode 100644
index 0000000..a727a30
--- /dev/null
+++ b/fdk-aac/libAACenc/src/dyn_bits.h
@@ -0,0 +1,160 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Noiseless coder module
+
+*******************************************************************************/
+
+#ifndef DYN_BITS_H
+#define DYN_BITS_H
+
+#include "common_fix.h"
+
+#include "psy_const.h"
+#include "aacenc_tns.h"
+
+#define MAX_SECTIONS MAX_GROUPED_SFB
+#define SECT_ESC_VAL_LONG 31
+#define SECT_ESC_VAL_SHORT 7
+#define CODE_BOOK_BITS 4
+#define SECT_BITS_LONG 5
+#define SECT_BITS_SHORT 3
+#define PNS_PCM_BITS 9
+
+typedef struct {
+ INT codeBook;
+ INT sfbStart;
+ INT sfbCnt;
+ INT sectionBits; /* huff + si ! */
+} SECTION_INFO;
+
+typedef struct {
+ INT blockType;
+ INT noOfGroups;
+ INT sfbCnt;
+ INT maxSfbPerGroup;
+ INT sfbPerGroup;
+ INT noOfSections;
+ SECTION_INFO huffsection[MAX_SECTIONS];
+ INT sideInfoBits; /* sectioning bits */
+ INT huffmanBits; /* huffman coded bits */
+ INT scalefacBits; /* scalefac coded bits */
+ INT noiseNrgBits; /* noiseEnergy coded bits */
+ INT firstScf; /* first scf to be coded */
+} SECTION_DATA;
+
+struct BITCNTR_STATE {
+ INT* bitLookUp;
+ INT* mergeGainLookUp;
+};
+
+INT FDKaacEnc_BCNew(BITCNTR_STATE** phBC, UCHAR* dynamic_RAM);
+
+void FDKaacEnc_BCClose(BITCNTR_STATE** phBC);
+
+INT FDKaacEnc_dynBitCount(BITCNTR_STATE* const hBC,
+ const SHORT* const quantSpectrum,
+ const UINT* const maxValueInSfb,
+ const INT* const scalefac, const INT blockType,
+ const INT sfbCnt, const INT maxSfbPerGroup,
+ const INT sfbPerGroup, const INT* const sfbOffset,
+ SECTION_DATA* const RESTRICT sectionData,
+ const INT* const noiseNrg, const INT* const isBook,
+ const INT* const isScale, const UINT syntaxFlags);
+
+#endif
diff --git a/fdk-aac/libAACenc/src/grp_data.cpp b/fdk-aac/libAACenc/src/grp_data.cpp
new file mode 100644
index 0000000..bc9d85f
--- /dev/null
+++ b/fdk-aac/libAACenc/src/grp_data.cpp
@@ -0,0 +1,264 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Short block grouping
+
+*******************************************************************************/
+
+#include "psy_const.h"
+#include "interface.h"
+
+/*
+ * this routine does not work in-place
+ */
+
+/*
+ * Don't use fAddSaturate2() because it looses one bit accuracy which is
+ * usefull for quality.
+ */
+static inline FIXP_DBL nrgAddSaturate(const FIXP_DBL a, const FIXP_DBL b) {
+ return ((a >= (FIXP_DBL)MAXVAL_DBL - b) ? (FIXP_DBL)MAXVAL_DBL : (a + b));
+}
+
+void FDKaacEnc_groupShortData(FIXP_DBL *mdctSpectrum, /* in-out */
+ SFB_THRESHOLD *sfbThreshold, /* in-out */
+ SFB_ENERGY *sfbEnergy, /* in-out */
+ SFB_ENERGY *sfbEnergyMS, /* in-out */
+ SFB_ENERGY *sfbSpreadEnergy, const INT sfbCnt,
+ const INT sfbActive, const INT *sfbOffset,
+ const FIXP_DBL *sfbMinSnrLdData,
+ INT *groupedSfbOffset, /* out */
+ INT *maxSfbPerGroup, /* out */
+ FIXP_DBL *groupedSfbMinSnrLdData,
+ const INT noOfGroups, const INT *groupLen,
+ const INT granuleLength) {
+ INT i, j;
+ INT line; /* counts through lines */
+ INT sfb; /* counts through scalefactor bands */
+ INT grp; /* counts through groups */
+ INT wnd; /* counts through windows in a group */
+ INT offset; /* needed in sfbOffset grouping */
+ INT highestSfb;
+ INT granuleLength_short = granuleLength / TRANS_FAC;
+
+ C_ALLOC_SCRATCH_START(tmpSpectrum, FIXP_DBL, (1024))
+
+ /* for short blocks: regroup spectrum and */
+ /* group energies and thresholds according to grouping */
+
+ /* calculate maxSfbPerGroup */
+ highestSfb = 0;
+ for (wnd = 0; wnd < TRANS_FAC; wnd++) {
+ for (sfb = sfbActive - 1; sfb >= highestSfb; sfb--) {
+ for (line = sfbOffset[sfb + 1] - 1; line >= sfbOffset[sfb]; line--) {
+ if (mdctSpectrum[wnd * granuleLength_short + line] !=
+ FL2FXCONST_SPC(0.0))
+ break; /* this band is not completely zero */
+ }
+ if (line >= sfbOffset[sfb]) break; /* this band was not completely zero */
+ }
+ highestSfb = fixMax(highestSfb, sfb);
+ }
+ highestSfb = highestSfb > 0 ? highestSfb : 0;
+ *maxSfbPerGroup = highestSfb + 1;
+
+ /* calculate groupedSfbOffset */
+ i = 0;
+ offset = 0;
+ for (grp = 0; grp < noOfGroups; grp++) {
+ for (sfb = 0; sfb < sfbActive + 1; sfb++) {
+ groupedSfbOffset[i++] = offset + sfbOffset[sfb] * groupLen[grp];
+ }
+ i += sfbCnt - sfb;
+ offset += groupLen[grp] * granuleLength_short;
+ }
+ groupedSfbOffset[i++] = granuleLength;
+
+ /* calculate groupedSfbMinSnr */
+ i = 0;
+ for (grp = 0; grp < noOfGroups; grp++) {
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ groupedSfbMinSnrLdData[i++] = sfbMinSnrLdData[sfb];
+ }
+ i += sfbCnt - sfb;
+ }
+
+ /* sum up sfbThresholds */
+ wnd = 0;
+ i = 0;
+ for (grp = 0; grp < noOfGroups; grp++) {
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ FIXP_DBL thresh = sfbThreshold->Short[wnd][sfb];
+ for (j = 1; j < groupLen[grp]; j++) {
+ thresh = nrgAddSaturate(thresh, sfbThreshold->Short[wnd + j][sfb]);
+ }
+ sfbThreshold->Long[i++] = thresh;
+ }
+ i += sfbCnt - sfb;
+ wnd += groupLen[grp];
+ }
+
+ /* sum up sfbEnergies left/right */
+ wnd = 0;
+ i = 0;
+ for (grp = 0; grp < noOfGroups; grp++) {
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ FIXP_DBL energy = sfbEnergy->Short[wnd][sfb];
+ for (j = 1; j < groupLen[grp]; j++) {
+ energy = nrgAddSaturate(energy, sfbEnergy->Short[wnd + j][sfb]);
+ }
+ sfbEnergy->Long[i++] = energy;
+ }
+ i += sfbCnt - sfb;
+ wnd += groupLen[grp];
+ }
+
+ /* sum up sfbEnergies mid/side */
+ wnd = 0;
+ i = 0;
+ for (grp = 0; grp < noOfGroups; grp++) {
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ FIXP_DBL energy = sfbEnergyMS->Short[wnd][sfb];
+ for (j = 1; j < groupLen[grp]; j++) {
+ energy = nrgAddSaturate(energy, sfbEnergyMS->Short[wnd + j][sfb]);
+ }
+ sfbEnergyMS->Long[i++] = energy;
+ }
+ i += sfbCnt - sfb;
+ wnd += groupLen[grp];
+ }
+
+ /* sum up sfbSpreadEnergies */
+ wnd = 0;
+ i = 0;
+ for (grp = 0; grp < noOfGroups; grp++) {
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ FIXP_DBL energy = sfbSpreadEnergy->Short[wnd][sfb];
+ for (j = 1; j < groupLen[grp]; j++) {
+ energy = nrgAddSaturate(energy, sfbSpreadEnergy->Short[wnd + j][sfb]);
+ }
+ sfbSpreadEnergy->Long[i++] = energy;
+ }
+ i += sfbCnt - sfb;
+ wnd += groupLen[grp];
+ }
+
+ /* re-group spectrum */
+ wnd = 0;
+ i = 0;
+ for (grp = 0; grp < noOfGroups; grp++) {
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ int width = sfbOffset[sfb + 1] - sfbOffset[sfb];
+ FIXP_DBL *pMdctSpectrum =
+ &mdctSpectrum[sfbOffset[sfb]] + wnd * granuleLength_short;
+ for (j = 0; j < groupLen[grp]; j++) {
+ FIXP_DBL *pTmp = pMdctSpectrum;
+ for (line = width; line > 0; line--) {
+ tmpSpectrum[i++] = *pTmp++;
+ }
+ pMdctSpectrum += granuleLength_short;
+ }
+ }
+ i += (groupLen[grp] * (sfbOffset[sfbCnt] - sfbOffset[sfb]));
+ wnd += groupLen[grp];
+ }
+
+ FDKmemcpy(mdctSpectrum, tmpSpectrum, granuleLength * sizeof(FIXP_DBL));
+
+ C_ALLOC_SCRATCH_END(tmpSpectrum, FIXP_DBL, (1024))
+}
diff --git a/fdk-aac/libAACenc/src/grp_data.h b/fdk-aac/libAACenc/src/grp_data.h
new file mode 100644
index 0000000..3e1a708
--- /dev/null
+++ b/fdk-aac/libAACenc/src/grp_data.h
@@ -0,0 +1,123 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Short block grouping
+
+*******************************************************************************/
+
+#ifndef GRP_DATA_H
+#define GRP_DATA_H
+
+#include "common_fix.h"
+
+#include "psy_data.h"
+
+void FDKaacEnc_groupShortData(FIXP_DBL *mdctSpectrum, /* in-out */
+ SFB_THRESHOLD *sfbThreshold, /* in-out */
+ SFB_ENERGY *sfbEnergy, /* in-out */
+ SFB_ENERGY *sfbEnergyMS, /* in-out */
+ SFB_ENERGY *sfbSpreadEnergy, const INT sfbCnt,
+ const INT sfbActive, const INT *sfbOffset,
+ const FIXP_DBL *sfbMinSnrLdData,
+ INT *groupedSfbOffset, /* out */
+ INT *maxSfbPerGroup,
+ FIXP_DBL *groupedSfbMinSnrLdData,
+ const INT noOfGroups, const INT *groupLen,
+ const INT granuleLength);
+
+#endif /* _INTERFACE_H */
diff --git a/fdk-aac/libAACenc/src/intensity.cpp b/fdk-aac/libAACenc/src/intensity.cpp
new file mode 100644
index 0000000..8cb1b45
--- /dev/null
+++ b/fdk-aac/libAACenc/src/intensity.cpp
@@ -0,0 +1,810 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): A. Horndasch (code originally from lwr) / Josef Hoepfl (FDK)
+
+ Description: intensity stereo processing
+
+*******************************************************************************/
+
+#include "intensity.h"
+
+#include "interface.h"
+#include "psy_configuration.h"
+#include "psy_const.h"
+#include "qc_main.h"
+#include "bit_cnt.h"
+
+/* only set an IS seed it left/right channel correlation is above IS_CORR_THRESH
+ */
+#define IS_CORR_THRESH FL2FXCONST_DBL(0.95f)
+
+/* when expanding the IS region to more SFBs only accept an error that is
+ * not more than IS_TOTAL_ERROR_THRESH overall and
+ * not more than IS_LOCAL_ERROR_THRESH for the current SFB */
+#define IS_TOTAL_ERROR_THRESH FL2FXCONST_DBL(0.04f)
+#define IS_LOCAL_ERROR_THRESH FL2FXCONST_DBL(0.01f)
+
+/* the maximum allowed change of the intensity direction (unit: IS scale) -
+ * scaled with factor 0.25 - */
+#define IS_DIRECTION_DEVIATION_THRESH_SF 2
+#define IS_DIRECTION_DEVIATION_THRESH \
+ FL2FXCONST_DBL(2.0f / (1 << IS_DIRECTION_DEVIATION_THRESH_SF))
+
+/* IS regions need to have a minimal percentage of the overall loudness, e.g.
+ * 0.06 == 6% */
+#define IS_REGION_MIN_LOUDNESS FL2FXCONST_DBL(0.1f)
+
+/* only perform IS if IS_MIN_SFBS neighboring SFBs can be processed */
+#define IS_MIN_SFBS 6
+
+/* only do IS if
+ * if IS_LEFT_RIGHT_RATIO_THRESH < sfbEnergyLeft[sfb]/sfbEnergyRight[sfb] < 1 /
+ * IS_LEFT_RIGHT_RATIO_THRESH
+ * -> no IS if the panning angle is not far from the middle, MS will do */
+/* this is equivalent to a scale of +/-1.02914634566 */
+#define IS_LEFT_RIGHT_RATIO_THRESH FL2FXCONST_DBL(0.7f)
+
+/* scalefactor of realScale */
+#define REAL_SCALE_SF 1
+
+/* scalefactor overallLoudness */
+#define OVERALL_LOUDNESS_SF 6
+
+/* scalefactor for sum over max samples per goup */
+#define MAX_SFB_PER_GROUP_SF 6
+
+/* scalefactor for sum of mdct spectrum */
+#define MDCT_SPEC_SF 6
+
+typedef struct {
+ FIXP_DBL corr_thresh; /*!< Only set an IS seed it left/right channel
+ correlation is above corr_thresh */
+
+ FIXP_DBL total_error_thresh; /*!< When expanding the IS region to more SFBs
+ only accept an error that is not more than
+ 'total_error_thresh' overall. */
+
+ FIXP_DBL local_error_thresh; /*!< When expanding the IS region to more SFBs
+ only accept an error that is not more than
+ 'local_error_thresh' for the current SFB. */
+
+ FIXP_DBL direction_deviation_thresh; /*!< The maximum allowed change of the
+ intensity direction (unit: IS scale)
+ */
+
+ FIXP_DBL is_region_min_loudness; /*!< IS regions need to have a minimal
+ percentage of the overall loudness, e.g.
+ 0.06 == 6% */
+
+ INT min_is_sfbs; /*!< Only perform IS if 'min_is_sfbs' neighboring SFBs can be
+ processed */
+
+ FIXP_DBL left_right_ratio_threshold; /*!< No IS if the panning angle is not
+ far from the middle, MS will do */
+
+} INTENSITY_PARAMETERS;
+
+/*****************************************************************************
+
+ functionname: calcSfbMaxScale
+
+ description: Calc max value in scalefactor band
+
+ input: *mdctSpectrum
+ l1
+ l2
+
+ output: none
+
+ returns: scalefactor
+
+*****************************************************************************/
+static INT calcSfbMaxScale(const FIXP_DBL *mdctSpectrum, const INT l1,
+ const INT l2) {
+ INT i;
+ INT sfbMaxScale;
+ FIXP_DBL maxSpc;
+
+ maxSpc = FL2FXCONST_DBL(0.0);
+ for (i = l1; i < l2; i++) {
+ FIXP_DBL tmp = fixp_abs((FIXP_DBL)mdctSpectrum[i]);
+ maxSpc = fixMax(maxSpc, tmp);
+ }
+ sfbMaxScale = (maxSpc == FL2FXCONST_DBL(0.0)) ? (DFRACT_BITS - 2)
+ : CntLeadingZeros(maxSpc) - 1;
+
+ return sfbMaxScale;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_initIsParams
+
+ description: Initialization of intensity parameters
+
+ input: isParams
+
+ output: isParams
+
+ returns: none
+
+*****************************************************************************/
+static void FDKaacEnc_initIsParams(INTENSITY_PARAMETERS *isParams) {
+ isParams->corr_thresh = IS_CORR_THRESH;
+ isParams->total_error_thresh = IS_TOTAL_ERROR_THRESH;
+ isParams->local_error_thresh = IS_LOCAL_ERROR_THRESH;
+ isParams->direction_deviation_thresh = IS_DIRECTION_DEVIATION_THRESH;
+ isParams->is_region_min_loudness = IS_REGION_MIN_LOUDNESS;
+ isParams->min_is_sfbs = IS_MIN_SFBS;
+ isParams->left_right_ratio_threshold = IS_LEFT_RIGHT_RATIO_THRESH;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_prepareIntensityDecision
+
+ description: Prepares intensity decision
+
+ input: sfbEnergyLeft
+ sfbEnergyRight
+ sfbEnergyLdDataLeft
+ sfbEnergyLdDataRight
+ mdctSpectrumLeft
+ sfbEnergyLdDataRight
+ isParams
+
+ output: hrrErr scale: none
+ isMask scale: none
+ realScale scale: LD_DATA_SHIFT + REAL_SCALE_SF
+ normSfbLoudness scale: none
+
+ returns: none
+
+*****************************************************************************/
+static void FDKaacEnc_prepareIntensityDecision(
+ const FIXP_DBL *sfbEnergyLeft, const FIXP_DBL *sfbEnergyRight,
+ const FIXP_DBL *sfbEnergyLdDataLeft, const FIXP_DBL *sfbEnergyLdDataRight,
+ const FIXP_DBL *mdctSpectrumLeft, const FIXP_DBL *mdctSpectrumRight,
+ const INTENSITY_PARAMETERS *isParams, FIXP_DBL *hrrErr, INT *isMask,
+ FIXP_DBL *realScale, FIXP_DBL *normSfbLoudness, const INT sfbCnt,
+ const INT sfbPerGroup, const INT maxSfbPerGroup, const INT *sfbOffset) {
+ INT j, sfb, sfboffs;
+ INT grpCounter;
+
+ /* temporary variables to compute loudness */
+ FIXP_DBL overallLoudness[MAX_NO_OF_GROUPS];
+
+ /* temporary variables to compute correlation */
+ FIXP_DBL channelCorr[MAX_GROUPED_SFB];
+ FIXP_DBL ml, mr;
+ FIXP_DBL prod_lr;
+ FIXP_DBL square_l, square_r;
+ FIXP_DBL tmp_l, tmp_r;
+ FIXP_DBL inv_n;
+
+ FDKmemclear(channelCorr, MAX_GROUPED_SFB * sizeof(FIXP_DBL));
+ FDKmemclear(normSfbLoudness, MAX_GROUPED_SFB * sizeof(FIXP_DBL));
+ FDKmemclear(overallLoudness, MAX_NO_OF_GROUPS * sizeof(FIXP_DBL));
+ FDKmemclear(realScale, MAX_GROUPED_SFB * sizeof(FIXP_DBL));
+
+ for (grpCounter = 0, sfboffs = 0; sfboffs < sfbCnt;
+ sfboffs += sfbPerGroup, grpCounter++) {
+ overallLoudness[grpCounter] = FL2FXCONST_DBL(0.0f);
+ for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+ INT sL, sR, s;
+ FIXP_DBL isValue = sfbEnergyLdDataLeft[sfb + sfboffs] -
+ sfbEnergyLdDataRight[sfb + sfboffs];
+
+ /* delimitate intensity scale value to representable range */
+ realScale[sfb + sfboffs] = fixMin(
+ FL2FXCONST_DBL(60.f / (1 << (REAL_SCALE_SF + LD_DATA_SHIFT))),
+ fixMax(FL2FXCONST_DBL(-60.f / (1 << (REAL_SCALE_SF + LD_DATA_SHIFT))),
+ isValue));
+
+ sL = fixMax(0, (CntLeadingZeros(sfbEnergyLeft[sfb + sfboffs]) - 1));
+ sR = fixMax(0, (CntLeadingZeros(sfbEnergyRight[sfb + sfboffs]) - 1));
+ s = (fixMin(sL, sR) >> 2) << 2;
+ normSfbLoudness[sfb + sfboffs] =
+ sqrtFixp(sqrtFixp(((sfbEnergyLeft[sfb + sfboffs] << s) >> 1) +
+ ((sfbEnergyRight[sfb + sfboffs] << s) >> 1))) >>
+ (s >> 2);
+
+ overallLoudness[grpCounter] +=
+ normSfbLoudness[sfb + sfboffs] >> OVERALL_LOUDNESS_SF;
+ /* don't do intensity if
+ * - panning angle is too close to the middle or
+ * - one channel is non-existent or
+ * - if it is dual mono */
+ if ((sfbEnergyLeft[sfb + sfboffs] >=
+ fMult(isParams->left_right_ratio_threshold,
+ sfbEnergyRight[sfb + sfboffs])) &&
+ (fMult(isParams->left_right_ratio_threshold,
+ sfbEnergyLeft[sfb + sfboffs]) <=
+ sfbEnergyRight[sfb + sfboffs])) {
+ /* this will prevent post processing from considering this SFB for
+ * merging */
+ hrrErr[sfb + sfboffs] = FL2FXCONST_DBL(1.0 / 8.0);
+ }
+ }
+ }
+
+ for (grpCounter = 0, sfboffs = 0; sfboffs < sfbCnt;
+ sfboffs += sfbPerGroup, grpCounter++) {
+ INT invOverallLoudnessSF;
+ FIXP_DBL invOverallLoudness;
+
+ if (overallLoudness[grpCounter] == FL2FXCONST_DBL(0.0)) {
+ invOverallLoudness = FL2FXCONST_DBL(0.0);
+ invOverallLoudnessSF = 0;
+ } else {
+ invOverallLoudness =
+ fDivNorm((FIXP_DBL)MAXVAL_DBL, overallLoudness[grpCounter],
+ &invOverallLoudnessSF);
+ invOverallLoudnessSF =
+ invOverallLoudnessSF - OVERALL_LOUDNESS_SF +
+ 1; /* +1: compensate fMultDiv2() in subsequent loop */
+ }
+ invOverallLoudnessSF = fixMin(
+ fixMax(invOverallLoudnessSF, -(DFRACT_BITS - 1)), DFRACT_BITS - 1);
+
+ for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+ FIXP_DBL tmp;
+
+ tmp = fMultDiv2((normSfbLoudness[sfb + sfboffs] >> OVERALL_LOUDNESS_SF)
+ << OVERALL_LOUDNESS_SF,
+ invOverallLoudness);
+
+ normSfbLoudness[sfb + sfboffs] = scaleValue(tmp, invOverallLoudnessSF);
+
+ channelCorr[sfb + sfboffs] = FL2FXCONST_DBL(0.0f);
+
+ /* max width of scalefactorband is 96; width's are always even */
+ /* inv_n is scaled with factor 2 to compensate fMultDiv2() in subsequent
+ * loops */
+ inv_n = GetInvInt(
+ (sfbOffset[sfb + sfboffs + 1] - sfbOffset[sfb + sfboffs]) >> 1);
+
+ if (inv_n > FL2FXCONST_DBL(0.0f)) {
+ INT s, sL, sR;
+
+ /* correlation := Pearson's product-moment coefficient */
+ /* compute correlation between channels and check if it is over
+ * threshold */
+ ml = FL2FXCONST_DBL(0.0f);
+ mr = FL2FXCONST_DBL(0.0f);
+ prod_lr = FL2FXCONST_DBL(0.0f);
+ square_l = FL2FXCONST_DBL(0.0f);
+ square_r = FL2FXCONST_DBL(0.0f);
+
+ sL = calcSfbMaxScale(mdctSpectrumLeft, sfbOffset[sfb + sfboffs],
+ sfbOffset[sfb + sfboffs + 1]);
+ sR = calcSfbMaxScale(mdctSpectrumRight, sfbOffset[sfb + sfboffs],
+ sfbOffset[sfb + sfboffs + 1]);
+ s = fixMin(sL, sR);
+
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1];
+ j++) {
+ ml += fMultDiv2((mdctSpectrumLeft[j] << s),
+ inv_n); // scaled with mdctScale - s + inv_n
+ mr += fMultDiv2((mdctSpectrumRight[j] << s),
+ inv_n); // scaled with mdctScale - s + inv_n
+ }
+ ml = fMultDiv2(ml, inv_n); // scaled with mdctScale - s + inv_n
+ mr = fMultDiv2(mr, inv_n); // scaled with mdctScale - s + inv_n
+
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1];
+ j++) {
+ tmp_l = fMultDiv2((mdctSpectrumLeft[j] << s), inv_n) -
+ ml; // scaled with mdctScale - s + inv_n
+ tmp_r = fMultDiv2((mdctSpectrumRight[j] << s), inv_n) -
+ mr; // scaled with mdctScale - s + inv_n
+
+ prod_lr += fMultDiv2(
+ tmp_l, tmp_r); // scaled with 2*(mdctScale - s + inv_n) + 1
+ square_l +=
+ fPow2Div2(tmp_l); // scaled with 2*(mdctScale - s + inv_n) + 1
+ square_r +=
+ fPow2Div2(tmp_r); // scaled with 2*(mdctScale - s + inv_n) + 1
+ }
+ prod_lr = prod_lr << 1; // scaled with 2*(mdctScale - s + inv_n)
+ square_l = square_l << 1; // scaled with 2*(mdctScale - s + inv_n)
+ square_r = square_r << 1; // scaled with 2*(mdctScale - s + inv_n)
+
+ if (square_l > FL2FXCONST_DBL(0.0f) &&
+ square_r > FL2FXCONST_DBL(0.0f)) {
+ INT channelCorrSF = 0;
+
+ /* local scaling of square_l and square_r is compensated after sqrt
+ * calculation */
+ sL = fixMax(0, (CntLeadingZeros(square_l) - 1));
+ sR = fixMax(0, (CntLeadingZeros(square_r) - 1));
+ s = ((sL + sR) >> 1) << 1;
+ sL = fixMin(sL, s);
+ sR = s - sL;
+ tmp = fMult(square_l << sL, square_r << sR);
+ tmp = sqrtFixp(tmp);
+
+ FDK_ASSERT(tmp > FL2FXCONST_DBL(0.0f));
+
+ /* numerator and denominator have the same scaling */
+ if (prod_lr < FL2FXCONST_DBL(0.0f)) {
+ channelCorr[sfb + sfboffs] =
+ -(fDivNorm(-prod_lr, tmp, &channelCorrSF));
+
+ } else {
+ channelCorr[sfb + sfboffs] =
+ (fDivNorm(prod_lr, tmp, &channelCorrSF));
+ }
+ channelCorrSF = fixMin(
+ fixMax((channelCorrSF + ((sL + sR) >> 1)), -(DFRACT_BITS - 1)),
+ DFRACT_BITS - 1);
+
+ if (channelCorrSF < 0) {
+ channelCorr[sfb + sfboffs] =
+ channelCorr[sfb + sfboffs] >> (-channelCorrSF);
+ } else {
+ /* avoid overflows due to limited computational accuracy */
+ if (fAbs(channelCorr[sfb + sfboffs]) >
+ (((FIXP_DBL)MAXVAL_DBL) >> channelCorrSF)) {
+ if (channelCorr[sfb + sfboffs] < FL2FXCONST_DBL(0.0f))
+ channelCorr[sfb + sfboffs] = -(FIXP_DBL)MAXVAL_DBL;
+ else
+ channelCorr[sfb + sfboffs] = (FIXP_DBL)MAXVAL_DBL;
+ } else {
+ channelCorr[sfb + sfboffs] = channelCorr[sfb + sfboffs]
+ << channelCorrSF;
+ }
+ }
+ }
+ }
+
+ /* for post processing: hrrErr is the error in terms of (too little)
+ * correlation weighted with the loudness of the SFB; SFBs with small
+ * hrrErr can be merged */
+ if (hrrErr[sfb + sfboffs] == FL2FXCONST_DBL(1.0 / 8.0)) {
+ continue;
+ }
+
+ hrrErr[sfb + sfboffs] =
+ fMultDiv2((FL2FXCONST_DBL(0.25f) - (channelCorr[sfb + sfboffs] >> 2)),
+ normSfbLoudness[sfb + sfboffs]);
+
+ /* set IS mask/vector to 1, if correlation is high enough */
+ if (fAbs(channelCorr[sfb + sfboffs]) >= isParams->corr_thresh) {
+ isMask[sfb + sfboffs] = 1;
+ }
+ }
+ }
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_finalizeIntensityDecision
+
+ description: Finalizes intensity decision
+
+ input: isParams scale: none
+ hrrErr scale: none
+ realIsScale scale: LD_DATA_SHIFT + REAL_SCALE_SF
+ normSfbLoudness scale: none
+
+ output: isMask scale: none
+
+ returns: none
+
+*****************************************************************************/
+static void FDKaacEnc_finalizeIntensityDecision(
+ const FIXP_DBL *hrrErr, INT *isMask, const FIXP_DBL *realIsScale,
+ const FIXP_DBL *normSfbLoudness, const INTENSITY_PARAMETERS *isParams,
+ const INT sfbCnt, const INT sfbPerGroup, const INT maxSfbPerGroup) {
+ INT sfb, sfboffs, j;
+ FIXP_DBL isScaleLast = FL2FXCONST_DBL(0.0f);
+ INT isStartValueFound = 0;
+
+ for (sfboffs = 0; sfboffs < sfbCnt; sfboffs += sfbPerGroup) {
+ INT startIsSfb = 0;
+ INT inIsBlock = 0;
+ INT currentIsSfbCount = 0;
+ FIXP_DBL overallHrrError = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL isRegionLoudness = FL2FXCONST_DBL(0.0f);
+
+ for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+ if (isMask[sfboffs + sfb] == 1) {
+ if (currentIsSfbCount == 0) {
+ startIsSfb = sfboffs + sfb;
+ }
+ if (isStartValueFound == 0) {
+ isScaleLast = realIsScale[sfboffs + sfb];
+ isStartValueFound = 1;
+ }
+ inIsBlock = 1;
+ currentIsSfbCount++;
+ overallHrrError += hrrErr[sfboffs + sfb] >> (MAX_SFB_PER_GROUP_SF - 3);
+ isRegionLoudness +=
+ normSfbLoudness[sfboffs + sfb] >> MAX_SFB_PER_GROUP_SF;
+ } else {
+ /* based on correlation, IS should not be used
+ * -> use it anyway, if overall error is below threshold
+ * and if local error does not exceed threshold
+ * otherwise: check if there are enough IS SFBs
+ */
+ if (inIsBlock) {
+ overallHrrError +=
+ hrrErr[sfboffs + sfb] >> (MAX_SFB_PER_GROUP_SF - 3);
+ isRegionLoudness +=
+ normSfbLoudness[sfboffs + sfb] >> MAX_SFB_PER_GROUP_SF;
+
+ if ((hrrErr[sfboffs + sfb] < (isParams->local_error_thresh >> 3)) &&
+ (overallHrrError <
+ (isParams->total_error_thresh >> MAX_SFB_PER_GROUP_SF))) {
+ currentIsSfbCount++;
+ /* overwrite correlation based decision */
+ isMask[sfboffs + sfb] = 1;
+ } else {
+ inIsBlock = 0;
+ }
+ }
+ }
+ /* check for large direction deviation */
+ if (inIsBlock) {
+ if (fAbs(isScaleLast - realIsScale[sfboffs + sfb]) <
+ (isParams->direction_deviation_thresh >>
+ (REAL_SCALE_SF + LD_DATA_SHIFT -
+ IS_DIRECTION_DEVIATION_THRESH_SF))) {
+ isScaleLast = realIsScale[sfboffs + sfb];
+ } else {
+ isMask[sfboffs + sfb] = 0;
+ inIsBlock = 0;
+ currentIsSfbCount--;
+ }
+ }
+
+ if (currentIsSfbCount > 0 && (!inIsBlock || sfb == maxSfbPerGroup - 1)) {
+ /* not enough SFBs -> do not use IS */
+ if (currentIsSfbCount < isParams->min_is_sfbs ||
+ (isRegionLoudness<isParams->is_region_min_loudness>>
+ MAX_SFB_PER_GROUP_SF)) {
+ for (j = startIsSfb; j <= sfboffs + sfb; j++) {
+ isMask[j] = 0;
+ }
+ isScaleLast = FL2FXCONST_DBL(0.0f);
+ isStartValueFound = 0;
+ for (j = 0; j < startIsSfb; j++) {
+ if (isMask[j] != 0) {
+ isScaleLast = realIsScale[j];
+ isStartValueFound = 1;
+ }
+ }
+ }
+ currentIsSfbCount = 0;
+ overallHrrError = FL2FXCONST_DBL(0.0f);
+ isRegionLoudness = FL2FXCONST_DBL(0.0f);
+ }
+ }
+ }
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_IntensityStereoProcessing
+
+ description: Intensity stereo processing tool
+
+ input: sfbEnergyLeft
+ sfbEnergyRight
+ mdctSpectrumLeft
+ mdctSpectrumRight
+ sfbThresholdLeft
+ sfbThresholdRight
+ sfbSpreadEnLeft
+ sfbSpreadEnRight
+ sfbEnergyLdDataLeft
+ sfbEnergyLdDataRight
+
+ output: isBook
+ isScale
+ pnsData->pnsFlag
+ msDigest zeroed from start to sfbCnt
+ msMask zeroed from start to sfbCnt
+ mdctSpectrumRight zeroed where isBook!=0
+ sfbEnergyRight zeroed where isBook!=0
+ sfbSpreadEnRight zeroed where isBook!=0
+ sfbThresholdRight zeroed where isBook!=0
+ sfbEnergyLdDataRight FL2FXCONST_DBL(-1.0) where isBook!=0
+ sfbThresholdLdDataRight FL2FXCONST_DBL(-0.515625f) where
+isBook!=0
+
+ returns: none
+
+*****************************************************************************/
+void FDKaacEnc_IntensityStereoProcessing(
+ FIXP_DBL *sfbEnergyLeft, FIXP_DBL *sfbEnergyRight,
+ FIXP_DBL *mdctSpectrumLeft, FIXP_DBL *mdctSpectrumRight,
+ FIXP_DBL *sfbThresholdLeft, FIXP_DBL *sfbThresholdRight,
+ FIXP_DBL *sfbThresholdLdDataRight, FIXP_DBL *sfbSpreadEnLeft,
+ FIXP_DBL *sfbSpreadEnRight, FIXP_DBL *sfbEnergyLdDataLeft,
+ FIXP_DBL *sfbEnergyLdDataRight, INT *msDigest, INT *msMask,
+ const INT sfbCnt, const INT sfbPerGroup, const INT maxSfbPerGroup,
+ const INT *sfbOffset, const INT allowIS, INT *isBook, INT *isScale,
+ PNS_DATA *RESTRICT pnsData[2]) {
+ INT sfb, sfboffs, j;
+ FIXP_DBL scale;
+ FIXP_DBL lr;
+ FIXP_DBL hrrErr[MAX_GROUPED_SFB];
+ FIXP_DBL normSfbLoudness[MAX_GROUPED_SFB];
+ FIXP_DBL realIsScale[MAX_GROUPED_SFB];
+ INTENSITY_PARAMETERS isParams;
+ INT isMask[MAX_GROUPED_SFB];
+
+ FDKmemclear((void *)isBook, sfbCnt * sizeof(INT));
+ FDKmemclear((void *)isMask, sfbCnt * sizeof(INT));
+ FDKmemclear((void *)realIsScale, sfbCnt * sizeof(FIXP_DBL));
+ FDKmemclear((void *)isScale, sfbCnt * sizeof(INT));
+ FDKmemclear((void *)hrrErr, sfbCnt * sizeof(FIXP_DBL));
+
+ if (!allowIS) return;
+
+ FDKaacEnc_initIsParams(&isParams);
+
+ /* compute / set the following values per SFB:
+ * - left/right ratio between channels
+ * - normalized loudness
+ * + loudness == average of energy in channels to 0.25
+ * + normalization: division by sum of all SFB loudnesses
+ * - isMask (is set to 0 if channels are the same or one is 0)
+ */
+ FDKaacEnc_prepareIntensityDecision(
+ sfbEnergyLeft, sfbEnergyRight, sfbEnergyLdDataLeft, sfbEnergyLdDataRight,
+ mdctSpectrumLeft, mdctSpectrumRight, &isParams, hrrErr, isMask,
+ realIsScale, normSfbLoudness, sfbCnt, sfbPerGroup, maxSfbPerGroup,
+ sfbOffset);
+
+ FDKaacEnc_finalizeIntensityDecision(hrrErr, isMask, realIsScale,
+ normSfbLoudness, &isParams, sfbCnt,
+ sfbPerGroup, maxSfbPerGroup);
+
+ for (sfb = 0; sfb < sfbCnt; sfb += sfbPerGroup) {
+ for (sfboffs = 0; sfboffs < maxSfbPerGroup; sfboffs++) {
+ INT sL, sR;
+ FIXP_DBL inv_n;
+
+ msMask[sfb + sfboffs] = 0;
+ if (isMask[sfb + sfboffs] == 0) {
+ continue;
+ }
+
+ if ((sfbEnergyLeft[sfb + sfboffs] < sfbThresholdLeft[sfb + sfboffs]) &&
+ (fMult(FL2FXCONST_DBL(1.0f / 1.5f), sfbEnergyRight[sfb + sfboffs]) >
+ sfbThresholdRight[sfb + sfboffs])) {
+ continue;
+ }
+ /* NEW: if there is a big-enough IS region, switch off PNS */
+ if (pnsData[0]) {
+ if (pnsData[0]->pnsFlag[sfb + sfboffs]) {
+ pnsData[0]->pnsFlag[sfb + sfboffs] = 0;
+ }
+ if (pnsData[1]->pnsFlag[sfb + sfboffs]) {
+ pnsData[1]->pnsFlag[sfb + sfboffs] = 0;
+ }
+ }
+
+ inv_n = GetInvInt(
+ (sfbOffset[sfb + sfboffs + 1] - sfbOffset[sfb + sfboffs]) >>
+ 1); // scaled with 2 to compensate fMultDiv2() in subsequent loop
+ sL = calcSfbMaxScale(mdctSpectrumLeft, sfbOffset[sfb + sfboffs],
+ sfbOffset[sfb + sfboffs + 1]);
+ sR = calcSfbMaxScale(mdctSpectrumRight, sfbOffset[sfb + sfboffs],
+ sfbOffset[sfb + sfboffs + 1]);
+
+ lr = FL2FXCONST_DBL(0.0f);
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; j++)
+ lr += fMultDiv2(
+ fMultDiv2(mdctSpectrumLeft[j] << sL, mdctSpectrumRight[j] << sR),
+ inv_n);
+ lr = lr << 1;
+
+ if (lr < FL2FXCONST_DBL(0.0f)) {
+ /* This means OUT OF phase intensity stereo, cf. standard */
+ INT s0, s1, s2;
+ FIXP_DBL tmp, d, ed = FL2FXCONST_DBL(0.0f);
+
+ s0 = fixMin(sL, sR);
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1];
+ j++) {
+ d = ((mdctSpectrumLeft[j] << s0) >> 1) -
+ ((mdctSpectrumRight[j] << s0) >> 1);
+ ed += fMultDiv2(d, d) >> (MDCT_SPEC_SF - 1);
+ }
+ msMask[sfb + sfboffs] = 1;
+ tmp = fDivNorm(sfbEnergyLeft[sfb + sfboffs], ed, &s1);
+ s2 = (s1) + (2 * s0) - 2 - MDCT_SPEC_SF;
+ if (s2 & 1) {
+ tmp = tmp >> 1;
+ s2 = s2 + 1;
+ }
+ s2 = (s2 >> 1) + 1; // +1 compensate fMultDiv2() in subsequent loop
+ s2 = fixMin(fixMax(s2, -(DFRACT_BITS - 1)), (DFRACT_BITS - 1));
+ scale = sqrtFixp(tmp);
+ if (s2 < 0) {
+ s2 = -s2;
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1];
+ j++) {
+ mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j], scale) -
+ fMultDiv2(mdctSpectrumRight[j], scale)) >>
+ s2;
+ mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f);
+ }
+ } else {
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1];
+ j++) {
+ mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j], scale) -
+ fMultDiv2(mdctSpectrumRight[j], scale))
+ << s2;
+ mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f);
+ }
+ }
+ } else {
+ /* This means IN phase intensity stereo, cf. standard */
+ INT s0, s1, s2;
+ FIXP_DBL tmp, s, es = FL2FXCONST_DBL(0.0f);
+
+ s0 = fixMin(sL, sR);
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1];
+ j++) {
+ s = ((mdctSpectrumLeft[j] << s0) >> 1) +
+ ((mdctSpectrumRight[j] << s0) >> 1);
+ es = fAddSaturate(es, fMultDiv2(s, s) >>
+ (MDCT_SPEC_SF -
+ 1)); // scaled 2*(mdctScale - s0 + 1) + MDCT_SPEC_SF
+ }
+ msMask[sfb + sfboffs] = 0;
+ tmp = fDivNorm(sfbEnergyLeft[sfb + sfboffs], es, &s1);
+ s2 = (s1) + (2 * s0) - 2 - MDCT_SPEC_SF;
+ if (s2 & 1) {
+ tmp = tmp >> 1;
+ s2 = s2 + 1;
+ }
+ s2 = (s2 >> 1) + 1; // +1 compensate fMultDiv2() in subsequent loop
+ s2 = fixMin(fixMax(s2, -(DFRACT_BITS - 1)), (DFRACT_BITS - 1));
+ scale = sqrtFixp(tmp);
+ if (s2 < 0) {
+ s2 = -s2;
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1];
+ j++) {
+ mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j], scale) +
+ fMultDiv2(mdctSpectrumRight[j], scale)) >>
+ s2;
+ mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f);
+ }
+ } else {
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1];
+ j++) {
+ mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j], scale) +
+ fMultDiv2(mdctSpectrumRight[j], scale))
+ << s2;
+ mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f);
+ }
+ }
+ }
+
+ isBook[sfb + sfboffs] = CODE_BOOK_IS_IN_PHASE_NO;
+
+ if (realIsScale[sfb + sfboffs] < FL2FXCONST_DBL(0.0f)) {
+ isScale[sfb + sfboffs] =
+ (INT)(((realIsScale[sfb + sfboffs] >> 1) -
+ FL2FXCONST_DBL(
+ 0.5f / (1 << (REAL_SCALE_SF + LD_DATA_SHIFT + 1)))) >>
+ (DFRACT_BITS - 1 - REAL_SCALE_SF - LD_DATA_SHIFT - 1)) +
+ 1;
+ } else {
+ isScale[sfb + sfboffs] =
+ (INT)(((realIsScale[sfb + sfboffs] >> 1) +
+ FL2FXCONST_DBL(
+ 0.5f / (1 << (REAL_SCALE_SF + LD_DATA_SHIFT + 1)))) >>
+ (DFRACT_BITS - 1 - REAL_SCALE_SF - LD_DATA_SHIFT - 1));
+ }
+
+ sfbEnergyRight[sfb + sfboffs] = FL2FXCONST_DBL(0.0f);
+ sfbEnergyLdDataRight[sfb + sfboffs] = FL2FXCONST_DBL(-1.0f);
+ sfbThresholdRight[sfb + sfboffs] = FL2FXCONST_DBL(0.0f);
+ sfbThresholdLdDataRight[sfb + sfboffs] = FL2FXCONST_DBL(-0.515625f);
+ sfbSpreadEnRight[sfb + sfboffs] = FL2FXCONST_DBL(0.0f);
+
+ *msDigest = MS_SOME;
+ }
+ }
+}
diff --git a/fdk-aac/libAACenc/src/intensity.h b/fdk-aac/libAACenc/src/intensity.h
new file mode 100644
index 0000000..70f23d5
--- /dev/null
+++ b/fdk-aac/libAACenc/src/intensity.h
@@ -0,0 +1,121 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): A. Horndasch (code originally from lwr and rtb) / Josef Hoepfl
+(FDK)
+
+ Description: intensity stereo prototype
+
+*******************************************************************************/
+
+#ifndef INTENSITY_H
+#define INTENSITY_H
+
+#include "aacenc_pns.h"
+#include "common_fix.h"
+
+void FDKaacEnc_IntensityStereoProcessing(
+ FIXP_DBL *sfbEnergyLeft, FIXP_DBL *sfbEnergyRight,
+ FIXP_DBL *mdctSpectrumLeft, FIXP_DBL *mdctSpectrumRight,
+ FIXP_DBL *sfbThresholdLeft, FIXP_DBL *sfbThresholdRight,
+ FIXP_DBL *sfbThresholdLdDataRight, FIXP_DBL *sfbSpreadEnLeft,
+ FIXP_DBL *sfbSpreadEnRight, FIXP_DBL *sfbEnergyLdDataLeft,
+ FIXP_DBL *sfbEnergyLdDataRight, INT *msDigest, INT *msMask,
+ const INT sfbCnt, const INT sfbPerGroup, const INT maxSfbPerGroup,
+ const INT *sfbOffset, const INT allowIS, INT *isBook, INT *isScale,
+ PNS_DATA *RESTRICT pnsData[2]);
+
+#endif /* INTENSITY_H */
diff --git a/fdk-aac/libAACenc/src/interface.h b/fdk-aac/libAACenc/src/interface.h
new file mode 100644
index 0000000..b1a31ef
--- /dev/null
+++ b/fdk-aac/libAACenc/src/interface.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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Interface psychoaccoustic/quantizer
+
+*******************************************************************************/
+
+#ifndef INTERFACE_H
+#define INTERFACE_H
+
+#include "common_fix.h"
+#include "FDK_audio.h"
+
+#include "psy_data.h"
+#include "aacenc_tns.h"
+
+enum { MS_NONE = 0, MS_SOME = 1, MS_ALL = 2 };
+
+enum { MS_ON = 1 };
+
+struct TOOLSINFO {
+ INT msDigest; /* 0 = no MS; 1 = some MS, 2 = all MS */
+ INT msMask[MAX_GROUPED_SFB];
+};
+
+typedef struct {
+ INT sfbCnt;
+ INT sfbPerGroup;
+ INT maxSfbPerGroup;
+ INT lastWindowSequence;
+ INT windowShape;
+ INT groupingMask;
+ INT sfbOffsets[MAX_GROUPED_SFB + 1];
+
+ INT mdctScale; /* number of transform shifts */
+ INT groupLen[MAX_NO_OF_GROUPS];
+
+ TNS_INFO tnsInfo;
+ INT noiseNrg[MAX_GROUPED_SFB];
+ INT isBook[MAX_GROUPED_SFB];
+ INT isScale[MAX_GROUPED_SFB];
+
+ /* memory located in QC_OUT_CHANNEL */
+ FIXP_DBL *mdctSpectrum;
+ FIXP_DBL *sfbEnergy;
+ FIXP_DBL *sfbSpreadEnergy;
+ FIXP_DBL *sfbThresholdLdData;
+ FIXP_DBL *sfbMinSnrLdData;
+ FIXP_DBL *sfbEnergyLdData;
+
+} PSY_OUT_CHANNEL;
+
+typedef struct {
+ /* information specific to each channel */
+ PSY_OUT_CHANNEL *psyOutChannel[(2)];
+
+ /* information shared by both channels */
+ INT commonWindow;
+ struct TOOLSINFO toolsInfo;
+
+} PSY_OUT_ELEMENT;
+
+typedef struct {
+ PSY_OUT_ELEMENT *psyOutElement[((8))];
+ PSY_OUT_CHANNEL *pPsyOutChannels[(8)];
+
+} PSY_OUT;
+
+inline int isLowDelay(AUDIO_OBJECT_TYPE aot) {
+ return (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD);
+}
+
+#endif /* INTERFACE_H */
diff --git a/fdk-aac/libAACenc/src/line_pe.cpp b/fdk-aac/libAACenc/src/line_pe.cpp
new file mode 100644
index 0000000..47734e5
--- /dev/null
+++ b/fdk-aac/libAACenc/src/line_pe.cpp
@@ -0,0 +1,234 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Perceptual entropie module
+
+*******************************************************************************/
+
+#include "line_pe.h"
+#include "sf_estim.h"
+#include "bit_cnt.h"
+
+#include "genericStds.h"
+
+static const FIXP_DBL C1LdData =
+ FL2FXCONST_DBL(3.0 / LD_DATA_SCALING); /* C1 = 3.0 = log(8.0)/log(2) */
+static const FIXP_DBL C2LdData = FL2FXCONST_DBL(
+ 1.3219281 / LD_DATA_SCALING); /* C2 = 1.3219281 = log(2.5)/log(2) */
+static const FIXP_DBL C3LdData = FL2FXCONST_DBL(0.5593573); /* 1-C2/C1 */
+
+/* constants that do not change during successive pe calculations */
+void FDKaacEnc_prepareSfbPe(PE_CHANNEL_DATA *RESTRICT const peChanData,
+ const FIXP_DBL *RESTRICT const sfbEnergyLdData,
+ const FIXP_DBL *RESTRICT const sfbThresholdLdData,
+ const FIXP_DBL *RESTRICT const sfbFormFactorLdData,
+ const INT *RESTRICT const sfbOffset,
+ const INT sfbCnt, const INT sfbPerGroup,
+ const INT maxSfbPerGroup) {
+ INT sfbGrp, sfb;
+ INT sfbWidth;
+ FIXP_DBL avgFormFactorLdData;
+ const FIXP_DBL formFacScaling =
+ FL2FXCONST_DBL((float)FORM_FAC_SHIFT / LD_DATA_SCALING);
+
+ for (sfbGrp = 0; sfbGrp < sfbCnt; sfbGrp += sfbPerGroup) {
+ for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+ if ((FIXP_DBL)sfbEnergyLdData[sfbGrp + sfb] >
+ (FIXP_DBL)sfbThresholdLdData[sfbGrp + sfb]) {
+ sfbWidth = sfbOffset[sfbGrp + sfb + 1] - sfbOffset[sfbGrp + sfb];
+ /* estimate number of active lines */
+ avgFormFactorLdData = ((-sfbEnergyLdData[sfbGrp + sfb] >> 1) +
+ (CalcLdInt(sfbWidth) >> 1)) >>
+ 1;
+ peChanData->sfbNLines[sfbGrp + sfb] = (INT)CalcInvLdData(
+ (sfbFormFactorLdData[sfbGrp + sfb] + formFacScaling) +
+ avgFormFactorLdData);
+ /* Make sure sfbNLines is never greater than sfbWidth due to
+ * unaccuracies (e.g. sfbEnergyLdData[sfbGrp+sfb] = 0x80000000) */
+ peChanData->sfbNLines[sfbGrp + sfb] =
+ fMin(sfbWidth, peChanData->sfbNLines[sfbGrp + sfb]);
+ } else {
+ peChanData->sfbNLines[sfbGrp + sfb] = 0;
+ }
+ }
+ }
+}
+
+/*
+ formula for one sfb:
+ pe = n * ld(en/thr), if ld(en/thr) >= C1
+ pe = n * (C2 + C3 * ld(en/thr)), if ld(en/thr) < C1
+ n: estimated number of lines in sfb,
+ ld(x) = log(x)/log(2)
+
+ constPart is sfbPe without the threshold part n*ld(thr) or n*C3*ld(thr)
+*/
+void FDKaacEnc_calcSfbPe(PE_CHANNEL_DATA *RESTRICT const peChanData,
+ const FIXP_DBL *RESTRICT const sfbEnergyLdData,
+ const FIXP_DBL *RESTRICT const sfbThresholdLdData,
+ const INT sfbCnt, const INT sfbPerGroup,
+ const INT maxSfbPerGroup,
+ const INT *RESTRICT const isBook,
+ const INT *RESTRICT const isScale) {
+ INT sfbGrp, sfb, thisSfb;
+ INT nLines;
+ FIXP_DBL logDataRatio;
+ FIXP_DBL scaleLd = (FIXP_DBL)0;
+ INT lastValIs = 0;
+
+ FIXP_DBL pe = 0;
+ FIXP_DBL constPart = 0;
+ FIXP_DBL nActiveLines = 0;
+
+ FIXP_DBL tmpPe, tmpConstPart, tmpNActiveLines;
+
+ for (sfbGrp = 0; sfbGrp < sfbCnt; sfbGrp += sfbPerGroup) {
+ for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+ tmpPe = (FIXP_DBL)0;
+ tmpConstPart = (FIXP_DBL)0;
+ tmpNActiveLines = (FIXP_DBL)0;
+
+ thisSfb = sfbGrp + sfb;
+
+ if (sfbEnergyLdData[thisSfb] > sfbThresholdLdData[thisSfb]) {
+ logDataRatio = sfbEnergyLdData[thisSfb] - sfbThresholdLdData[thisSfb];
+ nLines = peChanData->sfbNLines[thisSfb];
+
+ FIXP_DBL factor = nLines << (LD_DATA_SHIFT + PE_CONSTPART_SHIFT + 1);
+ if (logDataRatio >= C1LdData) {
+ /* scale sfbPe and sfbConstPart with PE_CONSTPART_SHIFT */
+ tmpPe = fMultDiv2(logDataRatio, factor);
+ tmpConstPart = fMultDiv2(sfbEnergyLdData[thisSfb] + scaleLd, factor);
+ } else {
+ /* scale sfbPe and sfbConstPart with PE_CONSTPART_SHIFT */
+ tmpPe = fMultDiv2(
+ ((FIXP_DBL)C2LdData + fMult(C3LdData, logDataRatio)), factor);
+ tmpConstPart =
+ fMultDiv2(((FIXP_DBL)C2LdData +
+ fMult(C3LdData, sfbEnergyLdData[thisSfb] + scaleLd)),
+ factor);
+
+ nLines = fMultI(C3LdData, nLines);
+ }
+ tmpNActiveLines = (FIXP_DBL)nLines;
+ } else if (isBook[thisSfb]) {
+ /* provide for cost of scale factor for Intensity */
+ INT delta = isScale[thisSfb] - lastValIs;
+ lastValIs = isScale[thisSfb];
+ peChanData->sfbPe[thisSfb] = FDKaacEnc_bitCountScalefactorDelta(delta)
+ << PE_CONSTPART_SHIFT;
+ peChanData->sfbConstPart[thisSfb] = 0;
+ peChanData->sfbNActiveLines[thisSfb] = 0;
+ }
+ peChanData->sfbPe[thisSfb] = tmpPe;
+ peChanData->sfbConstPart[thisSfb] = tmpConstPart;
+ peChanData->sfbNActiveLines[thisSfb] = tmpNActiveLines;
+
+ /* sum up peChanData values */
+ pe += tmpPe;
+ constPart += tmpConstPart;
+ nActiveLines += tmpNActiveLines;
+ }
+ }
+
+ /* correct scaled pe and constPart values */
+ peChanData->pe = pe >> PE_CONSTPART_SHIFT;
+ peChanData->constPart = constPart >> PE_CONSTPART_SHIFT;
+
+ peChanData->nActiveLines = nActiveLines;
+}
diff --git a/fdk-aac/libAACenc/src/line_pe.h b/fdk-aac/libAACenc/src/line_pe.h
new file mode 100644
index 0000000..ecc2388
--- /dev/null
+++ b/fdk-aac/libAACenc/src/line_pe.h
@@ -0,0 +1,148 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Perceptual entropie module
+
+*******************************************************************************/
+
+#ifndef LINE_PE_H
+#define LINE_PE_H
+
+#include "common_fix.h"
+
+#include "psy_const.h"
+
+#define PE_CONSTPART_SHIFT FRACT_BITS
+
+typedef struct {
+ /* calculated by FDKaacEnc_prepareSfbPe */
+ INT sfbNLines[MAX_GROUPED_SFB]; /* number of relevant lines in sfb */
+ /* the rest is calculated by FDKaacEnc_calcSfbPe */
+ INT sfbPe[MAX_GROUPED_SFB]; /* pe for each sfb */
+ INT sfbConstPart[MAX_GROUPED_SFB]; /* constant part for each sfb */
+ INT sfbNActiveLines[MAX_GROUPED_SFB]; /* number of active lines in sfb */
+ INT pe; /* sum of sfbPe */
+ INT constPart; /* sum of sfbConstPart */
+ INT nActiveLines; /* sum of sfbNActiveLines */
+} PE_CHANNEL_DATA;
+
+typedef struct {
+ PE_CHANNEL_DATA peChannelData[(2)];
+ INT pe;
+ INT constPart;
+ INT nActiveLines;
+ INT offset;
+} PE_DATA;
+
+void FDKaacEnc_prepareSfbPe(PE_CHANNEL_DATA *RESTRICT const peChanData,
+ const FIXP_DBL *RESTRICT const sfbEnergyLdData,
+ const FIXP_DBL *RESTRICT const sfbThresholdLdData,
+ const FIXP_DBL *RESTRICT const sfbFormFactorLdData,
+ const INT *RESTRICT const sfbOffset,
+ const INT sfbCnt, const INT sfbPerGroup,
+ const INT maxSfbPerGroup);
+
+void FDKaacEnc_calcSfbPe(PE_CHANNEL_DATA *RESTRICT const peChanData,
+ const FIXP_DBL *RESTRICT const sfbEnergyLdData,
+ const FIXP_DBL *RESTRICT const sfbThresholdLdData,
+ const INT sfbCnt, const INT sfbPerGroup,
+ const INT maxSfbPerGroup,
+ const INT *RESTRICT const isBook,
+ const INT *RESTRICT const isScale);
+
+#endif
diff --git a/fdk-aac/libAACenc/src/metadata_compressor.cpp b/fdk-aac/libAACenc/src/metadata_compressor.cpp
new file mode 100644
index 0000000..bdac80a
--- /dev/null
+++ b/fdk-aac/libAACenc/src/metadata_compressor.cpp
@@ -0,0 +1,1579 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Neusinger
+
+ Description: Compressor for AAC Metadata Generator
+
+*******************************************************************************/
+
+#include "metadata_compressor.h"
+#include "channel_map.h"
+
+#define LOG2 0.69314718056f /* natural logarithm of 2 */
+#define ILOG2 1.442695041f /* 1/LOG2 */
+#define FIXP_ILOG2_DIV2 (FL2FXCONST_DBL(ILOG2 / 2))
+
+/*----------------- defines ----------------------*/
+
+#define MAX_DRC_CHANNELS (8) /*!< Max number of audio input channels. */
+#define DOWNMIX_SHIFT (3) /*!< Max 8 channel. */
+#define WEIGHTING_FILTER_SHIFT (2) /*!< Scaling used in weighting filter. */
+
+#define METADATA_INT_BITS 10
+#define METADATA_LINT_BITS 20
+#define METADATA_INT_SCALE (INT64(1) << (METADATA_INT_BITS))
+#define METADATA_FRACT_BITS (DFRACT_BITS - 1 - METADATA_INT_BITS)
+#define METADATA_FRACT_SCALE (INT64(1) << (METADATA_FRACT_BITS))
+
+/**
+ * Enum for channel assignment.
+ */
+enum { L = 0, R = 1, C = 2, LFE = 3, LS = 4, RS = 5, S = 6, LS2 = 7, RS2 = 8 };
+
+/*--------------- structure definitions --------------------*/
+
+/**
+ * Structure holds weighting filter filter states.
+ */
+struct WEIGHTING_STATES {
+ FIXP_DBL x1;
+ FIXP_DBL x2;
+ FIXP_DBL y1;
+ FIXP_DBL y2;
+};
+
+/**
+ * Dynamic Range Control compressor structure.
+ */
+struct DRC_COMP {
+ FIXP_DBL maxBoostThr[2]; /*!< Max boost threshold. */
+ FIXP_DBL boostThr[2]; /*!< Boost threshold. */
+ FIXP_DBL earlyCutThr[2]; /*!< Early cut threshold. */
+ FIXP_DBL cutThr[2]; /*!< Cut threshold. */
+ FIXP_DBL maxCutThr[2]; /*!< Max cut threshold. */
+
+ FIXP_DBL boostFac[2]; /*!< Precalculated factor for boost compression. */
+ FIXP_DBL
+ earlyCutFac[2]; /*!< Precalculated factor for early cut compression. */
+ FIXP_DBL cutFac[2]; /*!< Precalculated factor for cut compression. */
+
+ FIXP_DBL maxBoost[2]; /*!< Maximum boost. */
+ FIXP_DBL maxCut[2]; /*!< Maximum cut. */
+ FIXP_DBL maxEarlyCut[2]; /*!< Maximum early cut. */
+
+ FIXP_DBL fastAttack[2]; /*!< Fast attack coefficient. */
+ FIXP_DBL fastDecay[2]; /*!< Fast release coefficient. */
+ FIXP_DBL slowAttack[2]; /*!< Slow attack coefficient. */
+ FIXP_DBL slowDecay[2]; /*!< Slow release coefficient. */
+ UINT holdOff[2]; /*!< Hold time in blocks. */
+
+ FIXP_DBL attackThr[2]; /*!< Slow/fast attack threshold. */
+ FIXP_DBL decayThr[2]; /*!< Slow/fast release threshold. */
+
+ DRC_PROFILE profile[2]; /*!< DRC profile. */
+ INT blockLength; /*!< Block length in samples. */
+ UINT sampleRate; /*!< Sample rate. */
+ CHANNEL_MODE chanConfig; /*!< Channel configuration. */
+
+ UCHAR useWeighting; /*!< Use weighting filter. */
+
+ UINT channels; /*!< Number of channels. */
+ UINT fullChannels; /*!< Number of full range channels. */
+ INT channelIdx[9]; /*!< Offsets of interleaved channel samples (L, R, C, LFE,
+ Ls, Rs, S, Ls2, Rs2). */
+
+ FIXP_DBL smoothLevel[2]; /*!< level smoothing states */
+ FIXP_DBL smoothGain[2]; /*!< gain smoothing states */
+ UINT holdCnt[2]; /*!< hold counter */
+
+ FIXP_DBL limGain[2]; /*!< limiter gain */
+ FIXP_DBL limDecay; /*!< limiter decay (linear) */
+ FIXP_DBL prevPeak[2]; /*!< max peak of previous block (stereo/mono)*/
+
+ WEIGHTING_STATES
+ filter[MAX_DRC_CHANNELS]; /*!< array holds weighting filter states */
+};
+
+/*---------------- constants -----------------------*/
+
+/**
+ * Profile tables.
+ */
+static const FIXP_DBL tabMaxBoostThr[] = {
+ (FIXP_DBL)(-(43 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(53 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(55 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(65 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(50 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(40 << METADATA_FRACT_BITS))};
+static const FIXP_DBL tabBoostThr[] = {
+ (FIXP_DBL)(-(31 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(41 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(31 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(41 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(31 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(31 << METADATA_FRACT_BITS))};
+static const FIXP_DBL tabEarlyCutThr[] = {
+ (FIXP_DBL)(-(26 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(21 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(26 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(21 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(26 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(20 << METADATA_FRACT_BITS))};
+static const FIXP_DBL tabCutThr[] = {(FIXP_DBL)(-(16 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(11 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(16 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(21 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(16 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(10 << METADATA_FRACT_BITS))};
+static const FIXP_DBL tabMaxCutThr[] = {
+ (FIXP_DBL)(4 << METADATA_FRACT_BITS), (FIXP_DBL)(9 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(4 << METADATA_FRACT_BITS), (FIXP_DBL)(9 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(4 << METADATA_FRACT_BITS), (FIXP_DBL)(4 << METADATA_FRACT_BITS)};
+static const FIXP_DBL tabBoostRatio[] = {
+ FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f)),
+ FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f)),
+ FL2FXCONST_DBL(((1.f / 5.f) - 1.f)), FL2FXCONST_DBL(((1.f / 5.f) - 1.f))};
+static const FIXP_DBL tabEarlyCutRatio[] = {
+ FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f)),
+ FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 1.f) - 1.f)),
+ FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f))};
+static const FIXP_DBL tabCutRatio[] = {
+ FL2FXCONST_DBL(((1.f / 20.f) - 1.f)), FL2FXCONST_DBL(((1.f / 20.f) - 1.f)),
+ FL2FXCONST_DBL(((1.f / 20.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f)),
+ FL2FXCONST_DBL(((1.f / 20.f) - 1.f)), FL2FXCONST_DBL(((1.f / 20.f) - 1.f))};
+static const FIXP_DBL tabMaxBoost[] = {(FIXP_DBL)(6 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(6 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(12 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(12 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(15 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(15 << METADATA_FRACT_BITS)};
+static const FIXP_DBL tabMaxCut[] = {(FIXP_DBL)(24 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(24 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(24 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(15 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(24 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(24 << METADATA_FRACT_BITS)};
+static const FIXP_DBL tabFastAttack[] = {
+ FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((0.f / 1000.f) / METADATA_INT_SCALE)};
+static const FIXP_DBL tabFastDecay[] = {
+ FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((200.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((0.f / 1000.f) / METADATA_INT_SCALE)};
+static const FIXP_DBL tabSlowAttack[] = {
+ FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((0.f / 1000.f) / METADATA_INT_SCALE)};
+static const FIXP_DBL tabSlowDecay[] = {
+ FL2FXCONST_DBL((3000.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((3000.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((10000.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((3000.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((0.f / 1000.f) / METADATA_INT_SCALE)};
+
+static const INT tabHoldOff[] = {10, 10, 10, 10, 10, 0};
+
+static const FIXP_DBL tabAttackThr[] = {(FIXP_DBL)(15 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(15 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(15 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(15 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(10 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(0 << METADATA_FRACT_BITS)};
+static const FIXP_DBL tabDecayThr[] = {(FIXP_DBL)(20 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(20 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(20 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(20 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(10 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(0 << METADATA_FRACT_BITS)};
+
+/**
+ * Weighting filter coefficients (biquad bandpass).
+ */
+static const FIXP_DBL b0 = FL2FXCONST_DBL(0.53050662f); /* b1 = 0, b2 = -b0 */
+static const FIXP_DBL a1 = FL2FXCONST_DBL(-0.95237983f),
+ a2 = FL2FXCONST_DBL(-0.02248836f); /* a0 = 1 */
+
+/*------------- function definitions ----------------*/
+
+/**
+ * \brief Calculate scaling factor for denoted processing block.
+ *
+ * \param blockLength Length of processing block.
+ *
+ * \return shiftFactor
+ */
+static UINT getShiftFactor(const UINT length) {
+ UINT ldN;
+ for (ldN = 1; (((UINT)1) << ldN) < length; ldN++)
+ ;
+
+ return ldN;
+}
+
+/**
+ * \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 fixpAdd(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, (*pQ2) - resultScale);
+ *pQ2 = (*pValue2 != (FIXP_DBL)0) ? resultScale : DFRACT_BITS - 1;
+}
+
+/**
+ * \brief Function for converting time constant to filter coefficient.
+ *
+ * \param t Time constant.
+ * \param sampleRate Sampling rate in Hz.
+ * \param blockLength Length of processing block in samples per channel.
+ *
+ * \return result = 1.0 - exp(-1.0/((t) * (f)))
+ */
+static FIXP_DBL tc2Coeff(const FIXP_DBL t, const INT sampleRate,
+ const INT blockLength) {
+ FIXP_DBL sampleRateFract;
+ FIXP_DBL blockLengthFract;
+ FIXP_DBL f, product;
+ FIXP_DBL exponent, result;
+ INT e_res;
+
+ /* f = sampleRate/blockLength */
+ sampleRateFract =
+ (FIXP_DBL)(sampleRate << (DFRACT_BITS - 1 - METADATA_LINT_BITS));
+ blockLengthFract =
+ (FIXP_DBL)(blockLength << (DFRACT_BITS - 1 - METADATA_LINT_BITS));
+ f = fDivNorm(sampleRateFract, blockLengthFract, &e_res);
+ f = scaleValue(f, e_res - METADATA_INT_BITS); /* convert to METADATA_FRACT */
+
+ /* product = t*f */
+ product = fMultNorm(t, f, &e_res);
+ product = scaleValue(
+ product, e_res + METADATA_INT_BITS); /* convert to METADATA_FRACT */
+
+ /* exponent = (-1.0/((t) * (f))) */
+ exponent = fDivNorm(METADATA_FRACT_SCALE, product, &e_res);
+ exponent = scaleValue(
+ exponent, e_res - METADATA_INT_BITS); /* convert to METADATA_FRACT */
+
+ /* exponent * ld(e) */
+ exponent = fMult(exponent, FIXP_ILOG2_DIV2) << 1; /* e^(x) = 2^(x*ld(e)) */
+
+ /* exp(-1.0/((t) * (f))) */
+ result = f2Pow(-exponent, DFRACT_BITS - 1 - METADATA_FRACT_BITS, &e_res);
+
+ /* result = 1.0 - exp(-1.0/((t) * (f))) */
+ result = (FIXP_DBL)MAXVAL_DBL - scaleValue(result, e_res);
+
+ return result;
+}
+
+static void findPeakLevels(HDRC_COMP drcComp, const INT_PCM* const inSamples,
+ const FIXP_DBL clev, const FIXP_DBL slev,
+ const FIXP_DBL ext_leva, const FIXP_DBL ext_levb,
+ const FIXP_DBL lfe_lev, const FIXP_DBL dmxGain5,
+ const FIXP_DBL dmxGain2, FIXP_DBL peak[2]) {
+ int i, c;
+ FIXP_DBL tmp = FL2FXCONST_DBL(0.f);
+ INT_PCM maxSample = 0;
+
+ /* find peak level */
+ peak[0] = peak[1] = FL2FXCONST_DBL(0.f);
+ for (i = 0; i < drcComp->blockLength; i++) {
+ const INT_PCM* pSamples = &inSamples[i * drcComp->channels];
+
+ /* single channels */
+ for (c = 0; c < (int)drcComp->channels; c++) {
+ maxSample = fMax(maxSample, (INT_PCM)fAbs(pSamples[c]));
+ }
+ }
+ peak[0] = fixMax(peak[0], FX_PCM2FX_DBL(maxSample) >> DOWNMIX_SHIFT);
+
+ /* 7.1/6.1 to 5.1 downmixes */
+ if (drcComp->fullChannels > 5) {
+ for (i = 0; i < drcComp->blockLength; i++) {
+ const INT_PCM* pSamples = &inSamples[i * drcComp->channels];
+
+ /* channel 1 (L, Ls,...) */
+ tmp = FL2FXCONST_DBL(0.f);
+ switch (drcComp->chanConfig) {
+ case MODE_6_1:
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >>
+ (DOWNMIX_SHIFT - 1); /* Cs */
+ break;
+ case MODE_7_1_BACK:
+ case MODE_7_1_REAR_SURROUND:
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lrs / Lss */
+ break;
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_FRONT_CENTER:
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
+ DOWNMIX_SHIFT); /* L */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lc */
+ break;
+ case MODE_7_1_TOP_FRONT:
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
+ (DOWNMIX_SHIFT - 1); /* L */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lvh */
+ break;
+ default:
+ break;
+ }
+ peak[0] = fixMax(peak[0], fixp_abs(tmp));
+
+ /* channel 2 (R, Rs,...) */
+ tmp = FL2FXCONST_DBL(0.f);
+ switch (drcComp->chanConfig) {
+ case MODE_6_1:
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >>
+ (DOWNMIX_SHIFT - 1); /* Cs */
+ break;
+ case MODE_7_1_BACK:
+ case MODE_7_1_REAR_SURROUND:
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rrs / Rss */
+ break;
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_FRONT_CENTER:
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
+ DOWNMIX_SHIFT); /* R */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rc */
+ break;
+ case MODE_7_1_TOP_FRONT:
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
+ (DOWNMIX_SHIFT - 1); /* R */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rvh */
+ break;
+ default:
+ break;
+ }
+ peak[0] = fixMax(peak[0], fixp_abs(tmp));
+
+ /* channel 3 (C) */
+ tmp = FL2FXCONST_DBL(0.f);
+ switch (drcComp->chanConfig) {
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_FRONT_CENTER:
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ DOWNMIX_SHIFT); /* C */
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lc */
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rc */
+ break;
+ default:
+ break;
+ }
+ peak[0] = fixMax(peak[0], fixp_abs(tmp));
+
+ } /* for (blocklength) */
+
+ /* take downmix gain into accout */
+ peak[0] = fMult(dmxGain5, peak[0])
+ << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+
+ /* 7.1 / 5.1 to stereo downmixes */
+ if (drcComp->fullChannels > 2) {
+ /* Lt/Rt downmix */
+ for (i = 0; i < drcComp->blockLength; i++) {
+ const INT_PCM* pSamples = &inSamples[i * drcComp->channels];
+
+ /* Lt */
+ tmp = FL2FXCONST_DBL(0.f);
+ if (drcComp->channelIdx[LS] >= 0)
+ tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ if (drcComp->channelIdx[LS2] >= 0)
+ tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls2 */
+ if (drcComp->channelIdx[RS] >= 0)
+ tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ if (drcComp->channelIdx[RS2] >= 0)
+ tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs2 */
+ if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0))
+ tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
+ if (drcComp->channelIdx[S] >= 0)
+ tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[S]]) >>
+ (DOWNMIX_SHIFT - 1); /* S */
+ if (drcComp->channelIdx[C] >= 0)
+ tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >>
+ DOWNMIX_SHIFT); /* L */
+
+ /* apply scaling of downmix gains */
+ /* only for positive values only, as legacy decoders might not know this
+ * parameter */
+ if (dmxGain2 > FL2FXCONST_DBL(0.f)) {
+ if (drcComp->fullChannels > 5) {
+ tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+ tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+ peak[0] = fixMax(peak[0], fixp_abs(tmp));
+
+ /* Rt */
+ tmp = FL2FXCONST_DBL(0.f);
+ if (drcComp->channelIdx[LS] >= 0)
+ tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ if (drcComp->channelIdx[LS2] >= 0)
+ tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls2 */
+ if (drcComp->channelIdx[RS] >= 0)
+ tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ if (drcComp->channelIdx[RS2] >= 0)
+ tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs2 */
+ if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0))
+ tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
+ if (drcComp->channelIdx[S] >= 0)
+ tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[S]]) >>
+ (DOWNMIX_SHIFT - 1); /* S */
+ if (drcComp->channelIdx[C] >= 0)
+ tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >>
+ DOWNMIX_SHIFT); /* R */
+
+ /* apply scaling of downmix gains */
+ /* only for positive values only, as legacy decoders might not know this
+ * parameter */
+ if (dmxGain2 > FL2FXCONST_DBL(0.f)) {
+ if (drcComp->fullChannels > 5) {
+ tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+ tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+ peak[0] = fixMax(peak[0], fixp_abs(tmp));
+ }
+
+ /* Lo/Ro downmix */
+ for (i = 0; i < drcComp->blockLength; i++) {
+ const INT_PCM* pSamples = &inSamples[i * drcComp->channels];
+
+ /* Lo */
+ tmp = FL2FXCONST_DBL(0.f);
+ switch (drcComp->chanConfig) {
+ case MODE_6_1:
+ tmp += fMultDiv2(fMult(slev, ext_leva),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ tmp += fMultDiv2(fMult(slev, ext_levb),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >>
+ (DOWNMIX_SHIFT - 1); /* Cs */
+ tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
+ DOWNMIX_SHIFT); /* L */
+ tmp +=
+ fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ case MODE_7_1_BACK:
+ case MODE_7_1_REAR_SURROUND:
+ tmp += fMultDiv2(fMult(slev, ext_leva),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ tmp += fMultDiv2(fMult(slev, ext_levb),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lrs / Lss*/
+ tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
+ DOWNMIX_SHIFT); /* L */
+ tmp +=
+ fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_FRONT_CENTER:
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
+ DOWNMIX_SHIFT); /* L */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lc */
+ tmp += fMultDiv2(fMult(ext_leva, clev),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lc - second path*/
+ tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ tmp +=
+ fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ case MODE_7_1_TOP_FRONT:
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
+ (DOWNMIX_SHIFT - 1); /* L */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lvh */
+ tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ tmp +=
+ fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ default:
+ if (drcComp->channelIdx[LS] >= 0)
+ tmp +=
+ fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ if (drcComp->channelIdx[LS2] >= 0)
+ tmp +=
+ fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls2 */
+ if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0))
+ tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
+ if (drcComp->channelIdx[S] >= 0)
+ tmp +=
+ fMultDiv2(slev,
+ fMult(FL2FXCONST_DBL(0.7f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >>
+ (DOWNMIX_SHIFT - 1); /* S */
+ if (drcComp->channelIdx[C] >= 0)
+ tmp +=
+ fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ if (drcComp->channelIdx[3] >= 0)
+ tmp += fMultDiv2(lfe_lev,
+ (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >>
+ DOWNMIX_SHIFT); /* L */
+ break;
+ }
+
+ /* apply scaling of downmix gains */
+ /* only for positive values only, as legacy decoders might not know this
+ * parameter */
+ if (dmxGain2 > FL2FXCONST_DBL(0.f)) {
+ if (drcComp->fullChannels > 5) {
+ tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+ tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+ peak[0] = fixMax(peak[0], fixp_abs(tmp));
+
+ /* Ro */
+ tmp = FL2FXCONST_DBL(0.f);
+ switch (drcComp->chanConfig) {
+ case MODE_6_1:
+ tmp += fMultDiv2(fMult(slev, ext_leva),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ tmp += fMultDiv2(fMult(slev, ext_levb),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >>
+ (DOWNMIX_SHIFT - 1); /* Cs */
+ tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
+ DOWNMIX_SHIFT); /* R */
+ tmp +=
+ fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ case MODE_7_1_BACK:
+ case MODE_7_1_REAR_SURROUND:
+ tmp += fMultDiv2(fMult(slev, ext_leva),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ tmp += fMultDiv2(fMult(slev, ext_levb),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rrs / Rss*/
+ tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
+ DOWNMIX_SHIFT); /* R */
+ tmp +=
+ fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_FRONT_CENTER:
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
+ DOWNMIX_SHIFT); /* R */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rc */
+ tmp += fMultDiv2(fMult(ext_leva, clev),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rc - second path*/
+ tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ tmp +=
+ fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ case MODE_7_1_TOP_FRONT:
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
+ (DOWNMIX_SHIFT - 1); /* R */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rvh */
+ tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ tmp +=
+ fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ default:
+ if (drcComp->channelIdx[RS] >= 0)
+ tmp +=
+ fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ if (drcComp->channelIdx[RS2] >= 0)
+ tmp +=
+ fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs2 */
+ if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0))
+ tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
+ if (drcComp->channelIdx[S] >= 0)
+ tmp +=
+ fMultDiv2(slev,
+ fMult(FL2FXCONST_DBL(0.7f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >>
+ (DOWNMIX_SHIFT - 1); /* S */
+ if (drcComp->channelIdx[C] >= 0)
+ tmp +=
+ fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ if (drcComp->channelIdx[3] >= 0)
+ tmp += fMultDiv2(lfe_lev,
+ (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >>
+ DOWNMIX_SHIFT); /* R */
+ }
+
+ /* apply scaling of downmix gains */
+ /* only for positive values only, as legacy decoders might not know this
+ * parameter */
+ if (dmxGain2 > FL2FXCONST_DBL(0.f)) {
+ if (drcComp->fullChannels > 5) {
+ tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+ tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+ peak[0] = fixMax(peak[0], fixp_abs(tmp));
+ }
+ }
+
+ peak[1] = fixMax(peak[0], peak[1]);
+
+ /* Mono Downmix - for comp_val only */
+ if (drcComp->fullChannels > 1) {
+ for (i = 0; i < drcComp->blockLength; i++) {
+ const INT_PCM* pSamples = &inSamples[i * drcComp->channels];
+
+ tmp = FL2FXCONST_DBL(0.f);
+ switch (drcComp->chanConfig) {
+ case MODE_6_1:
+ tmp += fMultDiv2(fMult(slev, ext_leva),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ tmp += fMultDiv2(fMult(slev, ext_leva),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ tmp += fMult(fMult(slev, ext_levb),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >>
+ (DOWNMIX_SHIFT - 1); /* Cs */
+ tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
+ DOWNMIX_SHIFT); /* L */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
+ DOWNMIX_SHIFT); /* R */
+ tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ case MODE_7_1_BACK:
+ case MODE_7_1_REAR_SURROUND:
+ tmp += fMultDiv2(fMult(slev, ext_leva),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ tmp += fMultDiv2(fMult(slev, ext_leva),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ tmp += fMultDiv2(fMult(slev, ext_levb),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lrs / Lss*/
+ tmp += fMultDiv2(fMult(slev, ext_levb),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rrs / Rss*/
+ tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
+ DOWNMIX_SHIFT); /* L */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
+ DOWNMIX_SHIFT); /* R */
+ tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_FRONT_CENTER:
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
+ DOWNMIX_SHIFT); /* L */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
+ DOWNMIX_SHIFT); /* R */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lc */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rc */
+ tmp += fMultDiv2(fMult(ext_leva, clev),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lc - second path*/
+ tmp += fMultDiv2(fMult(ext_leva, clev),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rc - second path*/
+ tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ case MODE_7_1_TOP_FRONT:
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
+ (DOWNMIX_SHIFT - 1); /* L */
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
+ (DOWNMIX_SHIFT - 1); /* R */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lvh */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rvh */
+ tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ default:
+ if (drcComp->channelIdx[LS] >= 0)
+ tmp +=
+ fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ if (drcComp->channelIdx[LS2] >= 0)
+ tmp +=
+ fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls2 */
+ if (drcComp->channelIdx[RS] >= 0)
+ tmp +=
+ fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ if (drcComp->channelIdx[RS2] >= 0)
+ tmp +=
+ fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs2 */
+ if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0))
+ tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
+ /*if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp *=0.707f;*/ /* 7.1ch */
+ if (drcComp->channelIdx[S] >= 0)
+ tmp +=
+ fMultDiv2(slev,
+ fMult(FL2FXCONST_DBL(0.7f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >>
+ (DOWNMIX_SHIFT - 1); /* S */
+ if (drcComp->channelIdx[C] >= 0)
+ tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >>
+ (DOWNMIX_SHIFT - 1); /* C (2*clev) */
+ if (drcComp->channelIdx[3] >= 0)
+ tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >>
+ DOWNMIX_SHIFT); /* L */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >>
+ DOWNMIX_SHIFT); /* R */
+ }
+
+ /* apply scaling of downmix gains */
+ /* only for positive values only, as legacy decoders might not know this
+ * parameter */
+ if (dmxGain2 > FL2FXCONST_DBL(0.f)) {
+ if (drcComp->fullChannels > 5) {
+ tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+ tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+ peak[1] = fixMax(peak[1], fixp_abs(tmp));
+ }
+ }
+}
+
+INT FDK_DRC_Generator_Open(HDRC_COMP* phDrcComp) {
+ INT err = 0;
+ HDRC_COMP hDcComp = NULL;
+
+ if (phDrcComp == NULL) {
+ err = -1;
+ goto bail;
+ }
+
+ /* allocate memory */
+ hDcComp = (HDRC_COMP)FDKcalloc(1, sizeof(DRC_COMP));
+
+ if (hDcComp == NULL) {
+ err = -1;
+ goto bail;
+ }
+
+ FDKmemclear(hDcComp, sizeof(DRC_COMP));
+
+ /* Return drc compressor instance */
+ *phDrcComp = hDcComp;
+ return err;
+bail:
+ FDK_DRC_Generator_Close(&hDcComp);
+ return err;
+}
+
+INT FDK_DRC_Generator_Close(HDRC_COMP* phDrcComp) {
+ if (phDrcComp == NULL) {
+ return -1;
+ }
+ if (*phDrcComp != NULL) {
+ FDKfree(*phDrcComp);
+ *phDrcComp = NULL;
+ }
+ return 0;
+}
+
+INT FDK_DRC_Generator_Initialize(HDRC_COMP drcComp,
+ const DRC_PROFILE profileLine,
+ const DRC_PROFILE profileRF,
+ const INT blockLength, const UINT sampleRate,
+ const CHANNEL_MODE channelMode,
+ const CHANNEL_ORDER channelOrder,
+ const UCHAR useWeighting) {
+ int i;
+ CHANNEL_MAPPING channelMapping;
+
+ drcComp->limDecay =
+ FL2FXCONST_DBL(((0.006f / 256) * blockLength) / METADATA_INT_SCALE);
+
+ /* Save parameters. */
+ drcComp->blockLength = blockLength;
+ drcComp->sampleRate = sampleRate;
+ drcComp->chanConfig = channelMode;
+ drcComp->useWeighting = useWeighting;
+
+ if (FDK_DRC_Generator_setDrcProfile(drcComp, profileLine, profileRF) !=
+ 0) { /* expects initialized blockLength and sampleRate */
+ return (-1);
+ }
+
+ /* Set number of channels and channel offsets. */
+ if (FDKaacEnc_InitChannelMapping(channelMode, channelOrder,
+ &channelMapping) != AAC_ENC_OK) {
+ return (-2);
+ }
+
+ for (i = 0; i < 9; i++) drcComp->channelIdx[i] = -1;
+
+ switch (channelMode) {
+ case MODE_1: /* mono */
+ drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
+ break;
+ case MODE_2: /* stereo */
+ drcComp->channelIdx[L] = channelMapping.elInfo[0].ChannelIndex[0];
+ drcComp->channelIdx[R] = channelMapping.elInfo[0].ChannelIndex[1];
+ break;
+ case MODE_1_2: /* 3ch */
+ drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0];
+ drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1];
+ drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
+ break;
+ case MODE_1_2_1: /* 4ch */
+ drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0];
+ drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1];
+ drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
+ drcComp->channelIdx[S] = channelMapping.elInfo[2].ChannelIndex[0];
+ break;
+ case MODE_1_2_2: /* 5ch */
+ drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0];
+ drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1];
+ drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
+ drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0];
+ drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1];
+ break;
+ case MODE_1_2_2_1: /* 5.1 ch */
+ drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0];
+ drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1];
+ drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
+ drcComp->channelIdx[LFE] = channelMapping.elInfo[3].ChannelIndex[0];
+ drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0];
+ drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1];
+ break;
+ case MODE_1_2_2_2_1: /* 7.1 ch */
+ case MODE_7_1_FRONT_CENTER:
+ drcComp->channelIdx[L] = channelMapping.elInfo[2].ChannelIndex[0]; /* l */
+ drcComp->channelIdx[R] = channelMapping.elInfo[2].ChannelIndex[1]; /* r */
+ drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */
+ drcComp->channelIdx[LFE] =
+ channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */
+ drcComp->channelIdx[LS] =
+ channelMapping.elInfo[3].ChannelIndex[0]; /* ls */
+ drcComp->channelIdx[RS] =
+ channelMapping.elInfo[3].ChannelIndex[1]; /* rs */
+ drcComp->channelIdx[LS2] =
+ channelMapping.elInfo[1].ChannelIndex[0]; /* lc */
+ drcComp->channelIdx[RS2] =
+ channelMapping.elInfo[1].ChannelIndex[1]; /* rc */
+ break;
+ case MODE_7_1_BACK:
+ case MODE_7_1_REAR_SURROUND:
+ drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */
+ drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */
+ drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */
+ drcComp->channelIdx[LFE] =
+ channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */
+ drcComp->channelIdx[LS] =
+ channelMapping.elInfo[3].ChannelIndex[0]; /* lrear */
+ drcComp->channelIdx[RS] =
+ channelMapping.elInfo[3].ChannelIndex[1]; /* rrear */
+ drcComp->channelIdx[LS2] =
+ channelMapping.elInfo[2].ChannelIndex[0]; /* ls */
+ drcComp->channelIdx[RS2] =
+ channelMapping.elInfo[2].ChannelIndex[1]; /* rs */
+ break;
+ case MODE_6_1:
+ drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */
+ drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */
+ drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */
+ drcComp->channelIdx[LFE] =
+ channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */
+ drcComp->channelIdx[LS] =
+ channelMapping.elInfo[2].ChannelIndex[0]; /* ls */
+ drcComp->channelIdx[RS] =
+ channelMapping.elInfo[2].ChannelIndex[1]; /* rs */
+ drcComp->channelIdx[S] = channelMapping.elInfo[3].ChannelIndex[0]; /* s */
+ break;
+ case MODE_7_1_TOP_FRONT:
+ drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */
+ drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */
+ drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */
+ drcComp->channelIdx[LFE] =
+ channelMapping.elInfo[3].ChannelIndex[0]; /* lfe */
+ drcComp->channelIdx[LS] =
+ channelMapping.elInfo[2].ChannelIndex[0]; /* ls */
+ drcComp->channelIdx[RS] =
+ channelMapping.elInfo[2].ChannelIndex[1]; /* rs */
+ drcComp->channelIdx[LS2] =
+ channelMapping.elInfo[4].ChannelIndex[0]; /* lvh2 */
+ drcComp->channelIdx[RS2] =
+ channelMapping.elInfo[4].ChannelIndex[1]; /* rvh2 */
+ break;
+ default:
+ return (-1);
+ }
+
+ drcComp->fullChannels = channelMapping.nChannelsEff;
+ drcComp->channels = channelMapping.nChannels;
+
+ /* Init states. */
+ drcComp->smoothLevel[0] = drcComp->smoothLevel[1] =
+ (FIXP_DBL)(-(135 << METADATA_FRACT_BITS));
+
+ FDKmemclear(drcComp->smoothGain, sizeof(drcComp->smoothGain));
+ FDKmemclear(drcComp->holdCnt, sizeof(drcComp->holdCnt));
+ FDKmemclear(drcComp->limGain, sizeof(drcComp->limGain));
+ FDKmemclear(drcComp->prevPeak, sizeof(drcComp->prevPeak));
+ FDKmemclear(drcComp->filter, sizeof(drcComp->filter));
+
+ return (0);
+}
+
+INT FDK_DRC_Generator_setDrcProfile(HDRC_COMP drcComp,
+ const DRC_PROFILE profileLine,
+ const DRC_PROFILE profileRF) {
+ int profileIdx, i;
+
+ drcComp->profile[0] = profileLine;
+ drcComp->profile[1] = profileRF;
+
+ for (i = 0; i < 2; i++) {
+ /* get profile index */
+ switch (drcComp->profile[i]) {
+ case DRC_NONE:
+ case DRC_NOT_PRESENT:
+ case DRC_FILMSTANDARD:
+ profileIdx = 0;
+ break;
+ case DRC_FILMLIGHT:
+ profileIdx = 1;
+ break;
+ case DRC_MUSICSTANDARD:
+ profileIdx = 2;
+ break;
+ case DRC_MUSICLIGHT:
+ profileIdx = 3;
+ break;
+ case DRC_SPEECH:
+ profileIdx = 4;
+ break;
+ case DRC_DELAY_TEST:
+ profileIdx = 5;
+ break;
+ default:
+ return (-1);
+ }
+
+ /* get parameters for selected profile */
+ if (profileIdx >= 0) {
+ drcComp->maxBoostThr[i] = tabMaxBoostThr[profileIdx];
+ drcComp->boostThr[i] = tabBoostThr[profileIdx];
+ drcComp->earlyCutThr[i] = tabEarlyCutThr[profileIdx];
+ drcComp->cutThr[i] = tabCutThr[profileIdx];
+ drcComp->maxCutThr[i] = tabMaxCutThr[profileIdx];
+
+ drcComp->boostFac[i] = tabBoostRatio[profileIdx];
+ drcComp->earlyCutFac[i] = tabEarlyCutRatio[profileIdx];
+ drcComp->cutFac[i] = tabCutRatio[profileIdx];
+
+ drcComp->maxBoost[i] = tabMaxBoost[profileIdx];
+ drcComp->maxCut[i] = tabMaxCut[profileIdx];
+ drcComp->maxEarlyCut[i] =
+ -fMult((drcComp->cutThr[i] - drcComp->earlyCutThr[i]),
+ drcComp->earlyCutFac[i]); /* no scaling after mult needed,
+ earlyCutFac is in FIXP_DBL */
+
+ drcComp->fastAttack[i] = tc2Coeff(
+ tabFastAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength);
+ drcComp->fastDecay[i] = tc2Coeff(
+ tabFastDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength);
+ drcComp->slowAttack[i] = tc2Coeff(
+ tabSlowAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength);
+ drcComp->slowDecay[i] = tc2Coeff(
+ tabSlowDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength);
+ drcComp->holdOff[i] = tabHoldOff[profileIdx] * 256 / drcComp->blockLength;
+
+ drcComp->attackThr[i] = tabAttackThr[profileIdx];
+ drcComp->decayThr[i] = tabDecayThr[profileIdx];
+ }
+
+ drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f);
+ }
+ return (0);
+}
+
+INT FDK_DRC_Generator_Calc(HDRC_COMP drcComp, const INT_PCM* const inSamples,
+ const UINT inSamplesBufSize, const INT dialnorm,
+ const INT drc_TargetRefLevel,
+ const INT comp_TargetRefLevel, const FIXP_DBL clev,
+ const FIXP_DBL slev, const FIXP_DBL ext_leva,
+ const FIXP_DBL ext_levb, const FIXP_DBL lfe_lev,
+ const INT dmxGain5, const INT dmxGain2,
+ INT* const pDynrng, INT* const pCompr) {
+ int i, c;
+ FIXP_DBL peak[2];
+
+ /**************************************************************************
+ * compressor
+ **************************************************************************/
+ if ((drcComp->profile[0] != DRC_NONE) || (drcComp->profile[1] != DRC_NONE)) {
+ /* Calc loudness level */
+ FIXP_DBL level_b = FL2FXCONST_DBL(0.f);
+ int level_e = DFRACT_BITS - 1;
+
+ /* Increase energy time resolution with shorter processing blocks. 16 is an
+ * empiric value. */
+ const int granuleLength = fixMin(16, drcComp->blockLength);
+
+ if (drcComp->useWeighting) {
+ FIXP_DBL x1, x2, y, y1, y2;
+ /* sum of filter coefficients about 2.5 -> squared value is 6.25
+ WEIGHTING_FILTER_SHIFT is 2 -> scaling about 16, therefore reduce
+ granuleShift by 1.
+ */
+ const int granuleShift = getShiftFactor(granuleLength) - 1;
+
+ for (c = 0; c < (int)drcComp->channels; c++) {
+ const INT_PCM* pSamples = inSamples + c * inSamplesBufSize;
+
+ if (c == drcComp->channelIdx[LFE]) {
+ continue; /* skip LFE */
+ }
+
+ /* get filter states */
+ x1 = drcComp->filter[c].x1;
+ x2 = drcComp->filter[c].x2;
+ y1 = drcComp->filter[c].y1;
+ y2 = drcComp->filter[c].y2;
+
+ i = 0;
+
+ do {
+ int offset = i;
+ FIXP_DBL accu = FL2FXCONST_DBL(0.f);
+
+ for (i = offset;
+ i < fixMin(offset + granuleLength, drcComp->blockLength); i++) {
+ /* apply weighting filter */
+ FIXP_DBL x =
+ FX_PCM2FX_DBL((FIXP_PCM)pSamples[i]) >> WEIGHTING_FILTER_SHIFT;
+
+ /* y = b0 * (x - x2) - a1 * y1 - a2 * y2; */
+ y = fMult(b0, x - x2) - fMult(a1, y1) - fMult(a2, y2);
+
+ x2 = x1;
+ x1 = x;
+ y2 = y1;
+ y1 = y;
+
+ accu += fPow2Div2(y) >> (granuleShift - 1); /* partial energy */
+ } /* i */
+
+ fixpAdd(accu, granuleShift + 2 * WEIGHTING_FILTER_SHIFT, &level_b,
+ &level_e); /* sup up partial energies */
+
+ } while (i < drcComp->blockLength);
+
+ /* save filter states */
+ drcComp->filter[c].x1 = x1;
+ drcComp->filter[c].x2 = x2;
+ drcComp->filter[c].y1 = y1;
+ drcComp->filter[c].y2 = y2;
+ } /* c */
+ } /* weighting */
+ else {
+ const int granuleShift = getShiftFactor(granuleLength);
+
+ for (c = 0; c < (int)drcComp->channels; c++) {
+ const INT_PCM* pSamples = inSamples + c * inSamplesBufSize;
+
+ if ((int)c == drcComp->channelIdx[LFE]) {
+ continue; /* skip LFE */
+ }
+
+ i = 0;
+
+ do {
+ int offset = i;
+ FIXP_DBL accu = FL2FXCONST_DBL(0.f);
+
+ for (i = offset;
+ i < fixMin(offset + granuleLength, drcComp->blockLength); i++) {
+ /* partial energy */
+ accu += fPow2Div2((FIXP_PCM)pSamples[i]) >> (granuleShift - 1);
+ } /* i */
+
+ fixpAdd(accu, granuleShift, &level_b,
+ &level_e); /* sup up partial energies */
+
+ } while (i < drcComp->blockLength);
+ }
+ } /* weighting */
+
+ /*
+ * Convert to dBFS, apply dialnorm
+ */
+ /* level scaling */
+
+ /* descaled level in ld64 representation */
+ FIXP_DBL ldLevel =
+ CalcLdData(level_b) +
+ (FIXP_DBL)((level_e - 12) << (DFRACT_BITS - 1 - LD_DATA_SHIFT)) -
+ CalcLdData((FIXP_DBL)(drcComp->blockLength << (DFRACT_BITS - 1 - 12)));
+
+ /* if (level < 1e-10) level = 1e-10f; */
+ ldLevel =
+ fMax(ldLevel, FL2FXCONST_DBL(-0.51905126482615036685473741085772f));
+
+ /* level = 10 * log(level)/log(10) + 3;
+ * = 10*log(2)/log(10) * ld(level) + 3;
+ * = 10 * 0.30102999566398119521373889472449 * ld(level) + 3
+ * = 10 * (0.30102999566398119521373889472449 * ld(level) + 0.3)
+ * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64)
+ * * 64
+ *
+ * additional scaling with METADATA_FRACT_BITS:
+ * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64)
+ * * 64 * 2^(METADATA_FRACT_BITS) = 10 * (0.30102999566398119521373889472449
+ * * ld64(level) + 0.3/64) * 2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) =
+ * 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * (
+ * 0.30102999566398119521373889472449 * ld64(level) + 0.3/64 )
+ * */
+ FIXP_DBL level = fMult(
+ (FIXP_DBL)(10 << (METADATA_FRACT_BITS + LD_DATA_SHIFT)),
+ fMult(FL2FXCONST_DBL(0.30102999566398119521373889472449f), ldLevel) +
+ (FIXP_DBL)(FL2FXCONST_DBL(0.3f) >> LD_DATA_SHIFT));
+
+ /* level -= dialnorm + 31 */ /* this is fixed to Dolby-ReferenceLevel as
+ compressor profiles are defined relative to
+ this */
+ level -= ((FIXP_DBL)(dialnorm << (METADATA_FRACT_BITS - 16)) +
+ (FIXP_DBL)(31 << METADATA_FRACT_BITS));
+
+ for (i = 0; i < 2; i++) {
+ if (drcComp->profile[i] == DRC_NONE) {
+ /* no compression */
+ drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f);
+ } else {
+ FIXP_DBL gain, alpha, lvl2smthlvl;
+
+ /* calc static gain */
+ if (level <= drcComp->maxBoostThr[i]) {
+ /* max boost */
+ gain = drcComp->maxBoost[i];
+ } else if (level < drcComp->boostThr[i]) {
+ /* boost range */
+ gain = fMult((level - drcComp->boostThr[i]), drcComp->boostFac[i]);
+ } else if (level <= drcComp->earlyCutThr[i]) {
+ /* null band */
+ gain = FL2FXCONST_DBL(0.f);
+ } else if (level <= drcComp->cutThr[i]) {
+ /* early cut range */
+ gain =
+ fMult((level - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]);
+ } else if (level < drcComp->maxCutThr[i]) {
+ /* cut range */
+ gain = fMult((level - drcComp->cutThr[i]), drcComp->cutFac[i]) -
+ drcComp->maxEarlyCut[i];
+ } else {
+ /* max cut */
+ gain = -drcComp->maxCut[i];
+ }
+
+ /* choose time constant */
+ lvl2smthlvl = level - drcComp->smoothLevel[i];
+ if (gain < drcComp->smoothGain[i]) {
+ /* attack */
+ if (lvl2smthlvl > drcComp->attackThr[i]) {
+ /* fast attack */
+ alpha = drcComp->fastAttack[i];
+ } else {
+ /* slow attack */
+ alpha = drcComp->slowAttack[i];
+ }
+ } else {
+ /* release */
+ if (lvl2smthlvl < -drcComp->decayThr[i]) {
+ /* fast release */
+ alpha = drcComp->fastDecay[i];
+ } else {
+ /* slow release */
+ alpha = drcComp->slowDecay[i];
+ }
+ }
+
+ /* smooth gain & level */
+ if ((gain < drcComp->smoothGain[i]) ||
+ (drcComp->holdCnt[i] ==
+ 0)) { /* hold gain unless we have an attack or hold
+ period is over */
+ FIXP_DBL accu;
+
+ /* drcComp->smoothLevel[i] = (1-alpha) * drcComp->smoothLevel[i] +
+ * alpha * level; */
+ accu = fMult(((FIXP_DBL)MAXVAL_DBL - alpha), drcComp->smoothLevel[i]);
+ accu += fMult(alpha, level);
+ drcComp->smoothLevel[i] = accu;
+
+ /* drcComp->smoothGain[i] = (1-alpha) * drcComp->smoothGain[i] +
+ * alpha * gain; */
+ accu = fMult(((FIXP_DBL)MAXVAL_DBL - alpha), drcComp->smoothGain[i]);
+ accu += fMult(alpha, gain);
+ drcComp->smoothGain[i] = accu;
+ }
+
+ /* hold counter */
+ if (drcComp->holdCnt[i]) {
+ drcComp->holdCnt[i]--;
+ }
+ if (gain < drcComp->smoothGain[i]) {
+ drcComp->holdCnt[i] = drcComp->holdOff[i];
+ }
+ } /* profile != DRC_NONE */
+ } /* for i=1..2 */
+ } else {
+ /* no compression */
+ drcComp->smoothGain[0] = FL2FXCONST_DBL(0.f);
+ drcComp->smoothGain[1] = FL2FXCONST_DBL(0.f);
+ }
+
+ /**************************************************************************
+ * limiter
+ **************************************************************************/
+
+ findPeakLevels(drcComp, inSamples, clev, slev, ext_leva, ext_levb, lfe_lev,
+ (FIXP_DBL)((LONG)(dmxGain5) << (METADATA_FRACT_BITS - 16)),
+ (FIXP_DBL)((LONG)(dmxGain2) << (METADATA_FRACT_BITS - 16)),
+ peak);
+
+ for (i = 0; i < 2; i++) {
+ FIXP_DBL tmp = drcComp->prevPeak[i];
+ drcComp->prevPeak[i] = peak[i];
+ peak[i] = fixMax(peak[i], tmp);
+
+ /*
+ * Convert to dBFS, apply dialnorm
+ */
+ /* descaled peak in ld64 representation */
+ FIXP_DBL ld_peak =
+ CalcLdData(peak[i]) +
+ (FIXP_DBL)((LONG)DOWNMIX_SHIFT << (DFRACT_BITS - 1 - LD_DATA_SHIFT));
+
+ /* if (peak < 1e-6) level = 1e-6f; */
+ ld_peak =
+ fMax(ld_peak, FL2FXCONST_DBL(-0.31143075889569022011284244651463f));
+
+ /* peak[i] = 20 * log(peak[i])/log(10) + 0.2f +
+ * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) peak[i] = 20 *
+ * log(2)/log(10) * ld(peak[i]) + 0.2f +
+ * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) peak[i] = 10 *
+ * 2*0.30102999566398119521373889472449 * ld(peak[i]) + 0.2f +
+ * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS)
+ *
+ * additional scaling with METADATA_FRACT_BITS:
+ * peak[i] = (10 * 2*0.30102999566398119521373889472449 * ld64(peak[i]) * 64
+ * + 0.2f +
+ * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS))*2^(-METADATA_FRACT_BITS)
+ * peak[i] = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) *
+ * 2*0.30102999566398119521373889472449 * ld64(peak[i])
+ * + 0.2f*2^(-METADATA_FRACT_BITS) + drcComp->smoothGain[i]
+ */
+ peak[i] = fMult(
+ (FIXP_DBL)(10 << (METADATA_FRACT_BITS + LD_DATA_SHIFT)),
+ fMult(FL2FX_DBL(2 * 0.30102999566398119521373889472449f), ld_peak));
+ peak[i] +=
+ (FL2FX_DBL(0.5f) >> METADATA_INT_BITS); /* add a little bit headroom */
+ peak[i] += drcComp->smoothGain[i];
+ }
+
+ /* peak -= dialnorm + 31; */ /* this is Dolby style only */
+ peak[0] -= (FIXP_DBL)((dialnorm - drc_TargetRefLevel)
+ << (METADATA_FRACT_BITS -
+ 16)); /* peak[0] -= dialnorm - drc_TargetRefLevel */
+
+ /* peak += 11; */
+ /* this is Dolby style only */ /* RF mode output is 11dB higher */
+ /*peak += comp_TargetRefLevel - drc_TargetRefLevel;*/
+ peak[1] -=
+ (FIXP_DBL)((dialnorm - comp_TargetRefLevel)
+ << (METADATA_FRACT_BITS -
+ 16)); /* peak[1] -= dialnorm - comp_TargetRefLevel */
+
+ /* limiter gain */
+ drcComp->limGain[0] += drcComp->limDecay; /* linear limiter release */
+ drcComp->limGain[0] = fixMin(drcComp->limGain[0], -peak[0]);
+
+ drcComp->limGain[1] += 2 * drcComp->limDecay; /* linear limiter release */
+ drcComp->limGain[1] = fixMin(drcComp->limGain[1], -peak[1]);
+
+ /*************************************************************************/
+
+ /* apply limiting, return DRC gains*/
+ {
+ FIXP_DBL tmp;
+
+ tmp = drcComp->smoothGain[0];
+ if (drcComp->limGain[0] < FL2FXCONST_DBL(0.f)) {
+ tmp += drcComp->limGain[0];
+ }
+ *pDynrng = (LONG)scaleValue(tmp, -(METADATA_FRACT_BITS - 16));
+
+ tmp = drcComp->smoothGain[1];
+ if (drcComp->limGain[1] < FL2FXCONST_DBL(0.f)) {
+ tmp += drcComp->limGain[1];
+ }
+ *pCompr = (LONG)scaleValue(tmp, -(METADATA_FRACT_BITS - 16));
+ }
+
+ return 0;
+}
+
+DRC_PROFILE FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp) {
+ return drcComp->profile[0];
+}
+
+DRC_PROFILE FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp) {
+ return drcComp->profile[1];
+}
diff --git a/fdk-aac/libAACenc/src/metadata_compressor.h b/fdk-aac/libAACenc/src/metadata_compressor.h
new file mode 100644
index 0000000..1d0aa42
--- /dev/null
+++ b/fdk-aac/libAACenc/src/metadata_compressor.h
@@ -0,0 +1,255 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Neusinger
+
+ Description: Compressor for AAC Metadata Generator
+
+*******************************************************************************/
+
+#ifndef METADATA_COMPRESSOR_H
+#define METADATA_COMPRESSOR_H
+
+#include "FDK_audio.h"
+#include "common_fix.h"
+
+#include "aacenc.h"
+
+#define LFE_LEV_SCALE 2
+
+/**
+ * DRC compression profiles.
+ */
+typedef enum DRC_PROFILE {
+ DRC_NONE = 0,
+ DRC_FILMSTANDARD = 1,
+ DRC_FILMLIGHT = 2,
+ DRC_MUSICSTANDARD = 3,
+ DRC_MUSICLIGHT = 4,
+ DRC_SPEECH = 5,
+ DRC_DELAY_TEST = 6,
+ DRC_NOT_PRESENT = -2
+
+} DRC_PROFILE;
+
+/**
+ * DRC Compressor handle.
+ */
+typedef struct DRC_COMP DRC_COMP, *HDRC_COMP;
+
+/**
+ * \brief Open a DRC Compressor instance.
+ *
+ * Allocate memory for a compressor instance.
+ *
+ * \param phDrcComp A pointer to a compressor handle. Initialized on
+ * return.
+ *
+ * \return
+ * - 0, on succes.
+ * - unequal 0, on failure.
+ */
+INT FDK_DRC_Generator_Open(HDRC_COMP *phDrcComp);
+
+/**
+ * \brief Close the DRC Compressor instance.
+ *
+ * Deallocate instance and free whole memory.
+ *
+ * \param phDrcComp Pointer to the compressor handle to be
+ * deallocated.
+ *
+ * \return
+ * - 0, on succes.
+ * - unequal 0, on failure.
+ */
+INT FDK_DRC_Generator_Close(HDRC_COMP *phDrcComp);
+
+/**
+ * \brief Configure DRC Compressor.
+ *
+ * \param drcComp Compressor handle.
+ * \param profileLine DRC profile for line mode.
+ * \param profileRF DRC profile for RF mode.
+ * \param blockLength Length of processing block in samples per
+ * channel.
+ * \param sampleRate Sampling rate in Hz.
+ * \param channelMode Channel configuration.
+ * \param channelOrder Channel order, MPEG or WAV.
+ * \param useWeighting Use weighting filter for loudness calculation
+ *
+ * \return
+ * - 0, on success,
+ * - unequal 0, on failure
+ */
+INT FDK_DRC_Generator_Initialize(HDRC_COMP drcComp,
+ const DRC_PROFILE profileLine,
+ const DRC_PROFILE profileRF,
+ const INT blockLength, const UINT sampleRate,
+ const CHANNEL_MODE channelMode,
+ const CHANNEL_ORDER channelOrder,
+ const UCHAR useWeighting);
+
+/**
+ * \brief Calculate DRC Compressor Gain.
+ *
+ * \param drcComp Compressor handle.
+ * \param inSamples Pointer to interleaved input audio samples.
+ * \param inSamplesBufSize Size of inSamples for one channel.
+ * \param dialnorm Dialog Level in dB (typically -31...-1).
+ * \param drc_TargetRefLevel
+ * \param comp_TargetRefLevel
+ * \param clev Downmix center mix factor (typically 0.707,
+ * 0.595 or 0.5)
+ * \param slev Downmix surround mix factor (typically 0.707,
+ * 0.5, or 0)
+ * \param ext_leva Downmix gain factor A
+ * \param ext_levb Downmix gain factor B
+ * \param lfe_lev LFE gain factor
+ * \param dmxGain5 Gain factor for downmix to 5 channels
+ * \param dmxGain2 Gain factor for downmix to 2 channels
+ * \param dynrng Pointer to variable receiving line mode DRC gain
+ * in dB
+ * \param compr Pointer to variable receiving RF mode DRC gain
+ * in dB
+ *
+ * \return
+ * - 0, on success,
+ * - unequal 0, on failure
+ */
+INT FDK_DRC_Generator_Calc(HDRC_COMP drcComp, const INT_PCM *const inSamples,
+ const UINT inSamplesBufSize, const INT dialnorm,
+ const INT drc_TargetRefLevel,
+ const INT comp_TargetRefLevel, const FIXP_DBL clev,
+ const FIXP_DBL slev, const FIXP_DBL ext_leva,
+ const FIXP_DBL ext_levb, const FIXP_DBL lfe_lev,
+ const INT dmxGain5, const INT dmxGain2,
+ INT *const dynrng, INT *const compr);
+
+/**
+ * \brief Configure DRC Compressor Profile.
+ *
+ * \param drcComp Compressor handle.
+ * \param profileLine DRC profile for line mode.
+ * \param profileRF DRC profile for RF mode.
+ *
+ * \return
+ * - 0, on success,
+ * - unequal 0, on failure
+ */
+INT FDK_DRC_Generator_setDrcProfile(HDRC_COMP drcComp,
+ const DRC_PROFILE profileLine,
+ const DRC_PROFILE profileRF);
+
+/**
+ * \brief Get DRC profile for line mode.
+ *
+ * \param drcComp Compressor handle.
+ *
+ * \return Current Profile.
+ */
+DRC_PROFILE FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp);
+
+/**
+ * \brief Get DRC profile for RF mode.
+ *
+ * \param drcComp Compressor handle.
+ *
+ * \return Current Profile.
+ */
+DRC_PROFILE FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp);
+
+#endif /* METADATA_COMPRESSOR_H */
diff --git a/fdk-aac/libAACenc/src/metadata_main.cpp b/fdk-aac/libAACenc/src/metadata_main.cpp
new file mode 100644
index 0000000..ada4502
--- /dev/null
+++ b/fdk-aac/libAACenc/src/metadata_main.cpp
@@ -0,0 +1,1191 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): V. Bacigalupo
+
+ Description: Metadata Encoder library interface functions
+
+*******************************************************************************/
+
+#include "metadata_main.h"
+#include "metadata_compressor.h"
+#include "FDK_bitstream.h"
+#include "FDK_audio.h"
+#include "genericStds.h"
+
+/*----------------- defines ----------------------*/
+#define MAX_DRC_BANDS (1 << 4)
+#define MAX_DRC_FRAMELEN (2 * 1024)
+#define MAX_DELAY_FRAMES (3)
+
+/*--------------- structure definitions --------------------*/
+
+typedef struct AAC_METADATA {
+ /* MPEG: Dynamic Range Control */
+ struct {
+ UCHAR prog_ref_level_present;
+ SCHAR prog_ref_level;
+
+ UCHAR dyn_rng_sgn[MAX_DRC_BANDS];
+ UCHAR dyn_rng_ctl[MAX_DRC_BANDS];
+
+ UCHAR drc_bands_present;
+ UCHAR drc_band_incr;
+ UCHAR drc_band_top[MAX_DRC_BANDS];
+ UCHAR drc_interpolation_scheme;
+ AACENC_METADATA_DRC_PROFILE drc_profile;
+ INT drc_TargetRefLevel; /* used for Limiter */
+
+ /* excluded channels */
+ UCHAR excluded_chns_present;
+ UCHAR exclude_mask[2]; /* MAX_NUMBER_CHANNELS/8 */
+ } mpegDrc;
+
+ /* ETSI: addtl ancillary data */
+ struct {
+ /* Heavy Compression */
+ UCHAR compression_on; /* flag, if compression value should be written */
+ UCHAR compression_value; /* compression value */
+ AACENC_METADATA_DRC_PROFILE comp_profile;
+ INT comp_TargetRefLevel; /* used for Limiter */
+ INT timecode_coarse_status;
+ INT timecode_fine_status;
+
+ UCHAR extAncDataStatus;
+
+ struct {
+ UCHAR ext_downmix_lvl_status;
+ UCHAR ext_downmix_gain_status;
+ UCHAR ext_lfe_downmix_status;
+ UCHAR
+ ext_dmix_a_idx; /* extended downmix level (0..7, according to table)
+ */
+ UCHAR
+ ext_dmix_b_idx; /* extended downmix level (0..7, according to table)
+ */
+ UCHAR dmx_gain_5_sgn;
+ UCHAR dmx_gain_5_idx;
+ UCHAR dmx_gain_2_sgn;
+ UCHAR dmx_gain_2_idx;
+ UCHAR ext_dmix_lfe_idx; /* extended downmix level for lfe (0..15,
+ according to table) */
+
+ } extAncData;
+
+ } etsiAncData;
+
+ SCHAR centerMixLevel; /* center downmix level (0...7, according to table) */
+ SCHAR
+ surroundMixLevel; /* surround downmix level (0...7, according to table) */
+ UCHAR WritePCEMixDwnIdx; /* flag */
+ UCHAR DmxLvl_On; /* flag */
+
+ UCHAR dolbySurroundMode;
+ UCHAR drcPresentationMode;
+
+ UCHAR
+ metadataMode; /* indicate meta data mode in current frame (delay line) */
+
+} AAC_METADATA;
+
+typedef struct FDK_METADATA_ENCODER {
+ INT metadataMode;
+ HDRC_COMP hDrcComp;
+ AACENC_MetaData submittedMetaData;
+
+ INT nAudioDataDelay; /* Additional delay to round up to next frame border (in
+ samples) */
+ INT nMetaDataDelay; /* Meta data delay (in frames) */
+ INT nChannels;
+ CHANNEL_MODE channelMode;
+
+ INT_PCM* pAudioDelayBuffer;
+
+ AAC_METADATA metaDataBuffer[MAX_DELAY_FRAMES];
+ INT metaDataDelayIdx;
+
+ UCHAR drcInfoPayload[12];
+ UCHAR drcDsePayload[8];
+
+ INT matrix_mixdown_idx;
+
+ AACENC_EXT_PAYLOAD exPayload[2];
+ INT nExtensions;
+
+ UINT maxChannels; /* Maximum number of audio channels to be supported. */
+
+ INT finalizeMetaData; /* Delay switch off by one frame and write default
+ configuration to finalize the metadata setup. */
+ INT initializeMetaData; /* Fill up delay line with first meta data info. This
+ is required to have meta data already in first
+ frame. */
+} FDK_METADATA_ENCODER;
+
+/*---------------- constants -----------------------*/
+static const AACENC_MetaData defaultMetaDataSetup = {
+ AACENC_METADATA_DRC_NONE, /* drc_profile */
+ AACENC_METADATA_DRC_NOT_PRESENT, /* comp_profile */
+ -(31 << 16), /* drc_TargetRefLevel */
+ -(23 << 16), /* comp_TargetRefLevel */
+ 0, /* prog_ref_level_present */
+ -(23 << 16), /* prog_ref_level */
+ 0, /* PCE_mixdown_idx_present */
+ 0, /* ETSI_DmxLvl_present */
+ 0, /* centerMixLevel */
+ 0, /* surroundMixLevel */
+ 0, /* dolbySurroundMode */
+ 0, /* drcPresentationMode */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0} /* ExtMetaData */
+};
+
+static const FIXP_DBL dmxTable[8] = {
+ ((FIXP_DBL)MAXVAL_DBL), FL2FXCONST_DBL(0.841f), FL2FXCONST_DBL(0.707f),
+ FL2FXCONST_DBL(0.596f), FL2FXCONST_DBL(0.500f), FL2FXCONST_DBL(0.422f),
+ FL2FXCONST_DBL(0.355f), FL2FXCONST_DBL(0.000f)};
+
+#define FL2DMXLFE(a) FL2FXCONST_DBL((a) / (1 << LFE_LEV_SCALE))
+static const FIXP_DBL dmxLfeTable[16] = {
+ FL2DMXLFE(3.162f), FL2DMXLFE(2.000f), FL2DMXLFE(1.679f), FL2DMXLFE(1.413f),
+ FL2DMXLFE(1.189f), FL2DMXLFE(1.000f), FL2DMXLFE(0.841f), FL2DMXLFE(0.707f),
+ FL2DMXLFE(0.596f), FL2DMXLFE(0.500f), FL2DMXLFE(0.316f), FL2DMXLFE(0.178f),
+ FL2DMXLFE(0.100f), FL2DMXLFE(0.032f), FL2DMXLFE(0.010f), FL2DMXLFE(0.000f)};
+
+static const UCHAR surmix2matrix_mixdown_idx[8] = {0, 0, 0, 1, 1, 2, 2, 3};
+
+/*--------------- function declarations --------------------*/
+static FDK_METADATA_ERROR WriteMetadataPayload(
+ const HANDLE_FDK_METADATA_ENCODER hMetaData,
+ const AAC_METADATA* const pMetadata);
+
+static INT WriteDynamicRangeInfoPayload(const AAC_METADATA* const pMetadata,
+ UCHAR* const pExtensionPayload);
+
+static INT WriteEtsiAncillaryDataPayload(const AAC_METADATA* const pMetadata,
+ UCHAR* const pExtensionPayload);
+
+static FDK_METADATA_ERROR CompensateAudioDelay(
+ HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples,
+ const UINT audioSamplesBufSize, const INT nAudioSamples);
+
+static FDK_METADATA_ERROR LoadSubmittedMetadata(
+ const AACENC_MetaData* const hMetadata, const INT nChannels,
+ const INT metadataMode, AAC_METADATA* const pAacMetaData);
+
+static FDK_METADATA_ERROR ProcessCompressor(AAC_METADATA* pMetadata,
+ HDRC_COMP hDrcComp,
+ const INT_PCM* const pSamples,
+ const UINT samplesBufSize,
+ const INT nSamples);
+
+/*------------- function definitions ----------------*/
+
+static DRC_PROFILE convertProfile(AACENC_METADATA_DRC_PROFILE aacProfile) {
+ DRC_PROFILE drcProfile = DRC_NONE;
+
+ switch (aacProfile) {
+ case AACENC_METADATA_DRC_NONE:
+ drcProfile = DRC_NONE;
+ break;
+ case AACENC_METADATA_DRC_FILMSTANDARD:
+ drcProfile = DRC_FILMSTANDARD;
+ break;
+ case AACENC_METADATA_DRC_FILMLIGHT:
+ drcProfile = DRC_FILMLIGHT;
+ break;
+ case AACENC_METADATA_DRC_MUSICSTANDARD:
+ drcProfile = DRC_MUSICSTANDARD;
+ break;
+ case AACENC_METADATA_DRC_MUSICLIGHT:
+ drcProfile = DRC_MUSICLIGHT;
+ break;
+ case AACENC_METADATA_DRC_SPEECH:
+ drcProfile = DRC_SPEECH;
+ break;
+ case AACENC_METADATA_DRC_NOT_PRESENT:
+ drcProfile = DRC_NOT_PRESENT;
+ break;
+ default:
+ drcProfile = DRC_NONE;
+ break;
+ }
+ return drcProfile;
+}
+
+/* convert dialog normalization to program reference level */
+/* NOTE: this only is correct, if the decoder target level is set to -31dB for
+ * line mode / -20dB for RF mode */
+static UCHAR dialnorm2progreflvl(const INT d) {
+ return ((UCHAR)fMax(0, fMin((-d + (1 << 13)) >> 14, 127)));
+}
+
+/* convert program reference level to dialog normalization */
+static INT progreflvl2dialnorm(const UCHAR p) {
+ return -((INT)(p << (16 - 2)));
+}
+
+/* encode downmix levels to Downmixing_levels_MPEG4 */
+static SCHAR encodeDmxLvls(const SCHAR cmixlev, const SCHAR surmixlev) {
+ SCHAR dmxLvls = 0;
+ dmxLvls |= 0x80 | (cmixlev << 4); /* center_mix_level_on */
+ dmxLvls |= 0x08 | surmixlev; /* surround_mix_level_on */
+
+ return dmxLvls;
+}
+
+/* encode AAC DRC gain (ISO/IEC 14496-3:2005 4.5.2.7) */
+static void encodeDynrng(INT gain, UCHAR* const dyn_rng_ctl,
+ UCHAR* const dyn_rng_sgn) {
+ if (gain < 0) {
+ *dyn_rng_sgn = 1;
+ gain = -gain;
+ } else {
+ *dyn_rng_sgn = 0;
+ }
+ gain = fMin(gain, (127 << 14));
+
+ *dyn_rng_ctl = (UCHAR)((gain + (1 << 13)) >> 14);
+}
+
+/* decode AAC DRC gain (ISO/IEC 14496-3:2005 4.5.2.7) */
+static INT decodeDynrng(const UCHAR dyn_rng_ctl, const UCHAR dyn_rng_sgn) {
+ INT tmp = ((INT)dyn_rng_ctl << (16 - 2));
+ if (dyn_rng_sgn) tmp = -tmp;
+
+ return tmp;
+}
+
+/* encode AAC compression value (ETSI TS 101 154 page 99) */
+static UCHAR encodeCompr(INT gain) {
+ UCHAR x, y;
+ INT tmp;
+
+ /* tmp = (int)((48.164f - gain) / 6.0206f * 15 + 0.5f); */
+ tmp = ((3156476 - gain) * 15 + 197283) / 394566;
+
+ if (tmp >= 240) {
+ return 0xFF;
+ } else if (tmp < 0) {
+ return 0;
+ } else {
+ x = tmp / 15;
+ y = tmp % 15;
+ }
+
+ return (x << 4) | y;
+}
+
+/* decode AAC compression value (ETSI TS 101 154 page 99) */
+static INT decodeCompr(const UCHAR compr) {
+ INT gain;
+ SCHAR x = compr >> 4; /* 4 MSB of compr */
+ UCHAR y = (compr & 0x0F); /* 4 LSB of compr */
+
+ /* gain = (INT)((48.164f - 6.0206f * x - 0.4014f * y) ); */
+ gain = (INT)(
+ scaleValue((FIXP_DBL)(((LONG)FL2FXCONST_DBL(6.0206f / 128.f) * (8 - x) -
+ (LONG)FL2FXCONST_DBL(0.4014f / 128.f) * y)),
+ -(DFRACT_BITS - 1 - 7 - 16)));
+
+ return gain;
+}
+
+FDK_METADATA_ERROR FDK_MetadataEnc_Open(HANDLE_FDK_METADATA_ENCODER* phMetaData,
+ const UINT maxChannels) {
+ FDK_METADATA_ERROR err = METADATA_OK;
+ HANDLE_FDK_METADATA_ENCODER hMetaData = NULL;
+
+ if (phMetaData == NULL) {
+ err = METADATA_INVALID_HANDLE;
+ goto bail;
+ }
+
+ /* allocate memory */
+ if (NULL == (hMetaData = (HANDLE_FDK_METADATA_ENCODER)FDKcalloc(
+ 1, sizeof(FDK_METADATA_ENCODER)))) {
+ err = METADATA_MEMORY_ERROR;
+ goto bail;
+ }
+ FDKmemclear(hMetaData, sizeof(FDK_METADATA_ENCODER));
+
+ if (NULL == (hMetaData->pAudioDelayBuffer = (INT_PCM*)FDKcalloc(
+ maxChannels * MAX_DRC_FRAMELEN, sizeof(INT_PCM)))) {
+ err = METADATA_MEMORY_ERROR;
+ goto bail;
+ }
+ FDKmemclear(hMetaData->pAudioDelayBuffer,
+ maxChannels * MAX_DRC_FRAMELEN * sizeof(INT_PCM));
+ hMetaData->maxChannels = maxChannels;
+
+ /* Allocate DRC Compressor. */
+ if (FDK_DRC_Generator_Open(&hMetaData->hDrcComp) != 0) {
+ err = METADATA_MEMORY_ERROR;
+ goto bail;
+ }
+ hMetaData->channelMode = MODE_UNKNOWN;
+
+ /* Return metadata instance */
+ *phMetaData = hMetaData;
+
+ return err;
+
+bail:
+ FDK_MetadataEnc_Close(&hMetaData);
+ return err;
+}
+
+FDK_METADATA_ERROR FDK_MetadataEnc_Close(
+ HANDLE_FDK_METADATA_ENCODER* phMetaData) {
+ FDK_METADATA_ERROR err = METADATA_OK;
+
+ if (phMetaData == NULL) {
+ err = METADATA_INVALID_HANDLE;
+ goto bail;
+ }
+
+ if (*phMetaData != NULL) {
+ FDK_DRC_Generator_Close(&(*phMetaData)->hDrcComp);
+ FDKfree((*phMetaData)->pAudioDelayBuffer);
+ FDKfree(*phMetaData);
+ *phMetaData = NULL;
+ }
+bail:
+ return err;
+}
+
+FDK_METADATA_ERROR FDK_MetadataEnc_Init(
+ HANDLE_FDK_METADATA_ENCODER hMetaData, const INT resetStates,
+ const INT metadataMode, const INT audioDelay, const UINT frameLength,
+ const UINT sampleRate, const UINT nChannels, const CHANNEL_MODE channelMode,
+ const CHANNEL_ORDER channelOrder) {
+ FDK_METADATA_ERROR err = METADATA_OK;
+ int i, nFrames, delay;
+
+ if (hMetaData == NULL) {
+ err = METADATA_INVALID_HANDLE;
+ goto bail;
+ }
+
+ /* Determine values for delay compensation. */
+ for (nFrames = 0, delay = audioDelay - (INT)frameLength; delay > 0;
+ delay -= (INT)frameLength, nFrames++)
+ ;
+
+ if ((nChannels > (8)) || (nChannels > hMetaData->maxChannels) ||
+ ((-delay) > MAX_DRC_FRAMELEN) || nFrames >= MAX_DELAY_FRAMES) {
+ err = METADATA_INIT_ERROR;
+ goto bail;
+ }
+
+ /* Initialize with default setup. */
+ FDKmemcpy(&hMetaData->submittedMetaData, &defaultMetaDataSetup,
+ sizeof(AACENC_MetaData));
+
+ hMetaData->finalizeMetaData =
+ 0; /* finalize meta data only while on/off switching, else disabled */
+ hMetaData->initializeMetaData =
+ 0; /* fill up meta data delay line only at a reset otherwise disabled */
+
+ /* Reset delay lines. */
+ if (resetStates || (hMetaData->nAudioDataDelay != -delay) ||
+ (hMetaData->channelMode != channelMode)) {
+ if (resetStates || (hMetaData->channelMode == MODE_UNKNOWN)) {
+ /* clear delay buffer */
+ FDKmemclear(hMetaData->pAudioDelayBuffer,
+ hMetaData->maxChannels * MAX_DRC_FRAMELEN * sizeof(INT_PCM));
+ } else {
+ /* if possible, keep static audio channels for seamless channel
+ * reconfiguration */
+ FDK_channelMapDescr mapDescrPrev, mapDescr;
+ int c, src[2] = {-1, -1}, dst[2] = {-1, -1};
+
+ if (channelOrder == CH_ORDER_WG4) {
+ FDK_chMapDescr_init(&mapDescrPrev, FDK_mapInfoTabWg4,
+ FDK_mapInfoTabLenWg4, 0);
+ FDK_chMapDescr_init(&mapDescr, FDK_mapInfoTabWg4,
+ FDK_mapInfoTabLenWg4, 0);
+ } else {
+ FDK_chMapDescr_init(&mapDescrPrev, NULL, 0,
+ (channelOrder == CH_ORDER_MPEG) ? 1 : 0);
+ FDK_chMapDescr_init(&mapDescr, NULL, 0,
+ (channelOrder == CH_ORDER_MPEG) ? 1 : 0);
+ }
+
+ switch (channelMode) {
+ case MODE_1:
+ if ((INT)nChannels != 2) {
+ /* preserve center channel */
+ src[0] = FDK_chMapDescr_getMapValue(&mapDescrPrev, 0,
+ hMetaData->channelMode);
+ dst[0] = FDK_chMapDescr_getMapValue(&mapDescr, 0, channelMode);
+ }
+ break;
+ case MODE_2:
+ case MODE_1_2:
+ case MODE_1_2_1:
+ case MODE_1_2_2:
+ case MODE_1_2_2_1:
+ if (hMetaData->nChannels >= 2) {
+ /* preserve left/right channel */
+ src[0] = FDK_chMapDescr_getMapValue(
+ &mapDescrPrev, ((hMetaData->channelMode == 2) ? 0 : 1),
+ hMetaData->channelMode);
+ src[1] = FDK_chMapDescr_getMapValue(
+ &mapDescrPrev, ((hMetaData->channelMode == 2) ? 1 : 2),
+ hMetaData->channelMode);
+ dst[0] = FDK_chMapDescr_getMapValue(
+ &mapDescr, ((channelMode == 2) ? 0 : 1), channelMode);
+ dst[1] = FDK_chMapDescr_getMapValue(
+ &mapDescr, ((channelMode == 2) ? 1 : 2), channelMode);
+ }
+ break;
+ default:;
+ }
+ C_ALLOC_SCRATCH_START(scratch_audioDelayBuffer, INT_PCM, (8));
+ FDKmemclear(scratch_audioDelayBuffer, (8) * sizeof(INT_PCM));
+
+ i = (hMetaData->nChannels > (INT)nChannels)
+ ? 0
+ : hMetaData->nAudioDataDelay - 1;
+ do {
+ for (c = 0; c < 2; c++) {
+ if (src[c] != -1 && dst[c] != -1) {
+ scratch_audioDelayBuffer[dst[c]] =
+ hMetaData->pAudioDelayBuffer[i * hMetaData->nChannels + src[c]];
+ }
+ }
+ FDKmemcpy(&hMetaData->pAudioDelayBuffer[i * nChannels],
+ scratch_audioDelayBuffer, nChannels * sizeof(INT_PCM));
+ i += (hMetaData->nChannels > (INT)nChannels) ? 1 : -1;
+ } while ((i < hMetaData->nAudioDataDelay) && (i >= 0));
+
+ C_ALLOC_SCRATCH_END(scratch_audioDelayBuffer, INT_PCM, (8));
+ }
+ FDKmemclear(hMetaData->metaDataBuffer, sizeof(hMetaData->metaDataBuffer));
+ hMetaData->metaDataDelayIdx = 0;
+ hMetaData->initializeMetaData =
+ 1; /* fill up delay line with first meta data info */
+ } else {
+ /* Enable meta data. */
+ if ((hMetaData->metadataMode == 0) && (metadataMode != 0)) {
+ /* disable meta data in all delay lines */
+ for (i = 0;
+ i < (int)(sizeof(hMetaData->metaDataBuffer) / sizeof(AAC_METADATA));
+ i++) {
+ LoadSubmittedMetadata(&hMetaData->submittedMetaData, nChannels, 0,
+ &hMetaData->metaDataBuffer[i]);
+ }
+ }
+
+ /* Disable meta data.*/
+ if ((hMetaData->metadataMode != 0) && (metadataMode == 0)) {
+ hMetaData->finalizeMetaData = hMetaData->metadataMode;
+ }
+ }
+
+ /* Initialize delay. */
+ hMetaData->nAudioDataDelay = -delay;
+ hMetaData->nMetaDataDelay = nFrames;
+ hMetaData->nChannels = nChannels;
+ hMetaData->channelMode = channelMode;
+ hMetaData->metadataMode = metadataMode;
+
+ /* Initialize compressor. */
+ if ((metadataMode == 1) || (metadataMode == 2)) {
+ if (FDK_DRC_Generator_Initialize(hMetaData->hDrcComp, DRC_NONE, DRC_NONE,
+ frameLength, sampleRate, channelMode,
+ channelOrder, 1) != 0) {
+ err = METADATA_INIT_ERROR;
+ }
+ }
+bail:
+ return err;
+}
+
+static FDK_METADATA_ERROR ProcessCompressor(AAC_METADATA* pMetadata,
+ HDRC_COMP hDrcComp,
+ const INT_PCM* const pSamples,
+ const UINT samplesBufSize,
+ const INT nSamples) {
+ FDK_METADATA_ERROR err = METADATA_OK;
+
+ INT dynrng, compr;
+ INT dmxGain5, dmxGain2;
+ DRC_PROFILE profileDrc;
+ DRC_PROFILE profileComp;
+
+ if ((pMetadata == NULL) || (hDrcComp == NULL)) {
+ err = METADATA_INVALID_HANDLE;
+ return err;
+ }
+
+ profileDrc = convertProfile(pMetadata->mpegDrc.drc_profile);
+ profileComp = convertProfile(pMetadata->etsiAncData.comp_profile);
+
+ /* first, check if profile is same as last frame
+ * otherwise, update setup */
+ if ((profileDrc != FDK_DRC_Generator_getDrcProfile(hDrcComp)) ||
+ (profileComp != FDK_DRC_Generator_getCompProfile(hDrcComp))) {
+ FDK_DRC_Generator_setDrcProfile(hDrcComp, profileDrc, profileComp);
+ }
+
+ /* Sanity check */
+ if (profileComp == DRC_NONE) {
+ pMetadata->etsiAncData.compression_value = 0x80; /* to ensure no external
+ values will be written
+ if not configured */
+ }
+
+ /* in case of embedding external values, copy this now (limiter may overwrite
+ * them) */
+ dynrng = decodeDynrng(pMetadata->mpegDrc.dyn_rng_ctl[0],
+ pMetadata->mpegDrc.dyn_rng_sgn[0]);
+ compr = decodeCompr(pMetadata->etsiAncData.compression_value);
+
+ dmxGain5 = decodeDynrng(pMetadata->etsiAncData.extAncData.dmx_gain_5_idx,
+ pMetadata->etsiAncData.extAncData.dmx_gain_5_sgn);
+ dmxGain2 = decodeDynrng(pMetadata->etsiAncData.extAncData.dmx_gain_2_idx,
+ pMetadata->etsiAncData.extAncData.dmx_gain_2_sgn);
+
+ /* Call compressor */
+ if (FDK_DRC_Generator_Calc(
+ hDrcComp, pSamples, samplesBufSize,
+ progreflvl2dialnorm(pMetadata->mpegDrc.prog_ref_level),
+ pMetadata->mpegDrc.drc_TargetRefLevel,
+ pMetadata->etsiAncData.comp_TargetRefLevel,
+ dmxTable[pMetadata->centerMixLevel],
+ dmxTable[pMetadata->surroundMixLevel],
+ dmxTable[pMetadata->etsiAncData.extAncData.ext_dmix_a_idx],
+ dmxTable[pMetadata->etsiAncData.extAncData.ext_dmix_b_idx],
+ pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status
+ ? dmxLfeTable[pMetadata->etsiAncData.extAncData.ext_dmix_lfe_idx]
+ : (FIXP_DBL)0,
+ dmxGain5, dmxGain2, &dynrng, &compr) != 0) {
+ err = METADATA_ENCODE_ERROR;
+ goto bail;
+ }
+
+ /* Write DRC values */
+ pMetadata->mpegDrc.drc_band_incr = 0;
+ encodeDynrng(dynrng, pMetadata->mpegDrc.dyn_rng_ctl,
+ pMetadata->mpegDrc.dyn_rng_sgn);
+ pMetadata->etsiAncData.compression_value = encodeCompr(compr);
+
+bail:
+ return err;
+}
+
+FDK_METADATA_ERROR FDK_MetadataEnc_Process(
+ HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples,
+ const UINT audioSamplesBufSize, const INT nAudioSamples,
+ const AACENC_MetaData* const pMetadata,
+ AACENC_EXT_PAYLOAD** ppMetaDataExtPayload, UINT* nMetaDataExtensions,
+ INT* matrix_mixdown_idx) {
+ FDK_METADATA_ERROR err = METADATA_OK;
+ int metaDataDelayWriteIdx, metaDataDelayReadIdx, metadataMode;
+
+ /* Where to write new meta data info */
+ metaDataDelayWriteIdx = hMetaDataEnc->metaDataDelayIdx;
+
+ /* How to write the data */
+ metadataMode = hMetaDataEnc->metadataMode;
+
+ /* Compensate meta data delay. */
+ hMetaDataEnc->metaDataDelayIdx++;
+ if (hMetaDataEnc->metaDataDelayIdx > hMetaDataEnc->nMetaDataDelay)
+ hMetaDataEnc->metaDataDelayIdx = 0;
+
+ /* Where to read pending meta data info from. */
+ metaDataDelayReadIdx = hMetaDataEnc->metaDataDelayIdx;
+
+ /* Submit new data if available. */
+ if (pMetadata != NULL) {
+ FDKmemcpy(&hMetaDataEnc->submittedMetaData, pMetadata,
+ sizeof(AACENC_MetaData));
+ }
+
+ /* Write one additional frame with default configuration of meta data. Ensure
+ * defined behaviour on decoder side. */
+ if ((hMetaDataEnc->finalizeMetaData != 0) &&
+ (hMetaDataEnc->metadataMode == 0)) {
+ FDKmemcpy(&hMetaDataEnc->submittedMetaData, &defaultMetaDataSetup,
+ sizeof(AACENC_MetaData));
+ metadataMode = hMetaDataEnc->finalizeMetaData;
+ hMetaDataEnc->finalizeMetaData = 0;
+ }
+
+ /* Get last submitted data. */
+ if ((err = LoadSubmittedMetadata(
+ &hMetaDataEnc->submittedMetaData, hMetaDataEnc->nChannels,
+ metadataMode,
+ &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx])) !=
+ METADATA_OK) {
+ goto bail;
+ }
+
+ /* Calculate compressor if necessary and updata meta data info */
+ if ((hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode == 1) ||
+ (hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode == 2)) {
+ if ((err = ProcessCompressor(
+ &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx],
+ hMetaDataEnc->hDrcComp, pAudioSamples, audioSamplesBufSize,
+ nAudioSamples)) != METADATA_OK) {
+ /* Get last submitted data again. */
+ LoadSubmittedMetadata(
+ &hMetaDataEnc->submittedMetaData, hMetaDataEnc->nChannels,
+ metadataMode, &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]);
+ }
+ }
+
+ /* Fill up delay line with initial meta data info.*/
+ if ((hMetaDataEnc->initializeMetaData != 0) &&
+ (hMetaDataEnc->metadataMode != 0)) {
+ int i;
+ for (i = 0;
+ i < (int)(sizeof(hMetaDataEnc->metaDataBuffer) / sizeof(AAC_METADATA));
+ i++) {
+ if (i != metaDataDelayWriteIdx) {
+ FDKmemcpy(&hMetaDataEnc->metaDataBuffer[i],
+ &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx],
+ sizeof(hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]));
+ }
+ }
+ hMetaDataEnc->initializeMetaData = 0;
+ }
+
+ /* Convert Meta Data side info to bitstream data. */
+ FDK_ASSERT(metaDataDelayReadIdx < MAX_DELAY_FRAMES);
+ if ((err = WriteMetadataPayload(
+ hMetaDataEnc,
+ &hMetaDataEnc->metaDataBuffer[metaDataDelayReadIdx])) !=
+ METADATA_OK) {
+ goto bail;
+ }
+
+ /* Assign meta data to output */
+ *ppMetaDataExtPayload = hMetaDataEnc->exPayload;
+ *nMetaDataExtensions = hMetaDataEnc->nExtensions;
+ *matrix_mixdown_idx = hMetaDataEnc->matrix_mixdown_idx;
+
+bail:
+ /* Compensate audio delay, reset err status. */
+ err = CompensateAudioDelay(hMetaDataEnc, pAudioSamples, audioSamplesBufSize,
+ nAudioSamples / hMetaDataEnc->nChannels);
+
+ return err;
+}
+
+static FDK_METADATA_ERROR CompensateAudioDelay(
+ HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples,
+ const UINT audioSamplesBufSize, const INT nAudioSamples) {
+ FDK_METADATA_ERROR err = METADATA_OK;
+
+ if (hMetaDataEnc->nAudioDataDelay) {
+ C_ALLOC_SCRATCH_START(scratch_audioDelayBuffer, INT_PCM, 1024);
+
+ for (int c = 0; c < hMetaDataEnc->nChannels; c++) {
+ int M = 1024;
+ INT_PCM* pAudioSamples2 = pAudioSamples + c * audioSamplesBufSize;
+ int delayIdx = hMetaDataEnc->nAudioDataDelay;
+
+ do {
+ M = fMin(M, delayIdx);
+ delayIdx -= M;
+
+ FDKmemcpy(&scratch_audioDelayBuffer[0],
+ &pAudioSamples2[(nAudioSamples - M)], sizeof(INT_PCM) * M);
+ FDKmemmove(&pAudioSamples2[M], &pAudioSamples2[0],
+ sizeof(INT_PCM) * (nAudioSamples - M));
+ FDKmemcpy(
+ &pAudioSamples2[0],
+ &hMetaDataEnc->pAudioDelayBuffer[delayIdx +
+ c * hMetaDataEnc->nAudioDataDelay],
+ sizeof(INT_PCM) * M);
+ FDKmemcpy(
+ &hMetaDataEnc->pAudioDelayBuffer[delayIdx +
+ c * hMetaDataEnc->nAudioDataDelay],
+ &scratch_audioDelayBuffer[0], sizeof(INT_PCM) * M);
+
+ } while (delayIdx > 0);
+ }
+
+ C_ALLOC_SCRATCH_END(scratch_audioDelayBuffer, INT_PCM, 1024);
+ }
+
+ return err;
+}
+
+/*-----------------------------------------------------------------------------
+
+ functionname: WriteMetadataPayload
+ description: fills anc data and extension payload
+ returns: Error status
+
+ ------------------------------------------------------------------------------*/
+static FDK_METADATA_ERROR WriteMetadataPayload(
+ const HANDLE_FDK_METADATA_ENCODER hMetaData,
+ const AAC_METADATA* const pMetadata) {
+ FDK_METADATA_ERROR err = METADATA_OK;
+
+ if ((hMetaData == NULL) || (pMetadata == NULL)) {
+ err = METADATA_INVALID_HANDLE;
+ goto bail;
+ }
+
+ hMetaData->nExtensions = 0;
+ hMetaData->matrix_mixdown_idx = -1;
+
+ if (pMetadata->metadataMode != 0) {
+ /* AAC-DRC */
+ if ((pMetadata->metadataMode == 1) || (pMetadata->metadataMode == 2)) {
+ hMetaData->exPayload[hMetaData->nExtensions].pData =
+ hMetaData->drcInfoPayload;
+ hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DYNAMIC_RANGE;
+ hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;
+
+ hMetaData->exPayload[hMetaData->nExtensions].dataSize =
+ WriteDynamicRangeInfoPayload(
+ pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData);
+
+ hMetaData->nExtensions++;
+ } /* pMetadata->metadataMode==1 || pMetadata->metadataMode==2 */
+
+ /* Matrix Mixdown Coefficient in PCE */
+ if (pMetadata->WritePCEMixDwnIdx) {
+ hMetaData->matrix_mixdown_idx =
+ surmix2matrix_mixdown_idx[pMetadata->surroundMixLevel];
+ }
+
+ /* ETSI TS 101 154 (DVB) - MPEG4 ancillary_data() */
+ if ((pMetadata->metadataMode == 2) ||
+ (pMetadata->metadataMode == 3)) /* MP4_METADATA_MPEG_ETSI */
+ {
+ hMetaData->exPayload[hMetaData->nExtensions].pData =
+ hMetaData->drcDsePayload;
+ hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DATA_ELEMENT;
+ hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;
+
+ hMetaData->exPayload[hMetaData->nExtensions].dataSize =
+ WriteEtsiAncillaryDataPayload(
+ pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData);
+
+ hMetaData->nExtensions++;
+ } /* metadataMode==2 || metadataMode==3 */
+
+ } /* metadataMode != 0 */
+
+bail:
+ return err;
+}
+
+static INT WriteDynamicRangeInfoPayload(const AAC_METADATA* const pMetadata,
+ UCHAR* const pExtensionPayload) {
+ const INT pce_tag_present = 0; /* yet fixed setting! */
+ const INT prog_ref_lev_res_bits = 0;
+ INT i, drc_num_bands = 1;
+
+ FDK_BITSTREAM bsWriter;
+ FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);
+
+ /* dynamic_range_info() */
+ FDKwriteBits(&bsWriter, pce_tag_present, 1); /* pce_tag_present */
+ if (pce_tag_present) {
+ FDKwriteBits(&bsWriter, 0x0, 4); /* pce_instance_tag */
+ FDKwriteBits(&bsWriter, 0x0, 4); /* drc_tag_reserved_bits */
+ }
+
+ /* Exclude channels */
+ FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.excluded_chns_present) ? 1 : 0,
+ 1); /* excluded_chns_present*/
+
+ /* Multiband DRC */
+ FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.drc_bands_present) ? 1 : 0,
+ 1); /* drc_bands_present */
+ if (pMetadata->mpegDrc.drc_bands_present) {
+ FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_incr,
+ 4); /* drc_band_incr */
+ FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_interpolation_scheme,
+ 4); /* drc_interpolation_scheme */
+ drc_num_bands += pMetadata->mpegDrc.drc_band_incr;
+ for (i = 0; i < drc_num_bands; i++) {
+ FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_top[i],
+ 8); /* drc_band_top */
+ }
+ }
+
+ /* Program Reference Level */
+ FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level_present,
+ 1); /* prog_ref_level_present */
+ if (pMetadata->mpegDrc.prog_ref_level_present) {
+ FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level,
+ 7); /* prog_ref_level */
+ FDKwriteBits(&bsWriter, prog_ref_lev_res_bits,
+ 1); /* prog_ref_level_reserved_bits */
+ }
+
+ /* DRC Values */
+ for (i = 0; i < drc_num_bands; i++) {
+ FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.dyn_rng_sgn[i]) ? 1 : 0,
+ 1); /* dyn_rng_sgn[ */
+ FDKwriteBits(&bsWriter, pMetadata->mpegDrc.dyn_rng_ctl[i],
+ 7); /* dyn_rng_ctl */
+ }
+
+ /* return number of valid bits in extension payload. */
+ return FDKgetValidBits(&bsWriter);
+}
+
+static INT WriteEtsiAncillaryDataPayload(const AAC_METADATA* const pMetadata,
+ UCHAR* const pExtensionPayload) {
+ FDK_BITSTREAM bsWriter;
+ FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);
+
+ /* ancillary_data_sync */
+ FDKwriteBits(&bsWriter, 0xBC, 8);
+
+ /* bs_info */
+ FDKwriteBits(&bsWriter, 0x3, 2); /* mpeg_audio_type */
+ FDKwriteBits(&bsWriter, pMetadata->dolbySurroundMode,
+ 2); /* dolby_surround_mode */
+ FDKwriteBits(&bsWriter, pMetadata->drcPresentationMode,
+ 2); /* DRC presentation mode */
+ FDKwriteBits(&bsWriter, 0x0, 1); /* stereo_downmix_mode */
+ FDKwriteBits(&bsWriter, 0x0, 1); /* reserved */
+
+ /* ancillary_data_status */
+ FDKwriteBits(&bsWriter, 0, 3); /* 3 bit Reserved, set to "0" */
+ FDKwriteBits(&bsWriter, (pMetadata->DmxLvl_On) ? 1 : 0,
+ 1); /* downmixing_levels_MPEG4_status */
+ FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncDataStatus,
+ 1); /* ext_anc_data_status */
+ FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.compression_on) ? 1 : 0,
+ 1); /* audio_coding_mode_and_compression status */
+ FDKwriteBits(&bsWriter,
+ (pMetadata->etsiAncData.timecode_coarse_status) ? 1 : 0,
+ 1); /* coarse_grain_timecode_status */
+ FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_fine_status) ? 1 : 0,
+ 1); /* fine_grain_timecode_status */
+
+ /* downmixing_levels_MPEG4_status */
+ if (pMetadata->DmxLvl_On) {
+ FDKwriteBits(
+ &bsWriter,
+ encodeDmxLvls(pMetadata->centerMixLevel, pMetadata->surroundMixLevel),
+ 8);
+ }
+
+ /* audio_coding_mode_and_compression_status */
+ if (pMetadata->etsiAncData.compression_on) {
+ FDKwriteBits(&bsWriter, 0x01, 8); /* audio coding mode */
+ FDKwriteBits(&bsWriter, pMetadata->etsiAncData.compression_value,
+ 8); /* compression value */
+ }
+
+ /* grain-timecode coarse/fine */
+ if (pMetadata->etsiAncData.timecode_coarse_status) {
+ FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */
+ }
+
+ if (pMetadata->etsiAncData.timecode_fine_status) {
+ FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */
+ }
+
+ /* extended ancillary data structure */
+ if (pMetadata->etsiAncData.extAncDataStatus) {
+ /* ext_ancillary_data_status */
+ FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
+ FDKwriteBits(&bsWriter,
+ pMetadata->etsiAncData.extAncData.ext_downmix_lvl_status,
+ 1); /* ext_downmixing_levels_status */
+ FDKwriteBits(&bsWriter,
+ pMetadata->etsiAncData.extAncData.ext_downmix_gain_status,
+ 1); /* ext_downmixing_global_gains_status */
+ FDKwriteBits(&bsWriter,
+ pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status,
+ 1); /* ext_downmixing_lfe_level_status" */
+ FDKwriteBits(&bsWriter, 0, 4); /* Reserved, set to "0" */
+
+ /* ext_downmixing_levels */
+ if (pMetadata->etsiAncData.extAncData.ext_downmix_lvl_status) {
+ FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.ext_dmix_a_idx,
+ 3); /* dmix_a_idx */
+ FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.ext_dmix_b_idx,
+ 3); /* dmix_b_idx */
+ FDKwriteBits(&bsWriter, 0, 2); /* Reserved, set to "0" */
+ }
+
+ /* ext_downmixing_gains */
+ if (pMetadata->etsiAncData.extAncData.ext_downmix_gain_status) {
+ FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_5_sgn,
+ 1); /* dmx_gain_5_sign */
+ FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_5_idx,
+ 6); /* dmx_gain_5_idx */
+ FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
+ FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_2_sgn,
+ 1); /* dmx_gain_2_sign */
+ FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_2_idx,
+ 6); /* dmx_gain_2_idx */
+ FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
+ }
+
+ if (pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status) {
+ FDKwriteBits(&bsWriter,
+ pMetadata->etsiAncData.extAncData.ext_dmix_lfe_idx,
+ 4); /* dmix_lfe_idx */
+ FDKwriteBits(&bsWriter, 0, 4); /* Reserved, set to "0" */
+ }
+ }
+
+ return FDKgetValidBits(&bsWriter);
+}
+
+static FDK_METADATA_ERROR LoadSubmittedMetadata(
+ const AACENC_MetaData* const hMetadata, const INT nChannels,
+ const INT metadataMode, AAC_METADATA* const pAacMetaData) {
+ FDK_METADATA_ERROR err = METADATA_OK;
+
+ if (pAacMetaData == NULL) {
+ err = METADATA_INVALID_HANDLE;
+ } else {
+ /* init struct */
+ FDKmemclear(pAacMetaData, sizeof(AAC_METADATA));
+
+ if (hMetadata != NULL) {
+ /* convert data */
+ pAacMetaData->mpegDrc.drc_profile = hMetadata->drc_profile;
+ pAacMetaData->etsiAncData.comp_profile = hMetadata->comp_profile;
+ pAacMetaData->mpegDrc.drc_TargetRefLevel = hMetadata->drc_TargetRefLevel;
+ pAacMetaData->etsiAncData.comp_TargetRefLevel =
+ hMetadata->comp_TargetRefLevel;
+ pAacMetaData->mpegDrc.prog_ref_level_present =
+ hMetadata->prog_ref_level_present;
+ pAacMetaData->mpegDrc.prog_ref_level =
+ dialnorm2progreflvl(hMetadata->prog_ref_level);
+
+ pAacMetaData->centerMixLevel = hMetadata->centerMixLevel;
+ pAacMetaData->surroundMixLevel = hMetadata->surroundMixLevel;
+ pAacMetaData->WritePCEMixDwnIdx = hMetadata->PCE_mixdown_idx_present;
+ pAacMetaData->DmxLvl_On = hMetadata->ETSI_DmxLvl_present;
+
+ pAacMetaData->etsiAncData.compression_on =
+ (hMetadata->comp_profile == AACENC_METADATA_DRC_NOT_PRESENT ? 0 : 1);
+
+ if (pAacMetaData->mpegDrc.drc_profile ==
+ AACENC_METADATA_DRC_NOT_PRESENT) {
+ pAacMetaData->mpegDrc.drc_profile =
+ AACENC_METADATA_DRC_NONE; /* MPEG DRC gains are
+ always present in BS
+ syntax */
+ /* we should give a warning, but ErrorHandler does not support this */
+ }
+
+ if (nChannels == 2) {
+ pAacMetaData->dolbySurroundMode =
+ hMetadata->dolbySurroundMode; /* dolby_surround_mode */
+ } else {
+ pAacMetaData->dolbySurroundMode = 0;
+ }
+
+ pAacMetaData->drcPresentationMode = hMetadata->drcPresentationMode;
+ /* override external values if DVB DRC presentation mode is given */
+ if (pAacMetaData->drcPresentationMode == 1) {
+ pAacMetaData->mpegDrc.drc_TargetRefLevel =
+ fMax(-(31 << 16), pAacMetaData->mpegDrc.drc_TargetRefLevel);
+ pAacMetaData->etsiAncData.comp_TargetRefLevel = fMax(
+ -(20 << 16),
+ pAacMetaData->etsiAncData.comp_TargetRefLevel); /* implies -23dB */
+ }
+ if (pAacMetaData->drcPresentationMode == 2) {
+ pAacMetaData->mpegDrc.drc_TargetRefLevel =
+ fMax(-(23 << 16), pAacMetaData->mpegDrc.drc_TargetRefLevel);
+ pAacMetaData->etsiAncData.comp_TargetRefLevel =
+ fMax(-(23 << 16), pAacMetaData->etsiAncData.comp_TargetRefLevel);
+ }
+ if (pAacMetaData->etsiAncData.comp_profile ==
+ AACENC_METADATA_DRC_NOT_PRESENT) {
+ /* DVB defines to revert to Light DRC if heavy is not present */
+ if (pAacMetaData->drcPresentationMode != 0) {
+ /* we exclude the "not indicated" mode as this requires the user to
+ * define desired levels anyway */
+ pAacMetaData->mpegDrc.drc_TargetRefLevel =
+ fMax(pAacMetaData->etsiAncData.comp_TargetRefLevel,
+ pAacMetaData->mpegDrc.drc_TargetRefLevel);
+ }
+ }
+
+ pAacMetaData->etsiAncData.timecode_coarse_status =
+ 0; /* not yet supported - attention: Update
+ GetEstMetadataBytesPerFrame() if enable this! */
+ pAacMetaData->etsiAncData.timecode_fine_status =
+ 0; /* not yet supported - attention: Update
+ GetEstMetadataBytesPerFrame() if enable this! */
+
+ /* extended ancillary data */
+ pAacMetaData->etsiAncData.extAncDataStatus =
+ ((hMetadata->ExtMetaData.extAncDataEnable == 1) ? 1 : 0);
+
+ if (pAacMetaData->etsiAncData.extAncDataStatus) {
+ pAacMetaData->etsiAncData.extAncData.ext_downmix_lvl_status =
+ (hMetadata->ExtMetaData.extDownmixLevelEnable ? 1 : 0);
+ pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status =
+ (hMetadata->ExtMetaData.dmxGainEnable ? 1 : 0);
+ pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status =
+ (hMetadata->ExtMetaData.lfeDmxEnable ? 1 : 0);
+
+ pAacMetaData->etsiAncData.extAncData.ext_dmix_a_idx =
+ hMetadata->ExtMetaData.extDownmixLevel_A;
+ pAacMetaData->etsiAncData.extAncData.ext_dmix_b_idx =
+ hMetadata->ExtMetaData.extDownmixLevel_B;
+
+ if (pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status) {
+ encodeDynrng(hMetadata->ExtMetaData.dmxGain5,
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx),
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn));
+ encodeDynrng(hMetadata->ExtMetaData.dmxGain2,
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx),
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn));
+ } else {
+ encodeDynrng(1 << 16,
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx),
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn));
+ encodeDynrng(1 << 16,
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx),
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn));
+ }
+
+ if (pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status) {
+ pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx =
+ hMetadata->ExtMetaData.lfeDmxLevel;
+ } else {
+ pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx =
+ 15; /* -inf dB */
+ }
+ } else {
+ pAacMetaData->etsiAncData.extAncData.ext_downmix_lvl_status = 0;
+ pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status = 0;
+ pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status = 0;
+
+ pAacMetaData->etsiAncData.extAncData.ext_dmix_a_idx = 7; /* -inf dB */
+ pAacMetaData->etsiAncData.extAncData.ext_dmix_b_idx = 7; /* -inf dB */
+
+ encodeDynrng(1 << 16,
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx),
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn));
+ encodeDynrng(1 << 16,
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx),
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn));
+
+ pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx =
+ 15; /* -inf dB */
+ }
+
+ pAacMetaData->metadataMode = metadataMode;
+ } else {
+ pAacMetaData->metadataMode = 0; /* there is no configuration available */
+ }
+ }
+
+ return err;
+}
+
+INT FDK_MetadataEnc_GetDelay(HANDLE_FDK_METADATA_ENCODER hMetadataEnc) {
+ INT delay = 0;
+
+ if (hMetadataEnc != NULL) {
+ delay = hMetadataEnc->nAudioDataDelay;
+ }
+
+ return delay;
+}
diff --git a/fdk-aac/libAACenc/src/metadata_main.h b/fdk-aac/libAACenc/src/metadata_main.h
new file mode 100644
index 0000000..d872c77
--- /dev/null
+++ b/fdk-aac/libAACenc/src/metadata_main.h
@@ -0,0 +1,226 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): V. Bacigalupo
+
+ Description: Metadata Encoder library interface functions
+
+*******************************************************************************/
+
+#ifndef METADATA_MAIN_H
+#define METADATA_MAIN_H
+
+/* Includes ******************************************************************/
+#include "aacenc_lib.h"
+#include "aacenc.h"
+
+/* Defines *******************************************************************/
+
+/* Data Types ****************************************************************/
+
+typedef enum {
+ METADATA_OK = 0x0000, /*!< No error happened. All fine. */
+ METADATA_INVALID_HANDLE =
+ 0x0020, /*!< Handle passed to function call was invalid. */
+ METADATA_MEMORY_ERROR = 0x0021, /*!< Memory allocation failed. */
+ METADATA_INIT_ERROR = 0x0040, /*!< General initialization error. */
+ METADATA_ENCODE_ERROR =
+ 0x0060 /*!< The encoding process was interrupted by an unexpected error.
+ */
+
+} FDK_METADATA_ERROR;
+
+/**
+ * Meta Data handle.
+ */
+typedef struct FDK_METADATA_ENCODER *HANDLE_FDK_METADATA_ENCODER;
+
+/**
+ * \brief Open a Meta Data instance.
+ *
+ * \param phMetadataEnc A pointer to a Meta Data handle to be allocated.
+ * Initialized on return.
+ * \param maxChannels Maximum number of supported audio channels.
+ *
+ * \return
+ * - METADATA_OK, on succes.
+ * - METADATA_INVALID_HANDLE, METADATA_MEMORY_ERROR, on failure.
+ */
+FDK_METADATA_ERROR FDK_MetadataEnc_Open(
+ HANDLE_FDK_METADATA_ENCODER *phMetadataEnc, const UINT maxChannels);
+
+/**
+ * \brief Initialize a Meta Data instance.
+ *
+ * \param hMetadataEnc Meta Data handle.
+ * \param resetStates Indication for full reset of all states.
+ * \param metadataMode Configures meta data output format (0,1,2,3).
+ * \param audioDelay Delay cause by the audio encoder.
+ * \param frameLength Number of samples to be processes within one
+ * frame.
+ * \param sampleRate Sampling rat in Hz of audio input signal.
+ * \param nChannels Number of audio input channels.
+ * \param channelMode Channel configuration which is used by the
+ * encoder.
+ * \param channelOrder Channel order of the input data. (WAV, MPEG)
+ *
+ * \return
+ * - METADATA_OK, on succes.
+ * - METADATA_INVALID_HANDLE, METADATA_INIT_ERROR, on failure.
+ */
+FDK_METADATA_ERROR FDK_MetadataEnc_Init(
+ HANDLE_FDK_METADATA_ENCODER hMetadataEnc, const INT resetStates,
+ const INT metadataMode, const INT audioDelay, const UINT frameLength,
+ const UINT sampleRate, const UINT nChannels, const CHANNEL_MODE channelMode,
+ const CHANNEL_ORDER channelOrder);
+
+/**
+ * \brief Calculate Meta Data processing.
+ *
+ * This function treats all step necessary for meta data processing.
+ * - Receive new meta data and make usable.
+ * - Calculate DRC compressor and extract meta data info.
+ * - Make meta data available for extern use.
+ * - Apply audio data and meta data delay compensation.
+ *
+ * \param hMetadataEnc Meta Data handle.
+ * \param pAudioSamples Pointer to audio input data. Existing function
+ * overwrites audio data with delayed audio samples.
+ * \param nAudioSamples Number of input audio samples to be prcessed.
+ * \param pMetadata Pointer to Metat Data input.
+ * \param ppMetaDataExtPayload Pointer to extension payload array. Filled on
+ * return.
+ * \param nMetaDataExtensions Pointer to variable to describe number of
+ * available extension payloads. Filled on return.
+ * \param matrix_mixdown_idx Pointer to variable for matrix mixdown
+ * coefficient. Filled on return.
+ *
+ * \return
+ * - METADATA_OK, on succes.
+ * - METADATA_INVALID_HANDLE, METADATA_ENCODE_ERROR, on failure.
+ */
+FDK_METADATA_ERROR FDK_MetadataEnc_Process(
+ HANDLE_FDK_METADATA_ENCODER hMetadataEnc, INT_PCM *const pAudioSamples,
+ const UINT audioSamplesBufSize, const INT nAudioSamples,
+ const AACENC_MetaData *const pMetadata,
+ AACENC_EXT_PAYLOAD **ppMetaDataExtPayload, UINT *nMetaDataExtensions,
+ INT *matrix_mixdown_idx);
+
+/**
+ * \brief Close the Meta Data instance.
+ *
+ * Deallocate instance and free whole memory.
+ *
+ * \param phMetaData Pointer to the Meta Data handle to be
+ * deallocated.
+ *
+ * \return
+ * - METADATA_OK, on succes.
+ * - METADATA_INVALID_HANDLE, on failure.
+ */
+FDK_METADATA_ERROR FDK_MetadataEnc_Close(
+ HANDLE_FDK_METADATA_ENCODER *phMetaData);
+
+/**
+ * \brief Get Meta Data Encoder delay.
+ *
+ * \param hMetadataEnc Meta Data Encoder handle.
+ *
+ * \return Delay caused by Meta Data module.
+ */
+INT FDK_MetadataEnc_GetDelay(HANDLE_FDK_METADATA_ENCODER hMetadataEnc);
+
+#endif /* METADATA_MAIN_H */
diff --git a/fdk-aac/libAACenc/src/mps_main.cpp b/fdk-aac/libAACenc/src/mps_main.cpp
new file mode 100644
index 0000000..1048228
--- /dev/null
+++ b/fdk-aac/libAACenc/src/mps_main.cpp
@@ -0,0 +1,529 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): Markus Lohwasser
+
+ Description: Mpeg Surround library interface functions
+
+*******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "mps_main.h"
+#include "sacenc_lib.h"
+
+/* Data Types ****************************************************************/
+struct MPS_ENCODER {
+ HANDLE_MP4SPACE_ENCODER hSacEncoder;
+
+ AUDIO_OBJECT_TYPE audioObjectType;
+
+ FDK_bufDescr inBufDesc;
+ FDK_bufDescr outBufDesc;
+ SACENC_InArgs inargs;
+ SACENC_OutArgs outargs;
+
+ void *pInBuffer[1];
+ UINT pInBufferSize[1];
+ UINT pInBufferElSize[1];
+ UINT pInBufferType[1];
+
+ void *pOutBuffer[2];
+ UINT pOutBufferSize[2];
+ UINT pOutBufferElSize[2];
+ UINT pOutBufferType[2];
+
+ UCHAR sacOutBuffer[1024]; /* Worst case memory consumption for ELDv2: 768
+ bytes => 6144 bits (Core + SBR + MPS) */
+};
+
+struct MPS_CONFIG_TAB {
+ AUDIO_OBJECT_TYPE audio_object_type;
+ CHANNEL_MODE channel_mode;
+ ULONG sbr_ratio;
+ ULONG sampling_rate;
+ ULONG bitrate_min;
+ ULONG bitrate_max;
+};
+
+/* Constants *****************************************************************/
+static const MPS_CONFIG_TAB mpsConfigTab[] = {
+ {AOT_ER_AAC_ELD, MODE_212, 0, 16000, 16000, 39999},
+ {AOT_ER_AAC_ELD, MODE_212, 0, 22050, 16000, 49999},
+ {AOT_ER_AAC_ELD, MODE_212, 0, 24000, 16000, 61999},
+ {AOT_ER_AAC_ELD, MODE_212, 0, 32000, 20000, 84999},
+ {AOT_ER_AAC_ELD, MODE_212, 0, 44100, 50000, 192000},
+ {AOT_ER_AAC_ELD, MODE_212, 0, 48000, 62000, 192000},
+
+ {AOT_ER_AAC_ELD, MODE_212, 1, 16000, 18000, 31999},
+ {AOT_ER_AAC_ELD, MODE_212, 1, 22050, 18000, 31999},
+ {AOT_ER_AAC_ELD, MODE_212, 1, 24000, 20000, 64000},
+
+ {AOT_ER_AAC_ELD, MODE_212, 2, 32000, 18000, 64000},
+ {AOT_ER_AAC_ELD, MODE_212, 2, 44100, 21000, 64000},
+ {AOT_ER_AAC_ELD, MODE_212, 2, 48000, 26000, 64000}
+
+};
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+static INT FDK_MpegsEnc_WriteFrameHeader(HANDLE_MPS_ENCODER hMpsEnc,
+ UCHAR *const pOutputBuffer,
+ const int outputBufferSize);
+
+MPS_ENCODER_ERROR FDK_MpegsEnc_Open(HANDLE_MPS_ENCODER *phMpsEnc) {
+ MPS_ENCODER_ERROR error = MPS_ENCODER_OK;
+ HANDLE_MPS_ENCODER hMpsEnc = NULL;
+
+ if (phMpsEnc == NULL) {
+ error = MPS_ENCODER_INVALID_HANDLE;
+ goto bail;
+ }
+
+ if (NULL ==
+ (hMpsEnc = (HANDLE_MPS_ENCODER)FDKcalloc(1, sizeof(MPS_ENCODER)))) {
+ error = MPS_ENCODER_MEMORY_ERROR;
+ goto bail;
+ }
+ FDKmemclear(hMpsEnc, sizeof(MPS_ENCODER));
+
+ if (SACENC_OK != FDK_sacenc_open(&hMpsEnc->hSacEncoder)) {
+ error = MPS_ENCODER_MEMORY_ERROR;
+ goto bail;
+ }
+
+ /* Return mps encoder instance */
+ *phMpsEnc = hMpsEnc;
+
+bail:
+ if (error != MPS_ENCODER_OK) {
+ FDK_MpegsEnc_Close(&hMpsEnc);
+ }
+ return error;
+}
+
+MPS_ENCODER_ERROR FDK_MpegsEnc_Close(HANDLE_MPS_ENCODER *phMpsEnc) {
+ MPS_ENCODER_ERROR error = MPS_ENCODER_OK;
+
+ if (phMpsEnc == NULL) {
+ error = MPS_ENCODER_INVALID_HANDLE;
+ goto bail;
+ }
+
+ if (*phMpsEnc != NULL) {
+ FDK_sacenc_close(&(*phMpsEnc)->hSacEncoder);
+ FDKfree(*phMpsEnc);
+ *phMpsEnc = NULL;
+ }
+bail:
+ return error;
+}
+
+MPS_ENCODER_ERROR FDK_MpegsEnc_Init(HANDLE_MPS_ENCODER hMpsEnc,
+ const AUDIO_OBJECT_TYPE audioObjectType,
+ const UINT samplingrate, const UINT bitrate,
+ const UINT sbrRatio, const UINT framelength,
+ const UINT inputBufferSizePerChannel,
+ const UINT coreCoderDelay) {
+ MPS_ENCODER_ERROR error = MPS_ENCODER_OK;
+ const UINT fs_low = 27713; /* low MPS sampling frequencies */
+ const UINT fs_high = 55426; /* high MPS sampling frequencies */
+ UINT nTimeSlots = 0, nQmfBandsLd = 0;
+
+ if (hMpsEnc == NULL) {
+ error = MPS_ENCODER_INVALID_HANDLE;
+ goto bail;
+ }
+
+ /* Combine MPS with SBR only if the number of QMF band fits together.*/
+ switch (sbrRatio) {
+ case 1: /* downsampled sbr - 32 QMF bands required */
+ if (!(samplingrate < fs_low)) {
+ error = MPS_ENCODER_INIT_ERROR;
+ goto bail;
+ }
+ break;
+ case 2: /* dualrate - 64 QMF bands required */
+ if (!((samplingrate >= fs_low) && (samplingrate < fs_high))) {
+ error = MPS_ENCODER_INIT_ERROR;
+ goto bail;
+ }
+ break;
+ case 0:
+ default:; /* time interface - no samplingrate restriction */
+ }
+
+ /* 32 QMF-Bands ( fs < 27713 )
+ * 64 QMF-Bands ( 27713 >= fs <= 55426 )
+ * 128 QMF-Bands ( fs > 55426 )
+ */
+ nQmfBandsLd =
+ (samplingrate < fs_low) ? 5 : ((samplingrate > fs_high) ? 7 : 6);
+ nTimeSlots = framelength >> nQmfBandsLd;
+
+ /* check if number of qmf bands is usable for given framelength */
+ if (framelength != (nTimeSlots << nQmfBandsLd)) {
+ error = MPS_ENCODER_INIT_ERROR;
+ goto bail;
+ }
+
+ /* is given bitrate intended to be supported */
+ if ((INT)bitrate != FDK_MpegsEnc_GetClosestBitRate(audioObjectType, MODE_212,
+ samplingrate, sbrRatio,
+ bitrate)) {
+ error = MPS_ENCODER_INIT_ERROR;
+ goto bail;
+ }
+
+ /* init SAC library */
+ switch (audioObjectType) {
+ case AOT_ER_AAC_ELD: {
+ const UINT noInterFrameCoding = 0;
+
+ if ((SACENC_OK !=
+ FDK_sacenc_setParam(hMpsEnc->hSacEncoder, SACENC_LOWDELAY,
+ (noInterFrameCoding == 1) ? 1 : 2)) ||
+ (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
+ SACENC_ENC_MODE, SACENC_212)) ||
+ (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
+ SACENC_SAMPLERATE, samplingrate)) ||
+ (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
+ SACENC_FRAME_TIME_SLOTS,
+ nTimeSlots)) ||
+ (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
+ SACENC_PARAM_BANDS,
+ SACENC_BANDS_15)) ||
+ (SACENC_OK !=
+ FDK_sacenc_setParam(hMpsEnc->hSacEncoder, SACENC_TIME_DOM_DMX, 2)) ||
+ (SACENC_OK !=
+ FDK_sacenc_setParam(hMpsEnc->hSacEncoder, SACENC_COARSE_QUANT, 0)) ||
+ (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
+ SACENC_QUANT_MODE,
+ SACENC_QUANTMODE_FINE)) ||
+ (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
+ SACENC_TIME_ALIGNMENT, 0)) ||
+ (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
+ SACENC_INDEPENDENCY_FACTOR, 20))) {
+ error = MPS_ENCODER_INIT_ERROR;
+ goto bail;
+ }
+ break;
+ }
+ default:
+ error = MPS_ENCODER_INIT_ERROR;
+ goto bail;
+ }
+
+ if (SACENC_OK != FDK_sacenc_init(hMpsEnc->hSacEncoder, coreCoderDelay)) {
+ error = MPS_ENCODER_INIT_ERROR;
+ }
+
+ hMpsEnc->audioObjectType = audioObjectType;
+
+ hMpsEnc->inBufDesc.ppBase = (void **)&hMpsEnc->pInBuffer;
+ hMpsEnc->inBufDesc.pBufSize = hMpsEnc->pInBufferSize;
+ hMpsEnc->inBufDesc.pEleSize = hMpsEnc->pInBufferElSize;
+ hMpsEnc->inBufDesc.pBufType = hMpsEnc->pInBufferType;
+ hMpsEnc->inBufDesc.numBufs = 1;
+
+ hMpsEnc->outBufDesc.ppBase = (void **)&hMpsEnc->pOutBuffer;
+ hMpsEnc->outBufDesc.pBufSize = hMpsEnc->pOutBufferSize;
+ hMpsEnc->outBufDesc.pEleSize = hMpsEnc->pOutBufferElSize;
+ hMpsEnc->outBufDesc.pBufType = hMpsEnc->pOutBufferType;
+ hMpsEnc->outBufDesc.numBufs = 2;
+
+ hMpsEnc->pInBuffer[0] = NULL;
+ hMpsEnc->pInBufferSize[0] = 0;
+ hMpsEnc->pInBufferElSize[0] = sizeof(INT_PCM);
+ hMpsEnc->pInBufferType[0] = (FDK_BUF_TYPE_INPUT | FDK_BUF_TYPE_PCM_DATA);
+
+ hMpsEnc->pOutBuffer[0] = NULL;
+ hMpsEnc->pOutBufferSize[0] = 0;
+ hMpsEnc->pOutBufferElSize[0] = sizeof(INT_PCM);
+ hMpsEnc->pOutBufferType[0] = (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_PCM_DATA);
+
+ hMpsEnc->pOutBuffer[1] = NULL;
+ hMpsEnc->pOutBufferSize[1] = 0;
+ hMpsEnc->pOutBufferElSize[1] = sizeof(UCHAR);
+ hMpsEnc->pOutBufferType[1] = (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_BS_DATA);
+
+ hMpsEnc->inargs.isInputInterleaved = 0;
+ hMpsEnc->inargs.inputBufferSizePerChannel = inputBufferSizePerChannel;
+
+bail:
+ return error;
+}
+
+MPS_ENCODER_ERROR FDK_MpegsEnc_Process(HANDLE_MPS_ENCODER hMpsEnc,
+ INT_PCM *const pAudioSamples,
+ const INT nAudioSamples,
+ AACENC_EXT_PAYLOAD *pMpsExtPayload) {
+ MPS_ENCODER_ERROR error = MPS_ENCODER_OK;
+
+ if (hMpsEnc == NULL) {
+ error = MPS_ENCODER_INVALID_HANDLE;
+ } else {
+ int sacHeaderFlag = 1;
+ int sacOutBufferOffset = 0;
+
+ /* In case of eld the ssc is explicit and doesn't need to be inband */
+ if (hMpsEnc->audioObjectType == AOT_ER_AAC_ELD) {
+ sacHeaderFlag = 0;
+ }
+
+ /* 4 bits nibble after extension type */
+ hMpsEnc->sacOutBuffer[0] = (sacHeaderFlag == 0) ? 0x3 : 0x7;
+ sacOutBufferOffset += 1;
+
+ if (sacHeaderFlag) {
+ sacOutBufferOffset += FDK_MpegsEnc_WriteFrameHeader(
+ hMpsEnc, &hMpsEnc->sacOutBuffer[sacOutBufferOffset],
+ sizeof(hMpsEnc->sacOutBuffer) - sacOutBufferOffset);
+ }
+
+ /* Register input and output buffer. */
+ hMpsEnc->pInBuffer[0] = (void *)pAudioSamples;
+ hMpsEnc->inargs.nInputSamples = nAudioSamples;
+
+ hMpsEnc->pOutBuffer[0] = (void *)pAudioSamples;
+ hMpsEnc->pOutBufferSize[0] = sizeof(INT_PCM) * nAudioSamples / 2;
+
+ hMpsEnc->pOutBuffer[1] = (void *)&hMpsEnc->sacOutBuffer[sacOutBufferOffset];
+ hMpsEnc->pOutBufferSize[1] =
+ sizeof(hMpsEnc->sacOutBuffer) - sacOutBufferOffset;
+
+ /* encode SAC frame */
+ if (SACENC_OK != FDK_sacenc_encode(hMpsEnc->hSacEncoder,
+ &hMpsEnc->inBufDesc,
+ &hMpsEnc->outBufDesc, &hMpsEnc->inargs,
+ &hMpsEnc->outargs)) {
+ error = MPS_ENCODER_ENCODE_ERROR;
+ goto bail;
+ }
+
+ /* export MPS payload */
+ pMpsExtPayload->pData = (UCHAR *)hMpsEnc->sacOutBuffer;
+ pMpsExtPayload->dataSize =
+ hMpsEnc->outargs.nOutputBits + 8 * (sacOutBufferOffset - 1);
+ pMpsExtPayload->dataType = EXT_LDSAC_DATA;
+ pMpsExtPayload->associatedChElement = -1;
+ }
+
+bail:
+ return error;
+}
+
+INT FDK_MpegsEnc_WriteSpatialSpecificConfig(HANDLE_MPS_ENCODER hMpsEnc,
+ HANDLE_FDK_BITSTREAM hBs) {
+ INT sscBits = 0;
+
+ if (NULL != hMpsEnc) {
+ MP4SPACEENC_INFO mp4SpaceEncoderInfo;
+ FDK_sacenc_getInfo(hMpsEnc->hSacEncoder, &mp4SpaceEncoderInfo);
+
+ if (hBs != NULL) {
+ int i;
+ int writtenBits = 0;
+ for (i = 0; i<mp4SpaceEncoderInfo.pSscBuf->nSscSizeBits>> 3; i++) {
+ FDKwriteBits(hBs, mp4SpaceEncoderInfo.pSscBuf->pSsc[i], 8);
+ writtenBits += 8;
+ }
+ FDKwriteBits(hBs, mp4SpaceEncoderInfo.pSscBuf->pSsc[i],
+ mp4SpaceEncoderInfo.pSscBuf->nSscSizeBits - writtenBits);
+ } /* hBS */
+
+ sscBits = mp4SpaceEncoderInfo.pSscBuf->nSscSizeBits;
+
+ } /* valid hMpsEnc */
+
+ return sscBits;
+}
+
+static INT FDK_MpegsEnc_WriteFrameHeader(HANDLE_MPS_ENCODER hMpsEnc,
+ UCHAR *const pOutputBuffer,
+ const int outputBufferSize) {
+ const int sacTimeAlignFlag = 0;
+
+ /* Initialize variables */
+ int numBits = 0;
+
+ if ((NULL != hMpsEnc) && (NULL != pOutputBuffer)) {
+ UINT alignAnchor, cnt;
+ FDK_BITSTREAM Bs;
+ FDKinitBitStream(&Bs, pOutputBuffer, outputBufferSize, 0, BS_WRITER);
+
+ /* Calculate SSC length information */
+ cnt = (FDK_MpegsEnc_WriteSpatialSpecificConfig(hMpsEnc, NULL) + 7) >> 3;
+
+ /* Write SSC */
+ FDKwriteBits(&Bs, sacTimeAlignFlag, 1);
+
+ if (cnt < 127) {
+ FDKwriteBits(&Bs, cnt, 7);
+ } else {
+ FDKwriteBits(&Bs, 127, 7);
+ FDKwriteBits(&Bs, cnt - 127, 16);
+ }
+
+ alignAnchor = FDKgetValidBits(&Bs);
+ FDK_MpegsEnc_WriteSpatialSpecificConfig(hMpsEnc, &Bs);
+ FDKbyteAlign(&Bs, alignAnchor); /* bsFillBits */
+
+ if (sacTimeAlignFlag) {
+ FDK_ASSERT(1); /* time alignment not supported */
+ }
+
+ numBits = FDKgetValidBits(&Bs);
+ } /* valid handle */
+
+ return ((numBits + 7) >> 3);
+}
+
+INT FDK_MpegsEnc_GetClosestBitRate(const AUDIO_OBJECT_TYPE audioObjectType,
+ const CHANNEL_MODE channelMode,
+ const UINT samplingrate, const UINT sbrRatio,
+ const UINT bitrate) {
+ unsigned int i;
+ int targetBitrate = -1;
+
+ for (i = 0; i < sizeof(mpsConfigTab) / sizeof(MPS_CONFIG_TAB); i++) {
+ if ((mpsConfigTab[i].audio_object_type == audioObjectType) &&
+ (mpsConfigTab[i].channel_mode == channelMode) &&
+ (mpsConfigTab[i].sbr_ratio == sbrRatio) &&
+ (mpsConfigTab[i].sampling_rate == samplingrate)) {
+ targetBitrate = fMin(fMax(bitrate, mpsConfigTab[i].bitrate_min),
+ mpsConfigTab[i].bitrate_max);
+ }
+ }
+
+ return targetBitrate;
+}
+
+INT FDK_MpegsEnc_GetDelay(HANDLE_MPS_ENCODER hMpsEnc) {
+ INT delay = 0;
+
+ if (NULL != hMpsEnc) {
+ MP4SPACEENC_INFO mp4SpaceEncoderInfo;
+ FDK_sacenc_getInfo(hMpsEnc->hSacEncoder, &mp4SpaceEncoderInfo);
+ delay = mp4SpaceEncoderInfo.nCodecDelay;
+ }
+
+ return delay;
+}
+
+INT FDK_MpegsEnc_GetDecDelay(HANDLE_MPS_ENCODER hMpsEnc) {
+ INT delay = 0;
+
+ if (NULL != hMpsEnc) {
+ MP4SPACEENC_INFO mp4SpaceEncoderInfo;
+ FDK_sacenc_getInfo(hMpsEnc->hSacEncoder, &mp4SpaceEncoderInfo);
+ delay = mp4SpaceEncoderInfo.nDecoderDelay;
+ }
+
+ return delay;
+}
+
+MPS_ENCODER_ERROR FDK_MpegsEnc_GetLibInfo(LIB_INFO *info) {
+ MPS_ENCODER_ERROR error = MPS_ENCODER_OK;
+
+ if (NULL == info) {
+ error = MPS_ENCODER_INVALID_HANDLE;
+ } else if (SACENC_OK != FDK_sacenc_getLibInfo(info)) {
+ error = MPS_ENCODER_INIT_ERROR;
+ }
+
+ return error;
+}
diff --git a/fdk-aac/libAACenc/src/mps_main.h b/fdk-aac/libAACenc/src/mps_main.h
new file mode 100644
index 0000000..f56678a
--- /dev/null
+++ b/fdk-aac/libAACenc/src/mps_main.h
@@ -0,0 +1,270 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): Markus Lohwasser
+
+ Description: Mpeg Surround library interface functions
+
+*******************************************************************************/
+
+#ifndef MPS_MAIN_H
+#define MPS_MAIN_H
+
+/* Includes ******************************************************************/
+#include "aacenc.h"
+#include "FDK_audio.h"
+#include "machine_type.h"
+
+/* Defines *******************************************************************/
+typedef enum {
+ MPS_ENCODER_OK = 0x0000, /*!< No error happened. All fine. */
+ MPS_ENCODER_INVALID_HANDLE =
+ 0x0020, /*!< Handle passed to function call was invalid. */
+ MPS_ENCODER_MEMORY_ERROR = 0x0021, /*!< Memory allocation failed. */
+ MPS_ENCODER_INIT_ERROR = 0x0040, /*!< General initialization error. */
+ MPS_ENCODER_ENCODE_ERROR =
+ 0x0060 /*!< The encoding process was interrupted by an unexpected error.
+ */
+
+} MPS_ENCODER_ERROR;
+
+/* Data Types ****************************************************************/
+
+/**
+ * MPEG Surround Encoder interface handle.
+ */
+typedef struct MPS_ENCODER MPS_ENCODER, *HANDLE_MPS_ENCODER;
+
+/* Function / Class Declarations *********************************************/
+
+/**
+ * \brief Open a Mpeg Surround Encoder instance.
+ *
+ * \phMpsEnc A pointer to a MPS handle to be allocated.
+ * Initialized on return.
+ *
+ * \return
+ * - MPS_ENCODER_OK, on succes.
+ * - MPS_ENCODER_INVALID_HANDLE, MPS_ENCODER_MEMORY_ERROR, on failure.
+ */
+MPS_ENCODER_ERROR FDK_MpegsEnc_Open(HANDLE_MPS_ENCODER *phMpsEnc);
+
+/**
+ * \brief Close the Mpeg Surround Encoder instance.
+ *
+ * Deallocate instance and free whole memory.
+ *
+ * \param phMpsEnc Pointer to the MPS handle to be deallocated.
+ *
+ * \return
+ * - MPS_ENCODER_OK, on succes.
+ * - MPS_ENCODER_INVALID_HANDLE, on failure.
+ */
+MPS_ENCODER_ERROR FDK_MpegsEnc_Close(HANDLE_MPS_ENCODER *phMpsEnc);
+
+/**
+ * \brief Initialize a Mpeg Surround Encoder instance.
+ *
+ * \param hMpsEnc MPS Encoder handle.
+ * \param audioObjectType Audio object type.
+ * \param samplingrate Sampling rate in Hz of audio input signal.
+ * \param bitrate Encder target bitrate.
+ * \param sbrRatio SBR sampling rate ratio.
+ * \param framelength Number of samples to be processes within one
+ * frame.
+ * \param inputBufferSizePerChannel Size of input buffer per channel.
+ * \param coreCoderDelay Core coder delay.
+ *
+ * \return
+ * - MPS_ENCODER_OK, on succes.
+ * - MPS_ENCODER_INVALID_HANDLE, MPS_ENCODER_ENCODE_ERROR, on failure.
+ */
+MPS_ENCODER_ERROR FDK_MpegsEnc_Init(HANDLE_MPS_ENCODER hMpsEnc,
+ const AUDIO_OBJECT_TYPE audioObjectType,
+ const UINT samplingrate, const UINT bitrate,
+ const UINT sbrRatio, const UINT framelength,
+ const UINT inputBufferSizePerChannel,
+ const UINT coreCoderDelay);
+
+/**
+ * \brief Calculate Mpeg Surround processing.
+ *
+ * This fuction applies the MPS processing. The MPS side info will be written to
+ * extension payload. The input audio data will be overwritten by the calculated
+ * downmix.
+ *
+ * \param hMpsEnc MPS Encoder handle.
+ * \param pAudioSamples Pointer to audio input/output data.
+ * \param nAudioSamples Number of input audio samples to be prcessed.
+ * \param pMpsExtPayload Pointer to extension payload to be filled on
+ * return.
+ *
+ * \return
+ * - MPS_ENCODER_OK, on succes.
+ * - MPS_ENCODER_INVALID_HANDLE, MPS_ENCODER_ENCODE_ERROR, on failure.
+ */
+MPS_ENCODER_ERROR FDK_MpegsEnc_Process(HANDLE_MPS_ENCODER hMpsEnc,
+ INT_PCM *const pAudioSamples,
+ const INT nAudioSamples,
+ AACENC_EXT_PAYLOAD *pMpsExtPayload);
+
+/**
+ * \brief Write Spatial Specific Config.
+ *
+ * This function can be called via call back from the transport library to write
+ * the Spatial Specific Config to given bitstream buffer.
+ *
+ * \param hMpsEnc MPS Encoder handle.
+ * \param hBs Bitstream buffer handle.
+ *
+ * \return Number of written bits.
+ */
+INT FDK_MpegsEnc_WriteSpatialSpecificConfig(HANDLE_MPS_ENCODER hMpsEnc,
+ HANDLE_FDK_BITSTREAM hBs);
+
+/**
+ * \brief Get closest valid bitrate supported by given config.
+ *
+ * \param audioObjectType Audio object type.
+ * \param channelMode Encoder channel mode.
+ * \param samplingrate Sampling rate in Hz of audio input signal.
+ * \param sbrRatio SBR sampling rate ratio.
+ * \param bitrate The desired target bitrate.
+ *
+ * \return Closest valid bitrate to given bitrate..
+ */
+INT FDK_MpegsEnc_GetClosestBitRate(const AUDIO_OBJECT_TYPE audioObjectType,
+ const CHANNEL_MODE channelMode,
+ const UINT samplingrate, const UINT sbrRatio,
+ const UINT bitrate);
+
+/**
+ * \brief Get codec delay.
+ *
+ * This function returns delay of the whole en-/decoded signal, including
+ * corecoder delay.
+ *
+ * \param hMpsEnc MPS Encoder handle.
+ *
+ * \return Codec delay in samples.
+ */
+INT FDK_MpegsEnc_GetDelay(HANDLE_MPS_ENCODER hMpsEnc);
+
+/**
+ * \brief Get Mpeg Surround Decoder delay.
+ *
+ * This function returns delay of the Mpeg Surround decoder.
+ *
+ * \param hMpsEnc MPS Encoder handle.
+ *
+ * \return Mpeg Surround Decoder delay in samples.
+ */
+INT FDK_MpegsEnc_GetDecDelay(HANDLE_MPS_ENCODER hMpsEnc);
+
+/**
+ * \brief Get information about encoder library build.
+ *
+ * Fill a given LIB_INFO structure with library version information.
+ *
+ * \param info Pointer to an allocated LIB_INFO struct.
+ *
+ * \return
+ * - MPS_ENCODER_OK, on succes.
+ * - MPS_ENCODER_INVALID_HANDLE, MPS_ENCODER_INIT_ERROR, on failure.
+ */
+MPS_ENCODER_ERROR FDK_MpegsEnc_GetLibInfo(LIB_INFO *info);
+
+#endif /* MPS_MAIN_H */
diff --git a/fdk-aac/libAACenc/src/ms_stereo.cpp b/fdk-aac/libAACenc/src/ms_stereo.cpp
new file mode 100644
index 0000000..6a121b2
--- /dev/null
+++ b/fdk-aac/libAACenc/src/ms_stereo.cpp
@@ -0,0 +1,295 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: MS stereo processing
+
+*******************************************************************************/
+
+#include "ms_stereo.h"
+
+#include "psy_const.h"
+
+/* static const float scaleMinThres = 1.0f; */ /* 0.75f for 3db boost */
+
+void FDKaacEnc_MsStereoProcessing(PSY_DATA *RESTRICT psyData[(2)],
+ PSY_OUT_CHANNEL *psyOutChannel[2],
+ const INT *isBook, INT *msDigest, /* output */
+ INT *msMask, /* output */
+ const INT allowMS, const INT sfbCnt,
+ const INT sfbPerGroup,
+ const INT maxSfbPerGroup,
+ const INT *sfbOffset) {
+ FIXP_DBL *sfbEnergyLeft =
+ psyData[0]->sfbEnergy.Long; /* modified where msMask==1 */
+ FIXP_DBL *sfbEnergyRight =
+ psyData[1]->sfbEnergy.Long; /* modified where msMask==1 */
+ const FIXP_DBL *sfbEnergyMid = psyData[0]->sfbEnergyMS.Long;
+ const FIXP_DBL *sfbEnergySide = psyData[1]->sfbEnergyMS.Long;
+ FIXP_DBL *sfbThresholdLeft =
+ psyData[0]->sfbThreshold.Long; /* modified where msMask==1 */
+ FIXP_DBL *sfbThresholdRight =
+ psyData[1]->sfbThreshold.Long; /* modified where msMask==1 */
+
+ FIXP_DBL *sfbSpreadEnLeft = psyData[0]->sfbSpreadEnergy.Long;
+ FIXP_DBL *sfbSpreadEnRight = psyData[1]->sfbSpreadEnergy.Long;
+
+ FIXP_DBL *sfbEnergyLeftLdData =
+ psyOutChannel[0]->sfbEnergyLdData; /* modified where msMask==1 */
+ FIXP_DBL *sfbEnergyRightLdData =
+ psyOutChannel[1]->sfbEnergyLdData; /* modified where msMask==1 */
+ FIXP_DBL *sfbEnergyMidLdData = psyData[0]->sfbEnergyMSLdData;
+ FIXP_DBL *sfbEnergySideLdData = psyData[1]->sfbEnergyMSLdData;
+ FIXP_DBL *sfbThresholdLeftLdData =
+ psyOutChannel[0]->sfbThresholdLdData; /* modified where msMask==1 */
+ FIXP_DBL *sfbThresholdRightLdData =
+ psyOutChannel[1]->sfbThresholdLdData; /* modified where msMask==1 */
+
+ FIXP_DBL *mdctSpectrumLeft =
+ psyData[0]->mdctSpectrum; /* modified where msMask==1 */
+ FIXP_DBL *mdctSpectrumRight =
+ psyData[1]->mdctSpectrum; /* modified where msMask==1 */
+
+ INT sfb, sfboffs, j; /* loop counters */
+ FIXP_DBL pnlrLdData, pnmsLdData;
+ FIXP_DBL minThresholdLdData;
+ FIXP_DBL minThreshold;
+ INT useMS;
+
+ INT msMaskTrueSomewhere = 0; /* to determine msDigest */
+ INT numMsMaskFalse =
+ 0; /* number of non-intensity bands where L/R coding is used */
+
+ for (sfb = 0; sfb < sfbCnt; sfb += sfbPerGroup) {
+ for (sfboffs = 0; sfboffs < maxSfbPerGroup; sfboffs++) {
+ if ((isBook == NULL) ? 1 : (isBook[sfb + sfboffs] == 0)) {
+ FIXP_DBL tmp;
+
+ /*
+ minThreshold=min(sfbThresholdLeft[sfb+sfboffs],
+ sfbThresholdRight[sfb+sfboffs])*scaleMinThres; pnlr =
+ (sfbThresholdLeft[sfb+sfboffs]/
+ max(sfbEnergyLeft[sfb+sfboffs],sfbThresholdLeft[sfb+sfboffs]))*
+ (sfbThresholdRight[sfb+sfboffs]/
+ max(sfbEnergyRight[sfb+sfboffs],sfbThresholdRight[sfb+sfboffs]));
+ pnms =
+ (minThreshold/max(sfbEnergyMid[sfb+sfboffs],minThreshold))*
+ (minThreshold/max(sfbEnergySide[sfb+sfboffs],minThreshold));
+ useMS = (pnms > pnlr);
+ */
+
+ /* we assume that scaleMinThres == 1.0f and we can drop it */
+ minThresholdLdData = fixMin(sfbThresholdLeftLdData[sfb + sfboffs],
+ sfbThresholdRightLdData[sfb + sfboffs]);
+
+ /* pnlrLdData = sfbThresholdLeftLdData[sfb+sfboffs] -
+ max(sfbEnergyLeftLdData[sfb+sfboffs],
+ sfbThresholdLeftLdData[sfb+sfboffs]) +
+ sfbThresholdRightLdData[sfb+sfboffs] -
+ max(sfbEnergyRightLdData[sfb+sfboffs],
+ sfbThresholdRightLdData[sfb+sfboffs]); */
+ tmp = fixMax(sfbEnergyLeftLdData[sfb + sfboffs],
+ sfbThresholdLeftLdData[sfb + sfboffs]);
+ pnlrLdData = (sfbThresholdLeftLdData[sfb + sfboffs] >> 1) - (tmp >> 1);
+ pnlrLdData = pnlrLdData + (sfbThresholdRightLdData[sfb + sfboffs] >> 1);
+ tmp = fixMax(sfbEnergyRightLdData[sfb + sfboffs],
+ sfbThresholdRightLdData[sfb + sfboffs]);
+ pnlrLdData = pnlrLdData - (tmp >> 1);
+
+ /* pnmsLdData = minThresholdLdData -
+ max(sfbEnergyMidLdData[sfb+sfboffs], minThresholdLdData) +
+ minThresholdLdData - max(sfbEnergySideLdData[sfb+sfboffs],
+ minThresholdLdData); */
+ tmp = fixMax(sfbEnergyMidLdData[sfb + sfboffs], minThresholdLdData);
+ pnmsLdData = minThresholdLdData - (tmp >> 1);
+ tmp = fixMax(sfbEnergySideLdData[sfb + sfboffs], minThresholdLdData);
+ pnmsLdData = pnmsLdData - (tmp >> 1);
+ useMS = ((allowMS != 0) && (pnmsLdData > pnlrLdData)) ? 1 : 0;
+
+ if (useMS) {
+ msMask[sfb + sfboffs] = 1;
+ msMaskTrueSomewhere = 1;
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1];
+ j++) {
+ FIXP_DBL specL, specR;
+ specL = mdctSpectrumLeft[j] >> 1;
+ specR = mdctSpectrumRight[j] >> 1;
+ mdctSpectrumLeft[j] = specL + specR;
+ mdctSpectrumRight[j] = specL - specR;
+ }
+ minThreshold = fixMin(sfbThresholdLeft[sfb + sfboffs],
+ sfbThresholdRight[sfb + sfboffs]);
+ sfbThresholdLeft[sfb + sfboffs] = sfbThresholdRight[sfb + sfboffs] =
+ minThreshold;
+ sfbThresholdLeftLdData[sfb + sfboffs] =
+ sfbThresholdRightLdData[sfb + sfboffs] = minThresholdLdData;
+ sfbEnergyLeft[sfb + sfboffs] = sfbEnergyMid[sfb + sfboffs];
+ sfbEnergyRight[sfb + sfboffs] = sfbEnergySide[sfb + sfboffs];
+ sfbEnergyLeftLdData[sfb + sfboffs] =
+ sfbEnergyMidLdData[sfb + sfboffs];
+ sfbEnergyRightLdData[sfb + sfboffs] =
+ sfbEnergySideLdData[sfb + sfboffs];
+
+ sfbSpreadEnLeft[sfb + sfboffs] = sfbSpreadEnRight[sfb + sfboffs] =
+ fixMin(sfbSpreadEnLeft[sfb + sfboffs],
+ sfbSpreadEnRight[sfb + sfboffs]) >>
+ 1;
+
+ } else {
+ msMask[sfb + sfboffs] = 0;
+ numMsMaskFalse++;
+ } /* useMS */
+ } /* isBook */
+ else {
+ /* keep mDigest from IS module */
+ if (msMask[sfb + sfboffs]) {
+ msMaskTrueSomewhere = 1;
+ }
+ /* prohibit MS_MASK_ALL in combination with IS */
+ numMsMaskFalse = 9;
+ } /* isBook */
+ } /* sfboffs */
+ } /* sfb */
+
+ if (msMaskTrueSomewhere == 1) {
+ if ((numMsMaskFalse == 0) ||
+ ((numMsMaskFalse < maxSfbPerGroup) && (numMsMaskFalse < 9))) {
+ *msDigest = SI_MS_MASK_ALL;
+ /* loop through M/S bands; if msMask==0, set it to 1 and apply M/S */
+ for (sfb = 0; sfb < sfbCnt; sfb += sfbPerGroup) {
+ for (sfboffs = 0; sfboffs < maxSfbPerGroup; sfboffs++) {
+ if (((isBook == NULL) ? 1 : (isBook[sfb + sfboffs] == 0)) &&
+ (msMask[sfb + sfboffs] == 0)) {
+ msMask[sfb + sfboffs] = 1;
+ /* apply M/S coding */
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1];
+ j++) {
+ FIXP_DBL specL, specR;
+ specL = mdctSpectrumLeft[j] >> 1;
+ specR = mdctSpectrumRight[j] >> 1;
+ mdctSpectrumLeft[j] = specL + specR;
+ mdctSpectrumRight[j] = specL - specR;
+ }
+ minThreshold = fixMin(sfbThresholdLeft[sfb + sfboffs],
+ sfbThresholdRight[sfb + sfboffs]);
+ sfbThresholdLeft[sfb + sfboffs] = sfbThresholdRight[sfb + sfboffs] =
+ minThreshold;
+ minThresholdLdData = fixMin(sfbThresholdLeftLdData[sfb + sfboffs],
+ sfbThresholdRightLdData[sfb + sfboffs]);
+ sfbThresholdLeftLdData[sfb + sfboffs] =
+ sfbThresholdRightLdData[sfb + sfboffs] = minThresholdLdData;
+ sfbEnergyLeft[sfb + sfboffs] = sfbEnergyMid[sfb + sfboffs];
+ sfbEnergyRight[sfb + sfboffs] = sfbEnergySide[sfb + sfboffs];
+ sfbEnergyLeftLdData[sfb + sfboffs] =
+ sfbEnergyMidLdData[sfb + sfboffs];
+ sfbEnergyRightLdData[sfb + sfboffs] =
+ sfbEnergySideLdData[sfb + sfboffs];
+
+ sfbSpreadEnLeft[sfb + sfboffs] = sfbSpreadEnRight[sfb + sfboffs] =
+ fixMin(sfbSpreadEnLeft[sfb + sfboffs],
+ sfbSpreadEnRight[sfb + sfboffs]) >>
+ 1;
+ }
+ }
+ }
+ } else {
+ *msDigest = SI_MS_MASK_SOME;
+ }
+ } else {
+ *msDigest = SI_MS_MASK_NONE;
+ }
+}
diff --git a/fdk-aac/libAACenc/src/ms_stereo.h b/fdk-aac/libAACenc/src/ms_stereo.h
new file mode 100644
index 0000000..a202307
--- /dev/null
+++ b/fdk-aac/libAACenc/src/ms_stereo.h
@@ -0,0 +1,117 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: MS stereo processing
+
+*******************************************************************************/
+
+#ifndef MS_STEREO_H
+#define MS_STEREO_H
+
+#include "interface.h"
+
+void FDKaacEnc_MsStereoProcessing(PSY_DATA *RESTRICT psyData[(2)],
+ PSY_OUT_CHANNEL *psyOutChannel[2],
+ const INT *isBook, INT *msDigest, /* output */
+ INT *msMask, /* output */
+ const INT allowMS, const INT sfbCnt,
+ const INT sfbPerGroup,
+ const INT maxSfbPerGroup,
+ const INT *sfbOffset);
+
+#endif /* MS_STEREO_H */
diff --git a/fdk-aac/libAACenc/src/noisedet.cpp b/fdk-aac/libAACenc/src/noisedet.cpp
new file mode 100644
index 0000000..c984304
--- /dev/null
+++ b/fdk-aac/libAACenc/src/noisedet.cpp
@@ -0,0 +1,235 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser
+
+ Description: noisedet.c
+ Routines for Noise Detection
+
+*******************************************************************************/
+
+#include "noisedet.h"
+
+#include "aacenc_pns.h"
+#include "pnsparam.h"
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_fuzzyIsSmaller
+ description: Fuzzy value calculation for "testVal is smaller than refVal"
+ returns: fuzzy value
+ input: test and ref Value,
+ low and high Lim
+ output: return fuzzy value
+
+*****************************************************************************/
+static FIXP_SGL FDKaacEnc_fuzzyIsSmaller(FIXP_DBL testVal, FIXP_DBL refVal,
+ FIXP_DBL loLim, FIXP_DBL hiLim) {
+ if (refVal <= FL2FXCONST_DBL(0.0))
+ return (FL2FXCONST_SGL(0.0f));
+ else if (testVal >= fMult((hiLim >> 1) + (loLim >> 1), refVal))
+ return (FL2FXCONST_SGL(0.0f));
+ else
+ return ((FIXP_SGL)MAXVAL_SGL);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_noiseDetect
+ description: detect tonal sfb's; two tests
+ Powerdistribution:
+ sfb splittet in four regions,
+ compare the energy in all sections
+ PsychTonality:
+ compare tonality from chaosmeasure with reftonality
+ returns:
+ input: spectrum of one large mdct
+ number of sfb's
+ pointer to offset of sfb's
+ pointer to noiseFuzzyMeasure (modified)
+ noiseparams struct
+ pointer to sfb energies
+ pointer to tonality calculated in chaosmeasure
+ output: noiseFuzzy Measure
+
+*****************************************************************************/
+
+void FDKaacEnc_noiseDetect(FIXP_DBL *RESTRICT mdctSpectrum,
+ INT *RESTRICT sfbMaxScaleSpec, INT sfbActive,
+ const INT *RESTRICT sfbOffset,
+ FIXP_SGL *RESTRICT noiseFuzzyMeasure,
+ NOISEPARAMS *np, FIXP_SGL *RESTRICT sfbtonality)
+
+{
+ int i, k, sfb, sfbWidth;
+ FIXP_SGL fuzzy, fuzzyTotal;
+ FIXP_DBL refVal, testVal;
+
+ /***** Start detection phase *****/
+ /* Start noise detection for each band based on a number of checks */
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ fuzzyTotal = (FIXP_SGL)MAXVAL_SGL;
+ sfbWidth = sfbOffset[sfb + 1] - sfbOffset[sfb];
+
+ /* Reset output for lower bands or too small bands */
+ if (sfb < np->startSfb || sfbWidth < np->minSfbWidth) {
+ noiseFuzzyMeasure[sfb] = FL2FXCONST_SGL(0.0f);
+ continue;
+ }
+
+ if ((np->detectionAlgorithmFlags & USE_POWER_DISTRIBUTION) &&
+ (fuzzyTotal > FL2FXCONST_SGL(0.5f))) {
+ FIXP_DBL fhelp1, fhelp2, fhelp3, fhelp4, maxVal, minVal;
+ INT leadingBits = fixMax(
+ 0, (sfbMaxScaleSpec[sfb] -
+ 3)); /* max sfbWidth = 96/4 ; 2^5=32 => 5/2 = 3 (spc*spc) */
+
+ /* check power distribution in four regions */
+ fhelp1 = fhelp2 = fhelp3 = fhelp4 = FL2FXCONST_DBL(0.0f);
+ k = sfbWidth >> 2; /* Width of a quarter band */
+
+ for (i = sfbOffset[sfb]; i < sfbOffset[sfb] + k; i++) {
+ fhelp1 = fPow2AddDiv2(fhelp1, mdctSpectrum[i] << leadingBits);
+ fhelp2 = fPow2AddDiv2(fhelp2, mdctSpectrum[i + k] << leadingBits);
+ fhelp3 = fPow2AddDiv2(fhelp3, mdctSpectrum[i + 2 * k] << leadingBits);
+ fhelp4 = fPow2AddDiv2(fhelp4, mdctSpectrum[i + 3 * k] << leadingBits);
+ }
+
+ /* get max into fhelp: */
+ maxVal = fixMax(fhelp1, fhelp2);
+ maxVal = fixMax(maxVal, fhelp3);
+ maxVal = fixMax(maxVal, fhelp4);
+
+ /* get min into fhelp1: */
+ minVal = fixMin(fhelp1, fhelp2);
+ minVal = fixMin(minVal, fhelp3);
+ minVal = fixMin(minVal, fhelp4);
+
+ /* Normalize min and max Val */
+ leadingBits = CountLeadingBits(maxVal);
+ testVal = maxVal << leadingBits;
+ refVal = minVal << leadingBits;
+
+ /* calculate fuzzy value for power distribution */
+ testVal = fMultDiv2(testVal, np->powDistPSDcurve[sfb]);
+
+ fuzzy = FDKaacEnc_fuzzyIsSmaller(
+ testVal, /* 1/2 * maxValue * PSDcurve */
+ refVal, /* 1 * minValue */
+ FL2FXCONST_DBL(0.495), /* 1/2 * loLim (0.99f/2) */
+ FL2FXCONST_DBL(0.505)); /* 1/2 * hiLim (1.01f/2) */
+
+ fuzzyTotal = fixMin(fuzzyTotal, fuzzy);
+ }
+
+ if ((np->detectionAlgorithmFlags & USE_PSYCH_TONALITY) &&
+ (fuzzyTotal > FL2FXCONST_SGL(0.5f))) {
+ /* Detection with tonality-value of psych. acoustic (here: 1 is tonal!)*/
+
+ testVal = FX_SGL2FX_DBL(sfbtonality[sfb]) >> 1; /* 1/2 * sfbTonality */
+ refVal = np->refTonality;
+
+ fuzzy = FDKaacEnc_fuzzyIsSmaller(
+ testVal, refVal, FL2FXCONST_DBL(0.45f), /* 1/2 * loLim (0.9f/2) */
+ FL2FXCONST_DBL(0.55f)); /* 1/2 * hiLim (1.1f/2) */
+
+ fuzzyTotal = fixMin(fuzzyTotal, fuzzy);
+ }
+
+ /* Output of final result */
+ noiseFuzzyMeasure[sfb] = fuzzyTotal;
+ }
+}
diff --git a/fdk-aac/libAACenc/src/noisedet.h b/fdk-aac/libAACenc/src/noisedet.h
new file mode 100644
index 0000000..478701f
--- /dev/null
+++ b/fdk-aac/libAACenc/src/noisedet.h
@@ -0,0 +1,116 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser
+
+ Description: noisedet.h
+
+*******************************************************************************/
+
+#ifndef NOISEDET_H
+#define NOISEDET_H
+
+#include "common_fix.h"
+
+#include "pnsparam.h"
+#include "psy_data.h"
+
+void FDKaacEnc_noiseDetect(FIXP_DBL *mdctSpectrum, INT *sfbMaxScaleSpec,
+ INT sfbActive, const INT *sfbOffset,
+ FIXP_SGL noiseFuzzyMeasure[], NOISEPARAMS *np,
+ FIXP_SGL *sfbtonality);
+
+#endif /* NOISEDET_H */
diff --git a/fdk-aac/libAACenc/src/pns_func.h b/fdk-aac/libAACenc/src/pns_func.h
new file mode 100644
index 0000000..88f4586
--- /dev/null
+++ b/fdk-aac/libAACenc/src/pns_func.h
@@ -0,0 +1,138 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser
+
+ Description: pns_func.h
+
+*******************************************************************************/
+
+#ifndef PNS_FUNC_H
+#define PNS_FUNC_H
+
+#include "common_fix.h"
+#include "aacenc_pns.h"
+#include "psy_data.h"
+
+AAC_ENCODER_ERROR FDKaacEnc_InitPnsConfiguration(
+ PNS_CONFIG *pnsConf, INT bitRate, INT sampleRate, INT usePns, INT sfbCnt,
+ const INT *sfbOffset, const INT numChan, const INT isLC);
+
+void FDKaacEnc_PnsDetect(PNS_CONFIG *pnsConf, PNS_DATA *pnsData,
+ const INT lastWindowSequence, const INT sfbActive,
+ const INT maxSfbPerGroup, FIXP_DBL *sfbThresholdLdData,
+ const INT *sfbOffset, FIXP_DBL *mdctSpectrum,
+ INT *sfbMaxScaleSpec, FIXP_SGL *sfbtonality,
+ int tnsOrder, INT tnsPredictionGain, INT tnsActive,
+ FIXP_DBL *sfbEnergyLdData, INT *noiseNrg);
+
+void FDKaacEnc_CodePnsChannel(const INT sfbActive, PNS_CONFIG *pnsConf,
+ INT *pnsFlag, FIXP_DBL *sfbEnergy, INT *noiseNrg,
+ FIXP_DBL *sfbThreshold);
+
+void FDKaacEnc_PreProcessPnsChannelPair(
+ const INT sfbActive, FIXP_DBL *sfbEnergyLeft, FIXP_DBL *sfbEnergyRight,
+ FIXP_DBL *sfbEnergyLeftLD, FIXP_DBL *sfbEnergyRightLD,
+ FIXP_DBL *sfbEnergyMid, PNS_CONFIG *pnsConfLeft, PNS_DATA *pnsDataLeft,
+ PNS_DATA *pnsDataRight);
+
+void FDKaacEnc_PostProcessPnsChannelPair(const INT sfbActive,
+ PNS_CONFIG *pnsConf,
+ PNS_DATA *pnsDataLeft,
+ PNS_DATA *pnsDataRight, INT *msMask,
+ INT *msDigest);
+
+#endif /* PNS_FUNC_H */
diff --git a/fdk-aac/libAACenc/src/pnsparam.cpp b/fdk-aac/libAACenc/src/pnsparam.cpp
new file mode 100644
index 0000000..a6aab06
--- /dev/null
+++ b/fdk-aac/libAACenc/src/pnsparam.cpp
@@ -0,0 +1,574 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Lohwasser
+
+ Description: PNS parameters depending on bitrate and bandwidth
+
+*******************************************************************************/
+
+#include "pnsparam.h"
+
+#include "psy_configuration.h"
+
+typedef struct {
+ SHORT startFreq;
+ /* Parameters for detection */
+ FIXP_SGL refPower;
+ FIXP_SGL refTonality;
+ SHORT tnsGainThreshold; /* scaled by TNS_PREDGAIN_SCALE (=1000) */
+ SHORT tnsPNSGainThreshold; /* scaled by TNS_PREDGAIN_SCALE (=1000) */
+ FIXP_SGL gapFillThr;
+ SHORT minSfbWidth;
+ USHORT detectionAlgorithmFlags;
+} PNS_INFO_TAB;
+
+typedef struct {
+ ULONG brFrom;
+ ULONG brTo;
+ UCHAR S16000;
+ UCHAR S22050;
+ UCHAR S24000;
+ UCHAR S32000;
+ UCHAR S44100;
+ UCHAR S48000;
+} AUTO_PNS_TAB;
+
+static const AUTO_PNS_TAB levelTable_mono[] = {
+ {
+ 0,
+ 11999,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ },
+ {
+ 12000,
+ 19999,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ },
+ {
+ 20000,
+ 28999,
+ 0,
+ 2,
+ 1,
+ 1,
+ 1,
+ 1,
+ },
+ {
+ 29000,
+ 40999,
+ 0,
+ 4,
+ 4,
+ 4,
+ 2,
+ 2,
+ },
+ {
+ 41000,
+ 55999,
+ 0,
+ 9,
+ 9,
+ 7,
+ 7,
+ 7,
+ },
+ {
+ 56000,
+ 61999,
+ 0,
+ 0,
+ 0,
+ 0,
+ 9,
+ 9,
+ },
+ {
+ 62000,
+ 75999,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ },
+ {
+ 76000,
+ 92999,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ },
+ {
+ 93000,
+ 999999,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ },
+};
+
+static const AUTO_PNS_TAB levelTable_stereo[] = {
+ {
+ 0,
+ 11999,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ },
+ {
+ 12000,
+ 19999,
+ 0,
+ 3,
+ 1,
+ 1,
+ 1,
+ 1,
+ },
+ {
+ 20000,
+ 28999,
+ 0,
+ 3,
+ 3,
+ 3,
+ 2,
+ 2,
+ },
+ {
+ 29000,
+ 40999,
+ 0,
+ 7,
+ 6,
+ 6,
+ 5,
+ 5,
+ },
+ {
+ 41000,
+ 55999,
+ 0,
+ 9,
+ 9,
+ 7,
+ 7,
+ 7,
+ },
+ {
+ 56000,
+ 79999,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ },
+ {
+ 80000,
+ 99999,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ },
+ {
+ 100000,
+ 999999,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ },
+};
+
+static const PNS_INFO_TAB pnsInfoTab[] = {
+ /*0 pns off */
+ /*1*/ {4000, FL2FXCONST_SGL(0.04), FL2FXCONST_SGL(0.06), 1150, 1200,
+ FL2FXCONST_SGL(0.02), 8,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS /*| JUST_LONG_WINDOW*/},
+ /*2*/
+ {4000, FL2FXCONST_SGL(0.04), FL2FXCONST_SGL(0.07), 1130, 1300,
+ FL2FXCONST_SGL(0.05), 8,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS /*| JUST_LONG_WINDOW*/},
+ /*3*/
+ {4100, FL2FXCONST_SGL(0.04), FL2FXCONST_SGL(0.07), 1100, 1400,
+ FL2FXCONST_SGL(0.10), 8,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS /*| JUST_LONG_WINDOW*/},
+ /*4*/
+ {4100, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.10), 1100, 1400,
+ FL2FXCONST_SGL(0.15), 8,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS /*| JUST_LONG_WINDOW*/},
+ /*5*/
+ {4300, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.10), 1100, 1400,
+ FL2FXCONST_SGL(0.15), 8,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS | JUST_LONG_WINDOW},
+ /*6*/
+ {5000, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.10), 1100, 1400,
+ FL2FXCONST_SGL(0.25), 8,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS | JUST_LONG_WINDOW},
+ /*7*/
+ {5500, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.12), 1100, 1400,
+ FL2FXCONST_SGL(0.35), 8,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS | JUST_LONG_WINDOW},
+ /*8*/
+ {6000, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.12), 1080, 1400,
+ FL2FXCONST_SGL(0.40), 8,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS | JUST_LONG_WINDOW},
+ /*9*/
+ {6000, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.14), 1070, 1400,
+ FL2FXCONST_SGL(0.45), 8,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS | JUST_LONG_WINDOW},
+};
+
+static const AUTO_PNS_TAB levelTable_lowComplexity[] = {
+ {
+ 0,
+ 27999,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ },
+ {
+ 28000,
+ 31999,
+ 0,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ },
+ {
+ 32000,
+ 47999,
+ 0,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ },
+ {
+ 48000,
+ 48000,
+ 0,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ },
+ {
+ 48001,
+ 999999,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ },
+};
+/* conversion of old LC tuning tables to new (LD enc) structure (only entries
+ * which are actually used were converted) */
+static const PNS_INFO_TAB pnsInfoTab_lowComplexity[] = {
+ /*0 pns off */
+ /* DEFAULT parameter set */
+ /*1*/ {4100, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.16), 1100, 1400,
+ FL2FXCONST_SGL(0.5), 16,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS | JUST_LONG_WINDOW},
+ /*2*/
+ {4100, FL2FXCONST_SGL(0.05), FL2FXCONST_SGL(0.10), 1410, 1400,
+ FL2FXCONST_SGL(0.5), 16,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS | JUST_LONG_WINDOW},
+ /*3*/
+ {4100, FL2FXCONST_SGL(0.05), FL2FXCONST_SGL(0.10), 1100, 1400,
+ FL2FXCONST_SGL(0.5), 16,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS | JUST_LONG_WINDOW},
+ /* LOWSUBST -> PNS is used less often than with DEFAULT parameter set (for
+ br: 48000 - 79999) */
+ /*4*/
+ {4100, FL2FXCONST_SGL(0.20), FL2FXCONST_SGL(0.10), 1410, 1400,
+ FL2FXCONST_SGL(0.5), 16,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS | JUST_LONG_WINDOW},
+};
+
+/****************************************************************************
+ function to look up used pns level
+****************************************************************************/
+int FDKaacEnc_lookUpPnsUse(int bitRate, int sampleRate, int numChan,
+ const int isLC) {
+ int hUsePns = 0, size, i;
+ const AUTO_PNS_TAB *levelTable;
+
+ if (isLC) {
+ levelTable = &levelTable_lowComplexity[0];
+ size = sizeof(levelTable_lowComplexity);
+ } else { /* (E)LD */
+ levelTable = (numChan > 1) ? &levelTable_stereo[0] : &levelTable_mono[0];
+ size = (numChan > 1) ? sizeof(levelTable_stereo) : sizeof(levelTable_mono);
+ }
+
+ for (i = 0; i < (int)(size / sizeof(AUTO_PNS_TAB)); i++) {
+ if (((ULONG)bitRate >= levelTable[i].brFrom) &&
+ ((ULONG)bitRate <= levelTable[i].brTo))
+ break;
+ }
+
+ /* sanity check */
+ if ((int)(sizeof(pnsInfoTab) / sizeof(PNS_INFO_TAB)) < i) {
+ return (PNS_TABLE_ERROR);
+ }
+
+ switch (sampleRate) {
+ case 16000:
+ hUsePns = levelTable[i].S16000;
+ break;
+ case 22050:
+ hUsePns = levelTable[i].S22050;
+ break;
+ case 24000:
+ hUsePns = levelTable[i].S24000;
+ break;
+ case 32000:
+ hUsePns = levelTable[i].S32000;
+ break;
+ case 44100:
+ hUsePns = levelTable[i].S44100;
+ break;
+ case 48000:
+ hUsePns = levelTable[i].S48000;
+ break;
+ default:
+ if (isLC) {
+ hUsePns = levelTable[i].S48000;
+ }
+ break;
+ }
+
+ return (hUsePns);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_GetPnsParam
+ description: Gets PNS parameters depending on bitrate and bandwidth or
+ bitsPerLine
+ returns: error status
+ input: Noiseparams struct, bitrate, sampling rate,
+ number of sfb's, pointer to sfb offset
+ output: PNS parameters
+
+*****************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_GetPnsParam(NOISEPARAMS *np, INT bitRate,
+ INT sampleRate, INT sfbCnt,
+ const INT *sfbOffset, INT *usePns,
+ INT numChan, const INT isLC) {
+ int i, hUsePns;
+ const PNS_INFO_TAB *pnsInfo;
+
+ if (*usePns <= 0) return AAC_ENC_OK;
+
+ if (isLC) {
+ np->detectionAlgorithmFlags = IS_LOW_COMPLEXITY;
+
+ pnsInfo = pnsInfoTab_lowComplexity;
+
+ /* new pns params */
+ hUsePns = FDKaacEnc_lookUpPnsUse(bitRate, sampleRate, numChan, isLC);
+ if (hUsePns == 0) {
+ *usePns = 0;
+ return AAC_ENC_OK;
+ }
+
+ if (hUsePns == PNS_TABLE_ERROR) {
+ return AAC_ENC_PNS_TABLE_ERROR;
+ }
+
+ /* select correct row of tuning table */
+ pnsInfo += hUsePns - 1;
+
+ } else {
+ np->detectionAlgorithmFlags = 0;
+ pnsInfo = pnsInfoTab;
+
+ /* new pns params */
+ hUsePns = FDKaacEnc_lookUpPnsUse(bitRate, sampleRate, numChan, isLC);
+ if (hUsePns == 0) {
+ *usePns = 0;
+ return AAC_ENC_OK;
+ }
+ if (hUsePns == PNS_TABLE_ERROR) return AAC_ENC_PNS_TABLE_ERROR;
+
+ /* select correct row of tuning table */
+ pnsInfo += hUsePns - 1;
+ }
+
+ np->startSfb = FDKaacEnc_FreqToBandWidthRounding(
+ pnsInfo->startFreq, sampleRate, sfbCnt, sfbOffset);
+
+ np->detectionAlgorithmFlags |= pnsInfo->detectionAlgorithmFlags;
+
+ np->refPower = FX_SGL2FX_DBL(pnsInfo->refPower);
+ np->refTonality = FX_SGL2FX_DBL(pnsInfo->refTonality);
+ np->tnsGainThreshold = pnsInfo->tnsGainThreshold;
+ np->tnsPNSGainThreshold = pnsInfo->tnsPNSGainThreshold;
+ np->minSfbWidth = pnsInfo->minSfbWidth;
+
+ np->gapFillThr =
+ pnsInfo->gapFillThr; /* for LC it is always FL2FXCONST_SGL(0.5) */
+
+ /* assuming a constant dB/Hz slope in the signal's PSD curve,
+ the detection threshold needs to be corrected for the width of the band */
+
+ for (i = 0; i < (sfbCnt - 1); i++) {
+ INT qtmp, sfbWidth;
+ FIXP_DBL tmp;
+
+ sfbWidth = sfbOffset[i + 1] - sfbOffset[i];
+
+ tmp = fPow(np->refPower, 0, sfbWidth, DFRACT_BITS - 1 - 5, &qtmp);
+ np->powDistPSDcurve[i] = (FIXP_SGL)((LONG)(scaleValue(tmp, qtmp) >> 16));
+ }
+ np->powDistPSDcurve[sfbCnt] = np->powDistPSDcurve[sfbCnt - 1];
+
+ return AAC_ENC_OK;
+}
diff --git a/fdk-aac/libAACenc/src/pnsparam.h b/fdk-aac/libAACenc/src/pnsparam.h
new file mode 100644
index 0000000..c37738a
--- /dev/null
+++ b/fdk-aac/libAACenc/src/pnsparam.h
@@ -0,0 +1,149 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser
+
+ Description: PNS parameters depending on bitrate and bandwidth
+
+*******************************************************************************/
+
+#ifndef PNSPARAM_H
+#define PNSPARAM_H
+
+#include "aacenc.h"
+#include "common_fix.h"
+#include "psy_const.h"
+
+#define NUM_PNSINFOTAB 4
+#define PNS_TABLE_ERROR -1
+
+/* detection algorithm flags */
+#define USE_POWER_DISTRIBUTION (1 << 0)
+#define USE_PSYCH_TONALITY (1 << 1)
+#define USE_TNS_GAIN_THR (1 << 2)
+#define USE_TNS_PNS (1 << 3)
+#define JUST_LONG_WINDOW (1 << 4)
+/* additional algorithm flags */
+#define IS_LOW_COMPLEXITY (1 << 5)
+
+typedef struct {
+ /* PNS start band */
+ short startSfb;
+
+ /* detection algorithm flags */
+ USHORT detectionAlgorithmFlags;
+
+ /* Parameters for detection */
+ FIXP_DBL refPower;
+ FIXP_DBL refTonality;
+ INT tnsGainThreshold;
+ INT tnsPNSGainThreshold;
+ INT minSfbWidth;
+ FIXP_SGL powDistPSDcurve[MAX_GROUPED_SFB];
+ FIXP_SGL gapFillThr;
+} NOISEPARAMS;
+
+int FDKaacEnc_lookUpPnsUse(int bitRate, int sampleRate, int numChan,
+ const int isLC);
+
+/****** Definition of prototypes ******/
+
+AAC_ENCODER_ERROR FDKaacEnc_GetPnsParam(NOISEPARAMS *np, INT bitRate,
+ INT sampleRate, INT sfbCnt,
+ const INT *sfbOffset, INT *usePns,
+ INT numChan, const INT isLC);
+
+#endif /* PNSPARAM_H */
diff --git a/fdk-aac/libAACenc/src/pre_echo_control.cpp b/fdk-aac/libAACenc/src/pre_echo_control.cpp
new file mode 100644
index 0000000..3d5d153
--- /dev/null
+++ b/fdk-aac/libAACenc/src/pre_echo_control.cpp
@@ -0,0 +1,176 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Pre echo control
+
+*******************************************************************************/
+
+#include "pre_echo_control.h"
+#include "psy_configuration.h"
+
+void FDKaacEnc_InitPreEchoControl(FIXP_DBL *RESTRICT pbThresholdNm1,
+ INT *calcPreEcho, INT numPb,
+ FIXP_DBL *RESTRICT sfbPcmQuantThreshold,
+ INT *mdctScalenm1) {
+ *mdctScalenm1 = PCM_QUANT_THR_SCALE >> 1;
+
+ FDKmemcpy(pbThresholdNm1, sfbPcmQuantThreshold, numPb * sizeof(FIXP_DBL));
+
+ *calcPreEcho = 1;
+}
+
+void FDKaacEnc_PreEchoControl(FIXP_DBL *RESTRICT pbThresholdNm1,
+ INT calcPreEcho, INT numPb,
+ INT maxAllowedIncreaseFactor,
+ FIXP_SGL minRemainingThresholdFactor,
+ FIXP_DBL *RESTRICT pbThreshold, INT mdctScale,
+ INT *mdctScalenm1) {
+ int i;
+ FIXP_DBL tmpThreshold1, tmpThreshold2;
+ int scaling;
+
+ /* If lastWindowSequence in previous frame was start- or stop-window,
+ skip preechocontrol calculation */
+ if (calcPreEcho == 0) {
+ /* copy thresholds to internal memory */
+ FDKmemcpy(pbThresholdNm1, pbThreshold, numPb * sizeof(FIXP_DBL));
+ *mdctScalenm1 = mdctScale;
+ return;
+ }
+
+ if (mdctScale > *mdctScalenm1) {
+ /* if current thresholds are downscaled more than the ones from the last
+ * block */
+ scaling = 2 * (mdctScale - *mdctScalenm1);
+ for (i = 0; i < numPb; i++) {
+ /* multiplication with return data type fract ist equivalent to int
+ * multiplication */
+ FDK_ASSERT(scaling >= 0);
+ tmpThreshold1 = maxAllowedIncreaseFactor * (pbThresholdNm1[i] >> scaling);
+ tmpThreshold2 = fMult(minRemainingThresholdFactor, pbThreshold[i]);
+
+ FIXP_DBL tmp = pbThreshold[i];
+
+ /* copy thresholds to internal memory */
+ pbThresholdNm1[i] = tmp;
+
+ tmp = fixMin(tmp, tmpThreshold1);
+ pbThreshold[i] = fixMax(tmp, tmpThreshold2);
+ }
+ } else {
+ /* if thresholds of last block are more downscaled than the current ones */
+ scaling = 2 * (*mdctScalenm1 - mdctScale);
+ for (i = 0; i < numPb; i++) {
+ /* multiplication with return data type fract ist equivalent to int
+ * multiplication */
+ tmpThreshold1 = (maxAllowedIncreaseFactor >> 1) * pbThresholdNm1[i];
+ tmpThreshold2 = fMult(minRemainingThresholdFactor, pbThreshold[i]);
+
+ /* copy thresholds to internal memory */
+ pbThresholdNm1[i] = pbThreshold[i];
+
+ FDK_ASSERT(scaling >= 0);
+ if ((pbThreshold[i] >> (scaling + 1)) > tmpThreshold1) {
+ pbThreshold[i] = tmpThreshold1 << (scaling + 1);
+ }
+ pbThreshold[i] = fixMax(pbThreshold[i], tmpThreshold2);
+ }
+ }
+
+ *mdctScalenm1 = mdctScale;
+}
diff --git a/fdk-aac/libAACenc/src/pre_echo_control.h b/fdk-aac/libAACenc/src/pre_echo_control.h
new file mode 100644
index 0000000..688efdb
--- /dev/null
+++ b/fdk-aac/libAACenc/src/pre_echo_control.h
@@ -0,0 +1,118 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Pre echo control
+
+*******************************************************************************/
+
+#ifndef PRE_ECHO_CONTROL_H
+#define PRE_ECHO_CONTROL_H
+
+#include "common_fix.h"
+
+void FDKaacEnc_InitPreEchoControl(FIXP_DBL *pbThresholdnm1, INT *calcPreEcho,
+ INT numPb, FIXP_DBL *sfbPcmQuantThreshold,
+ INT *mdctScalenm1);
+
+void FDKaacEnc_PreEchoControl(FIXP_DBL *pbThresholdNm1, INT calcPreEcho,
+ INT numPb, INT maxAllowedIncreaseFactor,
+ FIXP_SGL minRemainingThresholdFactor,
+ FIXP_DBL *pbThreshold, INT mdctScale,
+ INT *mdctScalenm1);
+
+#endif
diff --git a/fdk-aac/libAACenc/src/psy_configuration.cpp b/fdk-aac/libAACenc/src/psy_configuration.cpp
new file mode 100644
index 0000000..b444b58
--- /dev/null
+++ b/fdk-aac/libAACenc/src/psy_configuration.cpp
@@ -0,0 +1,801 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Psychoaccoustic configuration
+
+*******************************************************************************/
+
+#include "psy_configuration.h"
+#include "adj_thr.h"
+#include "aacEnc_rom.h"
+
+#include "genericStds.h"
+
+#include "FDK_trigFcts.h"
+
+typedef struct {
+ LONG sampleRate;
+ const SFB_PARAM_LONG *paramLong;
+ const SFB_PARAM_SHORT *paramShort;
+} SFB_INFO_TAB;
+
+static const SFB_INFO_TAB sfbInfoTab[] = {
+ {8000, &p_FDKaacEnc_8000_long_1024, &p_FDKaacEnc_8000_short_128},
+ {11025, &p_FDKaacEnc_11025_long_1024, &p_FDKaacEnc_11025_short_128},
+ {12000, &p_FDKaacEnc_12000_long_1024, &p_FDKaacEnc_12000_short_128},
+ {16000, &p_FDKaacEnc_16000_long_1024, &p_FDKaacEnc_16000_short_128},
+ {22050, &p_FDKaacEnc_22050_long_1024, &p_FDKaacEnc_22050_short_128},
+ {24000, &p_FDKaacEnc_24000_long_1024, &p_FDKaacEnc_24000_short_128},
+ {32000, &p_FDKaacEnc_32000_long_1024, &p_FDKaacEnc_32000_short_128},
+ {44100, &p_FDKaacEnc_44100_long_1024, &p_FDKaacEnc_44100_short_128},
+ {48000, &p_FDKaacEnc_48000_long_1024, &p_FDKaacEnc_48000_short_128},
+ {64000, &p_FDKaacEnc_64000_long_1024, &p_FDKaacEnc_64000_short_128},
+ {88200, &p_FDKaacEnc_88200_long_1024, &p_FDKaacEnc_88200_short_128},
+ {96000, &p_FDKaacEnc_96000_long_1024, &p_FDKaacEnc_96000_short_128}
+
+};
+
+
+
+const SFB_PARAM_LONG p_FDKaacEnc_8000_long_960 = {
+ 40,
+ { 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 16,
+ 16, 16, 16, 16, 16, 16, 20, 20, 20, 20, 24, 24, 24, 28,
+ 28, 32, 36, 36, 40, 44, 48, 52, 56, 60, 64, 16 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_8000_short_120 = {
+ 15,
+ { 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 16, 20, 12 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_11025_long_960 = {
+ 42,
+ { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24,
+ 24, 28, 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_11025_short_120 = {
+ 15,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 12 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_12000_long_960 = {
+ 42,
+ { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24,
+ 24, 28, 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_12000_short_120 = {
+ 15,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 12 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_16000_long_960 = {
+ 42,
+ { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24,
+ 24, 28, 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_16000_short_120 = {
+ 15,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 12 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_22050_long_960 = {
+ 46,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 16, 16, 16,
+ 20, 20, 24, 24, 28, 28, 32, 36, 36, 40, 44, 48, 52, 52,
+ 64, 64, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_22050_short_120 = {
+ 15,
+ { 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 12 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_24000_long_960 = {
+ 46,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 16, 16, 16,
+ 20, 20, 24, 24, 28, 28, 32, 36, 36, 40, 44, 48, 52, 52,
+ 64, 64, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_24000_short_120 = {
+ 15,
+ { 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 12 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_32000_long_960 = {
+ 49,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12,
+ 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32 }
+};
+
+const SFB_PARAM_SHORT p_FDKaacEnc_32000_short_120 = {
+ 14,
+ { 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 8 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_44100_long_960 = {
+ 49,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8,
+ 8, 8, 8, 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28,
+ 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32 }
+};
+
+const SFB_PARAM_SHORT p_FDKaacEnc_44100_short_120 = {
+ 14,
+ { 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 8 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_48000_long_960 = {
+ 49,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8,
+ 8, 8, 8, 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28,
+ 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_48000_short_120 = {
+ 14,
+ { 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 8 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_64000_long_960 = {
+ 46,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 12,
+ 12, 16, 16, 16, 20, 24, 24, 28, 36, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 16 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_64000_short_120 = {
+ 12,
+ { 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 28 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_88200_long_960 = {
+ 40,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 12,
+ 12, 12, 12, 12, 16, 16, 24, 28, 36, 44, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_88200_short_120 = {
+ 12,
+ { 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 28 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_96000_long_960 = {
+ 40,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 12,
+ 12, 12, 12, 12, 16, 16, 24, 28, 36, 44, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_96000_short_120 = {
+ 12,
+ { 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 28 }
+};
+
+
+static const SFB_INFO_TAB sfbInfoTab960[] = {
+ { 8000, &p_FDKaacEnc_8000_long_960, &p_FDKaacEnc_8000_short_120},
+ {11025, &p_FDKaacEnc_11025_long_960, &p_FDKaacEnc_11025_short_120},
+ {12000, &p_FDKaacEnc_12000_long_960, &p_FDKaacEnc_12000_short_120},
+ {16000, &p_FDKaacEnc_16000_long_960, &p_FDKaacEnc_16000_short_120},
+ {22050, &p_FDKaacEnc_22050_long_960, &p_FDKaacEnc_22050_short_120},
+ {24000, &p_FDKaacEnc_24000_long_960, &p_FDKaacEnc_24000_short_120},
+ {32000, &p_FDKaacEnc_32000_long_960, &p_FDKaacEnc_32000_short_120},
+ {44100, &p_FDKaacEnc_44100_long_960, &p_FDKaacEnc_44100_short_120},
+ {48000, &p_FDKaacEnc_48000_long_960, &p_FDKaacEnc_48000_short_120},
+ {64000, &p_FDKaacEnc_64000_long_960, &p_FDKaacEnc_64000_short_120},
+ {88200, &p_FDKaacEnc_88200_long_960, &p_FDKaacEnc_88200_short_120},
+ {96000, &p_FDKaacEnc_96000_long_960, &p_FDKaacEnc_96000_short_120},
+};
+
+
+/* 22050 and 24000 Hz */
+static const SFB_PARAM_LONG p_22050_long_512 = {
+ 31, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12,
+ 12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}};
+
+/* 32000 Hz */
+static const SFB_PARAM_LONG p_32000_long_512 = {
+ 37,
+ {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8,
+ 12, 12, 12, 12, 16, 16, 16, 20, 24, 24, 28, 32, 32, 32, 32, 32, 32, 32}};
+
+/* 44100 Hz */
+static const SFB_PARAM_LONG p_44100_long_512 = {
+ 36, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8,
+ 8, 8, 12, 12, 12, 12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32, 32, 52}};
+
+static const SFB_INFO_TAB sfbInfoTabLD512[] = {
+ {8000, &p_22050_long_512, NULL}, {11025, &p_22050_long_512, NULL},
+ {12000, &p_22050_long_512, NULL}, {16000, &p_22050_long_512, NULL},
+ {22050, &p_22050_long_512, NULL}, {24000, &p_22050_long_512, NULL},
+ {32000, &p_32000_long_512, NULL}, {44100, &p_44100_long_512, NULL},
+ {48000, &p_44100_long_512, NULL}, {64000, &p_44100_long_512, NULL},
+ {88200, &p_44100_long_512, NULL}, {96000, &p_44100_long_512, NULL},
+ {128000, &p_44100_long_512, NULL}, {176400, &p_44100_long_512, NULL},
+ {192000, &p_44100_long_512, NULL}, {256000, &p_44100_long_512, NULL},
+ {352800, &p_44100_long_512, NULL}, {384000, &p_44100_long_512, NULL},
+};
+
+/* 22050 and 24000 Hz */
+static const SFB_PARAM_LONG p_22050_long_480 = {
+ 30, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12,
+ 12, 12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32}};
+
+/* 32000 Hz */
+static const SFB_PARAM_LONG p_32000_long_480 = {
+ 37, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8,
+ 8, 8, 8, 12, 12, 12, 16, 16, 20, 24, 32, 32, 32, 32, 32, 32, 32, 32}};
+
+/* 44100 Hz */
+static const SFB_PARAM_LONG p_44100_long_480 = {
+ 35, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8,
+ 8, 12, 12, 12, 12, 12, 16, 16, 24, 28, 32, 32, 32, 32, 32, 32, 48}};
+
+static const SFB_INFO_TAB sfbInfoTabLD480[] = {
+ {8000, &p_22050_long_480, NULL}, {11025, &p_22050_long_480, NULL},
+ {12000, &p_22050_long_480, NULL}, {16000, &p_22050_long_480, NULL},
+ {22050, &p_22050_long_480, NULL}, {24000, &p_22050_long_480, NULL},
+ {32000, &p_32000_long_480, NULL}, {44100, &p_44100_long_480, NULL},
+ {48000, &p_44100_long_480, NULL}, {64000, &p_44100_long_480, NULL},
+ {88200, &p_44100_long_480, NULL}, {96000, &p_44100_long_480, NULL},
+ {128000, &p_44100_long_480, NULL}, {176400, &p_44100_long_480, NULL},
+ {192000, &p_44100_long_480, NULL}, {256000, &p_44100_long_480, NULL},
+ {352800, &p_44100_long_480, NULL}, {384000, &p_44100_long_480, NULL},
+};
+
+/* Fixed point precision definitions */
+#define Q_BARCVAL (25)
+
+AAC_ENCODER_ERROR FDKaacEnc_initSfbTable(const LONG sampleRate,
+ const INT blockType,
+ const INT granuleLength,
+ INT *const sfbOffset,
+ INT *const sfbCnt) {
+ INT i, specStartOffset = 0;
+ INT granuleLengthWindow = granuleLength;
+ const UCHAR *sfbWidth = NULL;
+ const SFB_INFO_TAB *sfbInfo = NULL;
+ int size;
+
+ /*
+ select table
+ */
+ switch (granuleLength) {
+ case 1024:
+ sfbInfo = sfbInfoTab;
+ size = (INT)(sizeof(sfbInfoTab) / sizeof(SFB_INFO_TAB));
+ break;
+ case 960:
+ sfbInfo = sfbInfoTab960;
+ size = (INT)(sizeof(sfbInfoTab960)/sizeof(SFB_INFO_TAB));
+ break;
+ case 512:
+ sfbInfo = sfbInfoTabLD512;
+ size = sizeof(sfbInfoTabLD512);
+ break;
+ case 480:
+ sfbInfo = sfbInfoTabLD480;
+ size = sizeof(sfbInfoTabLD480);
+ break;
+ default:
+ return AAC_ENC_INVALID_FRAME_LENGTH;
+ }
+
+ for (i = 0; i < size; i++) {
+ if (sfbInfo[i].sampleRate == sampleRate) {
+ switch (blockType) {
+ case LONG_WINDOW:
+ case START_WINDOW:
+ case STOP_WINDOW:
+ sfbWidth = sfbInfo[i].paramLong->sfbWidth;
+ *sfbCnt = sfbInfo[i].paramLong->sfbCnt;
+ break;
+ case SHORT_WINDOW:
+ sfbWidth = sfbInfo[i].paramShort->sfbWidth;
+ *sfbCnt = sfbInfo[i].paramShort->sfbCnt;
+ granuleLengthWindow /= TRANS_FAC;
+ break;
+ }
+ break;
+ }
+ }
+ if (i == size) {
+ return AAC_ENC_UNSUPPORTED_SAMPLINGRATE;
+ }
+
+ /*
+ calc sfb offsets
+ */
+ for (i = 0; i < *sfbCnt; i++) {
+ sfbOffset[i] = specStartOffset;
+ specStartOffset += sfbWidth[i];
+ if (specStartOffset >= granuleLengthWindow) {
+ i++;
+ break;
+ }
+ }
+ *sfbCnt = fixMin(i, *sfbCnt);
+ sfbOffset[*sfbCnt] = fixMin(specStartOffset, granuleLengthWindow);
+ return AAC_ENC_OK;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_BarcLineValue
+ description: Calculates barc value for one frequency line
+ returns: barc value of line
+ input: number of lines in transform, index of line to check, Fs
+ output:
+
+*****************************************************************************/
+static FIXP_DBL FDKaacEnc_BarcLineValue(INT noOfLines, INT fftLine,
+ LONG samplingFreq) {
+ FIXP_DBL FOURBY3EM4 = (FIXP_DBL)0x45e7b273; /* 4.0/3 * 0.0001 in q43 */
+ FIXP_DBL PZZZ76 = (FIXP_DBL)0x639d5e4a; /* 0.00076 in q41 */
+ FIXP_DBL ONE3P3 = (FIXP_DBL)0x35333333; /* 13.3 in q26 */
+ FIXP_DBL THREEP5 = (FIXP_DBL)0x1c000000; /* 3.5 in q27 */
+ FIXP_DBL INV480 = (FIXP_DBL)0x44444444; // 1/480 in q39
+
+ FIXP_DBL center_freq, x1, x2;
+ FIXP_DBL bvalFFTLine, atan1, atan2;
+
+ /* Theoritical maximum of center_freq (samp_freq*0.5) is 96khz * 0.5 = 48000
+ */
+ /* Theoritical maximum of x1 is 1.3333333e-4f * center_freq = 6.4, can keep in
+ * q28 */
+ /* Theoritical maximum of x2 is 0.00076f * center_freq = 36.48, can keep in
+ * q25 */
+
+ center_freq = fftLine * samplingFreq; /* q11 or q8 */
+
+
+ switch (noOfLines) {
+ case 1024:
+ center_freq = center_freq << 2; /* q13 */
+ break;
+ case 960:
+ center_freq = fMult(center_freq, INV480) << 3;
+ break;
+ case 128:
+ center_freq = center_freq << 5; /* q13 */
+ break;
+ case 120:
+ center_freq = fMult(center_freq, INV480) << 6;
+ break;
+ case 512:
+ center_freq = (fftLine * samplingFreq) << 3; // q13
+ break;
+ case 480:
+ center_freq = fMult(center_freq, INV480) << 4; // q13
+ break;
+ default:
+ center_freq = (FIXP_DBL)0;
+ }
+
+
+ x1 = fMult(center_freq, FOURBY3EM4); /* q13 * q43 - (DFRACT_BITS-1) = q25 */
+ x2 = fMult(center_freq, PZZZ76)
+ << 2; /* q13 * q41 - (DFRACT_BITS-1) + 2 = q25 */
+
+ atan1 = fixp_atan(x1);
+ atan2 = fixp_atan(x2);
+
+ /* q25 (q26 * q30 - (DFRACT_BITS-1)) + q25 (q27 * q30 * q30) */
+ bvalFFTLine = fMult(ONE3P3, atan2) + fMult(THREEP5, fMult(atan1, atan1));
+ return (bvalFFTLine);
+}
+
+/*
+ do not consider energies below a certain input signal level,
+ i.e. of -96dB or 1 bit at 16 bit PCM resolution,
+ might need to be configurable to e.g. 24 bit PCM Input or a lower
+ resolution for low bit rates
+*/
+static void FDKaacEnc_InitMinPCMResolution(int numPb, int *pbOffset,
+ FIXP_DBL *sfbPCMquantThreshold) {
+/* PCM_QUANT_NOISE = FDKpow(10.0f, - 20.f / 10.0f) * ABS_LOW * NORM_PCM_ENERGY *
+ * FDKpow(2,PCM_QUANT_THR_SCALE) */
+#define PCM_QUANT_NOISE ((FIXP_DBL)0x00547062)
+
+ for (int i = 0; i < numPb; i++) {
+ sfbPCMquantThreshold[i] = (pbOffset[i + 1] - pbOffset[i]) * PCM_QUANT_NOISE;
+ }
+}
+
+static FIXP_DBL getMaskFactor(const FIXP_DBL dbVal_fix, const INT dbVal_e,
+ const FIXP_DBL ten_fix, const INT ten_e) {
+ INT q_msk;
+ FIXP_DBL mask_factor;
+
+ mask_factor = fPow(ten_fix, DFRACT_BITS - 1 - ten_e, -dbVal_fix,
+ DFRACT_BITS - 1 - dbVal_e, &q_msk);
+ q_msk = fixMin(DFRACT_BITS - 1, fixMax(-(DFRACT_BITS - 1), q_msk));
+
+ if ((q_msk > 0) && (mask_factor > (FIXP_DBL)MAXVAL_DBL >> q_msk)) {
+ mask_factor = (FIXP_DBL)MAXVAL_DBL;
+ } else {
+ mask_factor = scaleValue(mask_factor, q_msk);
+ }
+
+ return (mask_factor);
+}
+
+static void FDKaacEnc_initSpreading(INT numPb, FIXP_DBL *pbBarcValue,
+ FIXP_DBL *pbMaskLoFactor,
+ FIXP_DBL *pbMaskHiFactor,
+ FIXP_DBL *pbMaskLoFactorSprEn,
+ FIXP_DBL *pbMaskHiFactorSprEn,
+ const LONG bitrate, const INT blockType)
+
+{
+ INT i;
+ FIXP_DBL MASKLOWSPREN, MASKHIGHSPREN;
+
+ FIXP_DBL MASKHIGH = (FIXP_DBL)0x30000000; /* 1.5 in q29 */
+ FIXP_DBL MASKLOW = (FIXP_DBL)0x60000000; /* 3.0 in q29 */
+ FIXP_DBL MASKLOWSPRENLONG = (FIXP_DBL)0x60000000; /* 3.0 in q29 */
+ FIXP_DBL MASKHIGHSPRENLONG = (FIXP_DBL)0x40000000; /* 2.0 in q29 */
+ FIXP_DBL MASKHIGHSPRENLONGLOWBR = (FIXP_DBL)0x30000000; /* 1.5 in q29 */
+ FIXP_DBL MASKLOWSPRENSHORT = (FIXP_DBL)0x40000000; /* 2.0 in q29 */
+ FIXP_DBL MASKHIGHSPRENSHORT = (FIXP_DBL)0x30000000; /* 1.5 in q29 */
+ FIXP_DBL TEN = (FIXP_DBL)0x50000000; /* 10.0 in q27 */
+
+ if (blockType != SHORT_WINDOW) {
+ MASKLOWSPREN = MASKLOWSPRENLONG;
+ MASKHIGHSPREN =
+ (bitrate > 20000) ? MASKHIGHSPRENLONG : MASKHIGHSPRENLONGLOWBR;
+ } else {
+ MASKLOWSPREN = MASKLOWSPRENSHORT;
+ MASKHIGHSPREN = MASKHIGHSPRENSHORT;
+ }
+
+ for (i = 0; i < numPb; i++) {
+ if (i > 0) {
+ pbMaskHiFactor[i] = getMaskFactor(
+ fMult(MASKHIGH, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, 27);
+
+ pbMaskLoFactor[i - 1] = getMaskFactor(
+ fMult(MASKLOW, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, 27);
+
+ pbMaskHiFactorSprEn[i] = getMaskFactor(
+ fMult(MASKHIGHSPREN, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN,
+ 27);
+
+ pbMaskLoFactorSprEn[i - 1] = getMaskFactor(
+ fMult(MASKLOWSPREN, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN,
+ 27);
+ } else {
+ pbMaskHiFactor[i] = (FIXP_DBL)0;
+ pbMaskLoFactor[numPb - 1] = (FIXP_DBL)0;
+ pbMaskHiFactorSprEn[i] = (FIXP_DBL)0;
+ pbMaskLoFactorSprEn[numPb - 1] = (FIXP_DBL)0;
+ }
+ }
+}
+
+static void FDKaacEnc_initBarcValues(INT numPb, INT *pbOffset, INT numLines,
+ INT samplingFrequency, FIXP_DBL *pbBval) {
+ INT i;
+ FIXP_DBL MAX_BARC = (FIXP_DBL)0x30000000; /* 24.0 in q25 */
+
+ for (i = 0; i < numPb; i++) {
+ FIXP_DBL v1, v2, cur_bark;
+ v1 = FDKaacEnc_BarcLineValue(numLines, pbOffset[i], samplingFrequency);
+ v2 = FDKaacEnc_BarcLineValue(numLines, pbOffset[i + 1], samplingFrequency);
+ cur_bark = (v1 >> 1) + (v2 >> 1);
+ pbBval[i] = fixMin(cur_bark, MAX_BARC);
+ }
+}
+
+static void FDKaacEnc_initMinSnr(const LONG bitrate, const LONG samplerate,
+ const INT numLines, const INT *sfbOffset,
+ const INT sfbActive, const INT blockType,
+ FIXP_DBL *sfbMinSnrLdData) {
+ INT sfb;
+
+ /* Fix conversion variables */
+ INT qbfac, qperwin, qdiv, qpeprt_const, qpeprt;
+ INT qtmp, qsnr, sfbWidth;
+
+ FIXP_DBL MAX_BARC = (FIXP_DBL)0x30000000; /* 24.0 in q25 */
+ FIXP_DBL MAX_BARCP1 = (FIXP_DBL)0x32000000; /* 25.0 in q25 */
+ FIXP_DBL BITS2PEFAC = (FIXP_DBL)0x4b851eb8; /* 1.18 in q30 */
+ FIXP_DBL PERS2P4 = (FIXP_DBL)0x624dd2f2; /* 0.024 in q36 */
+ FIXP_DBL ONEP5 = (FIXP_DBL)0x60000000; /* 1.5 in q30 */
+ FIXP_DBL MAX_SNR = (FIXP_DBL)0x33333333; /* 0.8 in q30 */
+ FIXP_DBL MIN_SNR = (FIXP_DBL)0x003126e9; /* 0.003 in q30 */
+
+ FIXP_DBL barcFactor, pePerWindow, pePart, barcWidth;
+ FIXP_DBL pePart_const, tmp, snr, one_qsnr, one_point5;
+
+ /* relative number of active barks */
+ barcFactor = fDivNorm(fixMin(FDKaacEnc_BarcLineValue(
+ numLines, sfbOffset[sfbActive], samplerate),
+ MAX_BARC),
+ MAX_BARCP1, &qbfac);
+
+ qbfac = DFRACT_BITS - 1 - qbfac;
+
+ pePerWindow = fDivNorm(bitrate, samplerate, &qperwin);
+ qperwin = DFRACT_BITS - 1 - qperwin;
+ pePerWindow = fMult(pePerWindow, BITS2PEFAC);
+ qperwin = qperwin + 30 - (DFRACT_BITS - 1);
+ pePerWindow = fMult(pePerWindow, PERS2P4);
+ qperwin = qperwin + 36 - (DFRACT_BITS - 1);
+
+ switch (numLines) {
+ case 1024:
+ qperwin = qperwin - 10;
+ break;
+ case 128:
+ qperwin = qperwin - 7;
+ break;
+ case 512:
+ qperwin = qperwin - 9;
+ break;
+ case 480:
+ qperwin = qperwin - 9;
+ pePerWindow = fMult(pePerWindow, FL2FXCONST_DBL(480.f / 512.f));
+ break;
+ case 960:
+ pePerWindow = fMult(pePerWindow, FL2FXCONST_DBL(960.f/1024.f));
+ qperwin = qperwin - 10;
+ break;
+ case 120:
+ pePerWindow = fMult(pePerWindow, FL2FXCONST_DBL(120.f/128.f));
+ qperwin = qperwin - 7;
+ break;
+ }
+
+ /* for short blocks it is assumed that more bits are available */
+ if (blockType == SHORT_WINDOW) {
+ pePerWindow = fMult(pePerWindow, ONEP5);
+ qperwin = qperwin + 30 - (DFRACT_BITS - 1);
+ }
+ pePart_const = fDivNorm(pePerWindow, barcFactor, &qdiv);
+ qpeprt_const = qperwin - qbfac + DFRACT_BITS - 1 - qdiv;
+
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ barcWidth =
+ FDKaacEnc_BarcLineValue(numLines, sfbOffset[sfb + 1], samplerate) -
+ FDKaacEnc_BarcLineValue(numLines, sfbOffset[sfb], samplerate);
+
+ /* adapt to sfb bands */
+ pePart = fMult(pePart_const, barcWidth);
+ qpeprt = qpeprt_const + 25 - (DFRACT_BITS - 1);
+
+ /* pe -> snr calculation */
+ sfbWidth = (sfbOffset[sfb + 1] - sfbOffset[sfb]);
+ pePart = fDivNorm(pePart, sfbWidth, &qdiv);
+ qpeprt += DFRACT_BITS - 1 - qdiv;
+
+ tmp = f2Pow(pePart, DFRACT_BITS - 1 - qpeprt, &qtmp);
+ qtmp = DFRACT_BITS - 1 - qtmp;
+
+ /* Subtract 1.5 */
+ qsnr = fixMin(qtmp, 30);
+ tmp = tmp >> (qtmp - qsnr);
+
+ if ((30 + 1 - qsnr) > (DFRACT_BITS - 1))
+ one_point5 = (FIXP_DBL)0;
+ else
+ one_point5 = (FIXP_DBL)(ONEP5 >> (30 + 1 - qsnr));
+
+ snr = (tmp >> 1) - (one_point5);
+ qsnr -= 1;
+
+ /* max(snr, 1.0) */
+ if (qsnr > 0)
+ one_qsnr = (FIXP_DBL)(1 << qsnr);
+ else
+ one_qsnr = (FIXP_DBL)0;
+
+ snr = fixMax(one_qsnr, snr);
+
+ /* 1/snr */
+ snr = fDivNorm(one_qsnr, snr, &qsnr);
+ qsnr = DFRACT_BITS - 1 - qsnr;
+ snr = (qsnr > 30) ? (snr >> (qsnr - 30)) : snr;
+
+ /* upper limit is -1 dB */
+ snr = (snr > MAX_SNR) ? MAX_SNR : snr;
+
+ /* lower limit is -25 dB */
+ snr = (snr < MIN_SNR) ? MIN_SNR : snr;
+ snr = snr << 1;
+
+ sfbMinSnrLdData[sfb] = CalcLdData(snr);
+ }
+}
+
+AAC_ENCODER_ERROR FDKaacEnc_InitPsyConfiguration(INT bitrate, INT samplerate,
+ INT bandwidth, INT blocktype,
+ INT granuleLength, INT useIS,
+ INT useMS,
+ PSY_CONFIGURATION *psyConf,
+ FB_TYPE filterbank) {
+ AAC_ENCODER_ERROR ErrorStatus;
+ INT sfb;
+ FIXP_DBL sfbBarcVal[MAX_SFB];
+ const INT frameLengthLong = granuleLength;
+ const INT frameLengthShort = granuleLength / TRANS_FAC;
+ INT downscaleFactor = 1;
+
+ switch (granuleLength) {
+ case 256:
+ case 240:
+ downscaleFactor = 2;
+ break;
+ case 128:
+ case 120:
+ downscaleFactor = 4;
+ break;
+ default:
+ downscaleFactor = 1;
+ break;
+ }
+
+ FDKmemclear(psyConf, sizeof(PSY_CONFIGURATION));
+ psyConf->granuleLength = granuleLength;
+ psyConf->filterbank = filterbank;
+
+ psyConf->allowIS = (useIS) && ((bitrate / bandwidth) < 5);
+ psyConf->allowMS = useMS;
+
+ /* init sfb table */
+ ErrorStatus = FDKaacEnc_initSfbTable(samplerate * downscaleFactor, blocktype,
+ granuleLength * downscaleFactor,
+ psyConf->sfbOffset, &psyConf->sfbCnt);
+
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+
+ /* calculate barc values for each pb */
+ FDKaacEnc_initBarcValues(psyConf->sfbCnt, psyConf->sfbOffset,
+ psyConf->sfbOffset[psyConf->sfbCnt], samplerate,
+ sfbBarcVal);
+
+ FDKaacEnc_InitMinPCMResolution(psyConf->sfbCnt, psyConf->sfbOffset,
+ psyConf->sfbPcmQuantThreshold);
+
+ /* calculate spreading function */
+ FDKaacEnc_initSpreading(psyConf->sfbCnt, sfbBarcVal,
+ psyConf->sfbMaskLowFactor, psyConf->sfbMaskHighFactor,
+ psyConf->sfbMaskLowFactorSprEn,
+ psyConf->sfbMaskHighFactorSprEn, bitrate, blocktype);
+
+ /* init ratio */
+
+ psyConf->maxAllowedIncreaseFactor = 2; /* integer */
+ psyConf->minRemainingThresholdFactor = (FIXP_SGL)0x0148;
+ /* FL2FXCONST_SGL(0.01f); */ /* fract */
+
+ psyConf->clipEnergy =
+ (FIXP_DBL)0x773593ff; /* FL2FXCONST_DBL(1.0e9*NORM_PCM_ENERGY); */
+
+ if (blocktype != SHORT_WINDOW) {
+ psyConf->lowpassLine =
+ (INT)((2 * bandwidth * frameLengthLong) / samplerate);
+ psyConf->lowpassLineLFE = LFE_LOWPASS_LINE;
+ } else {
+ psyConf->lowpassLine =
+ (INT)((2 * bandwidth * frameLengthShort) / samplerate);
+ psyConf->lowpassLineLFE = 0; /* LFE only in lonf blocks */
+ /* psyConf->clipEnergy /= (TRANS_FAC * TRANS_FAC); */
+ psyConf->clipEnergy >>= 6;
+ }
+
+ for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) {
+ if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLine) break;
+ }
+ psyConf->sfbActive = fMax(sfb, 1);
+
+ for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) {
+ if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLineLFE) break;
+ }
+ psyConf->sfbActiveLFE = sfb;
+ psyConf->sfbActive = fMax(psyConf->sfbActive, psyConf->sfbActiveLFE);
+
+ /* calculate minSnr */
+ FDKaacEnc_initMinSnr(bitrate, samplerate * downscaleFactor,
+ psyConf->sfbOffset[psyConf->sfbCnt], psyConf->sfbOffset,
+ psyConf->sfbActive, blocktype, psyConf->sfbMinSnrLdData);
+
+ return AAC_ENC_OK;
+}
diff --git a/fdk-aac/libAACenc/src/psy_configuration.h b/fdk-aac/libAACenc/src/psy_configuration.h
new file mode 100644
index 0000000..52b2887
--- /dev/null
+++ b/fdk-aac/libAACenc/src/psy_configuration.h
@@ -0,0 +1,171 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Psychoaccoustic configuration
+
+*******************************************************************************/
+
+#ifndef PSY_CONFIGURATION_H
+#define PSY_CONFIGURATION_H
+
+#include "aacenc.h"
+#include "common_fix.h"
+
+#include "psy_const.h"
+#include "aacenc_tns.h"
+#include "aacenc_pns.h"
+
+#define THR_SHIFTBITS 4
+#define PCM_QUANT_THR_SCALE 16
+#define BITS_PER_LINE_SHIFT 3
+
+#define C_RATIO \
+ (FIXP_DBL)0x02940a10 /* FL2FXCONST_DBL(0.001258925f) << THR_SHIFTBITS; */ /* pow(10.0f, -(29.0f/10.0f)) */
+
+typedef struct {
+ INT sfbCnt; /* number of existing sf bands */
+ INT sfbActive; /* number of sf bands containing energy after lowpass */
+ INT sfbActiveLFE;
+ INT sfbOffset[MAX_SFB + 1];
+
+ INT filterbank; /* LC, LD or ELD */
+
+ FIXP_DBL sfbPcmQuantThreshold[MAX_SFB];
+
+ INT maxAllowedIncreaseFactor; /* preecho control */
+ FIXP_SGL minRemainingThresholdFactor;
+
+ INT lowpassLine;
+ INT lowpassLineLFE;
+ FIXP_DBL clipEnergy; /* for level dependend tmn */
+
+ FIXP_DBL sfbMaskLowFactor[MAX_SFB];
+ FIXP_DBL sfbMaskHighFactor[MAX_SFB];
+
+ FIXP_DBL sfbMaskLowFactorSprEn[MAX_SFB];
+ FIXP_DBL sfbMaskHighFactorSprEn[MAX_SFB];
+
+ FIXP_DBL sfbMinSnrLdData[MAX_SFB]; /* minimum snr (formerly known as bmax) */
+
+ TNS_CONFIG tnsConf;
+ PNS_CONFIG pnsConf;
+
+ INT granuleLength;
+ INT allowIS;
+ INT allowMS;
+} PSY_CONFIGURATION;
+
+typedef struct {
+ UCHAR sfbCnt; /* Number of scalefactor bands */
+ UCHAR sfbWidth[MAX_SFB_LONG]; /* Width of scalefactor bands for long blocks */
+} SFB_PARAM_LONG;
+
+typedef struct {
+ UCHAR sfbCnt; /* Number of scalefactor bands */
+ UCHAR
+ sfbWidth[MAX_SFB_SHORT]; /* Width of scalefactor bands for short blocks */
+} SFB_PARAM_SHORT;
+
+AAC_ENCODER_ERROR FDKaacEnc_InitPsyConfiguration(INT bitrate, INT samplerate,
+ INT bandwidth, INT blocktype,
+ INT granuleLength, INT useIS,
+ INT useMS,
+ PSY_CONFIGURATION *psyConf,
+ FB_TYPE filterbank);
+
+#endif /* PSY_CONFIGURATION_H */
diff --git a/fdk-aac/libAACenc/src/psy_const.h b/fdk-aac/libAACenc/src/psy_const.h
new file mode 100644
index 0000000..c3f3f64
--- /dev/null
+++ b/fdk-aac/libAACenc/src/psy_const.h
@@ -0,0 +1,169 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Global psychoaccoustic constants
+
+*******************************************************************************/
+
+#ifndef PSY_CONST_H
+#define PSY_CONST_H
+
+#define TRUE 1
+#define FALSE 0
+
+#define TRANS_FAC 8 /* encoder short long ratio */
+
+#define FRAME_LEN_LONG_960 (960)
+#define FRAME_MAXLEN_SHORT ((1024) / TRANS_FAC)
+#define FRAME_LEN_SHORT_128 ((1024) / TRANS_FAC)
+#define FRAME_LEN_SHORT_120 (FRAME_LEN_LONG_960 / TRANS_FAC)
+
+/* Filterbank type*/
+enum FB_TYPE { FB_LC = 0, FB_LD = 1, FB_ELD = 2 };
+
+/* Block types */
+#define N_BLOCKTYPES 6
+enum {
+ LONG_WINDOW = 0,
+ START_WINDOW,
+ SHORT_WINDOW,
+ STOP_WINDOW,
+ _LOWOV_WINDOW, /* Do not use this block type out side of block_switch.cpp */
+ WRONG_WINDOW
+};
+
+/* Window shapes */
+enum {
+ SINE_WINDOW = 0,
+ KBD_WINDOW = 1,
+ LOL_WINDOW = 2 /* Low OverLap window shape for AAC-LD */
+};
+
+/*
+ MS stuff
+*/
+enum { SI_MS_MASK_NONE = 0, SI_MS_MASK_SOME = 1, SI_MS_MASK_ALL = 2 };
+
+#define MAX_NO_OF_GROUPS 4
+#define MAX_SFB_LONG \
+ 51 /* 51 for a memory optimized implementation, maybe 64 for convenient \
+ debugging */
+#define MAX_SFB_SHORT \
+ 15 /* 15 for a memory optimized implementation, maybe 16 for convenient \
+ debugging */
+
+#define MAX_SFB \
+ (MAX_SFB_SHORT > MAX_SFB_LONG ? MAX_SFB_SHORT : MAX_SFB_LONG) /* = 51 */
+#define MAX_GROUPED_SFB \
+ (MAX_NO_OF_GROUPS * MAX_SFB_SHORT > MAX_SFB_LONG \
+ ? MAX_NO_OF_GROUPS * MAX_SFB_SHORT \
+ : MAX_SFB_LONG) /* = 60 */
+
+#define MAX_INPUT_BUFFER_SIZE (2 * (1024)) /* 2048 */
+
+#define PCM_LEVEL 1.0f
+#define NORM_PCM (PCM_LEVEL / 32768.0f)
+#define NORM_PCM_ENERGY (NORM_PCM * NORM_PCM)
+#define LOG_NORM_PCM -15
+
+#define TNS_PREDGAIN_SCALE (1000)
+
+#define LFE_LOWPASS_LINE 12
+#define LFE_LOWPASS_LINE_MIN 4
+
+#endif /* PSY_CONST_H */
diff --git a/fdk-aac/libAACenc/src/psy_data.h b/fdk-aac/libAACenc/src/psy_data.h
new file mode 100644
index 0000000..fc04734
--- /dev/null
+++ b/fdk-aac/libAACenc/src/psy_data.h
@@ -0,0 +1,169 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Psychoaccoustic data
+
+*******************************************************************************/
+
+#ifndef PSY_DATA_H
+#define PSY_DATA_H
+
+#include "block_switch.h"
+#include "mdct.h"
+
+/* Be careful with MAX_SFB_LONG as length of the .Long arrays.
+ * sfbEnergy.Long and sfbEnergyMS.Long and sfbThreshold.Long are used as a
+ * temporary storage for the regrouped short energies and thresholds between
+ * FDKaacEnc_groupShortData() and BuildInterface() in FDKaacEnc_psyMain(). The
+ * space required for this is MAX_GROUPED_SFB ( = MAX_NO_OF_GROUPS*MAX_SFB_SHORT
+ * ). However, this is not important if unions are used (which is not possible
+ * with pfloat). */
+
+typedef shouldBeUnion {
+ FIXP_DBL Long[MAX_GROUPED_SFB];
+ FIXP_DBL Short[TRANS_FAC][MAX_SFB_SHORT];
+}
+SFB_THRESHOLD;
+
+typedef shouldBeUnion {
+ FIXP_DBL Long[MAX_GROUPED_SFB];
+ FIXP_DBL Short[TRANS_FAC][MAX_SFB_SHORT];
+}
+SFB_ENERGY;
+
+typedef shouldBeUnion {
+ FIXP_DBL Long[MAX_GROUPED_SFB];
+ FIXP_DBL Short[TRANS_FAC][MAX_SFB_SHORT];
+}
+SFB_LD_ENERGY;
+
+typedef shouldBeUnion {
+ INT Long[MAX_GROUPED_SFB];
+ INT Short[TRANS_FAC][MAX_SFB_SHORT];
+}
+SFB_MAX_SCALE;
+
+typedef struct {
+ INT_PCM* psyInputBuffer;
+ FIXP_DBL overlapAddBuffer[3 * 512 / 2];
+
+ mdct_t mdctPers; /* MDCT persistent data */
+ BLOCK_SWITCHING_CONTROL blockSwitchingControl; /* block switching */
+ FIXP_DBL sfbThresholdnm1[MAX_SFB]; /* FDKaacEnc_PreEchoControl */
+ INT mdctScalenm1; /* scale of last block's mdct (FDKaacEnc_PreEchoControl) */
+ INT calcPreEcho;
+ INT isLFE;
+} PSY_STATIC;
+
+typedef struct {
+ FIXP_DBL* mdctSpectrum;
+ SFB_THRESHOLD sfbThreshold; /* adapt */
+ SFB_ENERGY sfbEnergy; /* sfb energies */
+ SFB_LD_ENERGY sfbEnergyLdData; /* sfb energies in ldData format */
+ SFB_MAX_SCALE sfbMaxScaleSpec;
+ SFB_ENERGY sfbEnergyMS; /* mid/side sfb energies */
+ FIXP_DBL sfbEnergyMSLdData[MAX_GROUPED_SFB]; /* mid/side sfb energies in
+ ldData format */
+ SFB_ENERGY sfbSpreadEnergy;
+ INT mdctScale; /* exponent of data in mdctSpectrum */
+ INT groupedSfbOffset[MAX_GROUPED_SFB + 1];
+ INT sfbActive;
+ INT lowpassLine;
+} PSY_DATA;
+
+#endif /* PSY_DATA_H */
diff --git a/fdk-aac/libAACenc/src/psy_main.cpp b/fdk-aac/libAACenc/src/psy_main.cpp
new file mode 100644
index 0000000..f6345e4
--- /dev/null
+++ b/fdk-aac/libAACenc/src/psy_main.cpp
@@ -0,0 +1,1348 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Psychoaccoustic major function block
+
+*******************************************************************************/
+
+#include "psy_const.h"
+
+#include "block_switch.h"
+#include "transform.h"
+#include "spreading.h"
+#include "pre_echo_control.h"
+#include "band_nrg.h"
+#include "psy_configuration.h"
+#include "psy_data.h"
+#include "ms_stereo.h"
+#include "interface.h"
+#include "psy_main.h"
+#include "grp_data.h"
+#include "tns_func.h"
+#include "pns_func.h"
+#include "tonality.h"
+#include "aacEnc_ram.h"
+#include "intensity.h"
+
+/* blending to reduce gibbs artifacts */
+#define FADE_OUT_LEN 6
+static const FIXP_DBL fadeOutFactor[FADE_OUT_LEN] = {
+ 1840644096, 1533870080, 1227096064, 920322048, 613548032, 306774016};
+
+/* forward definitions */
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_PsyNew
+ description: allocates memory for psychoacoustic
+ returns: an error code
+ input: pointer to a psych handle
+
+*****************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_PsyNew(PSY_INTERNAL **phpsy, const INT nElements,
+ const INT nChannels, UCHAR *dynamic_RAM) {
+ AAC_ENCODER_ERROR ErrorStatus;
+ PSY_INTERNAL *hPsy;
+ INT i;
+
+ hPsy = GetRam_aacEnc_PsyInternal();
+ *phpsy = hPsy;
+ if (hPsy == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto bail;
+ }
+
+ for (i = 0; i < nElements; i++) {
+ /* PSY_ELEMENT */
+ hPsy->psyElement[i] = GetRam_aacEnc_PsyElement(i);
+ if (hPsy->psyElement[i] == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto bail;
+ }
+ }
+
+ for (i = 0; i < nChannels; i++) {
+ /* PSY_STATIC */
+ hPsy->pStaticChannels[i] = GetRam_aacEnc_PsyStatic(i);
+ if (hPsy->pStaticChannels[i] == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto bail;
+ }
+ /* AUDIO INPUT BUFFER */
+ hPsy->pStaticChannels[i]->psyInputBuffer = GetRam_aacEnc_PsyInputBuffer(i);
+ if (hPsy->pStaticChannels[i]->psyInputBuffer == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto bail;
+ }
+ }
+
+ /* reusable psych memory */
+ hPsy->psyDynamic = GetRam_aacEnc_PsyDynamic(0, dynamic_RAM);
+
+ return AAC_ENC_OK;
+
+bail:
+ FDKaacEnc_PsyClose(phpsy, NULL);
+
+ return ErrorStatus;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_PsyOutNew
+ description: allocates memory for psyOut struc
+ returns: an error code
+ input: pointer to a psych handle
+
+*****************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_PsyOutNew(PSY_OUT **phpsyOut, const INT nElements,
+ const INT nChannels, const INT nSubFrames,
+ UCHAR *dynamic_RAM) {
+ AAC_ENCODER_ERROR ErrorStatus;
+ int n, i;
+ int elInc = 0, chInc = 0;
+
+ for (n = 0; n < nSubFrames; n++) {
+ phpsyOut[n] = GetRam_aacEnc_PsyOut(n);
+
+ if (phpsyOut[n] == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto bail;
+ }
+
+ for (i = 0; i < nChannels; i++) {
+ phpsyOut[n]->pPsyOutChannels[i] = GetRam_aacEnc_PsyOutChannel(chInc++);
+ if (NULL == phpsyOut[n]->pPsyOutChannels[i]) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto bail;
+ }
+ }
+
+ for (i = 0; i < nElements; i++) {
+ phpsyOut[n]->psyOutElement[i] = GetRam_aacEnc_PsyOutElements(elInc++);
+ if (phpsyOut[n]->psyOutElement[i] == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto bail;
+ }
+ }
+ } /* nSubFrames */
+
+ return AAC_ENC_OK;
+
+bail:
+ FDKaacEnc_PsyClose(NULL, phpsyOut);
+ return ErrorStatus;
+}
+
+AAC_ENCODER_ERROR FDKaacEnc_psyInitStates(PSY_INTERNAL *hPsy,
+ PSY_STATIC *psyStatic,
+ AUDIO_OBJECT_TYPE audioObjectType) {
+ /* init input buffer */
+ FDKmemclear(psyStatic->psyInputBuffer,
+ MAX_INPUT_BUFFER_SIZE * sizeof(INT_PCM));
+
+ FDKaacEnc_InitBlockSwitching(&psyStatic->blockSwitchingControl,
+ isLowDelay(audioObjectType));
+
+ return AAC_ENC_OK;
+}
+
+AAC_ENCODER_ERROR FDKaacEnc_psyInit(PSY_INTERNAL *hPsy, PSY_OUT **phpsyOut,
+ const INT nSubFrames,
+ const INT nMaxChannels,
+ const AUDIO_OBJECT_TYPE audioObjectType,
+ CHANNEL_MAPPING *cm) {
+ AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
+ int i, ch, n, chInc = 0, resetChannels = 3;
+
+ if ((nMaxChannels > 2) && (cm->nChannels == 2)) {
+ chInc = 1;
+ FDKaacEnc_psyInitStates(hPsy, hPsy->pStaticChannels[0], audioObjectType);
+ }
+
+ if ((nMaxChannels == 2)) {
+ resetChannels = 0;
+ }
+
+ for (i = 0; i < cm->nElements; i++) {
+ for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) {
+ hPsy->psyElement[i]->psyStatic[ch] = hPsy->pStaticChannels[chInc];
+ if (cm->elInfo[i].elType != ID_LFE) {
+ if (chInc >= resetChannels) {
+ FDKaacEnc_psyInitStates(hPsy, hPsy->psyElement[i]->psyStatic[ch],
+ audioObjectType);
+ }
+ mdct_init(&(hPsy->psyElement[i]->psyStatic[ch]->mdctPers), NULL, 0);
+ hPsy->psyElement[i]->psyStatic[ch]->isLFE = 0;
+ } else {
+ hPsy->psyElement[i]->psyStatic[ch]->isLFE = 1;
+ }
+ chInc++;
+ }
+ }
+
+ for (n = 0; n < nSubFrames; n++) {
+ chInc = 0;
+ for (i = 0; i < cm->nElements; i++) {
+ for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) {
+ phpsyOut[n]->psyOutElement[i]->psyOutChannel[ch] =
+ phpsyOut[n]->pPsyOutChannels[chInc++];
+ }
+ }
+ }
+
+ return ErrorStatus;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_psyMainInit
+ description: initializes psychoacoustic
+ returns: an error code
+
+*****************************************************************************/
+
+AAC_ENCODER_ERROR FDKaacEnc_psyMainInit(
+ PSY_INTERNAL *hPsy, AUDIO_OBJECT_TYPE audioObjectType, CHANNEL_MAPPING *cm,
+ INT sampleRate, INT granuleLength, INT bitRate, INT tnsMask, INT bandwidth,
+ INT usePns, INT useIS, INT useMS, UINT syntaxFlags, ULONG initFlags) {
+ AAC_ENCODER_ERROR ErrorStatus;
+ int i, ch;
+ int channelsEff = cm->nChannelsEff;
+ int tnsChannels = 0;
+ FB_TYPE filterBank;
+
+ switch (FDKaacEnc_GetMonoStereoMode(cm->encMode)) {
+ /* ... and map to tnsChannels */
+ case EL_MODE_MONO:
+ tnsChannels = 1;
+ break;
+ case EL_MODE_STEREO:
+ tnsChannels = 2;
+ break;
+ default:
+ tnsChannels = 0;
+ }
+
+ switch (audioObjectType) {
+ default:
+ filterBank = FB_LC;
+ break;
+ case AOT_ER_AAC_LD:
+ filterBank = FB_LD;
+ break;
+ case AOT_ER_AAC_ELD:
+ filterBank = FB_ELD;
+ break;
+ }
+
+ hPsy->granuleLength = granuleLength;
+
+ ErrorStatus = FDKaacEnc_InitPsyConfiguration(
+ bitRate / channelsEff, sampleRate, bandwidth, LONG_WINDOW,
+ hPsy->granuleLength, useIS, useMS, &(hPsy->psyConf[0]), filterBank);
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+
+ ErrorStatus = FDKaacEnc_InitTnsConfiguration(
+ (bitRate * tnsChannels) / channelsEff, sampleRate, tnsChannels,
+ LONG_WINDOW, hPsy->granuleLength, isLowDelay(audioObjectType),
+ (syntaxFlags & AC_SBR_PRESENT) ? 1 : 0, &(hPsy->psyConf[0].tnsConf),
+ &hPsy->psyConf[0], (INT)(tnsMask & 2), (INT)(tnsMask & 8));
+
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+
+ if (granuleLength > 512) {
+ ErrorStatus = FDKaacEnc_InitPsyConfiguration(
+ bitRate / channelsEff, sampleRate, bandwidth, SHORT_WINDOW,
+ hPsy->granuleLength, useIS, useMS, &hPsy->psyConf[1], filterBank);
+
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+
+ ErrorStatus = FDKaacEnc_InitTnsConfiguration(
+ (bitRate * tnsChannels) / channelsEff, sampleRate, tnsChannels,
+ SHORT_WINDOW, hPsy->granuleLength, isLowDelay(audioObjectType),
+ (syntaxFlags & AC_SBR_PRESENT) ? 1 : 0, &hPsy->psyConf[1].tnsConf,
+ &hPsy->psyConf[1], (INT)(tnsMask & 1), (INT)(tnsMask & 4));
+
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+ }
+
+ for (i = 0; i < cm->nElements; i++) {
+ for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) {
+ if (initFlags) {
+ /* reset states */
+ FDKaacEnc_psyInitStates(hPsy, hPsy->psyElement[i]->psyStatic[ch],
+ audioObjectType);
+ }
+
+ FDKaacEnc_InitPreEchoControl(
+ hPsy->psyElement[i]->psyStatic[ch]->sfbThresholdnm1,
+ &hPsy->psyElement[i]->psyStatic[ch]->calcPreEcho,
+ hPsy->psyConf[0].sfbCnt, hPsy->psyConf[0].sfbPcmQuantThreshold,
+ &hPsy->psyElement[i]->psyStatic[ch]->mdctScalenm1);
+ }
+ }
+
+ ErrorStatus = FDKaacEnc_InitPnsConfiguration(
+ &hPsy->psyConf[0].pnsConf, bitRate / channelsEff, sampleRate, usePns,
+ hPsy->psyConf[0].sfbCnt, hPsy->psyConf[0].sfbOffset,
+ cm->elInfo[0].nChannelsInEl, (hPsy->psyConf[0].filterbank == FB_LC));
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+
+ if (granuleLength > 512) {
+ ErrorStatus = FDKaacEnc_InitPnsConfiguration(
+ &hPsy->psyConf[1].pnsConf, bitRate / channelsEff, sampleRate, usePns,
+ hPsy->psyConf[1].sfbCnt, hPsy->psyConf[1].sfbOffset,
+ cm->elInfo[1].nChannelsInEl, (hPsy->psyConf[1].filterbank == FB_LC));
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+ }
+
+ return ErrorStatus;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_psyMain
+ description: psychoacoustic
+ returns: an error code
+
+ This function assumes that enough input data is in the modulo buffer.
+
+*****************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels, PSY_ELEMENT *psyElement,
+ PSY_DYNAMIC *psyDynamic,
+ PSY_CONFIGURATION *psyConf,
+ PSY_OUT_ELEMENT *RESTRICT psyOutElement,
+ INT_PCM *pInput, const UINT inputBufSize,
+ INT *chIdx, INT totalChannels) {
+ const INT commonWindow = 1;
+ INT maxSfbPerGroup[(2)];
+ INT mdctSpectrum_e;
+ INT ch; /* counts through channels */
+ INT w; /* counts through windows */
+ INT sfb; /* counts through scalefactor bands */
+ INT line; /* counts through lines */
+
+ PSY_CONFIGURATION *RESTRICT hPsyConfLong = &psyConf[0];
+ PSY_CONFIGURATION *RESTRICT hPsyConfShort = &psyConf[1];
+ PSY_OUT_CHANNEL **RESTRICT psyOutChannel = psyOutElement->psyOutChannel;
+ FIXP_SGL sfbTonality[(2)][MAX_SFB_LONG];
+
+ PSY_STATIC **RESTRICT psyStatic = psyElement->psyStatic;
+
+ PSY_DATA *RESTRICT psyData[(2)];
+ TNS_DATA *RESTRICT tnsData[(2)];
+ PNS_DATA *RESTRICT pnsData[(2)];
+
+ INT zeroSpec = TRUE; /* means all spectral lines are zero */
+
+ INT blockSwitchingOffset;
+
+ PSY_CONFIGURATION *RESTRICT hThisPsyConf[(2)];
+ INT windowLength[(2)];
+ INT nWindows[(2)];
+ INT wOffset;
+
+ INT maxSfb[(2)];
+ INT *pSfbMaxScaleSpec[(2)];
+ FIXP_DBL *pSfbEnergy[(2)];
+ FIXP_DBL *pSfbSpreadEnergy[(2)];
+ FIXP_DBL *pSfbEnergyLdData[(2)];
+ FIXP_DBL *pSfbEnergyMS[(2)];
+ FIXP_DBL *pSfbThreshold[(2)];
+
+ INT isShortWindow[(2)];
+
+ /* number of incoming time samples to be processed */
+ const INT nTimeSamples = psyConf->granuleLength;
+
+ switch (hPsyConfLong->filterbank) {
+ case FB_LC:
+ blockSwitchingOffset =
+ nTimeSamples + (9 * nTimeSamples / (2 * TRANS_FAC));
+ break;
+ case FB_LD:
+ case FB_ELD:
+ blockSwitchingOffset = nTimeSamples;
+ break;
+ default:
+ return AAC_ENC_UNSUPPORTED_FILTERBANK;
+ }
+
+ for (ch = 0; ch < channels; ch++) {
+ psyData[ch] = &psyDynamic->psyData[ch];
+ tnsData[ch] = &psyDynamic->tnsData[ch];
+ pnsData[ch] = &psyDynamic->pnsData[ch];
+
+ psyData[ch]->mdctSpectrum = psyOutChannel[ch]->mdctSpectrum;
+ }
+
+ /* block switching */
+ if (hPsyConfLong->filterbank != FB_ELD) {
+ int err;
+
+ for (ch = 0; ch < channels; ch++) {
+ C_ALLOC_SCRATCH_START(pTimeSignal, INT_PCM, (1024))
+
+ /* copy input data and use for block switching */
+ FDKmemcpy(pTimeSignal, pInput + chIdx[ch] * inputBufSize,
+ nTimeSamples * sizeof(INT_PCM));
+
+ FDKaacEnc_BlockSwitching(&psyStatic[ch]->blockSwitchingControl,
+ nTimeSamples, psyStatic[ch]->isLFE, pTimeSignal);
+
+ /* fill up internal input buffer, to 2xframelength samples */
+ FDKmemcpy(psyStatic[ch]->psyInputBuffer + blockSwitchingOffset,
+ pTimeSignal,
+ (2 * nTimeSamples - blockSwitchingOffset) * sizeof(INT_PCM));
+
+ C_ALLOC_SCRATCH_END(pTimeSignal, INT_PCM, (1024))
+ }
+
+ /* synch left and right block type */
+ err = FDKaacEnc_SyncBlockSwitching(
+ &psyStatic[0]->blockSwitchingControl,
+ (channels > 1) ? &psyStatic[1]->blockSwitchingControl : NULL, channels,
+ commonWindow);
+
+ if (err) {
+ return AAC_ENC_UNSUPPORTED_AOT; /* mixed up LC and LD */
+ }
+
+ } else {
+ for (ch = 0; ch < channels; ch++) {
+ /* copy input data and use for block switching */
+ FDKmemcpy(psyStatic[ch]->psyInputBuffer + blockSwitchingOffset,
+ pInput + chIdx[ch] * inputBufSize,
+ nTimeSamples * sizeof(INT_PCM));
+ }
+ }
+
+ for (ch = 0; ch < channels; ch++)
+ isShortWindow[ch] =
+ (psyStatic[ch]->blockSwitchingControl.lastWindowSequence ==
+ SHORT_WINDOW);
+
+ /* set parameters according to window length */
+ for (ch = 0; ch < channels; ch++) {
+ if (isShortWindow[ch]) {
+ hThisPsyConf[ch] = hPsyConfShort;
+ windowLength[ch] = psyConf->granuleLength / TRANS_FAC;
+ nWindows[ch] = TRANS_FAC;
+ maxSfb[ch] = MAX_SFB_SHORT;
+
+ pSfbMaxScaleSpec[ch] = psyData[ch]->sfbMaxScaleSpec.Short[0];
+ pSfbEnergy[ch] = psyData[ch]->sfbEnergy.Short[0];
+ pSfbSpreadEnergy[ch] = psyData[ch]->sfbSpreadEnergy.Short[0];
+ pSfbEnergyLdData[ch] = psyData[ch]->sfbEnergyLdData.Short[0];
+ pSfbEnergyMS[ch] = psyData[ch]->sfbEnergyMS.Short[0];
+ pSfbThreshold[ch] = psyData[ch]->sfbThreshold.Short[0];
+
+ } else {
+ hThisPsyConf[ch] = hPsyConfLong;
+ windowLength[ch] = psyConf->granuleLength;
+ nWindows[ch] = 1;
+ maxSfb[ch] = MAX_GROUPED_SFB;
+
+ pSfbMaxScaleSpec[ch] = psyData[ch]->sfbMaxScaleSpec.Long;
+ pSfbEnergy[ch] = psyData[ch]->sfbEnergy.Long;
+ pSfbSpreadEnergy[ch] = psyData[ch]->sfbSpreadEnergy.Long;
+ pSfbEnergyLdData[ch] = psyData[ch]->sfbEnergyLdData.Long;
+ pSfbEnergyMS[ch] = psyData[ch]->sfbEnergyMS.Long;
+ pSfbThreshold[ch] = psyData[ch]->sfbThreshold.Long;
+ }
+ }
+
+ /* Transform and get mdctScaling for all channels and windows. */
+ for (ch = 0; ch < channels; ch++) {
+ /* update number of active bands */
+ if (psyStatic[ch]->isLFE) {
+ psyData[ch]->sfbActive = hThisPsyConf[ch]->sfbActiveLFE;
+ psyData[ch]->lowpassLine = hThisPsyConf[ch]->lowpassLineLFE;
+ } else {
+ psyData[ch]->sfbActive = hThisPsyConf[ch]->sfbActive;
+ psyData[ch]->lowpassLine = hThisPsyConf[ch]->lowpassLine;
+ }
+
+ if (hThisPsyConf[ch]->filterbank == FB_ELD) {
+ if (FDKaacEnc_Transform_Real_Eld(
+ psyStatic[ch]->psyInputBuffer, psyData[ch]->mdctSpectrum,
+ psyStatic[ch]->blockSwitchingControl.lastWindowSequence,
+ psyStatic[ch]->blockSwitchingControl.windowShape,
+ &psyStatic[ch]->blockSwitchingControl.lastWindowShape,
+ nTimeSamples, &mdctSpectrum_e, hThisPsyConf[ch]->filterbank,
+ psyStatic[ch]->overlapAddBuffer) != 0) {
+ return AAC_ENC_UNSUPPORTED_FILTERBANK;
+ }
+ } else {
+ if (FDKaacEnc_Transform_Real(
+ psyStatic[ch]->psyInputBuffer, psyData[ch]->mdctSpectrum,
+ psyStatic[ch]->blockSwitchingControl.lastWindowSequence,
+ psyStatic[ch]->blockSwitchingControl.windowShape,
+ &psyStatic[ch]->blockSwitchingControl.lastWindowShape,
+ &psyStatic[ch]->mdctPers, nTimeSamples, &mdctSpectrum_e,
+ hThisPsyConf[ch]->filterbank) != 0) {
+ return AAC_ENC_UNSUPPORTED_FILTERBANK;
+ }
+ }
+
+ for (w = 0; w < nWindows[ch]; w++) {
+ wOffset = w * windowLength[ch];
+
+ /* Low pass / highest sfb */
+ FDKmemclear(
+ &psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine + wOffset],
+ (windowLength[ch] - psyData[ch]->lowpassLine) * sizeof(FIXP_DBL));
+
+ if ((hPsyConfLong->filterbank != FB_LC) &&
+ (psyData[ch]->lowpassLine >= FADE_OUT_LEN)) {
+ /* Do blending to reduce gibbs artifacts */
+ for (int i = 0; i < FADE_OUT_LEN; i++) {
+ psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine + wOffset -
+ FADE_OUT_LEN + i] =
+ fMult(psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine +
+ wOffset - FADE_OUT_LEN + i],
+ fadeOutFactor[i]);
+ }
+ }
+
+ /* Check for zero spectrum. These loops will usually terminate very, very
+ * early. */
+ for (line = 0; (line < psyData[ch]->lowpassLine) && (zeroSpec == TRUE);
+ line++) {
+ if (psyData[ch]->mdctSpectrum[line + wOffset] != (FIXP_DBL)0) {
+ zeroSpec = FALSE;
+ break;
+ }
+ }
+
+ } /* w loop */
+
+ psyData[ch]->mdctScale = mdctSpectrum_e;
+
+ /* rotate internal time samples */
+ FDKmemmove(psyStatic[ch]->psyInputBuffer,
+ psyStatic[ch]->psyInputBuffer + nTimeSamples,
+ nTimeSamples * sizeof(INT_PCM));
+
+ /* ... and get remaining samples from input buffer */
+ FDKmemcpy(psyStatic[ch]->psyInputBuffer + nTimeSamples,
+ pInput + (2 * nTimeSamples - blockSwitchingOffset) +
+ chIdx[ch] * inputBufSize,
+ (blockSwitchingOffset - nTimeSamples) * sizeof(INT_PCM));
+
+ } /* ch */
+
+ /* Do some rescaling to get maximum possible accuracy for energies */
+ if (zeroSpec == FALSE) {
+ /* Calc possible spectrum leftshift for each sfb (1 means: 1 bit left shift
+ * is possible without overflow) */
+ INT minSpecShift = MAX_SHIFT_DBL;
+ INT nrgShift = MAX_SHIFT_DBL;
+ INT finalShift = MAX_SHIFT_DBL;
+ FIXP_DBL currNrg = 0;
+ FIXP_DBL maxNrg = 0;
+
+ for (ch = 0; ch < channels; ch++) {
+ for (w = 0; w < nWindows[ch]; w++) {
+ wOffset = w * windowLength[ch];
+ FDKaacEnc_CalcSfbMaxScaleSpec(
+ psyData[ch]->mdctSpectrum + wOffset, hThisPsyConf[ch]->sfbOffset,
+ pSfbMaxScaleSpec[ch] + w * maxSfb[ch], psyData[ch]->sfbActive);
+
+ for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++)
+ minSpecShift = fixMin(minSpecShift,
+ (pSfbMaxScaleSpec[ch] + w * maxSfb[ch])[sfb]);
+ }
+ }
+
+ /* Calc possible energy leftshift for each sfb (1 means: 1 bit left shift is
+ * possible without overflow) */
+ for (ch = 0; ch < channels; ch++) {
+ for (w = 0; w < nWindows[ch]; w++) {
+ wOffset = w * windowLength[ch];
+ currNrg = FDKaacEnc_CheckBandEnergyOptim(
+ psyData[ch]->mdctSpectrum + wOffset,
+ pSfbMaxScaleSpec[ch] + w * maxSfb[ch], hThisPsyConf[ch]->sfbOffset,
+ psyData[ch]->sfbActive, pSfbEnergy[ch] + w * maxSfb[ch],
+ pSfbEnergyLdData[ch] + w * maxSfb[ch], minSpecShift - 4);
+
+ maxNrg = fixMax(maxNrg, currNrg);
+ }
+ }
+
+ if (maxNrg != (FIXP_DBL)0) {
+ nrgShift = (CountLeadingBits(maxNrg) >> 1) + (minSpecShift - 4);
+ }
+
+ /* 2check: Hasn't this decision to be made for both channels? */
+ /* For short windows 1 additional bit headroom is necessary to prevent
+ * overflows when summing up energies in FDKaacEnc_groupShortData() */
+ if (isShortWindow[0]) nrgShift--;
+
+ /* both spectrum and energies mustn't overflow */
+ finalShift = fixMin(minSpecShift, nrgShift);
+
+ /* do not shift more than 3 bits more to the left than signal without
+ * blockfloating point would be to avoid overflow of scaled PCM quantization
+ * thresholds */
+ if (finalShift > psyData[0]->mdctScale + 3)
+ finalShift = psyData[0]->mdctScale + 3;
+
+ FDK_ASSERT(finalShift >= 0); /* right shift is not allowed */
+
+ /* correct sfbEnergy and sfbEnergyLdData with new finalShift */
+ FIXP_DBL ldShift = finalShift * FL2FXCONST_DBL(2.0 / 64);
+ for (ch = 0; ch < channels; ch++) {
+ INT maxSfb_ch = maxSfb[ch];
+ INT w_maxSfb_ch = 0;
+ for (w = 0; w < nWindows[ch]; w++) {
+ for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) {
+ INT scale = fixMax(0, (pSfbMaxScaleSpec[ch] + w_maxSfb_ch)[sfb] - 4);
+ scale = fixMin((scale - finalShift) << 1, DFRACT_BITS - 1);
+ if (scale >= 0)
+ (pSfbEnergy[ch] + w_maxSfb_ch)[sfb] >>= (scale);
+ else
+ (pSfbEnergy[ch] + w_maxSfb_ch)[sfb] <<= (-scale);
+ (pSfbThreshold[ch] + w_maxSfb_ch)[sfb] =
+ fMult((pSfbEnergy[ch] + w_maxSfb_ch)[sfb], C_RATIO);
+ (pSfbEnergyLdData[ch] + w_maxSfb_ch)[sfb] += ldShift;
+ }
+ w_maxSfb_ch += maxSfb_ch;
+ }
+ }
+
+ if (finalShift != 0) {
+ for (ch = 0; ch < channels; ch++) {
+ INT wLen = windowLength[ch];
+ INT lowpassLine = psyData[ch]->lowpassLine;
+ wOffset = 0;
+ FIXP_DBL *mdctSpectrum = &psyData[ch]->mdctSpectrum[0];
+ for (w = 0; w < nWindows[ch]; w++) {
+ FIXP_DBL *spectrum = &mdctSpectrum[wOffset];
+ for (line = 0; line < lowpassLine; line++) {
+ spectrum[line] <<= finalShift;
+ }
+ wOffset += wLen;
+
+ /* update sfbMaxScaleSpec */
+ for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++)
+ (pSfbMaxScaleSpec[ch] + w * maxSfb[ch])[sfb] -= finalShift;
+ }
+ /* update mdctScale */
+ psyData[ch]->mdctScale -= finalShift;
+ }
+ }
+
+ } else {
+ /* all spectral lines are zero */
+ for (ch = 0; ch < channels; ch++) {
+ psyData[ch]->mdctScale =
+ 0; /* otherwise mdctScale would be for example 7 and PCM quantization
+ * thresholds would be shifted 14 bits to the right causing some of
+ * them to become 0 (which causes problems later) */
+ /* clear sfbMaxScaleSpec */
+ for (w = 0; w < nWindows[ch]; w++) {
+ for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) {
+ (pSfbMaxScaleSpec[ch] + w * maxSfb[ch])[sfb] = 0;
+ (pSfbEnergy[ch] + w * maxSfb[ch])[sfb] = (FIXP_DBL)0;
+ (pSfbEnergyLdData[ch] + w * maxSfb[ch])[sfb] = FL2FXCONST_DBL(-1.0f);
+ (pSfbThreshold[ch] + w * maxSfb[ch])[sfb] = (FIXP_DBL)0;
+ }
+ }
+ }
+ }
+
+ /* Advance psychoacoustics: Tonality and TNS */
+ if ((channels >= 1) && (psyStatic[0]->isLFE)) {
+ tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] = 0;
+ tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT] = 0;
+ } else {
+ for (ch = 0; ch < channels; ch++) {
+ if (!isShortWindow[ch]) {
+ /* tonality */
+ FDKaacEnc_CalculateFullTonality(
+ psyData[ch]->mdctSpectrum, pSfbMaxScaleSpec[ch],
+ pSfbEnergyLdData[ch], sfbTonality[ch], psyData[ch]->sfbActive,
+ hThisPsyConf[ch]->sfbOffset, hThisPsyConf[ch]->pnsConf.usePns);
+ }
+ } /* ch */
+
+ if (hPsyConfLong->tnsConf.tnsActive || hPsyConfShort->tnsConf.tnsActive) {
+ INT tnsActive[TRANS_FAC] = {0};
+ INT nrgScaling[2] = {0, 0};
+ INT tnsSpecShift = 0;
+
+ for (ch = 0; ch < channels; ch++) {
+ for (w = 0; w < nWindows[ch]; w++) {
+ wOffset = w * windowLength[ch];
+ /* TNS */
+ FDKaacEnc_TnsDetect(
+ tnsData[ch], &hThisPsyConf[ch]->tnsConf,
+ &psyOutChannel[ch]->tnsInfo, hThisPsyConf[ch]->sfbCnt,
+ psyData[ch]->mdctSpectrum + wOffset, w,
+ psyStatic[ch]->blockSwitchingControl.lastWindowSequence);
+ }
+ }
+
+ if (channels == 2) {
+ FDKaacEnc_TnsSync(
+ tnsData[1], tnsData[0], &psyOutChannel[1]->tnsInfo,
+ &psyOutChannel[0]->tnsInfo,
+
+ psyStatic[1]->blockSwitchingControl.lastWindowSequence,
+ psyStatic[0]->blockSwitchingControl.lastWindowSequence,
+ &hThisPsyConf[1]->tnsConf);
+ }
+
+ if (channels >= 1) {
+ FDK_ASSERT(1 == commonWindow); /* all checks for TNS do only work for
+ common windows (which is always set)*/
+ for (w = 0; w < nWindows[0]; w++) {
+ if (isShortWindow[0])
+ tnsActive[w] =
+ tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive[HIFILT] ||
+ tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive[LOFILT] ||
+ tnsData[channels - 1]
+ ->dataRaw.Short.subBlockInfo[w]
+ .tnsActive[HIFILT] ||
+ tnsData[channels - 1]
+ ->dataRaw.Short.subBlockInfo[w]
+ .tnsActive[LOFILT];
+ else
+ tnsActive[w] =
+ tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] ||
+ tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT] ||
+ tnsData[channels - 1]
+ ->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] ||
+ tnsData[channels - 1]
+ ->dataRaw.Long.subBlockInfo.tnsActive[LOFILT];
+ }
+ }
+
+ for (ch = 0; ch < channels; ch++) {
+ if (tnsActive[0] && !isShortWindow[ch]) {
+ /* Scale down spectrum if tns is active in one of the two channels
+ * with same lastWindowSequence */
+ /* first part of threshold calculation; it's not necessary to update
+ * sfbMaxScaleSpec */
+ INT shift = 1;
+ for (sfb = 0; sfb < hThisPsyConf[ch]->lowpassLine; sfb++) {
+ psyData[ch]->mdctSpectrum[sfb] =
+ psyData[ch]->mdctSpectrum[sfb] >> shift;
+ }
+
+ /* update thresholds */
+ for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) {
+ pSfbThreshold[ch][sfb] >>= (2 * shift);
+ }
+
+ psyData[ch]->mdctScale += shift; /* update mdctScale */
+
+ /* calc sfbEnergies after tnsEncode again ! */
+ }
+ }
+
+ for (ch = 0; ch < channels; ch++) {
+ for (w = 0; w < nWindows[ch]; w++) {
+ wOffset = w * windowLength[ch];
+ FDKaacEnc_TnsEncode(
+ &psyOutChannel[ch]->tnsInfo, tnsData[ch],
+ hThisPsyConf[ch]->sfbCnt, &hThisPsyConf[ch]->tnsConf,
+ hThisPsyConf[ch]->sfbOffset[psyData[ch]->sfbActive],
+ /*hThisPsyConf[ch]->lowpassLine*/ /* filter stops
+ before that
+ line ! */
+ psyData[ch]->mdctSpectrum +
+ wOffset,
+ w, psyStatic[ch]->blockSwitchingControl.lastWindowSequence);
+
+ if (tnsActive[w]) {
+ /* Calc sfb-bandwise mdct-energies for left and right channel again,
+ */
+ /* if tns active in current channel or in one channel with same
+ * lastWindowSequence left and right */
+ FDKaacEnc_CalcSfbMaxScaleSpec(psyData[ch]->mdctSpectrum + wOffset,
+ hThisPsyConf[ch]->sfbOffset,
+ pSfbMaxScaleSpec[ch] + w * maxSfb[ch],
+ psyData[ch]->sfbActive);
+ }
+ }
+ }
+
+ for (ch = 0; ch < channels; ch++) {
+ for (w = 0; w < nWindows[ch]; w++) {
+ if (tnsActive[w]) {
+ if (isShortWindow[ch]) {
+ FDKaacEnc_CalcBandEnergyOptimShort(
+ psyData[ch]->mdctSpectrum + w * windowLength[ch],
+ pSfbMaxScaleSpec[ch] + w * maxSfb[ch],
+ hThisPsyConf[ch]->sfbOffset, psyData[ch]->sfbActive,
+ pSfbEnergy[ch] + w * maxSfb[ch]);
+ } else {
+ nrgScaling[ch] = /* with tns, energy calculation can overflow; ->
+ scaling */
+ FDKaacEnc_CalcBandEnergyOptimLong(
+ psyData[ch]->mdctSpectrum, pSfbMaxScaleSpec[ch],
+ hThisPsyConf[ch]->sfbOffset, psyData[ch]->sfbActive,
+ pSfbEnergy[ch], pSfbEnergyLdData[ch]);
+ tnsSpecShift =
+ fixMax(tnsSpecShift, nrgScaling[ch]); /* nrgScaling is set
+ only if nrg would
+ have an overflow */
+ }
+ } /* if tnsActive */
+ }
+ } /* end channel loop */
+
+ /* adapt scaling to prevent nrg overflow, only for long blocks */
+ for (ch = 0; ch < channels; ch++) {
+ if ((tnsSpecShift != 0) && !isShortWindow[ch]) {
+ /* scale down spectrum, nrg's and thresholds, if there was an overflow
+ * in sfbNrg calculation after tns */
+ for (line = 0; line < hThisPsyConf[ch]->lowpassLine; line++) {
+ psyData[ch]->mdctSpectrum[line] >>= tnsSpecShift;
+ }
+ INT scale = (tnsSpecShift - nrgScaling[ch]) << 1;
+ for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) {
+ pSfbEnergyLdData[ch][sfb] -=
+ scale * FL2FXCONST_DBL(1.0 / LD_DATA_SCALING);
+ pSfbEnergy[ch][sfb] >>= scale;
+ pSfbThreshold[ch][sfb] >>= (tnsSpecShift << 1);
+ }
+ psyData[ch]->mdctScale += tnsSpecShift; /* update mdctScale; not
+ necessary to update
+ sfbMaxScaleSpec */
+ }
+ } /* end channel loop */
+
+ } /* TNS active */
+ else {
+ /* In case of disable TNS, reset its dynamic data. Some of its elements is
+ * required in PNS detection below. */
+ FDKmemclear(psyDynamic->tnsData, sizeof(psyDynamic->tnsData));
+ }
+ } /* !isLFE */
+
+ /* Advance thresholds */
+ for (ch = 0; ch < channels; ch++) {
+ INT headroom;
+
+ FIXP_DBL clipEnergy;
+ INT energyShift = psyData[ch]->mdctScale * 2;
+ INT clipNrgShift = energyShift - THR_SHIFTBITS;
+ if (isShortWindow[ch])
+ headroom = 6;
+ else
+ headroom = 0;
+
+ if (clipNrgShift >= 0)
+ clipEnergy = hThisPsyConf[ch]->clipEnergy >> clipNrgShift;
+ else if (clipNrgShift >= -headroom)
+ clipEnergy = hThisPsyConf[ch]->clipEnergy << -clipNrgShift;
+ else
+ clipEnergy = (FIXP_DBL)MAXVAL_DBL;
+
+ for (w = 0; w < nWindows[ch]; w++) {
+ INT i;
+ /* limit threshold to avoid clipping */
+ for (i = 0; i < psyData[ch]->sfbActive; i++) {
+ *(pSfbThreshold[ch] + w * maxSfb[ch] + i) =
+ fixMin(*(pSfbThreshold[ch] + w * maxSfb[ch] + i), clipEnergy);
+ }
+
+ /* spreading */
+ FDKaacEnc_SpreadingMax(psyData[ch]->sfbActive,
+ hThisPsyConf[ch]->sfbMaskLowFactor,
+ hThisPsyConf[ch]->sfbMaskHighFactor,
+ pSfbThreshold[ch] + w * maxSfb[ch]);
+
+ /* PCM quantization threshold */
+ energyShift += PCM_QUANT_THR_SCALE;
+ if (energyShift >= 0) {
+ energyShift = fixMin(DFRACT_BITS - 1, energyShift);
+ for (i = 0; i < psyData[ch]->sfbActive; i++) {
+ *(pSfbThreshold[ch] + w * maxSfb[ch] + i) = fixMax(
+ *(pSfbThreshold[ch] + w * maxSfb[ch] + i) >> THR_SHIFTBITS,
+ (hThisPsyConf[ch]->sfbPcmQuantThreshold[i] >> energyShift));
+ }
+ } else {
+ energyShift = fixMin(DFRACT_BITS - 1, -energyShift);
+ for (i = 0; i < psyData[ch]->sfbActive; i++) {
+ *(pSfbThreshold[ch] + w * maxSfb[ch] + i) = fixMax(
+ *(pSfbThreshold[ch] + w * maxSfb[ch] + i) >> THR_SHIFTBITS,
+ (hThisPsyConf[ch]->sfbPcmQuantThreshold[i] << energyShift));
+ }
+ }
+
+ if (!psyStatic[ch]->isLFE) {
+ /* preecho control */
+ if (psyStatic[ch]->blockSwitchingControl.lastWindowSequence ==
+ STOP_WINDOW) {
+ /* prevent FDKaacEnc_PreEchoControl from comparing stop
+ thresholds with short thresholds */
+ for (i = 0; i < psyData[ch]->sfbActive; i++) {
+ psyStatic[ch]->sfbThresholdnm1[i] = (FIXP_DBL)MAXVAL_DBL;
+ }
+
+ psyStatic[ch]->mdctScalenm1 = 0;
+ psyStatic[ch]->calcPreEcho = 0;
+ }
+
+ FDKaacEnc_PreEchoControl(
+ psyStatic[ch]->sfbThresholdnm1, psyStatic[ch]->calcPreEcho,
+ psyData[ch]->sfbActive, hThisPsyConf[ch]->maxAllowedIncreaseFactor,
+ hThisPsyConf[ch]->minRemainingThresholdFactor,
+ pSfbThreshold[ch] + w * maxSfb[ch], psyData[ch]->mdctScale,
+ &psyStatic[ch]->mdctScalenm1);
+
+ psyStatic[ch]->calcPreEcho = 1;
+
+ if (psyStatic[ch]->blockSwitchingControl.lastWindowSequence ==
+ START_WINDOW) {
+ /* prevent FDKaacEnc_PreEchoControl in next frame to compare start
+ thresholds with short thresholds */
+ for (i = 0; i < psyData[ch]->sfbActive; i++) {
+ psyStatic[ch]->sfbThresholdnm1[i] = (FIXP_DBL)MAXVAL_DBL;
+ }
+
+ psyStatic[ch]->mdctScalenm1 = 0;
+ psyStatic[ch]->calcPreEcho = 0;
+ }
+ }
+
+ /* spread energy to avoid hole detection */
+ FDKmemcpy(pSfbSpreadEnergy[ch] + w * maxSfb[ch],
+ pSfbEnergy[ch] + w * maxSfb[ch],
+ psyData[ch]->sfbActive * sizeof(FIXP_DBL));
+
+ FDKaacEnc_SpreadingMax(psyData[ch]->sfbActive,
+ hThisPsyConf[ch]->sfbMaskLowFactorSprEn,
+ hThisPsyConf[ch]->sfbMaskHighFactorSprEn,
+ pSfbSpreadEnergy[ch] + w * maxSfb[ch]);
+ }
+ }
+
+ /* Calc bandwise energies for mid and side channel. Do it only if 2 channels
+ * exist */
+ if (channels == 2) {
+ for (w = 0; w < nWindows[1]; w++) {
+ wOffset = w * windowLength[1];
+ FDKaacEnc_CalcBandNrgMSOpt(
+ psyData[0]->mdctSpectrum + wOffset,
+ psyData[1]->mdctSpectrum + wOffset,
+ pSfbMaxScaleSpec[0] + w * maxSfb[0],
+ pSfbMaxScaleSpec[1] + w * maxSfb[1], hThisPsyConf[1]->sfbOffset,
+ psyData[0]->sfbActive, pSfbEnergyMS[0] + w * maxSfb[0],
+ pSfbEnergyMS[1] + w * maxSfb[1],
+ (psyStatic[1]->blockSwitchingControl.lastWindowSequence !=
+ SHORT_WINDOW),
+ psyData[0]->sfbEnergyMSLdData, psyData[1]->sfbEnergyMSLdData);
+ }
+ }
+
+ /* group short data (maxSfb[ch] for short blocks is determined here) */
+ for (ch = 0; ch < channels; ch++) {
+ if (isShortWindow[ch]) {
+ int sfbGrp;
+ int noSfb = psyStatic[ch]->blockSwitchingControl.noOfGroups *
+ hPsyConfShort->sfbCnt;
+ /* At this point, energies and thresholds are copied/regrouped from the
+ * ".Short" to the ".Long" arrays */
+ FDKaacEnc_groupShortData(
+ psyData[ch]->mdctSpectrum, &psyData[ch]->sfbThreshold,
+ &psyData[ch]->sfbEnergy, &psyData[ch]->sfbEnergyMS,
+ &psyData[ch]->sfbSpreadEnergy, hPsyConfShort->sfbCnt,
+ psyData[ch]->sfbActive, hPsyConfShort->sfbOffset,
+ hPsyConfShort->sfbMinSnrLdData, psyData[ch]->groupedSfbOffset,
+ &maxSfbPerGroup[ch], psyOutChannel[ch]->sfbMinSnrLdData,
+ psyStatic[ch]->blockSwitchingControl.noOfGroups,
+ psyStatic[ch]->blockSwitchingControl.groupLen,
+ psyConf[1].granuleLength);
+
+ /* calculate ldData arrays (short values are in .Long-arrays after
+ * FDKaacEnc_groupShortData) */
+ for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) {
+ LdDataVector(&psyData[ch]->sfbEnergy.Long[sfbGrp],
+ &psyOutChannel[ch]->sfbEnergyLdData[sfbGrp],
+ psyData[ch]->sfbActive);
+ }
+
+ /* calc sfbThrld and set Values smaller 2^-31 to 2^-33*/
+ for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) {
+ LdDataVector(&psyData[ch]->sfbThreshold.Long[sfbGrp],
+ &psyOutChannel[ch]->sfbThresholdLdData[sfbGrp],
+ psyData[ch]->sfbActive);
+ for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) {
+ psyOutChannel[ch]->sfbThresholdLdData[sfbGrp + sfb] =
+ fixMax(psyOutChannel[ch]->sfbThresholdLdData[sfbGrp + sfb],
+ FL2FXCONST_DBL(-0.515625f));
+ }
+ }
+
+ if (channels == 2) {
+ for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) {
+ LdDataVector(&psyData[ch]->sfbEnergyMS.Long[sfbGrp],
+ &psyData[ch]->sfbEnergyMSLdData[sfbGrp],
+ psyData[ch]->sfbActive);
+ }
+ }
+
+ FDKmemcpy(psyOutChannel[ch]->sfbOffsets, psyData[ch]->groupedSfbOffset,
+ (MAX_GROUPED_SFB + 1) * sizeof(INT));
+
+ } else {
+ int i;
+ /* maxSfb[ch] for long blocks */
+ for (sfb = psyData[ch]->sfbActive - 1; sfb >= 0; sfb--) {
+ for (line = hPsyConfLong->sfbOffset[sfb + 1] - 1;
+ line >= hPsyConfLong->sfbOffset[sfb]; line--) {
+ if (psyData[ch]->mdctSpectrum[line] != FL2FXCONST_SGL(0.0f)) break;
+ }
+ if (line > hPsyConfLong->sfbOffset[sfb]) break;
+ }
+ maxSfbPerGroup[ch] = sfb + 1;
+ maxSfbPerGroup[ch] =
+ fixMax(fixMin(5, psyData[ch]->sfbActive), maxSfbPerGroup[ch]);
+
+ /* sfbNrgLdData is calculated in FDKaacEnc_advancePsychLong, copy in
+ * psyOut structure */
+ FDKmemcpy(psyOutChannel[ch]->sfbEnergyLdData,
+ psyData[ch]->sfbEnergyLdData.Long,
+ psyData[ch]->sfbActive * sizeof(FIXP_DBL));
+
+ FDKmemcpy(psyOutChannel[ch]->sfbOffsets, hPsyConfLong->sfbOffset,
+ (MAX_GROUPED_SFB + 1) * sizeof(INT));
+
+ /* sfbMinSnrLdData modified in adjust threshold, copy necessary */
+ FDKmemcpy(psyOutChannel[ch]->sfbMinSnrLdData,
+ hPsyConfLong->sfbMinSnrLdData,
+ psyData[ch]->sfbActive * sizeof(FIXP_DBL));
+
+ /* sfbEnergyMSLdData ist already calculated in FDKaacEnc_CalcBandNrgMSOpt;
+ * only in long case */
+
+ /* calc sfbThrld and set Values smaller 2^-31 to 2^-33*/
+ LdDataVector(psyData[ch]->sfbThreshold.Long,
+ psyOutChannel[ch]->sfbThresholdLdData,
+ psyData[ch]->sfbActive);
+ for (i = 0; i < psyData[ch]->sfbActive; i++) {
+ psyOutChannel[ch]->sfbThresholdLdData[i] =
+ fixMax(psyOutChannel[ch]->sfbThresholdLdData[i],
+ FL2FXCONST_DBL(-0.515625f));
+ }
+ }
+ }
+
+ /*
+ Intensity parameter intialization.
+ */
+ for (ch = 0; ch < channels; ch++) {
+ FDKmemclear(psyOutChannel[ch]->isBook, MAX_GROUPED_SFB * sizeof(INT));
+ FDKmemclear(psyOutChannel[ch]->isScale, MAX_GROUPED_SFB * sizeof(INT));
+ }
+
+ for (ch = 0; ch < channels; ch++) {
+ INT win = (isShortWindow[ch] ? 1 : 0);
+ if (!psyStatic[ch]->isLFE) {
+ /* PNS Decision */
+ FDKaacEnc_PnsDetect(
+ &(psyConf[0].pnsConf), pnsData[ch],
+ psyStatic[ch]->blockSwitchingControl.lastWindowSequence,
+ psyData[ch]->sfbActive,
+ maxSfbPerGroup[ch], /* count of Sfb which are not zero. */
+ psyOutChannel[ch]->sfbThresholdLdData, psyConf[win].sfbOffset,
+ psyData[ch]->mdctSpectrum, psyData[ch]->sfbMaxScaleSpec.Long,
+ sfbTonality[ch], psyOutChannel[ch]->tnsInfo.order[0][0],
+ tnsData[ch]->dataRaw.Long.subBlockInfo.predictionGain[HIFILT],
+ tnsData[ch]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT],
+ psyOutChannel[ch]->sfbEnergyLdData, psyOutChannel[ch]->noiseNrg);
+ } /* !isLFE */
+ } /* ch */
+
+ /*
+ stereo Processing
+ */
+ if (channels == 2) {
+ psyOutElement->toolsInfo.msDigest = MS_NONE;
+ psyOutElement->commonWindow = commonWindow;
+ if (psyOutElement->commonWindow)
+ maxSfbPerGroup[0] = maxSfbPerGroup[1] =
+ fixMax(maxSfbPerGroup[0], maxSfbPerGroup[1]);
+ if (psyStatic[0]->blockSwitchingControl.lastWindowSequence !=
+ SHORT_WINDOW) {
+ /* PNS preprocessing depending on ms processing: PNS not in Short Window!
+ */
+ FDKaacEnc_PreProcessPnsChannelPair(
+ psyData[0]->sfbActive, (&psyData[0]->sfbEnergy)->Long,
+ (&psyData[1]->sfbEnergy)->Long, psyOutChannel[0]->sfbEnergyLdData,
+ psyOutChannel[1]->sfbEnergyLdData, psyData[0]->sfbEnergyMS.Long,
+ &(psyConf[0].pnsConf), pnsData[0], pnsData[1]);
+
+ FDKaacEnc_IntensityStereoProcessing(
+ psyData[0]->sfbEnergy.Long, psyData[1]->sfbEnergy.Long,
+ psyData[0]->mdctSpectrum, psyData[1]->mdctSpectrum,
+ psyData[0]->sfbThreshold.Long, psyData[1]->sfbThreshold.Long,
+ psyOutChannel[1]->sfbThresholdLdData,
+ psyData[0]->sfbSpreadEnergy.Long, psyData[1]->sfbSpreadEnergy.Long,
+ psyOutChannel[0]->sfbEnergyLdData, psyOutChannel[1]->sfbEnergyLdData,
+ &psyOutElement->toolsInfo.msDigest, psyOutElement->toolsInfo.msMask,
+ psyConf[0].sfbCnt, psyConf[0].sfbCnt, maxSfbPerGroup[0],
+ psyConf[0].sfbOffset,
+ psyConf[0].allowIS && psyOutElement->commonWindow,
+ psyOutChannel[1]->isBook, psyOutChannel[1]->isScale, pnsData);
+
+ FDKaacEnc_MsStereoProcessing(
+ psyData, psyOutChannel, psyOutChannel[1]->isBook,
+ &psyOutElement->toolsInfo.msDigest, psyOutElement->toolsInfo.msMask,
+ psyConf[0].allowMS, psyData[0]->sfbActive, psyData[0]->sfbActive,
+ maxSfbPerGroup[0], psyOutChannel[0]->sfbOffsets);
+
+ /* PNS postprocessing */
+ FDKaacEnc_PostProcessPnsChannelPair(
+ psyData[0]->sfbActive, &(psyConf[0].pnsConf), pnsData[0], pnsData[1],
+ psyOutElement->toolsInfo.msMask, &psyOutElement->toolsInfo.msDigest);
+
+ } else {
+ FDKaacEnc_IntensityStereoProcessing(
+ psyData[0]->sfbEnergy.Long, psyData[1]->sfbEnergy.Long,
+ psyData[0]->mdctSpectrum, psyData[1]->mdctSpectrum,
+ psyData[0]->sfbThreshold.Long, psyData[1]->sfbThreshold.Long,
+ psyOutChannel[1]->sfbThresholdLdData,
+ psyData[0]->sfbSpreadEnergy.Long, psyData[1]->sfbSpreadEnergy.Long,
+ psyOutChannel[0]->sfbEnergyLdData, psyOutChannel[1]->sfbEnergyLdData,
+ &psyOutElement->toolsInfo.msDigest, psyOutElement->toolsInfo.msMask,
+ psyStatic[0]->blockSwitchingControl.noOfGroups *
+ hPsyConfShort->sfbCnt,
+ psyConf[1].sfbCnt, maxSfbPerGroup[0], psyData[0]->groupedSfbOffset,
+ psyConf[0].allowIS && psyOutElement->commonWindow,
+ psyOutChannel[1]->isBook, psyOutChannel[1]->isScale, pnsData);
+
+ /* it's OK to pass the ".Long" arrays here. They contain grouped short
+ * data since FDKaacEnc_groupShortData() */
+ FDKaacEnc_MsStereoProcessing(
+ psyData, psyOutChannel, psyOutChannel[1]->isBook,
+ &psyOutElement->toolsInfo.msDigest, psyOutElement->toolsInfo.msMask,
+ psyConf[1].allowMS,
+ psyStatic[0]->blockSwitchingControl.noOfGroups *
+ hPsyConfShort->sfbCnt,
+ hPsyConfShort->sfbCnt, maxSfbPerGroup[0],
+ psyOutChannel[0]->sfbOffsets);
+ }
+ } /* (channels == 2) */
+
+ /*
+ PNS Coding
+ */
+ for (ch = 0; ch < channels; ch++) {
+ if (psyStatic[ch]->isLFE) {
+ /* no PNS coding */
+ for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) {
+ psyOutChannel[ch]->noiseNrg[sfb] = NO_NOISE_PNS;
+ }
+ } else {
+ FDKaacEnc_CodePnsChannel(
+ psyData[ch]->sfbActive, &(hThisPsyConf[ch]->pnsConf),
+ pnsData[ch]->pnsFlag, psyData[ch]->sfbEnergyLdData.Long,
+ psyOutChannel[ch]->noiseNrg, /* this is the energy that will be
+ written to the bitstream */
+ psyOutChannel[ch]->sfbThresholdLdData);
+ }
+ }
+
+ /*
+ build output
+ */
+ for (ch = 0; ch < channels; ch++) {
+ INT mask;
+ int grp;
+ psyOutChannel[ch]->maxSfbPerGroup = maxSfbPerGroup[ch];
+ psyOutChannel[ch]->mdctScale = psyData[ch]->mdctScale;
+ if (isShortWindow[ch] == 0) {
+ psyOutChannel[ch]->sfbCnt = hPsyConfLong->sfbActive;
+ psyOutChannel[ch]->sfbPerGroup = hPsyConfLong->sfbActive;
+ psyOutChannel[ch]->lastWindowSequence =
+ psyStatic[ch]->blockSwitchingControl.lastWindowSequence;
+ psyOutChannel[ch]->windowShape =
+ psyStatic[ch]->blockSwitchingControl.windowShape;
+ } else {
+ INT sfbCnt = psyStatic[ch]->blockSwitchingControl.noOfGroups *
+ hPsyConfShort->sfbCnt;
+
+ psyOutChannel[ch]->sfbCnt = sfbCnt;
+ psyOutChannel[ch]->sfbPerGroup = hPsyConfShort->sfbCnt;
+ psyOutChannel[ch]->lastWindowSequence = SHORT_WINDOW;
+ psyOutChannel[ch]->windowShape = SINE_WINDOW;
+ }
+ /* generate grouping mask */
+ mask = 0;
+ for (grp = 0; grp < psyStatic[ch]->blockSwitchingControl.noOfGroups;
+ grp++) {
+ int j;
+ mask <<= 1;
+ for (j = 1; j < psyStatic[ch]->blockSwitchingControl.groupLen[grp]; j++) {
+ mask = (mask << 1) | 1;
+ }
+ }
+ psyOutChannel[ch]->groupingMask = mask;
+
+ /* build interface */
+ FDKmemcpy(psyOutChannel[ch]->groupLen,
+ psyStatic[ch]->blockSwitchingControl.groupLen,
+ MAX_NO_OF_GROUPS * sizeof(INT));
+ FDKmemcpy(psyOutChannel[ch]->sfbEnergy, (&psyData[ch]->sfbEnergy)->Long,
+ MAX_GROUPED_SFB * sizeof(FIXP_DBL));
+ FDKmemcpy(psyOutChannel[ch]->sfbSpreadEnergy,
+ (&psyData[ch]->sfbSpreadEnergy)->Long,
+ MAX_GROUPED_SFB * sizeof(FIXP_DBL));
+ // FDKmemcpy(psyOutChannel[ch]->mdctSpectrum,
+ // psyData[ch]->mdctSpectrum, (1024)*sizeof(FIXP_DBL));
+ }
+
+ return AAC_ENC_OK;
+}
+
+void FDKaacEnc_PsyClose(PSY_INTERNAL **phPsyInternal, PSY_OUT **phPsyOut) {
+ int n, i;
+
+ if (phPsyInternal != NULL) {
+ PSY_INTERNAL *hPsyInternal = *phPsyInternal;
+
+ if (hPsyInternal) {
+ for (i = 0; i < (8); i++) {
+ if (hPsyInternal->pStaticChannels[i]) {
+ if (hPsyInternal->pStaticChannels[i]->psyInputBuffer)
+ FreeRam_aacEnc_PsyInputBuffer(
+ &hPsyInternal->pStaticChannels[i]
+ ->psyInputBuffer); /* AUDIO INPUT BUFFER */
+
+ FreeRam_aacEnc_PsyStatic(
+ &hPsyInternal->pStaticChannels[i]); /* PSY_STATIC */
+ }
+ }
+
+ for (i = 0; i < ((8)); i++) {
+ if (hPsyInternal->psyElement[i])
+ FreeRam_aacEnc_PsyElement(
+ &hPsyInternal->psyElement[i]); /* PSY_ELEMENT */
+ }
+
+ FreeRam_aacEnc_PsyInternal(phPsyInternal);
+ }
+ }
+
+ if (phPsyOut != NULL) {
+ for (n = 0; n < (1); n++) {
+ if (phPsyOut[n]) {
+ for (i = 0; i < (8); i++) {
+ if (phPsyOut[n]->pPsyOutChannels[i])
+ FreeRam_aacEnc_PsyOutChannel(
+ &phPsyOut[n]->pPsyOutChannels[i]); /* PSY_OUT_CHANNEL */
+ }
+
+ for (i = 0; i < ((8)); i++) {
+ if (phPsyOut[n]->psyOutElement[i])
+ FreeRam_aacEnc_PsyOutElements(
+ &phPsyOut[n]->psyOutElement[i]); /* PSY_OUT_ELEMENTS */
+ }
+
+ FreeRam_aacEnc_PsyOut(&phPsyOut[n]);
+ }
+ }
+ }
+}
diff --git a/fdk-aac/libAACenc/src/psy_main.h b/fdk-aac/libAACenc/src/psy_main.h
new file mode 100644
index 0000000..7cc01a3
--- /dev/null
+++ b/fdk-aac/libAACenc/src/psy_main.h
@@ -0,0 +1,161 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Psychoaccoustic major function block
+
+*******************************************************************************/
+
+#ifndef PSY_MAIN_H
+#define PSY_MAIN_H
+
+#include "psy_configuration.h"
+#include "qc_data.h"
+#include "aacenc_pns.h"
+
+/*
+ psych internal
+*/
+typedef struct {
+ PSY_STATIC *psyStatic[(2)];
+
+} PSY_ELEMENT;
+
+typedef struct {
+ PSY_DATA psyData[(2)];
+ TNS_DATA tnsData[(2)];
+ PNS_DATA pnsData[(2)];
+
+} PSY_DYNAMIC;
+
+typedef struct {
+ PSY_CONFIGURATION psyConf[2]; /* LONG / SHORT */
+ PSY_ELEMENT *psyElement[((8))];
+ PSY_STATIC *pStaticChannels[(8)];
+ PSY_DYNAMIC *psyDynamic;
+ INT granuleLength;
+
+} PSY_INTERNAL;
+
+AAC_ENCODER_ERROR FDKaacEnc_PsyNew(PSY_INTERNAL **phpsy, const INT nElements,
+ const INT nChannels, UCHAR *dynamic_RAM);
+
+AAC_ENCODER_ERROR FDKaacEnc_PsyOutNew(PSY_OUT **phpsyOut, const INT nElements,
+ const INT nChannels, const INT nSubFrames,
+ UCHAR *dynamic_RAM);
+
+AAC_ENCODER_ERROR FDKaacEnc_psyInit(PSY_INTERNAL *hPsy, PSY_OUT **phpsyOut,
+ const INT nSubFrames,
+ const INT nMaxChannels,
+ const AUDIO_OBJECT_TYPE audioObjectType,
+ CHANNEL_MAPPING *cm);
+
+AAC_ENCODER_ERROR FDKaacEnc_psyMainInit(
+ PSY_INTERNAL *hPsy, AUDIO_OBJECT_TYPE audioObjectType, CHANNEL_MAPPING *cm,
+ INT sampleRate, INT granuleLength, INT bitRate, INT tnsMask, INT bandwidth,
+ INT usePns, INT useIS, INT useMS, UINT syntaxFlags, ULONG initFlags);
+
+AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels, PSY_ELEMENT *psyElement,
+ PSY_DYNAMIC *psyDynamic,
+ PSY_CONFIGURATION *psyConf,
+ PSY_OUT_ELEMENT *psyOutElement,
+ INT_PCM *pInput, const UINT inputBufSize,
+ INT *chIdx, INT totalChannels);
+
+void FDKaacEnc_PsyClose(PSY_INTERNAL **phPsyInternal, PSY_OUT **phPsyOut);
+
+#endif /* PSY_MAIN_H */
diff --git a/fdk-aac/libAACenc/src/qc_data.h b/fdk-aac/libAACenc/src/qc_data.h
new file mode 100644
index 0000000..6e671ed
--- /dev/null
+++ b/fdk-aac/libAACenc/src/qc_data.h
@@ -0,0 +1,299 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Quantizing & coding data
+
+*******************************************************************************/
+
+#ifndef QC_DATA_H
+#define QC_DATA_H
+
+#include "aacenc.h"
+#include "psy_const.h"
+#include "dyn_bits.h"
+#include "adj_thr_data.h"
+#include "line_pe.h"
+#include "FDK_audio.h"
+#include "interface.h"
+
+typedef enum {
+ QCDATA_BR_MODE_INVALID = -1,
+ QCDATA_BR_MODE_CBR = 0, /* Constant bit rate, given average bitrate */
+ QCDATA_BR_MODE_VBR_1 = 1, /* Variable bit rate, very low */
+ QCDATA_BR_MODE_VBR_2 = 2, /* Variable bit rate, low */
+ QCDATA_BR_MODE_VBR_3 = 3, /* Variable bit rate, medium */
+ QCDATA_BR_MODE_VBR_4 = 4, /* Variable bit rate, high */
+ QCDATA_BR_MODE_VBR_5 = 5, /* Variable bit rate, very high */
+ QCDATA_BR_MODE_FF = 6, /* Fixed frame mode. */
+ QCDATA_BR_MODE_SFR = 7 /* Superframe mode. */
+
+} QCDATA_BR_MODE;
+
+typedef struct {
+ MP4_ELEMENT_ID elType;
+ INT instanceTag;
+ INT nChannelsInEl;
+ INT ChannelIndex[2];
+ FIXP_DBL relativeBits;
+} ELEMENT_INFO;
+
+typedef struct {
+ CHANNEL_MODE encMode;
+ INT nChannels;
+ INT nChannelsEff;
+ INT nElements;
+ ELEMENT_INFO elInfo[((8))];
+} CHANNEL_MAPPING;
+
+typedef struct {
+ INT paddingRest;
+} PADDING;
+
+/* Quantizing & coding stage */
+
+struct QC_INIT {
+ CHANNEL_MAPPING *channelMapping;
+ INT sceCpe; /* not used yet */
+ INT maxBits; /* maximum number of bits in reservoir */
+ INT averageBits; /* average number of bits we should use */
+ INT bitRes;
+ INT sampleRate; /* output sample rate */
+ INT isLowDelay; /* if set, calc bits2PE factor depending on samplerate */
+ INT staticBits; /* Bits per frame consumed by transport layers. */
+ QCDATA_BR_MODE bitrateMode;
+ INT meanPe;
+ INT chBitrate; /* Bitrate/channel */
+ INT invQuant;
+ INT maxIterations; /* Maximum number of allowed iterations before
+ FDKaacEnc_crashRecovery() is applied. */
+ FIXP_DBL maxBitFac;
+ INT bitrate;
+ INT nSubFrames; /* helper variable */
+ INT minBits; /* minimal number of bits in one frame*/
+ AACENC_BITRES_MODE bitResMode; /* 0: full bitreservoir, 1: reduced
+ bitreservoir, 2: disabled bitreservoir */
+ INT bitDistributionMode; /* Configure element-wise execution or execution over
+ all elements for the pe-dependent
+ threshold-adaption */
+
+ PADDING padding;
+};
+
+typedef struct {
+ FIXP_DBL mdctSpectrum[(1024)];
+
+ SHORT quantSpec[(1024)];
+
+ UINT maxValueInSfb[MAX_GROUPED_SFB];
+ INT scf[MAX_GROUPED_SFB];
+ INT globalGain;
+ SECTION_DATA sectionData;
+
+ FIXP_DBL sfbFormFactorLdData[MAX_GROUPED_SFB];
+
+ FIXP_DBL sfbThresholdLdData[MAX_GROUPED_SFB];
+ FIXP_DBL sfbMinSnrLdData[MAX_GROUPED_SFB];
+ FIXP_DBL sfbEnergyLdData[MAX_GROUPED_SFB];
+ FIXP_DBL sfbEnergy[MAX_GROUPED_SFB];
+ FIXP_DBL sfbWeightedEnergyLdData[MAX_GROUPED_SFB];
+
+ FIXP_DBL sfbEnFacLd[MAX_GROUPED_SFB];
+
+ FIXP_DBL sfbSpreadEnergy[MAX_GROUPED_SFB];
+
+} QC_OUT_CHANNEL;
+
+typedef struct {
+ EXT_PAYLOAD_TYPE type; /* type of the extension payload */
+ INT nPayloadBits; /* size of the payload */
+ UCHAR *pPayload; /* pointer to payload */
+
+} QC_OUT_EXTENSION;
+
+typedef struct {
+ INT staticBitsUsed; /* for verification purposes */
+ INT dynBitsUsed; /* for verification purposes */
+
+ INT extBitsUsed; /* bit consumption of extended fill elements */
+ INT nExtensions; /* number of extension payloads for this element */
+ QC_OUT_EXTENSION extension[(1)]; /* reffering extension payload */
+
+ INT grantedDynBits;
+
+ INT grantedPe;
+ INT grantedPeCorr;
+
+ PE_DATA peData;
+
+ QC_OUT_CHANNEL *qcOutChannel[(2)];
+
+ UCHAR
+ *dynMem_Ah_Flag; /* pointer to dynamic buffer used by AhFlag in function
+ FDKaacEnc_adaptThresholdsToPe() */
+ UCHAR
+ *dynMem_Thr_Exp; /* pointer to dynamic buffer used by ThrExp in function
+ FDKaacEnc_adaptThresholdsToPe() */
+ UCHAR *dynMem_SfbNActiveLinesLdData; /* pointer to dynamic buffer used by
+ sfbNActiveLinesLdData in function
+ FDKaacEnc_correctThresh() */
+
+} QC_OUT_ELEMENT;
+
+typedef struct {
+ QC_OUT_ELEMENT *qcElement[((8))];
+ QC_OUT_CHANNEL *pQcOutChannels[(8)];
+ QC_OUT_EXTENSION extension[(2 + 2)]; /* global extension payload */
+ INT nExtensions; /* number of extension payloads for this AU */
+ INT maxDynBits; /* maximal allowed dynamic bits in frame */
+ INT grantedDynBits; /* granted dynamic bits in frame */
+ INT totFillBits; /* fill bits */
+ INT elementExtBits; /* element associated extension payload bits, e.g. sbr,
+ drc ... */
+ INT globalExtBits; /* frame/au associated extension payload bits (anc data
+ ...) */
+ INT staticBits; /* aac side info bits */
+
+ INT totalNoRedPe;
+ INT totalGrantedPeCorr;
+
+ INT usedDynBits; /* number of dynamic bits in use */
+ INT alignBits; /* AU alignment bits */
+ INT totalBits; /* sum of static, dyn, sbr, fill, align and dse bits */
+
+} QC_OUT;
+
+typedef struct {
+ INT chBitrateEl; /* channel bitrate in element
+ (totalbitrate*el_relativeBits/el_channels) */
+ INT maxBitsEl; /* used in crash recovery */
+ INT bitResLevelEl; /* update bitreservoir level in each call of
+ FDKaacEnc_QCMain */
+ INT maxBitResBitsEl; /* nEffChannels*6144 - averageBitsInFrame */
+ FIXP_DBL relativeBitsEl; /* Bits relative to total Bits*/
+} ELEMENT_BITS;
+
+typedef struct {
+ /* this is basically struct QC_INIT */
+
+ INT globHdrBits;
+ INT maxBitsPerFrame; /* maximal allowed bits per frame, 6144*nChannelsEff */
+ INT minBitsPerFrame; /* minimal allowd bits per fram, superframing - DRM */
+ INT nElements;
+ QCDATA_BR_MODE bitrateMode;
+ AACENC_BITRES_MODE bitResMode; /* 0: full bitreservoir, 1: reduced
+ bitreservoir, 2: disabled bitreservoir */
+ INT bitResTot;
+ INT bitResTotMax;
+ INT maxIterations; /* Maximum number of allowed iterations before
+ FDKaacEnc_crashRecovery() is applied. */
+ INT invQuant;
+
+ FIXP_DBL vbrQualFactor;
+ FIXP_DBL maxBitFac;
+
+ PADDING padding;
+
+ ELEMENT_BITS *elementBits[((8))];
+ BITCNTR_STATE *hBitCounter;
+ ADJ_THR_STATE *hAdjThr;
+
+ INT dZoneQuantEnable; /* enable dead zone quantizer */
+
+} QC_STATE;
+
+#endif /* QC_DATA_H */
diff --git a/fdk-aac/libAACenc/src/qc_main.cpp b/fdk-aac/libAACenc/src/qc_main.cpp
new file mode 100644
index 0000000..0bf234c
--- /dev/null
+++ b/fdk-aac/libAACenc/src/qc_main.cpp
@@ -0,0 +1,1555 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Quantizing & coding
+
+*******************************************************************************/
+
+#include "qc_main.h"
+#include "quantize.h"
+#include "interface.h"
+#include "adj_thr.h"
+#include "sf_estim.h"
+#include "bit_cnt.h"
+#include "dyn_bits.h"
+#include "channel_map.h"
+#include "aacEnc_ram.h"
+
+#include "genericStds.h"
+
+#define AACENC_DZQ_BR_THR 32000 /* Dead zone quantizer bitrate threshold */
+
+typedef struct {
+ QCDATA_BR_MODE bitrateMode;
+ LONG vbrQualFactor;
+} TAB_VBR_QUAL_FACTOR;
+
+static const TAB_VBR_QUAL_FACTOR tableVbrQualFactor[] = {
+ {QCDATA_BR_MODE_VBR_1,
+ FL2FXCONST_DBL(0.160f)}, /* Approx. 32 - 48 (AC-LC), 32 - 56
+ (AAC-LD/ELD) kbps/channel */
+ {QCDATA_BR_MODE_VBR_2,
+ FL2FXCONST_DBL(0.148f)}, /* Approx. 40 - 56 (AC-LC), 40 - 64
+ (AAC-LD/ELD) kbps/channel */
+ {QCDATA_BR_MODE_VBR_3,
+ FL2FXCONST_DBL(0.135f)}, /* Approx. 48 - 64 (AC-LC), 48 - 72
+ (AAC-LD/ELD) kbps/channel */
+ {QCDATA_BR_MODE_VBR_4,
+ FL2FXCONST_DBL(0.111f)}, /* Approx. 64 - 80 (AC-LC), 64 - 88
+ (AAC-LD/ELD) kbps/channel */
+ {QCDATA_BR_MODE_VBR_5,
+ FL2FXCONST_DBL(0.070f)} /* Approx. 96 - 120 (AC-LC), 112 - 144
+ (AAC-LD/ELD) kbps/channel */
+};
+
+static INT isConstantBitrateMode(const QCDATA_BR_MODE bitrateMode) {
+ return (((bitrateMode == QCDATA_BR_MODE_CBR) ||
+ (bitrateMode == QCDATA_BR_MODE_SFR) ||
+ (bitrateMode == QCDATA_BR_MODE_FF))
+ ? 1
+ : 0);
+}
+
+typedef enum {
+ FRAME_LEN_BYTES_MODULO = 1,
+ FRAME_LEN_BYTES_INT = 2
+} FRAME_LEN_RESULT_MODE;
+
+/* forward declarations */
+
+static INT FDKaacEnc_calcMaxValueInSfb(INT sfbCnt, INT maxSfbPerGroup,
+ INT sfbPerGroup, INT* RESTRICT sfbOffset,
+ SHORT* RESTRICT quantSpectrum,
+ UINT* RESTRICT maxValue);
+
+static void FDKaacEnc_crashRecovery(INT nChannels,
+ PSY_OUT_ELEMENT* psyOutElement,
+ QC_OUT* qcOut, QC_OUT_ELEMENT* qcElement,
+ INT bitsToSave, AUDIO_OBJECT_TYPE aot,
+ UINT syntaxFlags, SCHAR epConfig);
+
+static AAC_ENCODER_ERROR FDKaacEnc_reduceBitConsumption(
+ int* iterations, const int maxIterations, int gainAdjustment,
+ int* chConstraintsFulfilled, int* calculateQuant, int nChannels,
+ PSY_OUT_ELEMENT* psyOutElement, QC_OUT* qcOut, QC_OUT_ELEMENT* qcOutElement,
+ ELEMENT_BITS* elBits, AUDIO_OBJECT_TYPE aot, UINT syntaxFlags,
+ SCHAR epConfig);
+
+void FDKaacEnc_QCClose(QC_STATE** phQCstate, QC_OUT** phQC);
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_calcFrameLen
+ description:
+ returns:
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_calcFrameLen(INT bitRate, INT sampleRate,
+ INT granuleLength,
+ FRAME_LEN_RESULT_MODE mode) {
+ INT result;
+
+ result = ((granuleLength) >> 3) * (bitRate);
+
+ switch (mode) {
+ case FRAME_LEN_BYTES_MODULO:
+ result %= sampleRate;
+ break;
+ case FRAME_LEN_BYTES_INT:
+ result /= sampleRate;
+ break;
+ }
+ return (result);
+}
+
+/*****************************************************************************
+
+ functionname:FDKaacEnc_framePadding
+ description: Calculates if padding is needed for actual frame
+ returns:
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_framePadding(INT bitRate, INT sampleRate,
+ INT granuleLength, INT* paddingRest) {
+ INT paddingOn;
+ INT difference;
+
+ paddingOn = 0;
+
+ difference = FDKaacEnc_calcFrameLen(bitRate, sampleRate, granuleLength,
+ FRAME_LEN_BYTES_MODULO);
+ *paddingRest -= difference;
+
+ if (*paddingRest <= 0) {
+ paddingOn = 1;
+ *paddingRest += sampleRate;
+ }
+
+ return (paddingOn);
+}
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_QCOutNew
+ description:
+ return:
+
+**********************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_QCOutNew(QC_OUT** phQC, const INT nElements,
+ const INT nChannels, const INT nSubFrames,
+ UCHAR* dynamic_RAM) {
+ AAC_ENCODER_ERROR ErrorStatus;
+ int n, i;
+ int elInc = 0, chInc = 0;
+
+ for (n = 0; n < nSubFrames; n++) {
+ phQC[n] = GetRam_aacEnc_QCout(n);
+ if (phQC[n] == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto QCOutNew_bail;
+ }
+
+ for (i = 0; i < nChannels; i++) {
+ phQC[n]->pQcOutChannels[i] = GetRam_aacEnc_QCchannel(chInc, dynamic_RAM);
+ if (phQC[n]->pQcOutChannels[i] == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto QCOutNew_bail;
+ }
+
+ chInc++;
+ } /* nChannels */
+
+ for (i = 0; i < nElements; i++) {
+ phQC[n]->qcElement[i] = GetRam_aacEnc_QCelement(elInc);
+ if (phQC[n]->qcElement[i] == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto QCOutNew_bail;
+ }
+ elInc++;
+
+ /* initialize pointer to dynamic buffer which are used in adjust
+ * thresholds */
+ phQC[n]->qcElement[i]->dynMem_Ah_Flag = dynamic_RAM + (P_BUF_1);
+ phQC[n]->qcElement[i]->dynMem_Thr_Exp =
+ dynamic_RAM + (P_BUF_1) + ADJ_THR_AH_FLAG_SIZE;
+ phQC[n]->qcElement[i]->dynMem_SfbNActiveLinesLdData =
+ dynamic_RAM + (P_BUF_1) + ADJ_THR_AH_FLAG_SIZE + ADJ_THR_THR_EXP_SIZE;
+
+ } /* nElements */
+
+ } /* nSubFrames */
+
+ return AAC_ENC_OK;
+
+QCOutNew_bail:
+ return ErrorStatus;
+}
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_QCOutInit
+ description:
+ return:
+
+**********************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_QCOutInit(QC_OUT* phQC[(1)], const INT nSubFrames,
+ const CHANNEL_MAPPING* cm) {
+ INT n, i, ch;
+
+ for (n = 0; n < nSubFrames; n++) {
+ INT chInc = 0;
+ for (i = 0; i < cm->nElements; i++) {
+ for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) {
+ phQC[n]->qcElement[i]->qcOutChannel[ch] =
+ phQC[n]->pQcOutChannels[chInc];
+ chInc++;
+ } /* chInEl */
+ } /* nElements */
+ } /* nSubFrames */
+
+ return AAC_ENC_OK;
+}
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_QCNew
+ description:
+ return:
+
+**********************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_QCNew(QC_STATE** phQC, INT nElements,
+ UCHAR* dynamic_RAM) {
+ AAC_ENCODER_ERROR ErrorStatus;
+ int i;
+
+ QC_STATE* hQC = GetRam_aacEnc_QCstate();
+ *phQC = hQC;
+ if (hQC == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto QCNew_bail;
+ }
+
+ if (FDKaacEnc_AdjThrNew(&hQC->hAdjThr, nElements)) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto QCNew_bail;
+ }
+
+ if (FDKaacEnc_BCNew(&(hQC->hBitCounter), dynamic_RAM)) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto QCNew_bail;
+ }
+
+ for (i = 0; i < nElements; i++) {
+ hQC->elementBits[i] = GetRam_aacEnc_ElementBits(i);
+ if (hQC->elementBits[i] == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto QCNew_bail;
+ }
+ }
+
+ return AAC_ENC_OK;
+
+QCNew_bail:
+ FDKaacEnc_QCClose(phQC, NULL);
+ return ErrorStatus;
+}
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_QCInit
+ description:
+ return:
+
+**********************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE* hQC, struct QC_INIT* init,
+ const ULONG initFlags) {
+ AAC_ENCODER_ERROR err = AAC_ENC_OK;
+
+ int i;
+ hQC->maxBitsPerFrame = init->maxBits;
+ hQC->minBitsPerFrame = init->minBits;
+ hQC->nElements = init->channelMapping->nElements;
+ if ((initFlags != 0) || ((init->bitrateMode != QCDATA_BR_MODE_FF) &&
+ (hQC->bitResTotMax != init->bitRes))) {
+ hQC->bitResTot = init->bitRes;
+ }
+ hQC->bitResTotMax = init->bitRes;
+ hQC->maxBitFac = init->maxBitFac;
+ hQC->bitrateMode = init->bitrateMode;
+ hQC->invQuant = init->invQuant;
+ hQC->maxIterations = init->maxIterations;
+
+ if (isConstantBitrateMode(hQC->bitrateMode)) {
+ /* 0: full bitreservoir, 1: reduced bitreservoir, 2: disabled bitreservoir
+ */
+ hQC->bitResMode = init->bitResMode;
+ } else {
+ hQC->bitResMode = AACENC_BR_MODE_FULL; /* full bitreservoir */
+ }
+
+ hQC->padding.paddingRest = init->padding.paddingRest;
+
+ hQC->globHdrBits = init->staticBits; /* Bit overhead due to transport */
+
+ err = FDKaacEnc_InitElementBits(
+ hQC, init->channelMapping, init->bitrate,
+ (init->averageBits / init->nSubFrames) - hQC->globHdrBits,
+ hQC->maxBitsPerFrame / init->channelMapping->nChannelsEff);
+ if (err != AAC_ENC_OK) goto bail;
+
+ hQC->vbrQualFactor = FL2FXCONST_DBL(0.f);
+ for (i = 0;
+ i < (int)(sizeof(tableVbrQualFactor) / sizeof(TAB_VBR_QUAL_FACTOR));
+ i++) {
+ if (hQC->bitrateMode == tableVbrQualFactor[i].bitrateMode) {
+ hQC->vbrQualFactor = (FIXP_DBL)tableVbrQualFactor[i].vbrQualFactor;
+ break;
+ }
+ }
+
+ if (init->channelMapping->nChannelsEff == 1 &&
+ (init->bitrate / init->channelMapping->nChannelsEff) <
+ AACENC_DZQ_BR_THR &&
+ init->isLowDelay !=
+ 0) /* watch out here: init->bitrate is the bitrate "minus" the
+ standard SBR bitrate (=2500kbps) --> for the FDK the OFFSTE
+ tuning should start somewhere below 32000kbps-2500kbps ... so
+ everything is fine here */
+ {
+ hQC->dZoneQuantEnable = 1;
+ } else {
+ hQC->dZoneQuantEnable = 0;
+ }
+
+ FDKaacEnc_AdjThrInit(
+ hQC->hAdjThr, init->meanPe, hQC->invQuant, init->channelMapping,
+ init->sampleRate, /* output sample rate */
+ init->bitrate, /* total bitrate */
+ init->isLowDelay, /* if set, calc bits2PE factor
+ depending on samplerate */
+ init->bitResMode /* for a small bitreservoir, the pe
+ correction is calc'd differently */
+ ,
+ hQC->dZoneQuantEnable, init->bitDistributionMode, hQC->vbrQualFactor);
+
+bail:
+ return err;
+}
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_QCMainPrepare
+ description:
+ return:
+
+**********************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_QCMainPrepare(
+ ELEMENT_INFO* elInfo, ATS_ELEMENT* RESTRICT adjThrStateElement,
+ PSY_OUT_ELEMENT* RESTRICT psyOutElement,
+ QC_OUT_ELEMENT* RESTRICT qcOutElement, AUDIO_OBJECT_TYPE aot,
+ UINT syntaxFlags, SCHAR epConfig) {
+ AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
+ INT nChannels = elInfo->nChannelsInEl;
+
+ PSY_OUT_CHANNEL** RESTRICT psyOutChannel =
+ psyOutElement->psyOutChannel; /* may be modified in-place */
+
+ FDKaacEnc_CalcFormFactor(qcOutElement->qcOutChannel, psyOutChannel,
+ nChannels);
+
+ /* prepare and calculate PE without reduction */
+ FDKaacEnc_peCalculation(&qcOutElement->peData, psyOutChannel,
+ qcOutElement->qcOutChannel, &psyOutElement->toolsInfo,
+ adjThrStateElement, nChannels);
+
+ ErrorStatus = FDKaacEnc_ChannelElementWrite(
+ NULL, elInfo, NULL, psyOutElement, psyOutElement->psyOutChannel,
+ syntaxFlags, aot, epConfig, &qcOutElement->staticBitsUsed, 0);
+
+ return ErrorStatus;
+}
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_AdjustBitrate
+ description: adjusts framelength via padding on a frame to frame
+basis, to achieve a bitrate that demands a non byte aligned framelength return:
+errorcode
+
+**********************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_AdjustBitrate(
+ QC_STATE* RESTRICT hQC, CHANNEL_MAPPING* RESTRICT cm, INT* avgTotalBits,
+ INT bitRate, /* total bitrate */
+ INT sampleRate, /* output sampling rate */
+ INT granuleLength) /* frame length */
+{
+ INT paddingOn;
+ INT frameLen;
+ //fprintf(stderr, "hQC->padding.paddingRest=%d bytes! (before)\n", hQC->padding.paddingRest);
+
+ /* Do we need an extra padding byte? */
+ paddingOn = FDKaacEnc_framePadding(bitRate, sampleRate, granuleLength,
+ &hQC->padding.paddingRest);
+
+ frameLen =
+ paddingOn + FDKaacEnc_calcFrameLen(bitRate, sampleRate, granuleLength,
+ FRAME_LEN_BYTES_INT);
+
+ *avgTotalBits = frameLen << 3;
+
+ return AAC_ENC_OK;
+}
+
+#define isAudioElement(elType) \
+ ((elType == ID_SCE) || (elType == ID_CPE) || (elType == ID_LFE))
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_distributeElementDynBits
+ description: distributes all bits over all elements. The relative bit
+ distibution is described in the ELEMENT_INFO of the
+ appropriate element. The bit distribution table is
+ initialized in FDKaacEnc_InitChannelMapping().
+ return: errorcode
+
+**********************************************************************************/
+static AAC_ENCODER_ERROR FDKaacEnc_distributeElementDynBits(
+ QC_STATE* hQC, QC_OUT_ELEMENT* qcElement[((8))], CHANNEL_MAPPING* cm,
+ INT codeBits) {
+ INT i; /* counter variable */
+ INT totalBits = 0; /* sum of bits over all elements */
+
+ for (i = (cm->nElements - 1); i >= 0; i--) {
+ if (isAudioElement(cm->elInfo[i].elType)) {
+ qcElement[i]->grantedDynBits =
+ fMax(0, fMultI(hQC->elementBits[i]->relativeBitsEl, codeBits));
+ totalBits += qcElement[i]->grantedDynBits;
+ }
+ }
+
+ /* Due to inaccuracies with the multiplication, codeBits may differ from
+ totalBits. For that case, the difference must be added/substracted again
+ to/from one element, i.e:
+ Negative differences are substracted from the element with the most bits.
+ Positive differences are added to the element with the least bits.
+ */
+ if (codeBits != totalBits) {
+ INT elMaxBits = cm->nElements - 1; /* element with the most bits */
+ INT elMinBits = cm->nElements - 1; /* element with the least bits */
+
+ /* Search for biggest and smallest audio element */
+ for (i = (cm->nElements - 1); i >= 0; i--) {
+ if (isAudioElement(cm->elInfo[i].elType)) {
+ if (qcElement[i]->grantedDynBits >
+ qcElement[elMaxBits]->grantedDynBits) {
+ elMaxBits = i;
+ }
+ if (qcElement[i]->grantedDynBits <
+ qcElement[elMinBits]->grantedDynBits) {
+ elMinBits = i;
+ }
+ }
+ }
+ /* Compensate for bit distibution difference */
+ if (codeBits - totalBits > 0) {
+ qcElement[elMinBits]->grantedDynBits += codeBits - totalBits;
+ } else {
+ qcElement[elMaxBits]->grantedDynBits += codeBits - totalBits;
+ }
+ }
+
+ return AAC_ENC_OK;
+}
+
+/**
+ * \brief Verify whether minBitsPerFrame criterion can be satisfied.
+ *
+ * This function evaluates the bit consumption only if minBitsPerFrame parameter
+ * is not 0. In hyperframing mode the difference between grantedDynBits and
+ * usedDynBits of all sub frames results the number of fillbits to be written.
+ * This bits can be distrubitued in superframe to reach minBitsPerFrame bit
+ * consumption in single AU's. The return value denotes if enough desired fill
+ * bits are available to achieve minBitsPerFrame in all frames. This check can
+ * only be used within superframes.
+ *
+ * \param qcOut Pointer to coding data struct.
+ * \param minBitsPerFrame Minimal number of bits to be consumed in each frame.
+ * \param nSubFrames Number of frames in superframe
+ *
+ * \return
+ * - 1: all fine
+ * - 0: criterion not fulfilled
+ */
+static int checkMinFrameBitsDemand(QC_OUT** qcOut, const INT minBitsPerFrame,
+ const INT nSubFrames) {
+ int result = 1; /* all fine*/
+ return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/*********************************************************************************
+
+ functionname: FDKaacEnc_getMinimalStaticBitdemand
+ description: calculate minmal size of static bits by reduction ,
+ to zero spectrum and deactivating tns and MS
+ return: number of static bits
+
+**********************************************************************************/
+static int FDKaacEnc_getMinimalStaticBitdemand(CHANNEL_MAPPING* cm,
+ PSY_OUT** psyOut) {
+ AUDIO_OBJECT_TYPE aot = AOT_AAC_LC;
+ UINT syntaxFlags = 0;
+ SCHAR epConfig = -1;
+ int i, bitcount = 0;
+
+ for (i = 0; i < cm->nElements; i++) {
+ ELEMENT_INFO elInfo = cm->elInfo[i];
+
+ if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
+ (elInfo.elType == ID_LFE)) {
+ INT minElBits = 0;
+
+ FDKaacEnc_ChannelElementWrite(NULL, &elInfo, NULL,
+ psyOut[0]->psyOutElement[i],
+ psyOut[0]->psyOutElement[i]->psyOutChannel,
+ syntaxFlags, aot, epConfig, &minElBits, 1);
+ bitcount += minElBits;
+ }
+ }
+
+ return bitcount;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static AAC_ENCODER_ERROR FDKaacEnc_prepareBitDistribution(
+ QC_STATE* hQC, PSY_OUT** psyOut, QC_OUT** qcOut, CHANNEL_MAPPING* cm,
+ QC_OUT_ELEMENT* qcElement[(1)][((8))], INT avgTotalBits,
+ INT* totalAvailableBits, INT* avgTotalDynBits) {
+ int i;
+ /* get maximal allowed dynamic bits */
+ qcOut[0]->grantedDynBits =
+ (fixMin(hQC->maxBitsPerFrame, avgTotalBits) - hQC->globHdrBits) & ~7;
+ qcOut[0]->grantedDynBits -= (qcOut[0]->globalExtBits + qcOut[0]->staticBits +
+ qcOut[0]->elementExtBits);
+ qcOut[0]->maxDynBits = ((hQC->maxBitsPerFrame) & ~7) -
+ (qcOut[0]->globalExtBits + qcOut[0]->staticBits +
+ qcOut[0]->elementExtBits);
+ /* assure that enough bits are available */
+ if ((qcOut[0]->grantedDynBits + hQC->bitResTot) < 0) {
+ /* crash recovery allows to reduce static bits to a minimum */
+ if ((qcOut[0]->grantedDynBits + hQC->bitResTot) <
+ (FDKaacEnc_getMinimalStaticBitdemand(cm, psyOut) -
+ qcOut[0]->staticBits))
+ return AAC_ENC_BITRES_TOO_LOW;
+ }
+
+ /* distribute dynamic bits to each element */
+ FDKaacEnc_distributeElementDynBits(hQC, qcElement[0], cm,
+ qcOut[0]->grantedDynBits);
+
+ *avgTotalDynBits = 0; /*frameDynBits;*/
+
+ *totalAvailableBits = avgTotalBits;
+
+ /* sum up corrected granted PE */
+ qcOut[0]->totalGrantedPeCorr = 0;
+
+ for (i = 0; i < cm->nElements; i++) {
+ ELEMENT_INFO elInfo = cm->elInfo[i];
+ int nChannels = elInfo.nChannelsInEl;
+
+ if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
+ (elInfo.elType == ID_LFE)) {
+ /* for ( all sub frames ) ... */
+ FDKaacEnc_DistributeBits(
+ hQC->hAdjThr, hQC->hAdjThr->adjThrStateElem[i],
+ psyOut[0]->psyOutElement[i]->psyOutChannel, &qcElement[0][i]->peData,
+ &qcElement[0][i]->grantedPe, &qcElement[0][i]->grantedPeCorr,
+ nChannels, psyOut[0]->psyOutElement[i]->commonWindow,
+ qcElement[0][i]->grantedDynBits, hQC->elementBits[i]->bitResLevelEl,
+ hQC->elementBits[i]->maxBitResBitsEl, hQC->maxBitFac,
+ hQC->bitResMode);
+
+ *totalAvailableBits += hQC->elementBits[i]->bitResLevelEl;
+ /* get total corrected granted PE */
+ qcOut[0]->totalGrantedPeCorr += qcElement[0][i]->grantedPeCorr;
+ } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */
+
+ } /* -end- element loop */
+
+ *totalAvailableBits = fMin(hQC->maxBitsPerFrame, (*totalAvailableBits));
+
+ return AAC_ENC_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static AAC_ENCODER_ERROR FDKaacEnc_updateUsedDynBits(
+ INT* sumDynBitsConsumed, QC_OUT_ELEMENT* qcElement[((8))],
+ CHANNEL_MAPPING* cm) {
+ INT i;
+
+ *sumDynBitsConsumed = 0;
+
+ for (i = 0; i < cm->nElements; i++) {
+ ELEMENT_INFO elInfo = cm->elInfo[i];
+
+ if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
+ (elInfo.elType == ID_LFE)) {
+ /* sum up bits consumed */
+ *sumDynBitsConsumed += qcElement[i]->dynBitsUsed;
+ } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */
+
+ } /* -end- element loop */
+
+ return AAC_ENC_OK;
+}
+
+static INT FDKaacEnc_getTotalConsumedDynBits(QC_OUT** qcOut, INT nSubFrames) {
+ INT c, totalBits = 0;
+
+ /* sum up bit consumption for all sub frames */
+ for (c = 0; c < nSubFrames; c++) {
+ /* bit consumption not valid if dynamic bits
+ not available in one sub frame */
+ if (qcOut[c]->usedDynBits == -1) return -1;
+ totalBits += qcOut[c]->usedDynBits;
+ }
+
+ return totalBits;
+}
+
+static INT FDKaacEnc_getTotalConsumedBits(QC_OUT** qcOut,
+ QC_OUT_ELEMENT* qcElement[(1)][((8))],
+ CHANNEL_MAPPING* cm, INT globHdrBits,
+ INT nSubFrames) {
+ int c, i;
+ int totalUsedBits = 0;
+
+ for (c = 0; c < nSubFrames; c++) {
+ int dataBits = 0;
+ for (i = 0; i < cm->nElements; i++) {
+ if ((cm->elInfo[i].elType == ID_SCE) ||
+ (cm->elInfo[i].elType == ID_CPE) ||
+ (cm->elInfo[i].elType == ID_LFE)) {
+ dataBits += qcElement[c][i]->dynBitsUsed +
+ qcElement[c][i]->staticBitsUsed +
+ qcElement[c][i]->extBitsUsed;
+ }
+ }
+ dataBits += qcOut[c]->globalExtBits;
+
+ totalUsedBits += (8 - (dataBits) % 8) % 8;
+ totalUsedBits += dataBits + globHdrBits; /* header bits for every frame */
+ }
+ return totalUsedBits;
+}
+
+static AAC_ENCODER_ERROR FDKaacEnc_BitResRedistribution(
+ QC_STATE* const hQC, const CHANNEL_MAPPING* const cm,
+ const INT avgTotalBits) {
+ /* check bitreservoir fill level */
+ if (hQC->bitResTot < 0) {
+ return AAC_ENC_BITRES_TOO_LOW;
+ } else if (hQC->bitResTot > hQC->bitResTotMax) {
+ return AAC_ENC_BITRES_TOO_HIGH;
+ } else {
+ INT i;
+ INT totalBits = 0, totalBits_max = 0;
+
+ const int totalBitreservoir =
+ fMin(hQC->bitResTot, (hQC->maxBitsPerFrame - avgTotalBits));
+ const int totalBitreservoirMax =
+ fMin(hQC->bitResTotMax, (hQC->maxBitsPerFrame - avgTotalBits));
+
+ for (i = (cm->nElements - 1); i >= 0; i--) {
+ if ((cm->elInfo[i].elType == ID_SCE) ||
+ (cm->elInfo[i].elType == ID_CPE) ||
+ (cm->elInfo[i].elType == ID_LFE)) {
+ hQC->elementBits[i]->bitResLevelEl =
+ fMultI(hQC->elementBits[i]->relativeBitsEl, totalBitreservoir);
+ totalBits += hQC->elementBits[i]->bitResLevelEl;
+
+ hQC->elementBits[i]->maxBitResBitsEl =
+ fMultI(hQC->elementBits[i]->relativeBitsEl, totalBitreservoirMax);
+ totalBits_max += hQC->elementBits[i]->maxBitResBitsEl;
+ }
+ }
+ for (i = 0; i < cm->nElements; i++) {
+ if ((cm->elInfo[i].elType == ID_SCE) ||
+ (cm->elInfo[i].elType == ID_CPE) ||
+ (cm->elInfo[i].elType == ID_LFE)) {
+ int deltaBits = fMax(totalBitreservoir - totalBits,
+ -hQC->elementBits[i]->bitResLevelEl);
+ hQC->elementBits[i]->bitResLevelEl += deltaBits;
+ totalBits += deltaBits;
+
+ deltaBits = fMax(totalBitreservoirMax - totalBits_max,
+ -hQC->elementBits[i]->maxBitResBitsEl);
+ hQC->elementBits[i]->maxBitResBitsEl += deltaBits;
+ totalBits_max += deltaBits;
+ }
+ }
+ }
+
+ return AAC_ENC_OK;
+}
+
+AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC, PSY_OUT** psyOut,
+ QC_OUT** qcOut, INT avgTotalBits,
+ CHANNEL_MAPPING* cm,
+ const AUDIO_OBJECT_TYPE aot,
+ UINT syntaxFlags, SCHAR epConfig) {
+ int i, c;
+ AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
+ INT avgTotalDynBits = 0; /* maximal allowed dynamic bits for all frames */
+ INT totalAvailableBits = 0;
+ INT nSubFrames = 1;
+
+ /*-------------------------------------------- */
+ /* redistribute total bitreservoir to elements */
+ ErrorStatus = FDKaacEnc_BitResRedistribution(hQC, cm, avgTotalBits);
+ if (ErrorStatus != AAC_ENC_OK) {
+ return ErrorStatus;
+ }
+
+ /*-------------------------------------------- */
+ /* fastenc needs one time threshold simulation,
+ in case of multiple frames, one more guess has to be calculated */
+
+ /*-------------------------------------------- */
+ /* helper pointer */
+ QC_OUT_ELEMENT* qcElement[(1)][((8))];
+
+ /* work on a copy of qcChannel and qcElement */
+ for (i = 0; i < cm->nElements; i++) {
+ ELEMENT_INFO elInfo = cm->elInfo[i];
+
+ if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
+ (elInfo.elType == ID_LFE)) {
+ /* for ( all sub frames ) ... */
+ for (c = 0; c < nSubFrames; c++) {
+ { qcElement[c][i] = qcOut[c]->qcElement[i]; }
+ }
+ }
+ }
+
+ /*-------------------------------------------- */
+ /*-------------------------------------------- */
+ if (isConstantBitrateMode(hQC->bitrateMode)) {
+ /* calc granted dynamic bits for sub frame and
+ distribute it to each element */
+ ErrorStatus = FDKaacEnc_prepareBitDistribution(
+ hQC, psyOut, qcOut, cm, qcElement, avgTotalBits, &totalAvailableBits,
+ &avgTotalDynBits);
+
+ if (ErrorStatus != AAC_ENC_OK) {
+ return ErrorStatus;
+ }
+ } else {
+ qcOut[0]->grantedDynBits =
+ ((hQC->maxBitsPerFrame - (hQC->globHdrBits)) & ~7) -
+ (qcOut[0]->globalExtBits + qcOut[0]->staticBits +
+ qcOut[0]->elementExtBits);
+ qcOut[0]->maxDynBits = qcOut[0]->grantedDynBits;
+
+ totalAvailableBits = hQC->maxBitsPerFrame;
+ avgTotalDynBits = 0;
+ }
+
+ /* for ( all sub frames ) ... */
+ for (c = 0; c < nSubFrames; c++) {
+ /* for CBR and VBR mode */
+ FDKaacEnc_AdjustThresholds(hQC->hAdjThr, qcElement[c], qcOut[c],
+ psyOut[c]->psyOutElement,
+ isConstantBitrateMode(hQC->bitrateMode), cm);
+
+ } /* -end- sub frame counter */
+
+ /*-------------------------------------------- */
+ INT iterations[(1)][((8))];
+ INT chConstraintsFulfilled[(1)][((8))][(2)];
+ INT calculateQuant[(1)][((8))][(2)];
+ INT constraintsFulfilled[(1)][((8))];
+ /*-------------------------------------------- */
+
+ /* for ( all sub frames ) ... */
+ for (c = 0; c < nSubFrames; c++) {
+ for (i = 0; i < cm->nElements; i++) {
+ ELEMENT_INFO elInfo = cm->elInfo[i];
+ INT ch, nChannels = elInfo.nChannelsInEl;
+
+ if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
+ (elInfo.elType == ID_LFE)) {
+ /* Turn thresholds into scalefactors, optimize bit consumption and
+ * verify conformance */
+ FDKaacEnc_EstimateScaleFactors(
+ psyOut[c]->psyOutElement[i]->psyOutChannel,
+ qcElement[c][i]->qcOutChannel, hQC->invQuant, hQC->dZoneQuantEnable,
+ cm->elInfo[i].nChannelsInEl);
+
+ /*-------------------------------------------- */
+ constraintsFulfilled[c][i] = 1;
+ iterations[c][i] = 0;
+
+ for (ch = 0; ch < nChannels; ch++) {
+ chConstraintsFulfilled[c][i][ch] = 1;
+ calculateQuant[c][i][ch] = 1;
+ }
+
+ /*-------------------------------------------- */
+
+ } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */
+
+ } /* -end- element loop */
+
+ qcOut[c]->usedDynBits = -1;
+
+ } /* -end- sub frame counter */
+
+ INT quantizationDone = 0;
+ INT sumDynBitsConsumedTotal = 0;
+ INT decreaseBitConsumption = -1; /* no direction yet! */
+
+ /*-------------------------------------------- */
+ /* -start- Quantization loop ... */
+ /*-------------------------------------------- */
+ do /* until max allowed bits per frame and maxDynBits!=-1*/
+ {
+ quantizationDone = 0;
+
+ c = 0; /* get frame to process */
+
+ for (i = 0; i < cm->nElements; i++) {
+ ELEMENT_INFO elInfo = cm->elInfo[i];
+ INT ch, nChannels = elInfo.nChannelsInEl;
+
+ if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
+ (elInfo.elType == ID_LFE)) {
+ do /* until element bits < nChannels*MIN_BUFSIZE_PER_EFF_CHAN */
+ {
+ do /* until spectral values < MAX_QUANT */
+ {
+ /*-------------------------------------------- */
+ if (!constraintsFulfilled[c][i]) {
+ if ((ErrorStatus = FDKaacEnc_reduceBitConsumption(
+ &iterations[c][i], hQC->maxIterations,
+ (decreaseBitConsumption) ? 1 : -1,
+ chConstraintsFulfilled[c][i], calculateQuant[c][i],
+ nChannels, psyOut[c]->psyOutElement[i], qcOut[c],
+ qcElement[c][i], hQC->elementBits[i], aot, syntaxFlags,
+ epConfig)) != AAC_ENC_OK) {
+ return ErrorStatus;
+ }
+ }
+
+ /*-------------------------------------------- */
+ /*-------------------------------------------- */
+ constraintsFulfilled[c][i] = 1;
+
+ /*-------------------------------------------- */
+ /* quantize spectrum (per each channel) */
+ for (ch = 0; ch < nChannels; ch++) {
+ /*-------------------------------------------- */
+ chConstraintsFulfilled[c][i][ch] = 1;
+
+ /*-------------------------------------------- */
+
+ if (calculateQuant[c][i][ch]) {
+ QC_OUT_CHANNEL* qcOutCh = qcElement[c][i]->qcOutChannel[ch];
+ PSY_OUT_CHANNEL* psyOutCh =
+ psyOut[c]->psyOutElement[i]->psyOutChannel[ch];
+
+ calculateQuant[c][i][ch] =
+ 0; /* calculate quantization only if necessary */
+
+ /*-------------------------------------------- */
+ FDKaacEnc_QuantizeSpectrum(
+ psyOutCh->sfbCnt, psyOutCh->maxSfbPerGroup,
+ psyOutCh->sfbPerGroup, psyOutCh->sfbOffsets,
+ qcOutCh->mdctSpectrum, qcOutCh->globalGain, qcOutCh->scf,
+ qcOutCh->quantSpec, hQC->dZoneQuantEnable);
+
+ /*-------------------------------------------- */
+ if (FDKaacEnc_calcMaxValueInSfb(
+ psyOutCh->sfbCnt, psyOutCh->maxSfbPerGroup,
+ psyOutCh->sfbPerGroup, psyOutCh->sfbOffsets,
+ qcOutCh->quantSpec,
+ qcOutCh->maxValueInSfb) > MAX_QUANT) {
+ chConstraintsFulfilled[c][i][ch] = 0;
+ constraintsFulfilled[c][i] = 0;
+ /* if quanizted value out of range; increase global gain! */
+ decreaseBitConsumption = 1;
+ }
+
+ /*-------------------------------------------- */
+
+ } /* if calculateQuant[c][i][ch] */
+
+ } /* channel loop */
+
+ /*-------------------------------------------- */
+ /* quantize spectrum (per each channel) */
+
+ /*-------------------------------------------- */
+
+ } while (!constraintsFulfilled[c][i]); /* does not regard bit
+ consumption */
+
+ /*-------------------------------------------- */
+ /*-------------------------------------------- */
+ qcElement[c][i]->dynBitsUsed = 0; /* reset dynamic bits */
+
+ /* quantization valid in current channel! */
+ for (ch = 0; ch < nChannels; ch++) {
+ QC_OUT_CHANNEL* qcOutCh = qcElement[c][i]->qcOutChannel[ch];
+ PSY_OUT_CHANNEL* psyOutCh =
+ psyOut[c]->psyOutElement[i]->psyOutChannel[ch];
+
+ /* count dynamic bits */
+ INT chDynBits = FDKaacEnc_dynBitCount(
+ hQC->hBitCounter, qcOutCh->quantSpec, qcOutCh->maxValueInSfb,
+ qcOutCh->scf, psyOutCh->lastWindowSequence, psyOutCh->sfbCnt,
+ psyOutCh->maxSfbPerGroup, psyOutCh->sfbPerGroup,
+ psyOutCh->sfbOffsets, &qcOutCh->sectionData, psyOutCh->noiseNrg,
+ psyOutCh->isBook, psyOutCh->isScale, syntaxFlags);
+
+ /* sum up dynamic channel bits */
+ qcElement[c][i]->dynBitsUsed += chDynBits;
+ }
+
+ /* save dynBitsUsed for correction of bits2pe relation */
+ if (hQC->hAdjThr->adjThrStateElem[i]->dynBitsLast == -1) {
+ hQC->hAdjThr->adjThrStateElem[i]->dynBitsLast =
+ qcElement[c][i]->dynBitsUsed;
+ }
+
+ /* hold total bit consumption in present element below maximum allowed
+ */
+ if (qcElement[c][i]->dynBitsUsed >
+ ((nChannels * MIN_BUFSIZE_PER_EFF_CHAN) -
+ qcElement[c][i]->staticBitsUsed -
+ qcElement[c][i]->extBitsUsed)) {
+ constraintsFulfilled[c][i] = 0;
+ }
+
+ } while (!constraintsFulfilled[c][i]);
+
+ } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */
+
+ } /* -end- element loop */
+
+ /* update dynBits of current subFrame */
+ FDKaacEnc_updateUsedDynBits(&qcOut[c]->usedDynBits, qcElement[c], cm);
+
+ /* get total consumed bits, dyn bits in all sub frames have to be valid */
+ sumDynBitsConsumedTotal =
+ FDKaacEnc_getTotalConsumedDynBits(qcOut, nSubFrames);
+
+ if (sumDynBitsConsumedTotal == -1) {
+ quantizationDone = 0; /* bit consumption not valid in all sub frames */
+ } else {
+ int sumBitsConsumedTotal = FDKaacEnc_getTotalConsumedBits(
+ qcOut, qcElement, cm, hQC->globHdrBits, nSubFrames);
+
+ /* in all frames are valid dynamic bits */
+ if (((sumBitsConsumedTotal < totalAvailableBits) ||
+ sumDynBitsConsumedTotal == 0) &&
+ (decreaseBitConsumption == 1) &&
+ checkMinFrameBitsDemand(qcOut, hQC->minBitsPerFrame, nSubFrames)
+ /*()*/) {
+ quantizationDone = 1; /* exit bit adjustment */
+ }
+ if (sumBitsConsumedTotal > totalAvailableBits &&
+ (decreaseBitConsumption == 0)) {
+ quantizationDone = 0; /* reset! */
+ }
+ }
+
+ /*-------------------------------------------- */
+
+ int emergencyIterations = 1;
+ int dynBitsOvershoot = 0;
+
+ for (c = 0; c < nSubFrames; c++) {
+ for (i = 0; i < cm->nElements; i++) {
+ ELEMENT_INFO elInfo = cm->elInfo[i];
+
+ if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
+ (elInfo.elType == ID_LFE)) {
+ /* iteration limitation */
+ emergencyIterations &=
+ ((iterations[c][i] < hQC->maxIterations) ? 0 : 1);
+ }
+ }
+ /* detection if used dyn bits exceeds the maximal allowed criterion */
+ dynBitsOvershoot |=
+ ((qcOut[c]->usedDynBits > qcOut[c]->maxDynBits) ? 1 : 0);
+ }
+
+ if (quantizationDone == 0 || dynBitsOvershoot) {
+ int sumBitsConsumedTotal = FDKaacEnc_getTotalConsumedBits(
+ qcOut, qcElement, cm, hQC->globHdrBits, nSubFrames);
+
+ if ((sumDynBitsConsumedTotal >= avgTotalDynBits) ||
+ (sumDynBitsConsumedTotal == 0)) {
+ quantizationDone = 1;
+ }
+ if (emergencyIterations && (sumBitsConsumedTotal < totalAvailableBits)) {
+ quantizationDone = 1;
+ }
+ if ((sumBitsConsumedTotal > totalAvailableBits) ||
+ !checkMinFrameBitsDemand(qcOut, hQC->minBitsPerFrame, nSubFrames)) {
+ quantizationDone = 0;
+ }
+ if ((sumBitsConsumedTotal < totalAvailableBits) &&
+ checkMinFrameBitsDemand(qcOut, hQC->minBitsPerFrame, nSubFrames)) {
+ decreaseBitConsumption = 0;
+ } else {
+ decreaseBitConsumption = 1;
+ }
+
+ if (dynBitsOvershoot) {
+ quantizationDone = 0;
+ decreaseBitConsumption = 1;
+ }
+
+ /* reset constraints fullfilled flags */
+ FDKmemclear(constraintsFulfilled, sizeof(constraintsFulfilled));
+ FDKmemclear(chConstraintsFulfilled, sizeof(chConstraintsFulfilled));
+
+ } /* quantizationDone */
+
+ } while (!quantizationDone);
+
+ /*-------------------------------------------- */
+ /* ... -end- Quantization loop */
+ /*-------------------------------------------- */
+
+ /*-------------------------------------------- */
+ /*-------------------------------------------- */
+
+ return AAC_ENC_OK;
+}
+
+static AAC_ENCODER_ERROR FDKaacEnc_reduceBitConsumption(
+ int* iterations, const int maxIterations, int gainAdjustment,
+ int* chConstraintsFulfilled, int* calculateQuant, int nChannels,
+ PSY_OUT_ELEMENT* psyOutElement, QC_OUT* qcOut, QC_OUT_ELEMENT* qcOutElement,
+ ELEMENT_BITS* elBits, AUDIO_OBJECT_TYPE aot, UINT syntaxFlags,
+ SCHAR epConfig) {
+ int ch;
+
+ /** SOLVING PROBLEM **/
+ if ((*iterations) < maxIterations) {
+ /* increase gain (+ next iteration) */
+ for (ch = 0; ch < nChannels; ch++) {
+ if (!chConstraintsFulfilled[ch]) {
+ qcOutElement->qcOutChannel[ch]->globalGain += gainAdjustment;
+ calculateQuant[ch] = 1; /* global gain has changed, recalculate
+ quantization in next iteration! */
+ }
+ }
+ } else if ((*iterations) == maxIterations) {
+ if (qcOutElement->dynBitsUsed == 0) {
+ return AAC_ENC_QUANT_ERROR;
+ } else {
+ /* crash recovery */
+ INT bitsToSave = 0;
+ if ((bitsToSave = fixMax(
+ (qcOutElement->dynBitsUsed + 8) -
+ (elBits->bitResLevelEl + qcOutElement->grantedDynBits),
+ (qcOutElement->dynBitsUsed + qcOutElement->staticBitsUsed + 8) -
+ (elBits->maxBitsEl))) > 0) {
+ FDKaacEnc_crashRecovery(nChannels, psyOutElement, qcOut, qcOutElement,
+ bitsToSave, aot, syntaxFlags, epConfig);
+ } else {
+ for (ch = 0; ch < nChannels; ch++) {
+ qcOutElement->qcOutChannel[ch]->globalGain += 1;
+ }
+ }
+ for (ch = 0; ch < nChannels; ch++) {
+ calculateQuant[ch] = 1;
+ }
+ }
+ } else {
+ /* (*iterations) > maxIterations */
+ return AAC_ENC_QUANT_ERROR;
+ }
+ (*iterations)++;
+
+ return AAC_ENC_OK;
+}
+
+AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING* cm,
+ QC_STATE* qcKernel,
+ ELEMENT_BITS* RESTRICT elBits[((8))],
+ QC_OUT** qcOut) {
+ switch (qcKernel->bitrateMode) {
+ case QCDATA_BR_MODE_SFR:
+ break;
+
+ case QCDATA_BR_MODE_FF:
+ break;
+ case QCDATA_BR_MODE_VBR_1:
+ case QCDATA_BR_MODE_VBR_2:
+ case QCDATA_BR_MODE_VBR_3:
+ case QCDATA_BR_MODE_VBR_4:
+ case QCDATA_BR_MODE_VBR_5:
+ qcOut[0]->totFillBits =
+ (qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits) &
+ 7; /* precalculate alignment bits */
+ qcOut[0]->totalBits = qcOut[0]->staticBits + qcOut[0]->usedDynBits +
+ qcOut[0]->totFillBits + qcOut[0]->elementExtBits +
+ qcOut[0]->globalExtBits;
+ qcOut[0]->totFillBits +=
+ (fixMax(0, qcKernel->minBitsPerFrame - qcOut[0]->totalBits) + 7) & ~7;
+ break;
+ case QCDATA_BR_MODE_CBR:
+ case QCDATA_BR_MODE_INVALID:
+ default:
+ INT bitResSpace = qcKernel->bitResTotMax - qcKernel->bitResTot;
+ /* processing fill-bits */
+ INT deltaBitRes = qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits;
+ qcOut[0]->totFillBits = fixMax(
+ (deltaBitRes & 7), (deltaBitRes - (fixMax(0, bitResSpace - 7) & ~7)));
+ qcOut[0]->totalBits = qcOut[0]->staticBits + qcOut[0]->usedDynBits +
+ qcOut[0]->totFillBits + qcOut[0]->elementExtBits +
+ qcOut[0]->globalExtBits;
+ qcOut[0]->totFillBits +=
+ (fixMax(0, qcKernel->minBitsPerFrame - qcOut[0]->totalBits) + 7) & ~7;
+ break;
+ } /* switch (qcKernel->bitrateMode) */
+
+ return AAC_ENC_OK;
+}
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_calcMaxValueInSfb
+ description:
+ return:
+
+**********************************************************************************/
+
+static INT FDKaacEnc_calcMaxValueInSfb(INT sfbCnt, INT maxSfbPerGroup,
+ INT sfbPerGroup, INT* RESTRICT sfbOffset,
+ SHORT* RESTRICT quantSpectrum,
+ UINT* RESTRICT maxValue) {
+ INT sfbOffs, sfb;
+ INT maxValueAll = 0;
+
+ for (sfbOffs = 0; sfbOffs < sfbCnt; sfbOffs += sfbPerGroup)
+ for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+ INT line;
+ INT maxThisSfb = 0;
+ for (line = sfbOffset[sfbOffs + sfb]; line < sfbOffset[sfbOffs + sfb + 1];
+ line++) {
+ INT tmp = fixp_abs(quantSpectrum[line]);
+ maxThisSfb = fixMax(tmp, maxThisSfb);
+ }
+
+ maxValue[sfbOffs + sfb] = maxThisSfb;
+ maxValueAll = fixMax(maxThisSfb, maxValueAll);
+ }
+ return maxValueAll;
+}
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_updateBitres
+ description:
+ return:
+
+**********************************************************************************/
+void FDKaacEnc_updateBitres(CHANNEL_MAPPING* cm, QC_STATE* qcKernel,
+ QC_OUT** qcOut) {
+ switch (qcKernel->bitrateMode) {
+ case QCDATA_BR_MODE_VBR_1:
+ case QCDATA_BR_MODE_VBR_2:
+ case QCDATA_BR_MODE_VBR_3:
+ case QCDATA_BR_MODE_VBR_4:
+ case QCDATA_BR_MODE_VBR_5:
+ /* variable bitrate */
+ qcKernel->bitResTot =
+ fMin(qcKernel->maxBitsPerFrame, qcKernel->bitResTotMax);
+ break;
+ case QCDATA_BR_MODE_CBR:
+ case QCDATA_BR_MODE_SFR:
+ case QCDATA_BR_MODE_INVALID:
+ default:
+ int c = 0;
+ /* constant bitrate */
+ {
+ qcKernel->bitResTot += qcOut[c]->grantedDynBits -
+ (qcOut[c]->usedDynBits + qcOut[c]->totFillBits +
+ qcOut[c]->alignBits);
+ }
+ break;
+ }
+}
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_FinalizeBitConsumption
+ description:
+ return:
+
+**********************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(
+ CHANNEL_MAPPING* cm, QC_STATE* qcKernel, QC_OUT* qcOut,
+ QC_OUT_ELEMENT** qcElement, HANDLE_TRANSPORTENC hTpEnc,
+ AUDIO_OBJECT_TYPE aot, UINT syntaxFlags, SCHAR epConfig) {
+ QC_OUT_EXTENSION fillExtPayload;
+ INT totFillBits, alignBits;
+
+ /* Get total consumed bits in AU */
+ qcOut->totalBits = qcOut->staticBits + qcOut->usedDynBits +
+ qcOut->totFillBits + qcOut->elementExtBits +
+ qcOut->globalExtBits;
+
+ if (qcKernel->bitrateMode == QCDATA_BR_MODE_CBR) {
+ /* Now we can get the exact transport bit amount, and hopefully it is equal
+ * to the estimated value */
+ INT exactTpBits = transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits);
+
+ if (exactTpBits != qcKernel->globHdrBits) {
+ INT diffFillBits = 0;
+
+ /* How many bits can be take by bitreservoir */
+ const INT bitresSpace =
+ qcKernel->bitResTotMax -
+ (qcKernel->bitResTot +
+ (qcOut->grantedDynBits - (qcOut->usedDynBits + qcOut->totFillBits)));
+
+ /* Number of bits which can be moved to bitreservoir. */
+ const INT bitsToBitres = qcKernel->globHdrBits - exactTpBits;
+ FDK_ASSERT(bitsToBitres >= 0); /* is always positive */
+
+ /* If bitreservoir can not take all bits, move ramaining bits to fillbits
+ */
+ diffFillBits = fMax(0, bitsToBitres - bitresSpace);
+
+ /* Assure previous alignment */
+ diffFillBits = (diffFillBits + 7) & ~7;
+
+ /* Move as many bits as possible to bitreservoir */
+ qcKernel->bitResTot += (bitsToBitres - diffFillBits);
+
+ /* Write remaing bits as fill bits */
+ qcOut->totFillBits += diffFillBits;
+ qcOut->totalBits += diffFillBits;
+ qcOut->grantedDynBits += diffFillBits;
+
+ /* Get new header bits */
+ qcKernel->globHdrBits =
+ transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits);
+
+ if (qcKernel->globHdrBits != exactTpBits) {
+ /* In previous step, fill bits and corresponding total bits were changed
+ when bitreservoir was completely filled. Now we can take the too much
+ taken bits caused by header overhead from bitreservoir.
+ */
+ qcKernel->bitResTot -= (qcKernel->globHdrBits - exactTpBits);
+ }
+ }
+
+ } /* MODE_CBR */
+
+ /* Update exact number of consumed header bits. */
+ qcKernel->globHdrBits = transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits);
+
+ /* Save total fill bits and distribut to alignment and fill bits */
+ totFillBits = qcOut->totFillBits;
+
+ /* fake a fill extension payload */
+ FDKmemclear(&fillExtPayload, sizeof(QC_OUT_EXTENSION));
+
+ fillExtPayload.type = EXT_FILL_DATA;
+ fillExtPayload.nPayloadBits = totFillBits;
+
+ /* ask bitstream encoder how many of that bits can be written in a fill
+ * extension data entity */
+ qcOut->totFillBits = FDKaacEnc_writeExtensionData(NULL, &fillExtPayload, 0, 0,
+ syntaxFlags, aot, epConfig);
+
+ //fprintf(stderr, "FinalizeBitConsumption(): totFillBits=%d, qcOut->totFillBits=%d \n", totFillBits, qcOut->totFillBits);
+
+ /* now distribute extra fillbits and alignbits */
+ alignBits =
+ 7 - (qcOut->staticBits + qcOut->usedDynBits + qcOut->elementExtBits +
+ qcOut->totFillBits + qcOut->globalExtBits - 1) %
+ 8;
+
+ /* Maybe we could remove this */
+ if (((alignBits + qcOut->totFillBits - totFillBits) == 8) &&
+ (qcOut->totFillBits > 8))
+ qcOut->totFillBits -= 8;
+
+ qcOut->totalBits = qcOut->staticBits + qcOut->usedDynBits +
+ qcOut->totFillBits + alignBits + qcOut->elementExtBits +
+ qcOut->globalExtBits;
+
+ if ((qcOut->totalBits > qcKernel->maxBitsPerFrame) ||
+ (qcOut->totalBits < qcKernel->minBitsPerFrame)) {
+ return AAC_ENC_QUANT_ERROR;
+ }
+
+ qcOut->alignBits = alignBits;
+
+ return AAC_ENC_OK;
+}
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_crashRecovery
+ description: fulfills constraints by means of brute force...
+ => bits are saved by cancelling out spectral lines!!
+ (beginning at the highest frequencies)
+ return: errorcode
+
+**********************************************************************************/
+
+static void FDKaacEnc_crashRecovery(INT nChannels,
+ PSY_OUT_ELEMENT* psyOutElement,
+ QC_OUT* qcOut, QC_OUT_ELEMENT* qcElement,
+ INT bitsToSave, AUDIO_OBJECT_TYPE aot,
+ UINT syntaxFlags, SCHAR epConfig) {
+ INT ch;
+ INT savedBits = 0;
+ INT sfb, sfbGrp;
+ INT bitsPerScf[(2)][MAX_GROUPED_SFB];
+ INT sectionToScf[(2)][MAX_GROUPED_SFB];
+ INT* sfbOffset;
+ INT sect, statBitsNew;
+ QC_OUT_CHANNEL** qcChannel = qcElement->qcOutChannel;
+ PSY_OUT_CHANNEL** psyChannel = psyOutElement->psyOutChannel;
+
+ /* create a table which converts frq-bins to bit-demand... [bitsPerScf] */
+ /* ...and another one which holds the corresponding sections [sectionToScf] */
+ for (ch = 0; ch < nChannels; ch++) {
+ sfbOffset = psyChannel[ch]->sfbOffsets;
+
+ for (sect = 0; sect < qcChannel[ch]->sectionData.noOfSections; sect++) {
+ INT codeBook = qcChannel[ch]->sectionData.huffsection[sect].codeBook;
+
+ for (sfb = qcChannel[ch]->sectionData.huffsection[sect].sfbStart;
+ sfb < qcChannel[ch]->sectionData.huffsection[sect].sfbStart +
+ qcChannel[ch]->sectionData.huffsection[sect].sfbCnt;
+ sfb++) {
+ bitsPerScf[ch][sfb] = 0;
+ if ((codeBook != CODE_BOOK_PNS_NO) /*&&
+ (sfb < (qcChannel[ch]->sectionData.noOfGroups*qcChannel[ch]->sectionData.maxSfbPerGroup))*/) {
+ INT sfbStartLine = sfbOffset[sfb];
+ INT noOfLines = sfbOffset[sfb + 1] - sfbStartLine;
+ bitsPerScf[ch][sfb] = FDKaacEnc_countValues(
+ &(qcChannel[ch]->quantSpec[sfbStartLine]), noOfLines, codeBook);
+ }
+ sectionToScf[ch][sfb] = sect;
+ }
+ }
+ }
+
+ /* LOWER [maxSfb] IN BOTH CHANNELS!! */
+ /* Attention: in case of stereo: maxSfbL == maxSfbR, GroupingL == GroupingR ;
+ */
+
+ for (sfb = qcChannel[0]->sectionData.maxSfbPerGroup - 1; sfb >= 0; sfb--) {
+ for (sfbGrp = 0; sfbGrp < psyChannel[0]->sfbCnt;
+ sfbGrp += psyChannel[0]->sfbPerGroup) {
+ for (ch = 0; ch < nChannels; ch++) {
+ sect = sectionToScf[ch][sfbGrp + sfb];
+ qcChannel[ch]->sectionData.huffsection[sect].sfbCnt--;
+ savedBits += bitsPerScf[ch][sfbGrp + sfb];
+
+ if (qcChannel[ch]->sectionData.huffsection[sect].sfbCnt == 0) {
+ savedBits += (psyChannel[ch]->lastWindowSequence != SHORT_WINDOW)
+ ? FDKaacEnc_sideInfoTabLong[0]
+ : FDKaacEnc_sideInfoTabShort[0];
+ }
+ }
+ }
+
+ /* ...have enough bits been saved? */
+ if (savedBits >= bitsToSave) break;
+
+ } /* sfb loop */
+
+ /* if not enough bits saved,
+ clean whole spectrum and remove side info overhead */
+ if (sfb == -1) {
+ sfb = 0;
+ }
+
+ for (ch = 0; ch < nChannels; ch++) {
+ qcChannel[ch]->sectionData.maxSfbPerGroup = sfb;
+ psyChannel[ch]->maxSfbPerGroup = sfb;
+ /* when no spectrum is coded save tools info in bitstream */
+ if (sfb == 0) {
+ FDKmemclear(&psyChannel[ch]->tnsInfo, sizeof(TNS_INFO));
+ FDKmemclear(&psyOutElement->toolsInfo, sizeof(TOOLSINFO));
+ }
+ }
+ /* dynamic bits will be updated in iteration loop */
+
+ { /* if stop sfb has changed save bits in side info, e.g. MS or TNS coding */
+ ELEMENT_INFO elInfo;
+
+ FDKmemclear(&elInfo, sizeof(ELEMENT_INFO));
+ elInfo.nChannelsInEl = nChannels;
+ elInfo.elType = (nChannels == 2) ? ID_CPE : ID_SCE;
+
+ FDKaacEnc_ChannelElementWrite(NULL, &elInfo, NULL, psyOutElement,
+ psyChannel, syntaxFlags, aot, epConfig,
+ &statBitsNew, 0);
+ }
+
+ savedBits = qcElement->staticBitsUsed - statBitsNew;
+
+ /* update static and dynamic bits */
+ qcElement->staticBitsUsed -= savedBits;
+ qcElement->grantedDynBits += savedBits;
+
+ qcOut->staticBits -= savedBits;
+ qcOut->grantedDynBits += savedBits;
+ qcOut->maxDynBits += savedBits;
+}
+
+void FDKaacEnc_QCClose(QC_STATE** phQCstate, QC_OUT** phQC) {
+ int n, i;
+
+ if (phQC != NULL) {
+ for (n = 0; n < (1); n++) {
+ if (phQC[n] != NULL) {
+ QC_OUT* hQC = phQC[n];
+ for (i = 0; i < (8); i++) {
+ }
+
+ for (i = 0; i < ((8)); i++) {
+ if (hQC->qcElement[i]) FreeRam_aacEnc_QCelement(&hQC->qcElement[i]);
+ }
+
+ FreeRam_aacEnc_QCout(&phQC[n]);
+ }
+ }
+ }
+
+ if (phQCstate != NULL) {
+ if (*phQCstate != NULL) {
+ QC_STATE* hQCstate = *phQCstate;
+
+ if (hQCstate->hAdjThr != NULL) FDKaacEnc_AdjThrClose(&hQCstate->hAdjThr);
+
+ if (hQCstate->hBitCounter != NULL)
+ FDKaacEnc_BCClose(&hQCstate->hBitCounter);
+
+ for (i = 0; i < ((8)); i++) {
+ if (hQCstate->elementBits[i] != NULL) {
+ FreeRam_aacEnc_ElementBits(&hQCstate->elementBits[i]);
+ }
+ }
+ FreeRam_aacEnc_QCstate(phQCstate);
+ }
+ }
+}
diff --git a/fdk-aac/libAACenc/src/qc_main.h b/fdk-aac/libAACenc/src/qc_main.h
new file mode 100644
index 0000000..b9e8e2d
--- /dev/null
+++ b/fdk-aac/libAACenc/src/qc_main.h
@@ -0,0 +1,158 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Quantizing & coding
+
+*******************************************************************************/
+
+#ifndef QC_MAIN_H
+#define QC_MAIN_H
+
+#include "aacenc.h"
+#include "qc_data.h"
+#include "interface.h"
+#include "psy_main.h"
+#include "tpenc_lib.h"
+
+/* Quantizing & coding stage */
+
+AAC_ENCODER_ERROR FDKaacEnc_QCOutNew(QC_OUT **phQC, const INT nElements,
+ const INT nChannels, const INT nSubFrames,
+ UCHAR *dynamic_RAM);
+
+AAC_ENCODER_ERROR FDKaacEnc_QCOutInit(QC_OUT *phQC[(1)], const INT nSubFrames,
+ const CHANNEL_MAPPING *cm);
+
+AAC_ENCODER_ERROR FDKaacEnc_QCNew(QC_STATE **phQC, INT nElements,
+ UCHAR *dynamic_RAM);
+
+AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC, struct QC_INIT *init,
+ const ULONG initFlags);
+
+AAC_ENCODER_ERROR FDKaacEnc_QCMainPrepare(
+ ELEMENT_INFO *elInfo, ATS_ELEMENT *RESTRICT adjThrStateElement,
+ PSY_OUT_ELEMENT *RESTRICT psyOutElement,
+ QC_OUT_ELEMENT *RESTRICT qcOutElement, /* returns error code */
+ AUDIO_OBJECT_TYPE aot, UINT syntaxFlags, SCHAR epConfig);
+
+AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE *RESTRICT hQC, PSY_OUT **psyOut,
+ QC_OUT **qcOut, INT avgTotalBits,
+ CHANNEL_MAPPING *cm, AUDIO_OBJECT_TYPE aot,
+ UINT syntaxFlags, SCHAR epConfig);
+
+AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING *cm,
+ QC_STATE *qcKernel,
+ ELEMENT_BITS *RESTRICT elBits[((8))],
+ QC_OUT **qcOut);
+
+void FDKaacEnc_updateBitres(CHANNEL_MAPPING *cm, QC_STATE *qcKernel,
+ QC_OUT **qcOut);
+
+AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(
+ CHANNEL_MAPPING *cm, QC_STATE *hQC, QC_OUT *qcOut,
+ QC_OUT_ELEMENT **qcElement, HANDLE_TRANSPORTENC hTpEnc,
+ AUDIO_OBJECT_TYPE aot, UINT syntaxFlags, SCHAR epConfig);
+
+AAC_ENCODER_ERROR FDKaacEnc_AdjustBitrate(QC_STATE *RESTRICT hQC,
+ CHANNEL_MAPPING *RESTRICT cm,
+ INT *avgTotalBits, INT bitRate,
+ INT sampleRate, INT granuleLength);
+
+void FDKaacEnc_QCClose(QC_STATE **phQCstate, QC_OUT **phQC);
+
+#endif /* QC_MAIN_H */
diff --git a/fdk-aac/libAACenc/src/quantize.cpp b/fdk-aac/libAACenc/src/quantize.cpp
new file mode 100644
index 0000000..4d25263
--- /dev/null
+++ b/fdk-aac/libAACenc/src/quantize.cpp
@@ -0,0 +1,401 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Quantization
+
+*******************************************************************************/
+
+#include "quantize.h"
+
+#include "aacEnc_rom.h"
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_quantizeLines
+ description: quantizes spectrum lines
+ returns:
+ input: global gain, number of lines to process, spectral data
+ output: quantized spectrum
+
+*****************************************************************************/
+static void FDKaacEnc_quantizeLines(INT gain, INT noOfLines,
+ const FIXP_DBL *mdctSpectrum,
+ SHORT *quaSpectrum, INT dZoneQuantEnable) {
+ int line;
+ FIXP_DBL k = FL2FXCONST_DBL(0.0f);
+ FIXP_QTD quantizer = FDKaacEnc_quantTableQ[(-gain) & 3];
+ INT quantizershift = ((-gain) >> 2) + 1;
+ const INT kShift = 16;
+
+ if (dZoneQuantEnable)
+ k = FL2FXCONST_DBL(0.23f) >> kShift;
+ else
+ k = FL2FXCONST_DBL(-0.0946f + 0.5f) >> kShift;
+
+ for (line = 0; line < noOfLines; line++) {
+ FIXP_DBL accu = fMultDiv2(mdctSpectrum[line], quantizer);
+
+ if (accu < FL2FXCONST_DBL(0.0f)) {
+ accu = -accu;
+ /* normalize */
+ INT accuShift = CntLeadingZeros(accu) - 1; /* CountLeadingBits() is not
+ necessary here since test
+ value is always > 0 */
+ accu <<= accuShift;
+ INT tabIndex =
+ (INT)(accu >> (DFRACT_BITS - 2 - MANT_DIGITS)) & (~MANT_SIZE);
+ INT totalShift = quantizershift - accuShift + 1;
+ accu = fMultDiv2(FDKaacEnc_mTab_3_4[tabIndex],
+ FDKaacEnc_quantTableE[totalShift & 3]);
+ totalShift = (16 - 4) - (3 * (totalShift >> 2));
+ FDK_ASSERT(totalShift >= 0); /* MAX_QUANT_VIOLATION */
+ accu >>= fixMin(totalShift, DFRACT_BITS - 1);
+ quaSpectrum[line] =
+ (SHORT)(-((LONG)(k + accu) >> (DFRACT_BITS - 1 - 16)));
+ } else if (accu > FL2FXCONST_DBL(0.0f)) {
+ /* normalize */
+ INT accuShift = CntLeadingZeros(accu) - 1; /* CountLeadingBits() is not
+ necessary here since test
+ value is always > 0 */
+ accu <<= accuShift;
+ INT tabIndex =
+ (INT)(accu >> (DFRACT_BITS - 2 - MANT_DIGITS)) & (~MANT_SIZE);
+ INT totalShift = quantizershift - accuShift + 1;
+ accu = fMultDiv2(FDKaacEnc_mTab_3_4[tabIndex],
+ FDKaacEnc_quantTableE[totalShift & 3]);
+ totalShift = (16 - 4) - (3 * (totalShift >> 2));
+ FDK_ASSERT(totalShift >= 0); /* MAX_QUANT_VIOLATION */
+ accu >>= fixMin(totalShift, DFRACT_BITS - 1);
+ quaSpectrum[line] = (SHORT)((LONG)(k + accu) >> (DFRACT_BITS - 1 - 16));
+ } else {
+ quaSpectrum[line] = 0;
+ }
+ }
+}
+
+/*****************************************************************************
+
+ functionname:iFDKaacEnc_quantizeLines
+ description: iquantizes spectrum lines
+ mdctSpectrum = iquaSpectrum^4/3 *2^(0.25*gain)
+ input: global gain, number of lines to process,quantized spectrum
+ output: spectral data
+
+*****************************************************************************/
+static void FDKaacEnc_invQuantizeLines(INT gain, INT noOfLines,
+ SHORT *quantSpectrum,
+ FIXP_DBL *mdctSpectrum)
+
+{
+ INT iquantizermod;
+ INT iquantizershift;
+ INT line;
+
+ iquantizermod = gain & 3;
+ iquantizershift = gain >> 2;
+
+ for (line = 0; line < noOfLines; line++) {
+ if (quantSpectrum[line] < 0) {
+ FIXP_DBL accu;
+ INT ex, specExp, tabIndex;
+ FIXP_DBL s, t;
+
+ accu = (FIXP_DBL)-quantSpectrum[line];
+
+ ex = CountLeadingBits(accu);
+ accu <<= ex;
+ specExp = (DFRACT_BITS - 1) - ex;
+
+ FDK_ASSERT(specExp < 14); /* this fails if abs(value) > 8191 */
+
+ tabIndex = (INT)(accu >> (DFRACT_BITS - 2 - MANT_DIGITS)) & (~MANT_SIZE);
+
+ /* calculate "mantissa" ^4/3 */
+ s = FDKaacEnc_mTab_4_3Elc[tabIndex];
+
+ /* get approperiate exponent multiplier for specExp^3/4 combined with
+ * scfMod */
+ t = FDKaacEnc_specExpMantTableCombElc[iquantizermod][specExp];
+
+ /* multiply "mantissa" ^4/3 with exponent multiplier */
+ accu = fMult(s, t);
+
+ /* get approperiate exponent shifter */
+ specExp = FDKaacEnc_specExpTableComb[iquantizermod][specExp] -
+ 1; /* -1 to avoid overflows in accu */
+
+ if ((-iquantizershift - specExp) < 0)
+ accu <<= -(-iquantizershift - specExp);
+ else
+ accu >>= -iquantizershift - specExp;
+
+ mdctSpectrum[line] = -accu;
+ } else if (quantSpectrum[line] > 0) {
+ FIXP_DBL accu;
+ INT ex, specExp, tabIndex;
+ FIXP_DBL s, t;
+
+ accu = (FIXP_DBL)(INT)quantSpectrum[line];
+
+ ex = CountLeadingBits(accu);
+ accu <<= ex;
+ specExp = (DFRACT_BITS - 1) - ex;
+
+ FDK_ASSERT(specExp < 14); /* this fails if abs(value) > 8191 */
+
+ tabIndex = (INT)(accu >> (DFRACT_BITS - 2 - MANT_DIGITS)) & (~MANT_SIZE);
+
+ /* calculate "mantissa" ^4/3 */
+ s = FDKaacEnc_mTab_4_3Elc[tabIndex];
+
+ /* get approperiate exponent multiplier for specExp^3/4 combined with
+ * scfMod */
+ t = FDKaacEnc_specExpMantTableCombElc[iquantizermod][specExp];
+
+ /* multiply "mantissa" ^4/3 with exponent multiplier */
+ accu = fMult(s, t);
+
+ /* get approperiate exponent shifter */
+ specExp = FDKaacEnc_specExpTableComb[iquantizermod][specExp] -
+ 1; /* -1 to avoid overflows in accu */
+
+ if ((-iquantizershift - specExp) < 0)
+ accu <<= -(-iquantizershift - specExp);
+ else
+ accu >>= -iquantizershift - specExp;
+
+ mdctSpectrum[line] = accu;
+ } else {
+ mdctSpectrum[line] = FL2FXCONST_DBL(0.0f);
+ }
+ }
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_QuantizeSpectrum
+ description: quantizes the entire spectrum
+ returns:
+ input: number of scalefactor bands to be quantized, ...
+ output: quantized spectrum
+
+*****************************************************************************/
+void FDKaacEnc_QuantizeSpectrum(INT sfbCnt, INT maxSfbPerGroup, INT sfbPerGroup,
+ const INT *sfbOffset,
+ const FIXP_DBL *mdctSpectrum, INT globalGain,
+ const INT *scalefactors,
+ SHORT *quantizedSpectrum,
+ INT dZoneQuantEnable) {
+ INT sfbOffs, sfb;
+
+ /* in FDKaacEnc_quantizeLines quaSpectrum is calculated with:
+ spec^(3/4) * 2^(-3/16*QSS) * 2^(3/4*scale) + k
+ simplify scaling calculation and reduce QSS before:
+ spec^(3/4) * 2^(-3/16*(QSS - 4*scale)) */
+
+ for (sfbOffs = 0; sfbOffs < sfbCnt; sfbOffs += sfbPerGroup)
+ for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+ INT scalefactor = scalefactors[sfbOffs + sfb];
+
+ FDKaacEnc_quantizeLines(
+ globalGain - scalefactor, /* QSS */
+ sfbOffset[sfbOffs + sfb + 1] - sfbOffset[sfbOffs + sfb],
+ mdctSpectrum + sfbOffset[sfbOffs + sfb],
+ quantizedSpectrum + sfbOffset[sfbOffs + sfb], dZoneQuantEnable);
+ }
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_calcSfbDist
+ description: calculates distortion of quantized values
+ returns: distortion
+ input: gain, number of lines to process, spectral data
+ output:
+
+*****************************************************************************/
+FIXP_DBL FDKaacEnc_calcSfbDist(const FIXP_DBL *mdctSpectrum,
+ SHORT *quantSpectrum, INT noOfLines, INT gain,
+ INT dZoneQuantEnable) {
+ INT i, scale;
+ FIXP_DBL xfsf;
+ FIXP_DBL diff;
+ FIXP_DBL invQuantSpec;
+
+ xfsf = FL2FXCONST_DBL(0.0f);
+
+ for (i = 0; i < noOfLines; i++) {
+ /* quantization */
+ FDKaacEnc_quantizeLines(gain, 1, &mdctSpectrum[i], &quantSpectrum[i],
+ dZoneQuantEnable);
+
+ if (fAbs(quantSpectrum[i]) > MAX_QUANT) {
+ return FL2FXCONST_DBL(0.0f);
+ }
+ /* inverse quantization */
+ FDKaacEnc_invQuantizeLines(gain, 1, &quantSpectrum[i], &invQuantSpec);
+
+ /* dist */
+ diff = fixp_abs(fixp_abs(invQuantSpec) - fixp_abs(mdctSpectrum[i] >> 1));
+
+ scale = CountLeadingBits(diff);
+ diff = scaleValue(diff, scale);
+ diff = fPow2(diff);
+ scale = fixMin(2 * (scale - 1), DFRACT_BITS - 1);
+
+ diff = scaleValue(diff, -scale);
+
+ xfsf = xfsf + diff;
+ }
+
+ xfsf = CalcLdData(xfsf);
+
+ return xfsf;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_calcSfbQuantEnergyAndDist
+ description: calculates energy and distortion of quantized values
+ returns:
+ input: gain, number of lines to process, quantized spectral data,
+ spectral data
+ output: energy, distortion
+
+*****************************************************************************/
+void FDKaacEnc_calcSfbQuantEnergyAndDist(FIXP_DBL *mdctSpectrum,
+ SHORT *quantSpectrum, INT noOfLines,
+ INT gain, FIXP_DBL *en,
+ FIXP_DBL *dist) {
+ INT i, scale;
+ FIXP_DBL invQuantSpec;
+ FIXP_DBL diff;
+
+ FIXP_DBL energy = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL distortion = FL2FXCONST_DBL(0.0f);
+
+ for (i = 0; i < noOfLines; i++) {
+ if (fAbs(quantSpectrum[i]) > MAX_QUANT) {
+ *en = FL2FXCONST_DBL(0.0f);
+ *dist = FL2FXCONST_DBL(0.0f);
+ return;
+ }
+
+ /* inverse quantization */
+ FDKaacEnc_invQuantizeLines(gain, 1, &quantSpectrum[i], &invQuantSpec);
+
+ /* energy */
+ energy += fPow2(invQuantSpec);
+
+ /* dist */
+ diff = fixp_abs(fixp_abs(invQuantSpec) - fixp_abs(mdctSpectrum[i] >> 1));
+
+ scale = CountLeadingBits(diff);
+ diff = scaleValue(diff, scale);
+ diff = fPow2(diff);
+
+ scale = fixMin(2 * (scale - 1), DFRACT_BITS - 1);
+
+ diff = scaleValue(diff, -scale);
+
+ distortion += diff;
+ }
+
+ *en = CalcLdData(energy) + FL2FXCONST_DBL(0.03125f);
+ *dist = CalcLdData(distortion);
+}
diff --git a/fdk-aac/libAACenc/src/quantize.h b/fdk-aac/libAACenc/src/quantize.h
new file mode 100644
index 0000000..dfc2206
--- /dev/null
+++ b/fdk-aac/libAACenc/src/quantize.h
@@ -0,0 +1,127 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Quantization
+
+*******************************************************************************/
+
+#ifndef QUANTIZE_H
+#define QUANTIZE_H
+
+#include "common_fix.h"
+
+/* quantizing */
+
+#define MAX_QUANT 8191
+
+void FDKaacEnc_QuantizeSpectrum(INT sfbCnt, INT maxSfbPerGroup, INT sfbPerGroup,
+ const INT *sfbOffset,
+ const FIXP_DBL *mdctSpectrum, INT globalGain,
+ const INT *scalefactors,
+ SHORT *quantizedSpectrum, INT dZoneQuantEnable);
+
+FIXP_DBL FDKaacEnc_calcSfbDist(const FIXP_DBL *mdctSpectrum,
+ SHORT *quantSpectrum, INT noOfLines, INT gain,
+ INT dZoneQuantEnable);
+
+void FDKaacEnc_calcSfbQuantEnergyAndDist(FIXP_DBL *mdctSpectrum,
+ SHORT *quantSpectrum, INT noOfLines,
+ INT gain, FIXP_DBL *en,
+ FIXP_DBL *dist);
+
+#endif /* QUANTIZE_H */
diff --git a/fdk-aac/libAACenc/src/sf_estim.cpp b/fdk-aac/libAACenc/src/sf_estim.cpp
new file mode 100644
index 0000000..17a8ae2
--- /dev/null
+++ b/fdk-aac/libAACenc/src/sf_estim.cpp
@@ -0,0 +1,1292 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Scale factor estimation
+
+*******************************************************************************/
+
+#include "sf_estim.h"
+#include "aacEnc_rom.h"
+#include "quantize.h"
+#include "bit_cnt.h"
+
+#ifdef __arm__
+#endif
+
+#define UPCOUNT_LIMIT 1
+#define AS_PE_FAC_SHIFT 7
+#define DIST_FAC_SHIFT 3
+#define AS_PE_FAC_FLOAT (float)(1 << AS_PE_FAC_SHIFT)
+static const INT MAX_SCF_DELTA = 60;
+
+static const FIXP_DBL PE_C1 = FL2FXCONST_DBL(
+ 3.0f / AS_PE_FAC_FLOAT); /* (log(8.0)/log(2)) >> AS_PE_FAC_SHIFT */
+static const FIXP_DBL PE_C2 = FL2FXCONST_DBL(
+ 1.3219281f / AS_PE_FAC_FLOAT); /* (log(2.5)/log(2)) >> AS_PE_FAC_SHIFT */
+static const FIXP_DBL PE_C3 = FL2FXCONST_DBL(0.5593573f); /* 1-C2/C1 */
+
+/*
+ Function; FDKaacEnc_FDKaacEnc_CalcFormFactorChannel
+
+ Description: Calculates the formfactor
+
+ sf: scale factor of the mdct spectrum
+ sfbFormFactorLdData is scaled with the factor 1/(((2^sf)^0.5) *
+ (2^FORM_FAC_SHIFT))
+*/
+static void FDKaacEnc_FDKaacEnc_CalcFormFactorChannel(
+ FIXP_DBL *RESTRICT sfbFormFactorLdData,
+ PSY_OUT_CHANNEL *RESTRICT psyOutChan) {
+ INT j, sfb, sfbGrp;
+ FIXP_DBL formFactor;
+
+ int tmp0 = psyOutChan->sfbCnt;
+ int tmp1 = psyOutChan->maxSfbPerGroup;
+ int step = psyOutChan->sfbPerGroup;
+ for (sfbGrp = 0; sfbGrp < tmp0; sfbGrp += step) {
+ for (sfb = 0; sfb < tmp1; sfb++) {
+ formFactor = FL2FXCONST_DBL(0.0f);
+ /* calc sum of sqrt(spec) */
+ for (j = psyOutChan->sfbOffsets[sfbGrp + sfb];
+ j < psyOutChan->sfbOffsets[sfbGrp + sfb + 1]; j++) {
+ formFactor +=
+ sqrtFixp(fixp_abs(psyOutChan->mdctSpectrum[j])) >> FORM_FAC_SHIFT;
+ }
+ sfbFormFactorLdData[sfbGrp + sfb] = CalcLdData(formFactor);
+ }
+ /* set sfbFormFactor for sfbs with zero spec to zero. Just for debugging. */
+ for (; sfb < psyOutChan->sfbPerGroup; sfb++) {
+ sfbFormFactorLdData[sfbGrp + sfb] = FL2FXCONST_DBL(-1.0f);
+ }
+ }
+}
+
+/*
+ Function: FDKaacEnc_CalcFormFactor
+
+ Description: Calls FDKaacEnc_FDKaacEnc_CalcFormFactorChannel() for each
+ channel
+*/
+
+void FDKaacEnc_CalcFormFactor(QC_OUT_CHANNEL *qcOutChannel[(2)],
+ PSY_OUT_CHANNEL *psyOutChannel[(2)],
+ const INT nChannels) {
+ INT j;
+ for (j = 0; j < nChannels; j++) {
+ FDKaacEnc_FDKaacEnc_CalcFormFactorChannel(
+ qcOutChannel[j]->sfbFormFactorLdData, psyOutChannel[j]);
+ }
+}
+
+/*
+ Function: FDKaacEnc_calcSfbRelevantLines
+
+ Description: Calculates sfbNRelevantLines
+
+ sfbNRelevantLines is scaled with the factor 1/((2^FORM_FAC_SHIFT) * 2.0)
+*/
+static void FDKaacEnc_calcSfbRelevantLines(
+ const FIXP_DBL *const sfbFormFactorLdData,
+ const FIXP_DBL *const sfbEnergyLdData,
+ const FIXP_DBL *const sfbThresholdLdData, const INT *const sfbOffsets,
+ const INT sfbCnt, const INT sfbPerGroup, const INT maxSfbPerGroup,
+ FIXP_DBL *sfbNRelevantLines) {
+ INT sfbOffs, sfb;
+ FIXP_DBL sfbWidthLdData;
+ FIXP_DBL asPeFacLdData =
+ FL2FXCONST_DBL(0.109375); /* AS_PE_FAC_SHIFT*ld64(2) */
+ FIXP_DBL accu;
+
+ /* sfbNRelevantLines[i] = 2^( (sfbFormFactorLdData[i] - 0.25 *
+ * (sfbEnergyLdData[i] - ld64(sfbWidth[i]/(2^7)) - AS_PE_FAC_SHIFT*ld64(2)) *
+ * 64); */
+
+ FDKmemclear(sfbNRelevantLines, sfbCnt * sizeof(FIXP_DBL));
+
+ for (sfbOffs = 0; sfbOffs < sfbCnt; sfbOffs += sfbPerGroup) {
+ for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+ /* calc sum of sqrt(spec) */
+ if ((FIXP_DBL)sfbEnergyLdData[sfbOffs + sfb] >
+ (FIXP_DBL)sfbThresholdLdData[sfbOffs + sfb]) {
+ INT sfbWidth =
+ sfbOffsets[sfbOffs + sfb + 1] - sfbOffsets[sfbOffs + sfb];
+
+ /* avgFormFactorLdData =
+ * sqrtFixp(sqrtFixp(sfbEnergyLdData[sfbOffs+sfb]/sfbWidth)); */
+ /* sfbNRelevantLines[sfbOffs+sfb] = sfbFormFactor[sfbOffs+sfb] /
+ * avgFormFactorLdData; */
+ sfbWidthLdData =
+ (FIXP_DBL)(sfbWidth << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT));
+ sfbWidthLdData = CalcLdData(sfbWidthLdData);
+
+ accu = sfbEnergyLdData[sfbOffs + sfb] - sfbWidthLdData - asPeFacLdData;
+ accu = sfbFormFactorLdData[sfbOffs + sfb] - (accu >> 2);
+
+ sfbNRelevantLines[sfbOffs + sfb] = CalcInvLdData(accu) >> 1;
+ }
+ }
+ }
+}
+
+/*
+ Function: FDKaacEnc_countSingleScfBits
+
+ Description:
+
+ scfBitsFract is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
+*/
+static FIXP_DBL FDKaacEnc_countSingleScfBits(INT scf, INT scfLeft,
+ INT scfRight) {
+ FIXP_DBL scfBitsFract;
+
+ scfBitsFract = (FIXP_DBL)(FDKaacEnc_bitCountScalefactorDelta(scfLeft - scf) +
+ FDKaacEnc_bitCountScalefactorDelta(scf - scfRight));
+
+ scfBitsFract = scfBitsFract << (DFRACT_BITS - 1 - (2 * AS_PE_FAC_SHIFT));
+
+ return scfBitsFract; /* output scaled by 1/(2^(2*AS_PE_FAC)) */
+}
+
+/*
+ Function: FDKaacEnc_calcSingleSpecPe
+
+ specPe is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
+*/
+static FIXP_DBL FDKaacEnc_calcSingleSpecPe(INT scf, FIXP_DBL sfbConstPePart,
+ FIXP_DBL nLines) {
+ FIXP_DBL specPe = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL ldRatio;
+ FIXP_DBL scfFract;
+
+ scfFract = (FIXP_DBL)(scf << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT));
+
+ ldRatio = sfbConstPePart - fMult(FL2FXCONST_DBL(0.375f), scfFract);
+
+ if (ldRatio >= PE_C1) {
+ specPe = fMult(FL2FXCONST_DBL(0.7f), fMult(nLines, ldRatio));
+ } else {
+ specPe = fMult(FL2FXCONST_DBL(0.7f),
+ fMult(nLines, (PE_C2 + fMult(PE_C3, ldRatio))));
+ }
+
+ return specPe; /* output scaled by 1/(2^(2*AS_PE_FAC)) */
+}
+
+/*
+ Function: FDKaacEnc_countScfBitsDiff
+
+ scfBitsDiff is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
+*/
+static FIXP_DBL FDKaacEnc_countScfBitsDiff(INT *scfOld, INT *scfNew, INT sfbCnt,
+ INT startSfb, INT stopSfb) {
+ FIXP_DBL scfBitsFract;
+ INT scfBitsDiff = 0;
+ INT sfb = 0, sfbLast;
+ INT sfbPrev, sfbNext;
+
+ /* search for first relevant sfb */
+ sfbLast = startSfb;
+ while ((sfbLast < stopSfb) && (scfOld[sfbLast] == FDK_INT_MIN)) sfbLast++;
+ /* search for previous relevant sfb and count diff */
+ sfbPrev = startSfb - 1;
+ while ((sfbPrev >= 0) && (scfOld[sfbPrev] == FDK_INT_MIN)) sfbPrev--;
+ if (sfbPrev >= 0)
+ scfBitsDiff +=
+ FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbPrev] - scfNew[sfbLast]) -
+ FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbPrev] - scfOld[sfbLast]);
+ /* now loop through all sfbs and count diffs of relevant sfbs */
+ for (sfb = sfbLast + 1; sfb < stopSfb; sfb++) {
+ if (scfOld[sfb] != FDK_INT_MIN) {
+ scfBitsDiff +=
+ FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfb]) -
+ FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfb]);
+ sfbLast = sfb;
+ }
+ }
+ /* search for next relevant sfb and count diff */
+ sfbNext = stopSfb;
+ while ((sfbNext < sfbCnt) && (scfOld[sfbNext] == FDK_INT_MIN)) sfbNext++;
+ if (sfbNext < sfbCnt)
+ scfBitsDiff +=
+ FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfbNext]) -
+ FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfbNext]);
+
+ scfBitsFract =
+ (FIXP_DBL)(scfBitsDiff << (DFRACT_BITS - 1 - (2 * AS_PE_FAC_SHIFT)));
+
+ return scfBitsFract;
+}
+
+/*
+ Function: FDKaacEnc_calcSpecPeDiff
+
+ specPeDiff is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
+*/
+static FIXP_DBL FDKaacEnc_calcSpecPeDiff(
+ PSY_OUT_CHANNEL *psyOutChan, QC_OUT_CHANNEL *qcOutChannel, INT *scfOld,
+ INT *scfNew, FIXP_DBL *sfbConstPePart, FIXP_DBL *sfbFormFactorLdData,
+ FIXP_DBL *sfbNRelevantLines, INT startSfb, INT stopSfb) {
+ FIXP_DBL specPeDiff = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL scfFract = FL2FXCONST_DBL(0.0f);
+ INT sfb;
+
+ /* loop through all sfbs and count pe difference */
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scfOld[sfb] != FDK_INT_MIN) {
+ FIXP_DBL ldRatioOld, ldRatioNew, pOld, pNew;
+
+ /* sfbConstPePart[sfb] = (float)log(psyOutChan->sfbEnergy[sfb] * 6.75f /
+ * sfbFormFactor[sfb]) * LOG2_1; */
+ /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for
+ * log2 */
+ /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */
+ if (sfbConstPePart[sfb] == (FIXP_DBL)FDK_INT_MIN)
+ sfbConstPePart[sfb] =
+ ((psyOutChan->sfbEnergyLdData[sfb] - sfbFormFactorLdData[sfb] -
+ FL2FXCONST_DBL(0.09375f)) >>
+ 1) +
+ FL2FXCONST_DBL(0.02152255861f);
+
+ scfFract = (FIXP_DBL)(scfOld[sfb] << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT));
+ ldRatioOld =
+ sfbConstPePart[sfb] - fMult(FL2FXCONST_DBL(0.375f), scfFract);
+
+ scfFract = (FIXP_DBL)(scfNew[sfb] << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT));
+ ldRatioNew =
+ sfbConstPePart[sfb] - fMult(FL2FXCONST_DBL(0.375f), scfFract);
+
+ if (ldRatioOld >= PE_C1)
+ pOld = ldRatioOld;
+ else
+ pOld = PE_C2 + fMult(PE_C3, ldRatioOld);
+
+ if (ldRatioNew >= PE_C1)
+ pNew = ldRatioNew;
+ else
+ pNew = PE_C2 + fMult(PE_C3, ldRatioNew);
+
+ specPeDiff += fMult(FL2FXCONST_DBL(0.7f),
+ fMult(sfbNRelevantLines[sfb], (pNew - pOld)));
+ }
+ }
+
+ return specPeDiff;
+}
+
+/*
+ Function: FDKaacEnc_improveScf
+
+ Description: Calculate the distortion by quantization and inverse quantization
+ of the spectrum with various scalefactors. The scalefactor which provides the
+ best results will be used.
+*/
+static INT FDKaacEnc_improveScf(const FIXP_DBL *spec, SHORT *quantSpec,
+ SHORT *quantSpecTmp, INT sfbWidth,
+ FIXP_DBL threshLdData, INT scf, INT minScf,
+ FIXP_DBL *distLdData, INT *minScfCalculated,
+ INT dZoneQuantEnable) {
+ FIXP_DBL sfbDistLdData;
+ INT scfBest = scf;
+ INT k;
+ FIXP_DBL distFactorLdData = FL2FXCONST_DBL(-0.0050301265); /* ld64(1/1.25) */
+
+ /* calc real distortion */
+ sfbDistLdData =
+ FDKaacEnc_calcSfbDist(spec, quantSpec, sfbWidth, scf, dZoneQuantEnable);
+ *minScfCalculated = scf;
+ /* nmr > 1.25 -> try to improve nmr */
+ if (sfbDistLdData > (threshLdData - distFactorLdData)) {
+ INT scfEstimated = scf;
+ FIXP_DBL sfbDistBestLdData = sfbDistLdData;
+ INT cnt;
+ /* improve by bigger scf ? */
+ cnt = 0;
+
+ while ((sfbDistLdData > (threshLdData - distFactorLdData)) &&
+ (cnt++ < UPCOUNT_LIMIT)) {
+ scf++;
+ sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf,
+ dZoneQuantEnable);
+
+ if (sfbDistLdData < sfbDistBestLdData) {
+ scfBest = scf;
+ sfbDistBestLdData = sfbDistLdData;
+ for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k];
+ }
+ }
+ /* improve by smaller scf ? */
+ cnt = 0;
+ scf = scfEstimated;
+ sfbDistLdData = sfbDistBestLdData;
+ while ((sfbDistLdData > (threshLdData - distFactorLdData)) && (cnt++ < 1) &&
+ (scf > minScf)) {
+ scf--;
+ sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf,
+ dZoneQuantEnable);
+
+ if (sfbDistLdData < sfbDistBestLdData) {
+ scfBest = scf;
+ sfbDistBestLdData = sfbDistLdData;
+ for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k];
+ }
+ *minScfCalculated = scf;
+ }
+ *distLdData = sfbDistBestLdData;
+ } else { /* nmr <= 1.25 -> try to find bigger scf to use less bits */
+ FIXP_DBL sfbDistBestLdData = sfbDistLdData;
+ FIXP_DBL sfbDistAllowedLdData =
+ fixMin(sfbDistLdData - distFactorLdData, threshLdData);
+ int cnt;
+ for (cnt = 0; cnt < UPCOUNT_LIMIT; cnt++) {
+ scf++;
+ sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf,
+ dZoneQuantEnable);
+
+ if (sfbDistLdData < sfbDistAllowedLdData) {
+ *minScfCalculated = scfBest + 1;
+ scfBest = scf;
+ sfbDistBestLdData = sfbDistLdData;
+ for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k];
+ }
+ }
+ *distLdData = sfbDistBestLdData;
+ }
+
+ /* return best scalefactor */
+ return scfBest;
+}
+
+/*
+ Function: FDKaacEnc_assimilateSingleScf
+
+*/
+static void FDKaacEnc_assimilateSingleScf(
+ const PSY_OUT_CHANNEL *psyOutChan, const QC_OUT_CHANNEL *qcOutChannel,
+ SHORT *quantSpec, SHORT *quantSpecTmp, INT dZoneQuantEnable, INT *scf,
+ const INT *minScf, FIXP_DBL *sfbDist, FIXP_DBL *sfbConstPePart,
+ const FIXP_DBL *sfbFormFactorLdData, const FIXP_DBL *sfbNRelevantLines,
+ INT *minScfCalculated, INT restartOnSuccess) {
+ INT sfbLast, sfbAct, sfbNext;
+ INT scfAct, *scfLast, *scfNext, scfMin, scfMax;
+ INT sfbWidth, sfbOffs;
+ FIXP_DBL enLdData;
+ FIXP_DBL sfbPeOld, sfbPeNew;
+ FIXP_DBL sfbDistNew;
+ INT i, k;
+ INT success = 0;
+ FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL deltaPeNew, deltaPeTmp;
+ INT prevScfLast[MAX_GROUPED_SFB], prevScfNext[MAX_GROUPED_SFB];
+ FIXP_DBL deltaPeLast[MAX_GROUPED_SFB];
+ INT updateMinScfCalculated;
+
+ for (i = 0; i < psyOutChan->sfbCnt; i++) {
+ prevScfLast[i] = FDK_INT_MAX;
+ prevScfNext[i] = FDK_INT_MAX;
+ deltaPeLast[i] = (FIXP_DBL)FDK_INT_MAX;
+ }
+
+ sfbLast = -1;
+ sfbAct = -1;
+ sfbNext = -1;
+ scfLast = 0;
+ scfNext = 0;
+ scfMin = FDK_INT_MAX;
+ scfMax = FDK_INT_MAX;
+ do {
+ /* search for new relevant sfb */
+ sfbNext++;
+ while ((sfbNext < psyOutChan->sfbCnt) && (scf[sfbNext] == FDK_INT_MIN))
+ sfbNext++;
+ if ((sfbLast >= 0) && (sfbAct >= 0) && (sfbNext < psyOutChan->sfbCnt)) {
+ /* relevant scfs to the left and to the right */
+ scfAct = scf[sfbAct];
+ scfLast = scf + sfbLast;
+ scfNext = scf + sfbNext;
+ scfMin = fixMin(*scfLast, *scfNext);
+ scfMax = fixMax(*scfLast, *scfNext);
+ } else if ((sfbLast == -1) && (sfbAct >= 0) &&
+ (sfbNext < psyOutChan->sfbCnt)) {
+ /* first relevant scf */
+ scfAct = scf[sfbAct];
+ scfLast = &scfAct;
+ scfNext = scf + sfbNext;
+ scfMin = *scfNext;
+ scfMax = *scfNext;
+ } else if ((sfbLast >= 0) && (sfbAct >= 0) &&
+ (sfbNext == psyOutChan->sfbCnt)) {
+ /* last relevant scf */
+ scfAct = scf[sfbAct];
+ scfLast = scf + sfbLast;
+ scfNext = &scfAct;
+ scfMin = *scfLast;
+ scfMax = *scfLast;
+ }
+ if (sfbAct >= 0) scfMin = fixMax(scfMin, minScf[sfbAct]);
+
+ if ((sfbAct >= 0) && (sfbLast >= 0 || sfbNext < psyOutChan->sfbCnt) &&
+ (scfAct > scfMin) && (scfAct <= scfMin + MAX_SCF_DELTA) &&
+ (scfAct >= scfMax - MAX_SCF_DELTA) &&
+ (scfAct <=
+ fixMin(scfMin, fixMin(*scfLast, *scfNext)) + MAX_SCF_DELTA) &&
+ (*scfLast != prevScfLast[sfbAct] || *scfNext != prevScfNext[sfbAct] ||
+ deltaPe < deltaPeLast[sfbAct])) {
+ /* bigger than neighbouring scf found, try to use smaller scf */
+ success = 0;
+
+ sfbWidth =
+ psyOutChan->sfbOffsets[sfbAct + 1] - psyOutChan->sfbOffsets[sfbAct];
+ sfbOffs = psyOutChan->sfbOffsets[sfbAct];
+
+ /* estimate required bits for actual scf */
+ enLdData = qcOutChannel->sfbEnergyLdData[sfbAct];
+
+ /* sfbConstPePart[sfbAct] = (float)log(6.75f*en/sfbFormFactor[sfbAct]) *
+ * LOG2_1; */
+ /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for
+ * log2 */
+ /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */
+ if (sfbConstPePart[sfbAct] == (FIXP_DBL)FDK_INT_MIN) {
+ sfbConstPePart[sfbAct] = ((enLdData - sfbFormFactorLdData[sfbAct] -
+ FL2FXCONST_DBL(0.09375f)) >>
+ 1) +
+ FL2FXCONST_DBL(0.02152255861f);
+ }
+
+ sfbPeOld = FDKaacEnc_calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct],
+ sfbNRelevantLines[sfbAct]) +
+ FDKaacEnc_countSingleScfBits(scfAct, *scfLast, *scfNext);
+
+ deltaPeNew = deltaPe;
+ updateMinScfCalculated = 1;
+
+ do {
+ /* estimate required bits for smaller scf */
+ scfAct--;
+ /* check only if the same check was not done before */
+ if (scfAct < minScfCalculated[sfbAct] &&
+ scfAct >= scfMax - MAX_SCF_DELTA) {
+ /* estimate required bits for new scf */
+ sfbPeNew = FDKaacEnc_calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct],
+ sfbNRelevantLines[sfbAct]) +
+ FDKaacEnc_countSingleScfBits(scfAct, *scfLast, *scfNext);
+
+ /* use new scf if no increase in pe and
+ quantization error is smaller */
+ deltaPeTmp = deltaPe + sfbPeNew - sfbPeOld;
+ /* 0.0006103515625f = 10.0f/(2^(2*AS_PE_FAC_SHIFT)) */
+ if (deltaPeTmp < FL2FXCONST_DBL(0.0006103515625f)) {
+ /* distortion of new scf */
+ sfbDistNew = FDKaacEnc_calcSfbDist(
+ qcOutChannel->mdctSpectrum + sfbOffs, quantSpecTmp + sfbOffs,
+ sfbWidth, scfAct, dZoneQuantEnable);
+
+ if (sfbDistNew < sfbDist[sfbAct]) {
+ /* success, replace scf by new one */
+ scf[sfbAct] = scfAct;
+ sfbDist[sfbAct] = sfbDistNew;
+
+ for (k = 0; k < sfbWidth; k++)
+ quantSpec[sfbOffs + k] = quantSpecTmp[sfbOffs + k];
+
+ deltaPeNew = deltaPeTmp;
+ success = 1;
+ }
+ /* mark as already checked */
+ if (updateMinScfCalculated) minScfCalculated[sfbAct] = scfAct;
+ } else {
+ /* from this scf value on not all new values have been checked */
+ updateMinScfCalculated = 0;
+ }
+ }
+ } while (scfAct > scfMin);
+
+ deltaPe = deltaPeNew;
+
+ /* save parameters to avoid multiple computations of the same sfb */
+ prevScfLast[sfbAct] = *scfLast;
+ prevScfNext[sfbAct] = *scfNext;
+ deltaPeLast[sfbAct] = deltaPe;
+ }
+
+ if (success && restartOnSuccess) {
+ /* start again at first sfb */
+ sfbLast = -1;
+ sfbAct = -1;
+ sfbNext = -1;
+ scfLast = 0;
+ scfNext = 0;
+ scfMin = FDK_INT_MAX;
+ scfMax = FDK_INT_MAX;
+ success = 0;
+ } else {
+ /* shift sfbs for next band */
+ sfbLast = sfbAct;
+ sfbAct = sfbNext;
+ }
+ } while (sfbNext < psyOutChan->sfbCnt);
+}
+
+/*
+ Function: FDKaacEnc_assimilateMultipleScf
+
+*/
+static void FDKaacEnc_assimilateMultipleScf(
+ PSY_OUT_CHANNEL *psyOutChan, QC_OUT_CHANNEL *qcOutChannel, SHORT *quantSpec,
+ SHORT *quantSpecTmp, INT dZoneQuantEnable, INT *scf, const INT *minScf,
+ FIXP_DBL *sfbDist, FIXP_DBL *sfbConstPePart, FIXP_DBL *sfbFormFactorLdData,
+ FIXP_DBL *sfbNRelevantLines) {
+ INT sfb, startSfb, stopSfb;
+ INT scfTmp[MAX_GROUPED_SFB], scfMin, scfMax, scfAct;
+ INT possibleRegionFound;
+ INT sfbWidth, sfbOffs, i, k;
+ FIXP_DBL sfbDistNew[MAX_GROUPED_SFB], distOldSum, distNewSum;
+ INT deltaScfBits;
+ FIXP_DBL deltaSpecPe;
+ FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL deltaPeNew;
+ INT sfbCnt = psyOutChan->sfbCnt;
+
+ /* calc min and max scalfactors */
+ scfMin = FDK_INT_MAX;
+ scfMax = FDK_INT_MIN;
+ for (sfb = 0; sfb < sfbCnt; sfb++) {
+ if (scf[sfb] != FDK_INT_MIN) {
+ scfMin = fixMin(scfMin, scf[sfb]);
+ scfMax = fixMax(scfMax, scf[sfb]);
+ }
+ }
+
+ if (scfMax != FDK_INT_MIN && scfMax <= scfMin + MAX_SCF_DELTA) {
+ scfAct = scfMax;
+
+ do {
+ /* try smaller scf */
+ scfAct--;
+ for (i = 0; i < MAX_GROUPED_SFB; i++) scfTmp[i] = scf[i];
+ stopSfb = 0;
+ do {
+ /* search for region where all scfs are bigger than scfAct */
+ sfb = stopSfb;
+ while (sfb < sfbCnt && (scf[sfb] == FDK_INT_MIN || scf[sfb] <= scfAct))
+ sfb++;
+ startSfb = sfb;
+ sfb++;
+ while (sfb < sfbCnt && (scf[sfb] == FDK_INT_MIN || scf[sfb] > scfAct))
+ sfb++;
+ stopSfb = sfb;
+
+ /* check if in all sfb of a valid region scfAct >= minScf[sfb] */
+ possibleRegionFound = 0;
+ if (startSfb < sfbCnt) {
+ possibleRegionFound = 1;
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scf[sfb] != FDK_INT_MIN)
+ if (scfAct < minScf[sfb]) {
+ possibleRegionFound = 0;
+ break;
+ }
+ }
+ }
+
+ if (possibleRegionFound) { /* region found */
+
+ /* replace scfs in region by scfAct */
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scfTmp[sfb] != FDK_INT_MIN) scfTmp[sfb] = scfAct;
+ }
+
+ /* estimate change in bit demand for new scfs */
+ deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt,
+ startSfb, stopSfb);
+
+ deltaSpecPe = FDKaacEnc_calcSpecPeDiff(
+ psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart,
+ sfbFormFactorLdData, sfbNRelevantLines, startSfb, stopSfb);
+
+ deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe;
+
+ /* new bit demand small enough ? */
+ /* 0.0006103515625f = 10.0f/(2^(2*AS_PE_FAC_SHIFT)) */
+ if (deltaPeNew < FL2FXCONST_DBL(0.0006103515625f)) {
+ /* quantize and calc sum of new distortion */
+ distOldSum = distNewSum = FL2FXCONST_DBL(0.0f);
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scfTmp[sfb] != FDK_INT_MIN) {
+ distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT;
+
+ sfbWidth = psyOutChan->sfbOffsets[sfb + 1] -
+ psyOutChan->sfbOffsets[sfb];
+ sfbOffs = psyOutChan->sfbOffsets[sfb];
+
+ sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(
+ qcOutChannel->mdctSpectrum + sfbOffs,
+ quantSpecTmp + sfbOffs, sfbWidth, scfAct, dZoneQuantEnable);
+
+ if (sfbDistNew[sfb] > qcOutChannel->sfbThresholdLdData[sfb]) {
+ /* no improvement, skip further dist. calculations */
+ distNewSum = distOldSum << 1;
+ break;
+ }
+ distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT;
+ }
+ }
+ /* distortion smaller ? -> use new scalefactors */
+ if (distNewSum < distOldSum) {
+ deltaPe = deltaPeNew;
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scf[sfb] != FDK_INT_MIN) {
+ sfbWidth = psyOutChan->sfbOffsets[sfb + 1] -
+ psyOutChan->sfbOffsets[sfb];
+ sfbOffs = psyOutChan->sfbOffsets[sfb];
+ scf[sfb] = scfAct;
+ sfbDist[sfb] = sfbDistNew[sfb];
+
+ for (k = 0; k < sfbWidth; k++)
+ quantSpec[sfbOffs + k] = quantSpecTmp[sfbOffs + k];
+ }
+ }
+ }
+ }
+ }
+
+ } while (stopSfb <= sfbCnt);
+
+ } while (scfAct > scfMin);
+ }
+}
+
+/*
+ Function: FDKaacEnc_FDKaacEnc_assimilateMultipleScf2
+
+*/
+static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(
+ PSY_OUT_CHANNEL *psyOutChan, QC_OUT_CHANNEL *qcOutChannel, SHORT *quantSpec,
+ SHORT *quantSpecTmp, INT dZoneQuantEnable, INT *scf, const INT *minScf,
+ FIXP_DBL *sfbDist, FIXP_DBL *sfbConstPePart, FIXP_DBL *sfbFormFactorLdData,
+ FIXP_DBL *sfbNRelevantLines) {
+ INT sfb, startSfb, stopSfb;
+ INT scfTmp[MAX_GROUPED_SFB], scfAct, scfNew;
+ INT scfPrev, scfNext, scfPrevNextMin, scfPrevNextMax, scfLo, scfHi;
+ INT scfMin, scfMax;
+ INT *sfbOffs = psyOutChan->sfbOffsets;
+ FIXP_DBL sfbDistNew[MAX_GROUPED_SFB], sfbDistMax[MAX_GROUPED_SFB];
+ FIXP_DBL distOldSum, distNewSum;
+ INT deltaScfBits;
+ FIXP_DBL deltaSpecPe;
+ FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL deltaPeNew = FL2FXCONST_DBL(0.0f);
+ INT sfbCnt = psyOutChan->sfbCnt;
+ INT bSuccess, bCheckScf;
+ INT i, k;
+
+ /* calc min and max scalfactors */
+ scfMin = FDK_INT_MAX;
+ scfMax = FDK_INT_MIN;
+ for (sfb = 0; sfb < sfbCnt; sfb++) {
+ if (scf[sfb] != FDK_INT_MIN) {
+ scfMin = fixMin(scfMin, scf[sfb]);
+ scfMax = fixMax(scfMax, scf[sfb]);
+ }
+ }
+
+ stopSfb = 0;
+ scfAct = FDK_INT_MIN;
+ do {
+ /* search for region with same scf values scfAct */
+ scfPrev = scfAct;
+
+ sfb = stopSfb;
+ while (sfb < sfbCnt && (scf[sfb] == FDK_INT_MIN)) sfb++;
+ startSfb = sfb;
+ scfAct = scf[startSfb];
+ sfb++;
+ while (sfb < sfbCnt &&
+ ((scf[sfb] == FDK_INT_MIN) || (scf[sfb] == scf[startSfb])))
+ sfb++;
+ stopSfb = sfb;
+
+ if (stopSfb < sfbCnt)
+ scfNext = scf[stopSfb];
+ else
+ scfNext = scfAct;
+
+ if (scfPrev == FDK_INT_MIN) scfPrev = scfAct;
+
+ scfPrevNextMax = fixMax(scfPrev, scfNext);
+ scfPrevNextMin = fixMin(scfPrev, scfNext);
+
+ /* try to reduce bits by checking scf values in the range
+ scf[startSfb]...scfHi */
+ scfHi = fixMax(scfPrevNextMax, scfAct);
+ /* try to find a better solution by reducing the scf difference to
+ the nearest possible lower scf */
+ if (scfPrevNextMax >= scfAct)
+ scfLo = fixMin(scfAct, scfPrevNextMin);
+ else
+ scfLo = scfPrevNextMax;
+
+ if (startSfb < sfbCnt &&
+ scfHi - scfLo <= MAX_SCF_DELTA) { /* region found */
+ /* 1. try to save bits by coarser quantization */
+ if (scfHi > scf[startSfb]) {
+ /* calculate the allowed distortion */
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scf[sfb] != FDK_INT_MIN) {
+ /* sfbDistMax[sfb] =
+ * (float)pow(qcOutChannel->sfbThreshold[sfb]*sfbDist[sfb]*sfbDist[sfb],1.0f/3.0f);
+ */
+ /* sfbDistMax[sfb] =
+ * fixMax(sfbDistMax[sfb],qcOutChannel->sfbEnergy[sfb]*FL2FXCONST_DBL(1.e-3f));
+ */
+ /* -0.15571537944 = ld64(1.e-3f)*/
+ sfbDistMax[sfb] = fMult(FL2FXCONST_DBL(1.0f / 3.0f),
+ qcOutChannel->sfbThresholdLdData[sfb]) +
+ fMult(FL2FXCONST_DBL(1.0f / 3.0f), sfbDist[sfb]) +
+ fMult(FL2FXCONST_DBL(1.0f / 3.0f), sfbDist[sfb]);
+ sfbDistMax[sfb] =
+ fixMax(sfbDistMax[sfb], qcOutChannel->sfbEnergyLdData[sfb] -
+ FL2FXCONST_DBL(0.15571537944));
+ sfbDistMax[sfb] =
+ fixMin(sfbDistMax[sfb], qcOutChannel->sfbThresholdLdData[sfb]);
+ }
+ }
+
+ /* loop over all possible scf values for this region */
+ bCheckScf = 1;
+ for (scfNew = scf[startSfb] + 1; scfNew <= scfHi; scfNew++) {
+ for (k = 0; k < MAX_GROUPED_SFB; k++) scfTmp[k] = scf[k];
+
+ /* replace scfs in region by scfNew */
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scfTmp[sfb] != FDK_INT_MIN) scfTmp[sfb] = scfNew;
+ }
+
+ /* estimate change in bit demand for new scfs */
+ deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt,
+ startSfb, stopSfb);
+
+ deltaSpecPe = FDKaacEnc_calcSpecPeDiff(
+ psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart,
+ sfbFormFactorLdData, sfbNRelevantLines, startSfb, stopSfb);
+
+ deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe;
+
+ /* new bit demand small enough ? */
+ if (deltaPeNew < FL2FXCONST_DBL(0.0f)) {
+ bSuccess = 1;
+
+ /* quantize and calc sum of new distortion */
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scfTmp[sfb] != FDK_INT_MIN) {
+ sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(
+ qcOutChannel->mdctSpectrum + sfbOffs[sfb],
+ quantSpecTmp + sfbOffs[sfb],
+ sfbOffs[sfb + 1] - sfbOffs[sfb], scfNew, dZoneQuantEnable);
+
+ if (sfbDistNew[sfb] > sfbDistMax[sfb]) {
+ /* no improvement, skip further dist. calculations */
+ bSuccess = 0;
+ if (sfbDistNew[sfb] == qcOutChannel->sfbEnergyLdData[sfb]) {
+ /* if whole sfb is already quantized to 0, further
+ checks with even coarser quant. are useless*/
+ bCheckScf = 0;
+ }
+ break;
+ }
+ }
+ }
+ if (bCheckScf == 0) /* further calculations useless ? */
+ break;
+ /* distortion small enough ? -> use new scalefactors */
+ if (bSuccess) {
+ deltaPe = deltaPeNew;
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scf[sfb] != FDK_INT_MIN) {
+ scf[sfb] = scfNew;
+ sfbDist[sfb] = sfbDistNew[sfb];
+
+ for (k = 0; k < sfbOffs[sfb + 1] - sfbOffs[sfb]; k++)
+ quantSpec[sfbOffs[sfb] + k] =
+ quantSpecTmp[sfbOffs[sfb] + k];
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* 2. only if coarser quantization was not successful, try to find
+ a better solution by finer quantization and reducing bits for
+ scalefactor coding */
+ if (scfAct == scf[startSfb] && scfLo < scfAct &&
+ scfMax - scfMin <= MAX_SCF_DELTA) {
+ int bminScfViolation = 0;
+
+ for (k = 0; k < MAX_GROUPED_SFB; k++) scfTmp[k] = scf[k];
+
+ scfNew = scfLo;
+
+ /* replace scfs in region by scfNew and
+ check if in all sfb scfNew >= minScf[sfb] */
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scfTmp[sfb] != FDK_INT_MIN) {
+ scfTmp[sfb] = scfNew;
+ if (scfNew < minScf[sfb]) bminScfViolation = 1;
+ }
+ }
+
+ if (!bminScfViolation) {
+ /* estimate change in bit demand for new scfs */
+ deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt,
+ startSfb, stopSfb);
+
+ deltaSpecPe = FDKaacEnc_calcSpecPeDiff(
+ psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart,
+ sfbFormFactorLdData, sfbNRelevantLines, startSfb, stopSfb);
+
+ deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe;
+ }
+
+ /* new bit demand small enough ? */
+ if (!bminScfViolation && deltaPeNew < FL2FXCONST_DBL(0.0f)) {
+ /* quantize and calc sum of new distortion */
+ distOldSum = distNewSum = FL2FXCONST_DBL(0.0f);
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scfTmp[sfb] != FDK_INT_MIN) {
+ distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT;
+
+ sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(
+ qcOutChannel->mdctSpectrum + sfbOffs[sfb],
+ quantSpecTmp + sfbOffs[sfb], sfbOffs[sfb + 1] - sfbOffs[sfb],
+ scfNew, dZoneQuantEnable);
+
+ if (sfbDistNew[sfb] > qcOutChannel->sfbThresholdLdData[sfb]) {
+ /* no improvement, skip further dist. calculations */
+ distNewSum = distOldSum << 1;
+ break;
+ }
+ distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT;
+ }
+ }
+ /* distortion smaller ? -> use new scalefactors */
+ if (distNewSum < fMult(FL2FXCONST_DBL(0.8f), distOldSum)) {
+ deltaPe = deltaPeNew;
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scf[sfb] != FDK_INT_MIN) {
+ scf[sfb] = scfNew;
+ sfbDist[sfb] = sfbDistNew[sfb];
+
+ for (k = 0; k < sfbOffs[sfb + 1] - sfbOffs[sfb]; k++)
+ quantSpec[sfbOffs[sfb] + k] = quantSpecTmp[sfbOffs[sfb] + k];
+ }
+ }
+ }
+ }
+ }
+
+ /* 3. try to find a better solution (save bits) by only reducing the
+ scalefactor without new quantization */
+ if (scfMax - scfMin <=
+ MAX_SCF_DELTA - 3) { /* 3 bec. scf is reduced 3 times,
+ see for loop below */
+
+ for (k = 0; k < sfbCnt; k++) scfTmp[k] = scf[k];
+
+ for (i = 0; i < 3; i++) {
+ scfNew = scfTmp[startSfb] - 1;
+ /* replace scfs in region by scfNew */
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scfTmp[sfb] != FDK_INT_MIN) scfTmp[sfb] = scfNew;
+ }
+ /* estimate change in bit demand for new scfs */
+ deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt,
+ startSfb, stopSfb);
+ deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits;
+ /* new bit demand small enough ? */
+ if (deltaPeNew <= FL2FXCONST_DBL(0.0f)) {
+ bSuccess = 1;
+ distOldSum = distNewSum = FL2FXCONST_DBL(0.0f);
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scfTmp[sfb] != FDK_INT_MIN) {
+ FIXP_DBL sfbEnQ;
+ /* calc the energy and distortion of the quantized spectrum for
+ a smaller scf */
+ FDKaacEnc_calcSfbQuantEnergyAndDist(
+ qcOutChannel->mdctSpectrum + sfbOffs[sfb],
+ quantSpec + sfbOffs[sfb], sfbOffs[sfb + 1] - sfbOffs[sfb],
+ scfNew, &sfbEnQ, &sfbDistNew[sfb]);
+
+ distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT;
+ distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT;
+
+ /* 0.00259488556167 = ld64(1.122f) */
+ /* -0.00778722686652 = ld64(0.7079f) */
+ if ((sfbDistNew[sfb] >
+ (sfbDist[sfb] + FL2FXCONST_DBL(0.00259488556167f))) ||
+ (sfbEnQ < (qcOutChannel->sfbEnergyLdData[sfb] -
+ FL2FXCONST_DBL(0.00778722686652f)))) {
+ bSuccess = 0;
+ break;
+ }
+ }
+ }
+ /* distortion smaller ? -> use new scalefactors */
+ if (distNewSum < distOldSum && bSuccess) {
+ deltaPe = deltaPeNew;
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scf[sfb] != FDK_INT_MIN) {
+ scf[sfb] = scfNew;
+ sfbDist[sfb] = sfbDistNew[sfb];
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } while (stopSfb <= sfbCnt);
+}
+
+static void FDKaacEnc_EstimateScaleFactorsChannel(
+ QC_OUT_CHANNEL *qcOutChannel, PSY_OUT_CHANNEL *psyOutChannel,
+ INT *RESTRICT scf, INT *RESTRICT globalGain,
+ FIXP_DBL *RESTRICT sfbFormFactorLdData, const INT invQuant,
+ SHORT *RESTRICT quantSpec, const INT dZoneQuantEnable) {
+ INT i, j, sfb, sfbOffs;
+ INT scfInt;
+ INT maxSf;
+ INT minSf;
+ FIXP_DBL threshLdData;
+ FIXP_DBL energyLdData;
+ FIXP_DBL energyPartLdData;
+ FIXP_DBL thresholdPartLdData;
+ FIXP_DBL scfFract;
+ FIXP_DBL maxSpec;
+ INT minScfCalculated[MAX_GROUPED_SFB];
+ FIXP_DBL sfbDistLdData[MAX_GROUPED_SFB];
+ C_ALLOC_SCRATCH_START(quantSpecTmp, SHORT, (1024))
+ INT minSfMaxQuant[MAX_GROUPED_SFB];
+
+ FIXP_DBL threshConstLdData =
+ FL2FXCONST_DBL(0.04304511722f); /* log10(6.75)/log10(2.0)/64.0 */
+ FIXP_DBL convConst = FL2FXCONST_DBL(0.30102999566f); /* log10(2.0) */
+ FIXP_DBL c1Const =
+ FL2FXCONST_DBL(-0.27083183594f); /* C1 = -69.33295 => C1/2^8 */
+
+ if (invQuant > 0) {
+ FDKmemclear(quantSpec, (1024) * sizeof(SHORT));
+ }
+
+ /* scfs without energy or with thresh>energy are marked with FDK_INT_MIN */
+ for (i = 0; i < psyOutChannel->sfbCnt; i++) {
+ scf[i] = FDK_INT_MIN;
+ }
+
+ for (i = 0; i < MAX_GROUPED_SFB; i++) {
+ minSfMaxQuant[i] = FDK_INT_MIN;
+ }
+
+ for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
+ sfbOffs += psyOutChannel->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
+ threshLdData = qcOutChannel->sfbThresholdLdData[sfbOffs + sfb];
+ energyLdData = qcOutChannel->sfbEnergyLdData[sfbOffs + sfb];
+
+ sfbDistLdData[sfbOffs + sfb] = energyLdData;
+
+ if (energyLdData > threshLdData) {
+ FIXP_DBL tmp;
+
+ /* energyPart = (float)log10(sfbFormFactor[sfbOffs+sfb]); */
+ /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */
+ energyPartLdData =
+ sfbFormFactorLdData[sfbOffs + sfb] + FL2FXCONST_DBL(0.09375f);
+
+ /* influence of allowed distortion */
+ /* thresholdPart = (float)log10(6.75*thresh+FLT_MIN); */
+ thresholdPartLdData = threshConstLdData + threshLdData;
+
+ /* scf calc */
+ /* scfFloat = 8.8585f * (thresholdPart - energyPart); */
+ scfFract = thresholdPartLdData - energyPartLdData;
+ /* conversion from log2 to log10 */
+ scfFract = fMult(convConst, scfFract);
+ /* (8.8585f * scfFract)/8 = 8/8 * scfFract + 0.8585 * scfFract/8 */
+ scfFract = scfFract + fMult(FL2FXCONST_DBL(0.8585f), scfFract >> 3);
+
+ /* integer scalefactor */
+ /* scfInt = (int)floor(scfFloat); */
+ scfInt =
+ (INT)(scfFract >>
+ ((DFRACT_BITS - 1) - 3 -
+ LD_DATA_SHIFT)); /* 3 bits => scfFract/8.0; 6 bits => ld64 */
+
+ /* maximum of spectrum */
+ maxSpec = FL2FXCONST_DBL(0.0f);
+
+ /* Unroll by 4, allow dual memory access */
+ DWORD_ALIGNED(qcOutChannel->mdctSpectrum);
+ for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb];
+ j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j += 4) {
+ maxSpec = fMax(maxSpec,
+ fMax(fMax(fAbs(qcOutChannel->mdctSpectrum[j + 0]),
+ fAbs(qcOutChannel->mdctSpectrum[j + 1])),
+ fMax(fAbs(qcOutChannel->mdctSpectrum[j + 2]),
+ fAbs(qcOutChannel->mdctSpectrum[j + 3]))));
+ }
+ /* lower scf limit to avoid quantized values bigger than MAX_QUANT */
+ /* C1 = -69.33295f, C2 = 5.77078f = 4/log(2) */
+ /* minSfMaxQuant[sfbOffs+sfb] = (int)ceil(C1 + C2*log(maxSpec)); */
+ /* C1/2^8 + 4/log(2.0)*log(maxSpec)/2^8 => C1/2^8 +
+ * log(maxSpec)/log(2.0)*4/2^8 => C1/2^8 + log(maxSpec)/log(2.0)/64.0 */
+
+ // minSfMaxQuant[sfbOffs+sfb] = ((INT) ((c1Const + CalcLdData(maxSpec))
+ // >> ((DFRACT_BITS-1)-8))) + 1;
+ tmp = CalcLdData(maxSpec);
+ if (c1Const > FL2FXCONST_DBL(-1.f) - tmp) {
+ minSfMaxQuant[sfbOffs + sfb] =
+ ((INT)((c1Const + tmp) >> ((DFRACT_BITS - 1) - 8))) + 1;
+ } else {
+ minSfMaxQuant[sfbOffs + sfb] =
+ ((INT)(FL2FXCONST_DBL(-1.f) >> ((DFRACT_BITS - 1) - 8))) + 1;
+ }
+
+ scfInt = fixMax(scfInt, minSfMaxQuant[sfbOffs + sfb]);
+
+ /* find better scalefactor with analysis by synthesis */
+ if (invQuant > 0) {
+ scfInt = FDKaacEnc_improveScf(
+ qcOutChannel->mdctSpectrum +
+ psyOutChannel->sfbOffsets[sfbOffs + sfb],
+ quantSpec + psyOutChannel->sfbOffsets[sfbOffs + sfb],
+ quantSpecTmp + psyOutChannel->sfbOffsets[sfbOffs + sfb],
+ psyOutChannel->sfbOffsets[sfbOffs + sfb + 1] -
+ psyOutChannel->sfbOffsets[sfbOffs + sfb],
+ threshLdData, scfInt, minSfMaxQuant[sfbOffs + sfb],
+ &sfbDistLdData[sfbOffs + sfb], &minScfCalculated[sfbOffs + sfb],
+ dZoneQuantEnable);
+ }
+ scf[sfbOffs + sfb] = scfInt;
+ }
+ }
+ }
+
+ if (invQuant > 0) {
+ /* try to decrease scf differences */
+ FIXP_DBL sfbConstPePart[MAX_GROUPED_SFB];
+ FIXP_DBL sfbNRelevantLines[MAX_GROUPED_SFB];
+
+ for (i = 0; i < psyOutChannel->sfbCnt; i++)
+ sfbConstPePart[i] = (FIXP_DBL)FDK_INT_MIN;
+
+ FDKaacEnc_calcSfbRelevantLines(
+ sfbFormFactorLdData, qcOutChannel->sfbEnergyLdData,
+ qcOutChannel->sfbThresholdLdData, psyOutChannel->sfbOffsets,
+ psyOutChannel->sfbCnt, psyOutChannel->sfbPerGroup,
+ psyOutChannel->maxSfbPerGroup, sfbNRelevantLines);
+
+ FDKaacEnc_assimilateSingleScf(
+ psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, dZoneQuantEnable,
+ scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart, sfbFormFactorLdData,
+ sfbNRelevantLines, minScfCalculated, 1);
+
+ if (invQuant > 1) {
+ FDKaacEnc_assimilateMultipleScf(
+ psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
+ dZoneQuantEnable, scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart,
+ sfbFormFactorLdData, sfbNRelevantLines);
+
+ FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(
+ psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
+ dZoneQuantEnable, scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart,
+ sfbFormFactorLdData, sfbNRelevantLines);
+ }
+ }
+
+ /* get min scalefac */
+ minSf = FDK_INT_MAX;
+ for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
+ sfbOffs += psyOutChannel->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
+ if (scf[sfbOffs + sfb] != FDK_INT_MIN)
+ minSf = fixMin(minSf, scf[sfbOffs + sfb]);
+ }
+ }
+
+ /* limit scf delta */
+ for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
+ sfbOffs += psyOutChannel->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
+ if ((scf[sfbOffs + sfb] != FDK_INT_MIN) &&
+ (minSf + MAX_SCF_DELTA) < scf[sfbOffs + sfb]) {
+ scf[sfbOffs + sfb] = minSf + MAX_SCF_DELTA;
+ if (invQuant > 0) { /* changed bands need to be quantized again */
+ sfbDistLdData[sfbOffs + sfb] = FDKaacEnc_calcSfbDist(
+ qcOutChannel->mdctSpectrum +
+ psyOutChannel->sfbOffsets[sfbOffs + sfb],
+ quantSpec + psyOutChannel->sfbOffsets[sfbOffs + sfb],
+ psyOutChannel->sfbOffsets[sfbOffs + sfb + 1] -
+ psyOutChannel->sfbOffsets[sfbOffs + sfb],
+ scf[sfbOffs + sfb], dZoneQuantEnable);
+ }
+ }
+ }
+ }
+
+ /* get max scalefac for global gain */
+ maxSf = FDK_INT_MIN;
+ for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
+ sfbOffs += psyOutChannel->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
+ maxSf = fixMax(maxSf, scf[sfbOffs + sfb]);
+ }
+ }
+
+ /* calc loop scalefactors, if spec is not all zero (i.e. maxSf == -99) */
+ if (maxSf > FDK_INT_MIN) {
+ *globalGain = maxSf;
+ for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
+ sfbOffs += psyOutChannel->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
+ if (scf[sfbOffs + sfb] == FDK_INT_MIN) {
+ scf[sfbOffs + sfb] = 0;
+ /* set band explicitely to zero */
+ for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb];
+ j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j++) {
+ qcOutChannel->mdctSpectrum[j] = FL2FXCONST_DBL(0.0f);
+ }
+ } else {
+ scf[sfbOffs + sfb] = maxSf - scf[sfbOffs + sfb];
+ }
+ }
+ }
+ } else {
+ *globalGain = 0;
+ /* set spectrum explicitely to zero */
+ for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
+ sfbOffs += psyOutChannel->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
+ scf[sfbOffs + sfb] = 0;
+ /* set band explicitely to zero */
+ for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb];
+ j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j++) {
+ qcOutChannel->mdctSpectrum[j] = FL2FXCONST_DBL(0.0f);
+ }
+ }
+ }
+ }
+
+ /* free quantSpecTmp from scratch */
+ C_ALLOC_SCRATCH_END(quantSpecTmp, SHORT, (1024))
+}
+
+void FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[],
+ QC_OUT_CHANNEL *qcOutChannel[],
+ const INT invQuant,
+ const INT dZoneQuantEnable,
+ const INT nChannels) {
+ int ch;
+
+ for (ch = 0; ch < nChannels; ch++) {
+ FDKaacEnc_EstimateScaleFactorsChannel(
+ qcOutChannel[ch], psyOutChannel[ch], qcOutChannel[ch]->scf,
+ &qcOutChannel[ch]->globalGain, qcOutChannel[ch]->sfbFormFactorLdData,
+ invQuant, qcOutChannel[ch]->quantSpec, dZoneQuantEnable);
+ }
+}
diff --git a/fdk-aac/libAACenc/src/sf_estim.h b/fdk-aac/libAACenc/src/sf_estim.h
new file mode 100644
index 0000000..ab2d3c2
--- /dev/null
+++ b/fdk-aac/libAACenc/src/sf_estim.h
@@ -0,0 +1,124 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Scale factor estimation
+
+*******************************************************************************/
+
+#ifndef SF_ESTIM_H
+#define SF_ESTIM_H
+
+#include "common_fix.h"
+
+#include "psy_const.h"
+#include "qc_data.h"
+#include "interface.h"
+
+#define FORM_FAC_SHIFT 6
+
+void FDKaacEnc_CalcFormFactor(QC_OUT_CHANNEL *qcOutChannel[(2)],
+ PSY_OUT_CHANNEL *psyOutChannel[(2)],
+ const INT nChannels);
+
+void FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[],
+ QC_OUT_CHANNEL *qcOutChannel[],
+ const INT invQuant,
+ const INT dZoneQuantEnable,
+ const INT nChannels);
+
+#endif
diff --git a/fdk-aac/libAACenc/src/spreading.cpp b/fdk-aac/libAACenc/src/spreading.cpp
new file mode 100644
index 0000000..0fb43bb
--- /dev/null
+++ b/fdk-aac/libAACenc/src/spreading.cpp
@@ -0,0 +1,125 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Spreading of energy
+
+*******************************************************************************/
+
+#include "spreading.h"
+
+void FDKaacEnc_SpreadingMax(const INT pbCnt,
+ const FIXP_DBL *RESTRICT maskLowFactor,
+ const FIXP_DBL *RESTRICT maskHighFactor,
+ FIXP_DBL *RESTRICT pbSpreadEnergy) {
+ int i;
+ FIXP_DBL delay;
+
+ /* slope to higher frequencies */
+ delay = pbSpreadEnergy[0];
+ for (i = 1; i < pbCnt; i++) {
+ delay = fixMax(pbSpreadEnergy[i], fMult(maskHighFactor[i], delay));
+ pbSpreadEnergy[i] = delay;
+ }
+
+ /* slope to lower frequencies */
+ delay = pbSpreadEnergy[pbCnt - 1];
+ for (i = pbCnt - 2; i >= 0; i--) {
+ delay = fixMax(pbSpreadEnergy[i], fMult(maskLowFactor[i], delay));
+ pbSpreadEnergy[i] = delay;
+ }
+}
diff --git a/fdk-aac/libAACenc/src/spreading.h b/fdk-aac/libAACenc/src/spreading.h
new file mode 100644
index 0000000..e693031
--- /dev/null
+++ b/fdk-aac/libAACenc/src/spreading.h
@@ -0,0 +1,113 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Spreading of energy and weighted tonality
+
+*******************************************************************************/
+
+#ifndef SPREADING_H
+#define SPREADING_H
+
+#include "common_fix.h"
+
+void FDKaacEnc_SpreadingMax(const INT pbCnt,
+ const FIXP_DBL *RESTRICT maskLowFactor,
+ const FIXP_DBL *RESTRICT maskHighFactor,
+ FIXP_DBL *RESTRICT pbSpreadEnergy);
+
+#endif /* #ifndef SPREADING_H */
diff --git a/fdk-aac/libAACenc/src/tns_func.h b/fdk-aac/libAACenc/src/tns_func.h
new file mode 100644
index 0000000..6099bc7
--- /dev/null
+++ b/fdk-aac/libAACenc/src/tns_func.h
@@ -0,0 +1,129 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): Alex Goeschel
+
+ Description: Temporal noise shaping
+
+*******************************************************************************/
+
+#ifndef TNS_FUNC_H
+#define TNS_FUNC_H
+
+#include "common_fix.h"
+
+#include "psy_configuration.h"
+
+AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(
+ INT bitrate, INT samplerate, INT channels, INT blocktype, INT granuleLength,
+ INT isLowDelay, INT ldSbrPresent, TNS_CONFIG *tnsConfig,
+ PSY_CONFIGURATION *psyConfig, INT active, INT useTnsPeak);
+
+INT FDKaacEnc_TnsDetect(TNS_DATA *tnsData, const TNS_CONFIG *tC,
+ TNS_INFO *tnsInfo, INT sfbCnt, const FIXP_DBL *spectrum,
+ INT subBlockNumber, INT blockType);
+
+void FDKaacEnc_TnsSync(TNS_DATA *tnsDataDest, const TNS_DATA *tnsDataSrc,
+ TNS_INFO *tnsInfoDest, TNS_INFO *tnsInfoSrc,
+ const INT blockTypeDest, const INT blockTypeSrc,
+ const TNS_CONFIG *tC);
+
+INT FDKaacEnc_TnsEncode(TNS_INFO *tnsInfo, TNS_DATA *tnsData,
+ const INT numOfSfb, const TNS_CONFIG *tC,
+ const INT lowPassLine, FIXP_DBL *spectrum,
+ const INT subBlockNumber, const INT blockType);
+
+#endif /* TNS_FUNC_H */
diff --git a/fdk-aac/libAACenc/src/tonality.cpp b/fdk-aac/libAACenc/src/tonality.cpp
new file mode 100644
index 0000000..334e0f1
--- /dev/null
+++ b/fdk-aac/libAACenc/src/tonality.cpp
@@ -0,0 +1,219 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Convert chaos measure to the tonality index
+
+*******************************************************************************/
+
+#include "tonality.h"
+
+#include "chaosmeasure.h"
+
+#if defined(__arm__)
+#endif
+
+static const FIXP_DBL normlog =
+ (FIXP_DBL)0xd977d949; /*FL2FXCONST_DBL(-0.4342944819f *
+ FDKlog(2.0)/FDKlog(2.7182818)); */
+
+static void FDKaacEnc_CalcSfbTonality(FIXP_DBL *RESTRICT spectrum,
+ INT *RESTRICT sfbMaxScaleSpec,
+ FIXP_DBL *RESTRICT chaosMeasure,
+ FIXP_SGL *RESTRICT sfbTonality,
+ INT sfbCnt, const INT *RESTRICT sfbOffset,
+ FIXP_DBL *RESTRICT sfbEnergyLD64);
+
+void FDKaacEnc_CalculateFullTonality(FIXP_DBL *RESTRICT spectrum,
+ INT *RESTRICT sfbMaxScaleSpec,
+ FIXP_DBL *RESTRICT sfbEnergyLD64,
+ FIXP_SGL *RESTRICT sfbTonality, INT sfbCnt,
+ const INT *sfbOffset, INT usePns) {
+ INT j;
+ INT numberOfLines = sfbOffset[sfbCnt];
+
+ if (usePns) {
+ C_ALLOC_SCRATCH_START(chaosMeasurePerLine, FIXP_DBL, (1024))
+
+ /* calculate chaos measure */
+ FDKaacEnc_CalculateChaosMeasure(spectrum, numberOfLines,
+ chaosMeasurePerLine);
+
+ /* smooth ChaosMeasure */
+ FIXP_DBL left = chaosMeasurePerLine[0];
+ FIXP_DBL right;
+ for (j = 1; j < (numberOfLines - 1); j += 2) {
+ right = chaosMeasurePerLine[j];
+ right = right - (right >> 2);
+ left = right + (left >> 2);
+ chaosMeasurePerLine[j] = left; /* 0.25 left + 0.75 right */
+
+ right = chaosMeasurePerLine[j + 1];
+ right = right - (right >> 2);
+ left = right + (left >> 2);
+ chaosMeasurePerLine[j + 1] = left;
+ }
+ if (j == (numberOfLines - 1)) {
+ right = chaosMeasurePerLine[j];
+ right = right - (right >> 2);
+ left = right + (left >> 2);
+ chaosMeasurePerLine[j] = left;
+ }
+
+ FDKaacEnc_CalcSfbTonality(spectrum, sfbMaxScaleSpec, chaosMeasurePerLine,
+ sfbTonality, sfbCnt, sfbOffset, sfbEnergyLD64);
+
+ C_ALLOC_SCRATCH_END(chaosMeasurePerLine, FIXP_DBL, (1024))
+ }
+}
+
+/*****************************************************************************
+
+ functionname: CalculateTonalityIndex
+ description: computes tonality values out of unpredictability values
+ limits range and computes log()
+ returns:
+ input: ptr to energies, ptr to chaos measure values,
+ number of sfb
+ output: sfb wise tonality values
+
+*****************************************************************************/
+static void FDKaacEnc_CalcSfbTonality(FIXP_DBL *RESTRICT spectrum,
+ INT *RESTRICT sfbMaxScaleSpec,
+ FIXP_DBL *RESTRICT chaosMeasure,
+ FIXP_SGL *RESTRICT sfbTonality,
+ INT sfbCnt, const INT *RESTRICT sfbOffset,
+ FIXP_DBL *RESTRICT sfbEnergyLD64) {
+ INT i;
+
+ for (i = 0; i < sfbCnt; i++) {
+ FIXP_DBL chaosMeasureSfbLD64;
+ INT shiftBits =
+ fixMax(0, sfbMaxScaleSpec[i] -
+ 4); /* max sfbWidth = 96 ; 2^7=128 => 7/2 = 4 (spc*spc) */
+
+ INT j;
+ FIXP_DBL chaosMeasureSfb = FL2FXCONST_DBL(0.0);
+
+ /* calc chaosMeasurePerSfb */
+ for (j = (sfbOffset[i + 1] - sfbOffset[i]) - 1; j >= 0; j--) {
+ FIXP_DBL tmp = (*spectrum++) << shiftBits;
+ FIXP_DBL lineNrg = fMultDiv2(tmp, tmp);
+ chaosMeasureSfb = fMultAddDiv2(chaosMeasureSfb, lineNrg, *chaosMeasure++);
+ }
+
+ /* calc tonalityPerSfb */
+ if (chaosMeasureSfb != FL2FXCONST_DBL(0.0)) {
+ /* add ld(convtone)/64 and 2/64 bec.fMultDiv2 */
+ chaosMeasureSfbLD64 = CalcLdData((chaosMeasureSfb)) - sfbEnergyLD64[i];
+ chaosMeasureSfbLD64 += FL2FXCONST_DBL(3.0f / 64) -
+ ((FIXP_DBL)(shiftBits) << (DFRACT_BITS - 6));
+
+ if (chaosMeasureSfbLD64 >
+ FL2FXCONST_DBL(-0.0519051)) /* > ld(0.05)+ld(2) */
+ {
+ if (chaosMeasureSfbLD64 <= FL2FXCONST_DBL(0.0))
+ sfbTonality[i] =
+ FX_DBL2FX_SGL(fMultDiv2(chaosMeasureSfbLD64, normlog) << 7);
+ else
+ sfbTonality[i] = FL2FXCONST_SGL(0.0);
+ } else
+ sfbTonality[i] = (FIXP_SGL)MAXVAL_SGL;
+ } else
+ sfbTonality[i] = (FIXP_SGL)MAXVAL_SGL;
+ }
+}
diff --git a/fdk-aac/libAACenc/src/tonality.h b/fdk-aac/libAACenc/src/tonality.h
new file mode 100644
index 0000000..c5cf4c5
--- /dev/null
+++ b/fdk-aac/libAACenc/src/tonality.h
@@ -0,0 +1,115 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser
+
+ Description: Calculate tonality index
+
+*******************************************************************************/
+
+#ifndef TONALITY_H
+#define TONALITY_H
+
+#include "common_fix.h"
+#include "chaosmeasure.h"
+
+void FDKaacEnc_CalculateFullTonality(FIXP_DBL *RESTRICT spectrum,
+ INT *RESTRICT sfbMaxScaleSpec,
+ FIXP_DBL *RESTRICT sfbEnergyLD64,
+ FIXP_SGL *RESTRICT sfbTonality, INT sfbCnt,
+ const INT *sfbOffset, INT usePns);
+
+#endif /* TONALITY_H */
diff --git a/fdk-aac/libAACenc/src/transform.cpp b/fdk-aac/libAACenc/src/transform.cpp
new file mode 100644
index 0000000..08b1c2f
--- /dev/null
+++ b/fdk-aac/libAACenc/src/transform.cpp
@@ -0,0 +1,294 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): Tobias Chalupka
+
+ Description: FDKaacLdEnc_MdctTransform480:
+ The module FDKaacLdEnc_MdctTransform will perform the MDCT.
+ The MDCT supports the sine window and
+ the zero padded window. The algorithm of the MDCT
+ can be divided in Windowing, PreModulation, Fft and
+ PostModulation.
+
+*******************************************************************************/
+
+#include "transform.h"
+#include "dct.h"
+#include "psy_const.h"
+#include "aacEnc_rom.h"
+#include "FDK_tools_rom.h"
+
+#if defined(__arm__)
+#endif
+
+INT FDKaacEnc_Transform_Real(const INT_PCM *pTimeData,
+ FIXP_DBL *RESTRICT mdctData, const INT blockType,
+ const INT windowShape, INT *prevWindowShape,
+ H_MDCT mdctPers, const INT frameLength,
+ INT *pMdctData_e, INT filterType) {
+ const INT_PCM *RESTRICT timeData;
+
+ UINT numSpec;
+ UINT numMdctLines;
+ UINT offset;
+ int fr; /* fr: right window slope length */
+ SHORT mdctData_e[8];
+
+ timeData = pTimeData;
+
+ if (blockType == SHORT_WINDOW) {
+ numSpec = 8;
+ numMdctLines = frameLength >> 3;
+ } else {
+ numSpec = 1;
+ numMdctLines = frameLength;
+ }
+
+ offset = (windowShape == LOL_WINDOW) ? ((frameLength * 3) >> 2) : 0;
+ switch (blockType) {
+ case LONG_WINDOW:
+ case STOP_WINDOW:
+ fr = frameLength - offset;
+ break;
+ case START_WINDOW: /* or StopStartSequence */
+ case SHORT_WINDOW:
+ fr = frameLength >> 3;
+ break;
+ default:
+ FDK_ASSERT(0);
+ return -1;
+ }
+
+ mdct_block(mdctPers, timeData, frameLength, mdctData, numSpec, numMdctLines,
+ FDKgetWindowSlope(fr, windowShape), fr, mdctData_e);
+
+ if (blockType == SHORT_WINDOW) {
+ if (!(mdctData_e[0] == mdctData_e[1] && mdctData_e[1] == mdctData_e[2] &&
+ mdctData_e[2] == mdctData_e[3] && mdctData_e[3] == mdctData_e[4] &&
+ mdctData_e[4] == mdctData_e[5] && mdctData_e[5] == mdctData_e[6] &&
+ mdctData_e[6] == mdctData_e[7])) {
+ return -1;
+ }
+ }
+ *prevWindowShape = windowShape;
+ *pMdctData_e = mdctData_e[0];
+
+ return 0;
+}
+
+INT FDKaacEnc_Transform_Real_Eld(const INT_PCM *pTimeData,
+ FIXP_DBL *RESTRICT mdctData,
+ const INT blockType, const INT windowShape,
+ INT *prevWindowShape, const INT frameLength,
+ INT *mdctData_e, INT filterType,
+ FIXP_DBL *RESTRICT overlapAddBuffer) {
+ const INT_PCM *RESTRICT timeData;
+
+ INT i;
+
+ /* tl: transform length
+ fl: left window slope length
+ nl: left window slope offset
+ fr: right window slope length
+ nr: right window slope offset */
+ const FIXP_WTB *pWindowELD = NULL;
+ int N = frameLength;
+ int L = frameLength;
+
+ timeData = pTimeData;
+
+ if (blockType != LONG_WINDOW) {
+ return -1;
+ }
+
+ /*
+ * MDCT scale:
+ * + 1: fMultDiv2() in windowing.
+ * + 1: Because of factor 1/2 in Princen-Bradley compliant windowed TDAC.
+ */
+ *mdctData_e = 1 + 1;
+
+ switch (frameLength) {
+ case 512:
+ pWindowELD = ELDAnalysis512;
+ break;
+ case 480:
+ pWindowELD = ELDAnalysis480;
+ break;
+ case 256:
+ pWindowELD = ELDAnalysis256;
+ *mdctData_e += 1;
+ break;
+ case 240:
+ pWindowELD = ELDAnalysis240;
+ *mdctData_e += 1;
+ break;
+ case 128:
+ pWindowELD = ELDAnalysis128;
+ *mdctData_e += 2;
+ break;
+ case 120:
+ pWindowELD = ELDAnalysis120;
+ *mdctData_e += 2;
+ break;
+ default:
+ FDK_ASSERT(0);
+ return -1;
+ }
+
+ for (i = 0; i < N / 4; i++) {
+ FIXP_DBL z0, outval;
+
+ z0 = (fMult((FIXP_PCM)timeData[L + N * 3 / 4 - 1 - i],
+ pWindowELD[N / 2 - 1 - i])
+ << (WTS0 - 1)) +
+ (fMult((FIXP_PCM)timeData[L + N * 3 / 4 + i], pWindowELD[N / 2 + i])
+ << (WTS0 - 1));
+
+ outval = (fMultDiv2((FIXP_PCM)timeData[L + N * 3 / 4 - 1 - i],
+ pWindowELD[N + N / 2 - 1 - i]) >>
+ (-WTS1));
+ outval += (fMultDiv2((FIXP_PCM)timeData[L + N * 3 / 4 + i],
+ pWindowELD[N + N / 2 + i]) >>
+ (-WTS1));
+ outval += (fMultDiv2(overlapAddBuffer[N / 2 + i], pWindowELD[2 * N + i]) >>
+ (-WTS2 - 1));
+
+ overlapAddBuffer[N / 2 + i] = overlapAddBuffer[i];
+
+ overlapAddBuffer[i] = z0;
+ mdctData[i] = overlapAddBuffer[N / 2 + i] +
+ (fMultDiv2(overlapAddBuffer[N + N / 2 - 1 - i],
+ pWindowELD[2 * N + N / 2 + i]) >>
+ (-WTS2 - 1));
+
+ mdctData[N - 1 - i] = outval;
+ overlapAddBuffer[N + N / 2 - 1 - i] = outval;
+ }
+
+ for (i = N / 4; i < N / 2; i++) {
+ FIXP_DBL z0, outval;
+
+ z0 = fMult((FIXP_PCM)timeData[L + N * 3 / 4 - 1 - i],
+ pWindowELD[N / 2 - 1 - i])
+ << (WTS0 - 1);
+
+ outval = (fMultDiv2((FIXP_PCM)timeData[L + N * 3 / 4 - 1 - i],
+ pWindowELD[N + N / 2 - 1 - i]) >>
+ (-WTS1));
+ outval += (fMultDiv2(overlapAddBuffer[N / 2 + i], pWindowELD[2 * N + i]) >>
+ (-WTS2 - 1));
+
+ overlapAddBuffer[N / 2 + i] =
+ overlapAddBuffer[i] +
+ (fMult((FIXP_PCM)timeData[L - N / 4 + i], pWindowELD[N / 2 + i])
+ << (WTS0 - 1));
+
+ overlapAddBuffer[i] = z0;
+ mdctData[i] = overlapAddBuffer[N / 2 + i] +
+ (fMultDiv2(overlapAddBuffer[N + N / 2 - 1 - i],
+ pWindowELD[2 * N + N / 2 + i]) >>
+ (-WTS2 - 1));
+
+ mdctData[N - 1 - i] = outval;
+ overlapAddBuffer[N + N / 2 - 1 - i] = outval;
+ }
+ dct_IV(mdctData, frameLength, mdctData_e);
+
+ *prevWindowShape = windowShape;
+
+ return 0;
+}
diff --git a/fdk-aac/libAACenc/src/transform.h b/fdk-aac/libAACenc/src/transform.h
new file mode 100644
index 0000000..8f5ff46
--- /dev/null
+++ b/fdk-aac/libAACenc/src/transform.h
@@ -0,0 +1,163 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: MDCT Transform
+
+*******************************************************************************/
+
+#ifndef TRANSFORM_H
+#define TRANSFORM_H
+
+#include "mdct.h"
+#include "common_fix.h"
+
+#define WTS0 1
+#define WTS1 0
+#define WTS2 -2
+
+/**
+ * \brief: Performe MDCT transform of time domain data.
+ * \param timeData pointer to time domain input signal.
+ * \param mdctData pointer to store frequency domain output data.
+ * \param blockType index indicating the type of block. Either
+ * LONG_WINDOW, START_WINDOW, SHORT_WINDOW or STOP_WINDOW.
+ * \param windowShape index indicating the window slope type to be used.
+ * Values allowed are either SINE_WINDOW or KBD_WINDOW.
+ * \param previndowShape index indicating the window slope type used
+ * in the last frame.
+ * Values allowed are either SINE_WINDOW or KBD_WINDOW.
+ * \param frameLength length of the block. Either 1024 or 960.
+ * \param mdctData_e pointer to an INT where the exponent of the frequency
+ * domain output data is stored into.
+ * \param filterType xxx
+ * \return 0 in case of success, non-zero in case of error (inconsistent
+ * parameters).
+ */
+INT FDKaacEnc_Transform_Real(const INT_PCM* pTimeData,
+ FIXP_DBL* RESTRICT mdctData, const INT blockType,
+ const INT windowShape, INT* prevWindowShape,
+ H_MDCT mdctPers, const INT frameLength,
+ INT* pMdctData_e, INT filterType);
+
+/**
+ * \brief: Performe ELD filterbnank transform of time domain data.
+ * \param timeData pointer to time domain input signal.
+ * \param mdctData pointer to store frequency domain output data.
+ * \param blockType index indicating the type of block. Either
+ * LONG_WINDOW, START_WINDOW, SHORT_WINDOW or STOP_WINDOW.
+ * \param windowShape index indicating the window slope type to be used.
+ * Values allowed are either SINE_WINDOW or KBD_WINDOW.
+ * \param previndowShape index indicating the window slope type used
+ * in the last frame.
+ * Values allowed are either SINE_WINDOW or KBD_WINDOW.
+ * \param frameLength length of the block. Either 1024 or 960.
+ * \param mdctData_e pointer to an INT where the exponent of the frequency
+ * domain output data is stored into.
+ * \param filterType xxx
+ * \param overlapAddBuffer overlap add buffer for overlap of ELD filterbank
+ * \return 0 in case of success, non-zero in case of error (inconsistent
+ * parameters).
+ */
+INT FDKaacEnc_Transform_Real_Eld(const INT_PCM* pTimeData,
+ FIXP_DBL* RESTRICT mdctData,
+ const INT blockType, const INT windowShape,
+ INT* prevWindowShape, const INT frameLength,
+ INT* mdctData_e, INT filterType,
+ FIXP_DBL* RESTRICT overlapAddBuffer);
+
+#endif /* #!defined (TRANSFORM_H) */